diff options
author | Jakub Zawadzki <darkjames-ws@darkjames.pl> | 2012-06-19 12:12:41 +0000 |
---|---|---|
committer | Jakub Zawadzki <darkjames-ws@darkjames.pl> | 2012-06-19 12:12:41 +0000 |
commit | addf9236dc80679fb0701b3808f7d5264a9753dd (patch) | |
tree | 018fddc20b899c0af6a73b0bc39b2d10186f4867 | |
parent | 9ee8562c32dd4bf1968247e21460bce3fb3963a7 (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.c | 33 | ||||
-rw-r--r-- | epan/dfilter/drange.h | 1 | ||||
-rw-r--r-- | epan/dfilter/grammar.lemon | 21 | ||||
-rw-r--r-- | epan/dfilter/sttype-function.c | 17 | ||||
-rw-r--r-- | epan/dfilter/sttype-integer.c | 1 | ||||
-rw-r--r-- | epan/dfilter/sttype-pointer.c | 2 | ||||
-rw-r--r-- | epan/dfilter/sttype-range.c | 14 | ||||
-rw-r--r-- | epan/dfilter/sttype-string.c | 8 | ||||
-rw-r--r-- | epan/dfilter/sttype-test.c | 24 | ||||
-rw-r--r-- | epan/dfilter/syntax-tree.c | 24 | ||||
-rw-r--r-- | epan/dfilter/syntax-tree.h | 5 |
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); |