aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Zawadzki <darkjames-ws@darkjames.pl>2012-06-19 12:12:41 +0000
committerJakub Zawadzki <darkjames-ws@darkjames.pl>2012-06-19 12:12:41 +0000
commitaddf9236dc80679fb0701b3808f7d5264a9753dd (patch)
tree018fddc20b899c0af6a73b0bc39b2d10186f4867
parent9ee8562c32dd4bf1968247e21460bce3fb3963a7 (diff)
Support multiple relation test without logic and (python-like)
Like: a == b == c or a < b <= c <= d < e Real life example: 6660 <= tcp.port <= 6669 Just syntactic sugar, this is *NOT* optimized. svn path=/trunk/; revision=43353
-rw-r--r--epan/dfilter/drange.c33
-rw-r--r--epan/dfilter/drange.h1
-rw-r--r--epan/dfilter/grammar.lemon21
-rw-r--r--epan/dfilter/sttype-function.c17
-rw-r--r--epan/dfilter/sttype-integer.c1
-rw-r--r--epan/dfilter/sttype-pointer.c2
-rw-r--r--epan/dfilter/sttype-range.c14
-rw-r--r--epan/dfilter/sttype-string.c8
-rw-r--r--epan/dfilter/sttype-test.c24
-rw-r--r--epan/dfilter/syntax-tree.c24
-rw-r--r--epan/dfilter/syntax-tree.h5
11 files changed, 147 insertions, 3 deletions
diff --git a/epan/dfilter/drange.c b/epan/dfilter/drange.c
index 531f4cb825..61ee50e527 100644
--- a/epan/dfilter/drange.c
+++ b/epan/dfilter/drange.c
@@ -43,6 +43,22 @@ drange_node_new(void)
return new_range_node;
}
+static drange_node*
+drange_node_dup(drange_node *org)
+{
+ drange_node *new_range_node;
+
+ if (!org)
+ return NULL;
+
+ new_range_node = g_new(drange_node,1);
+ new_range_node->start_offset = org->start_offset;
+ new_range_node->length = org->length;
+ new_range_node->end_offset = org->end_offset;
+ new_range_node->ending = org->ending;
+ return new_range_node;
+}
+
/* drange_node destructor */
void
drange_node_free(drange_node* drnode)
@@ -140,6 +156,23 @@ drange_new_from_list(GSList *list)
return new_drange;
}
+drange*
+drange_dup(drange *org)
+{
+ drange *new_drange;
+ GSList *p;
+
+ if (!org)
+ return NULL;
+
+ new_drange = drange_new();
+ for (p = org->range_list; p; p = p->next) {
+ drange_node *drnode = p->data;
+ drange_append_drange_node(new_drange, drange_node_dup(drnode));
+ }
+ return new_drange;
+}
+
static void
drange_node_free_wrapper(gpointer data, gpointer userdata _U_)
diff --git a/epan/dfilter/drange.h b/epan/dfilter/drange.h
index cededf01f4..ae78500e74 100644
--- a/epan/dfilter/drange.h
+++ b/epan/dfilter/drange.h
@@ -82,6 +82,7 @@ void drange_node_set_to_the_end(drange_node* drnode);
/* drange constructor */
drange* drange_new(void);
drange* drange_new_from_list(GSList *list);
+drange *drange_dup(drange *org);
/* drange destructor, only use this if you used drange_new() to creat
* the drange
diff --git a/epan/dfilter/grammar.lemon b/epan/dfilter/grammar.lemon
index c367f28a9f..a58b75406a 100644
--- a/epan/dfilter/grammar.lemon
+++ b/epan/dfilter/grammar.lemon
@@ -249,6 +249,27 @@ relation_test(T) ::= entity(E) rel_op2(O) entity(F).
sttype_test_set2(T, O, E, F);
}
+/* 'a == b == c' or 'a < b <= c <= d < e' */
+relation_test(T) ::= entity(E) rel_op2(O) relation_test(R).
+{
+ stnode_t *L, *F;
+ /* for now generate it like E O F TEST_OP_AND F P G, later it could be optimized
+ or semantically checked (to make a <= b >= c or a == b != c invalid)?
+ */
+
+ F = R;
+ do {
+ g_assert(F != NULL && stnode_type_id(F) == STTYPE_TEST);
+ sttype_test_get(F, NULL, &F, NULL);
+ } while (stnode_type_id(F) == STTYPE_TEST);
+
+ L = stnode_new(STTYPE_TEST, NULL);
+ sttype_test_set2(L, O, E, stnode_dup(F));
+
+ T = stnode_new(STTYPE_TEST, NULL);
+ sttype_test_set2(T, TEST_OP_AND, L, R);
+}
+
rel_op2(O) ::= TEST_EQ. { O = TEST_OP_EQ; }
rel_op2(O) ::= TEST_NE. { O = TEST_OP_NE; }
rel_op2(O) ::= TEST_GT. { O = TEST_OP_GT; }
diff --git a/epan/dfilter/sttype-function.c b/epan/dfilter/sttype-function.c
index 94dd383912..7924111f91 100644
--- a/epan/dfilter/sttype-function.c
+++ b/epan/dfilter/sttype-function.c
@@ -51,6 +51,22 @@ function_new(gpointer funcdef)
return (gpointer) stfuncrec;
}
+static gpointer
+function_dup(gconstpointer data)
+{
+ const function_t *org = data;
+ function_t *stfuncrec;
+ GSList *p;
+
+ stfuncrec = function_new(org->funcdef);
+
+ for (p = org->params; p; p = p->next) {
+ const stnode_t *param = p->data;
+ stfuncrec->params = g_slist_append(stfuncrec->params, stnode_dup(param));
+ }
+ return (gpointer) stfuncrec;
+}
+
static void
slist_stnode_free(gpointer data, gpointer user_data _U_)
{
@@ -118,6 +134,7 @@ sttype_register_function(void)
"FUNCTION",
function_new,
function_free,
+ function_dup
};
sttype_register(&function_type);
diff --git a/epan/dfilter/sttype-integer.c b/epan/dfilter/sttype-integer.c
index 63e1fd0340..4fc5df0ea1 100644
--- a/epan/dfilter/sttype-integer.c
+++ b/epan/dfilter/sttype-integer.c
@@ -36,6 +36,7 @@ sttype_register_integer(void)
"INTEGER",
NULL,
NULL,
+ NULL
};
sttype_register(&integer_type);
diff --git a/epan/dfilter/sttype-pointer.c b/epan/dfilter/sttype-pointer.c
index 650d444be3..107fd32301 100644
--- a/epan/dfilter/sttype-pointer.c
+++ b/epan/dfilter/sttype-pointer.c
@@ -36,12 +36,14 @@ sttype_register_pointer(void)
"FIELD",
NULL,
NULL,
+ NULL
};
static sttype_t fvalue_type = {
STTYPE_FVALUE,
"FVALUE",
NULL,
NULL,
+ NULL
};
sttype_register(&field_type);
diff --git a/epan/dfilter/sttype-range.c b/epan/dfilter/sttype-range.c
index 98d1930cb9..1bc7bfe00a 100644
--- a/epan/dfilter/sttype-range.c
+++ b/epan/dfilter/sttype-range.c
@@ -59,6 +59,19 @@ range_new(gpointer junk)
return (gpointer) range;
}
+static gpointer
+range_dup(gconstpointer data)
+{
+ const range_t *org = data;
+ range_t *range;
+
+ range = range_new(NULL);
+ range->hfinfo = org->hfinfo;
+ range->drange = drange_dup(org->drange);
+
+ return (gpointer) range;
+}
+
static void
range_free(gpointer value)
{
@@ -116,6 +129,7 @@ sttype_register_range(void)
"RANGE",
range_new,
range_free,
+ range_dup
};
sttype_register(&range_type);
diff --git a/epan/dfilter/sttype-string.c b/epan/dfilter/sttype-string.c
index 8b11a5671e..1106162caf 100644
--- a/epan/dfilter/sttype-string.c
+++ b/epan/dfilter/sttype-string.c
@@ -29,6 +29,12 @@ string_new(gpointer string)
return (gpointer) g_strdup((char*) string);
}
+static gpointer
+string_dup(gconstpointer string)
+{
+ return (gpointer) g_strdup((const char*) string);
+}
+
static void
string_free(gpointer value)
{
@@ -44,6 +50,7 @@ sttype_register_string(void)
"STRING",
string_new,
string_free,
+ string_dup
};
static sttype_t unparsed_type = {
@@ -51,6 +58,7 @@ sttype_register_string(void)
"UNPARSED",
string_new,
string_free,
+ string_dup
};
sttype_register(&string_type);
diff --git a/epan/dfilter/sttype-test.c b/epan/dfilter/sttype-test.c
index c9d3abfcde..91c0251ebc 100644
--- a/epan/dfilter/sttype-test.c
+++ b/epan/dfilter/sttype-test.c
@@ -50,6 +50,20 @@ test_new(gpointer junk)
return (gpointer) test;
}
+static gpointer
+test_dup(gconstpointer data)
+{
+ const test_t *org = data;
+ test_t *test;
+
+ test = test_new(NULL);
+ test->op = org->op;
+ test->val1 = stnode_dup(org->val1);
+ test->val2 = stnode_dup(org->val1);
+
+ return (gpointer) test;
+}
+
static void
test_free(gpointer value)
{
@@ -141,9 +155,12 @@ sttype_test_get(stnode_t *node, test_op_t *p_op, stnode_t **p_val1, stnode_t **p
test = (test_t*)stnode_data(node);
assert_magic(test, TEST_MAGIC);
- *p_op = test->op;
- *p_val1 = test->val1;
- *p_val2 = test->val2;
+ if (p_op)
+ *p_op = test->op;
+ if (p_val1)
+ *p_val1 = test->val1;
+ if (p_val2)
+ *p_val2 = test->val2;
}
void
@@ -154,6 +171,7 @@ sttype_register_test(void)
"TEST",
test_new,
test_free,
+ test_dup
};
sttype_register(&test_type);
diff --git a/epan/dfilter/syntax-tree.c b/epan/dfilter/syntax-tree.c
index 43ea095899..3c580b4d54 100644
--- a/epan/dfilter/syntax-tree.c
+++ b/epan/dfilter/syntax-tree.c
@@ -114,6 +114,30 @@ stnode_new(sttype_id_t type_id, gpointer data)
return node;
}
+stnode_t*
+stnode_dup(const stnode_t *org)
+{
+ sttype_t *type;
+ stnode_t *node;
+
+ if (!org)
+ return NULL;
+
+ type = org->type;
+
+ node = g_new(stnode_t, 1);
+ node->magic = STNODE_MAGIC;
+ node->deprecated_token = NULL;
+ node->type = type;
+ if (type && type->func_dup)
+ node->data = type->func_dup(org->data);
+ else
+ node->data = org->data;
+ node->value = org->value;
+
+ return node;
+}
+
void
stnode_init(stnode_t *node, sttype_id_t type_id, gpointer data)
{
diff --git a/epan/dfilter/syntax-tree.h b/epan/dfilter/syntax-tree.h
index 6318b02e8f..6abf654c36 100644
--- a/epan/dfilter/syntax-tree.h
+++ b/epan/dfilter/syntax-tree.h
@@ -43,6 +43,7 @@ typedef enum {
} sttype_id_t;
typedef gpointer (*STTypeNewFunc)(gpointer);
+typedef gpointer (*STTypeDupFunc)(gconstpointer);
typedef void (*STTypeFreeFunc)(gpointer);
@@ -52,6 +53,7 @@ typedef struct {
const char *name;
STTypeNewFunc func_new;
STTypeFreeFunc func_free;
+ STTypeDupFunc func_dup;
} sttype_t;
/** Node (type instance) information */
@@ -86,6 +88,9 @@ sttype_register(sttype_t *type);
stnode_t*
stnode_new(sttype_id_t type_id, gpointer data);
+stnode_t*
+stnode_dup(const stnode_t *org);
+
void
stnode_init(stnode_t *node, sttype_id_t type_id, gpointer data);