aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dfilter
diff options
context:
space:
mode:
authorJoão Valverde <j@v6e.pt>2022-04-04 11:33:38 +0100
committerJoão Valverde <j@v6e.pt>2022-04-05 12:04:37 +0100
commit20afbd46ecd4ffe954ea95240bf8862358fd7066 (patch)
treeffe6af1721e0e88fd18c74e45cf65520fef44c65 /epan/dfilter
parentfb08c4b4a809411d0da8397a5de7ff2923e103db (diff)
dfilter: Remove existence test syntax tree nodes
After some experimentation I don't think these two existence tests belong in the grammar, it's an implementation detail and removing it might avoid some artificial constraints.
Diffstat (limited to 'epan/dfilter')
-rw-r--r--epan/dfilter/gencode.c84
-rw-r--r--epan/dfilter/grammar.lemon6
-rw-r--r--epan/dfilter/semcheck.c17
-rw-r--r--epan/dfilter/sttype-test.c14
-rw-r--r--epan/dfilter/syntax-tree.h2
5 files changed, 55 insertions, 68 deletions
diff --git a/epan/dfilter/gencode.c b/epan/dfilter/gencode.c
index 2674417a10..d68ef697e2 100644
--- a/epan/dfilter/gencode.c
+++ b/epan/dfilter/gencode.c
@@ -430,6 +430,47 @@ gen_entity(dfwork_t *dfw, stnode_t *st_arg, GSList **jumps_ptr)
return val;
}
+static void
+gen_exists(dfwork_t *dfw, stnode_t *st_node)
+{
+ dfvm_insn_t *insn;
+ header_field_info *hfinfo;
+
+ hfinfo = stnode_data(st_node);
+
+ /* Rewind to find the first field of this name. */
+ while (hfinfo->same_name_prev_id != -1) {
+ hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id);
+ }
+ insn = dfvm_insn_new(CHECK_EXISTS);
+ insn->arg1 = dfvm_value_new_hfinfo(hfinfo);
+ dfw_append_insn(dfw, insn);
+
+ /* Record the FIELD_ID in hash of interesting fields. */
+ while (hfinfo) {
+ g_hash_table_insert(dfw->interesting_fields,
+ GINT_TO_POINTER(hfinfo->id),
+ GUINT_TO_POINTER(TRUE));
+ hfinfo = hfinfo->same_name_next;
+ }
+}
+
+static void
+gen_notzero(dfwork_t *dfw, stnode_t *st_node)
+{
+ dfvm_insn_t *insn;
+ dfvm_value_t *val1;
+ GSList *jumps = NULL;
+
+ val1 = gen_arithmetic(dfw, st_node, &jumps);
+ insn = dfvm_insn_new(ALL_ZERO);
+ insn->arg1 = dfvm_value_ref(val1);
+ dfw_append_insn(dfw, insn);
+ insn = dfvm_insn_new(NOT);
+ dfw_append_insn(dfw, insn);
+ g_slist_foreach(jumps, fixup_jumps, dfw);
+ g_slist_free(jumps);
+}
static void
gen_test(dfwork_t *dfw, stnode_t *st_node)
@@ -437,10 +478,8 @@ gen_test(dfwork_t *dfw, stnode_t *st_node)
test_op_t st_op;
stnode_t *st_arg1, *st_arg2;
dfvm_insn_t *insn;
- dfvm_value_t *jmp, *val1;
- GSList *jumps = NULL;
+ dfvm_value_t *jmp;
- header_field_info *hfinfo;
sttype_test_get(st_node, &st_op, &st_arg1, &st_arg2);
@@ -449,39 +488,6 @@ gen_test(dfwork_t *dfw, stnode_t *st_node)
ws_assert_not_reached();
break;
- case TEST_OP_EXISTS:
- hfinfo = stnode_data(st_arg1);
-
- /* Rewind to find the first field of this name. */
- while (hfinfo->same_name_prev_id != -1) {
- hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id);
- }
- insn = dfvm_insn_new(CHECK_EXISTS);
- insn->arg1 = dfvm_value_new_hfinfo(hfinfo);
- dfw_append_insn(dfw, insn);
-
- /* Record the FIELD_ID in hash of interesting fields. */
- while (hfinfo) {
- g_hash_table_insert(dfw->interesting_fields,
- GINT_TO_POINTER(hfinfo->id),
- GUINT_TO_POINTER(TRUE));
- hfinfo = hfinfo->same_name_next;
- }
-
- break;
-
- case TEST_OP_NOTZERO:
- val1 = gen_entity(dfw, st_arg1, &jumps);
- insn = dfvm_insn_new(ALL_ZERO);
- insn->arg1 = dfvm_value_ref(val1);
- dfw_append_insn(dfw, insn);
- insn = dfvm_insn_new(NOT);
- dfw_append_insn(dfw, insn);
- g_slist_foreach(jumps, fixup_jumps, dfw);
- g_slist_free(jumps);
- jumps = NULL;
- break;
-
case TEST_OP_NOT:
gencode(dfw, st_arg1);
insn = dfvm_insn_new(NOT);
@@ -575,6 +581,12 @@ gencode(dfwork_t *dfw, stnode_t *st_node)
case STTYPE_TEST:
gen_test(dfw, st_node);
break;
+ case STTYPE_FIELD:
+ gen_exists(dfw, st_node);
+ break;
+ case STTYPE_ARITHMETIC:
+ gen_notzero(dfw, st_node);
+ break;
default:
ws_assert_not_reached();
}
diff --git a/epan/dfilter/grammar.lemon b/epan/dfilter/grammar.lemon
index 78646f3dcc..7f6ac3857a 100644
--- a/epan/dfilter/grammar.lemon
+++ b/epan/dfilter/grammar.lemon
@@ -123,14 +123,12 @@ logical_test(T) ::= TEST_NOT(L) expr(E).
logical_test(T) ::= entity(E).
{
- T = new_test(dfw, TEST_OP_EXISTS, NULL);
- sttype_test_set1_args(T, E);
+ T = E;
}
logical_test(T) ::= arithmetic_term(E).
{
- T = new_test(dfw, TEST_OP_NOTZERO, NULL);
- sttype_test_set1_args(T, E);
+ T = E;
}
diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c
index ff176e179c..6798e9d457 100644
--- a/epan/dfilter/semcheck.c
+++ b/epan/dfilter/semcheck.c
@@ -470,6 +470,7 @@ check_exists(dfwork_t *dfw, stnode_t *st_arg1)
switch (stnode_type_id(st_arg1)) {
case STTYPE_FIELD:
+ case STTYPE_ARITHMETIC:
/* This is OK */
break;
case STTYPE_REFERENCE:
@@ -477,7 +478,6 @@ check_exists(dfwork_t *dfw, stnode_t *st_arg1)
case STTYPE_UNPARSED:
case STTYPE_LITERAL:
case STTYPE_CHARCONST:
- case STTYPE_ARITHMETIC:
FAIL(dfw, "%s is neither a field nor a protocol name.",
stnode_todisplay(st_arg1));
break;
@@ -1136,14 +1136,6 @@ check_test(dfwork_t *dfw, stnode_t *st_node)
ws_assert_not_reached();
break;
- case TEST_OP_EXISTS:
- check_exists(dfw, st_arg1);
- break;
-
- case TEST_OP_NOTZERO:
- check_arithmetic_operation(dfw, st_arg1, FT_NONE);
- break;
-
case TEST_OP_NOT:
semcheck(dfw, st_arg1);
break;
@@ -1316,14 +1308,15 @@ semcheck(dfwork_t *dfw, stnode_t *st_node)
{
LOG_NODE(st_node);
- /* The parser assures that the top-most syntax-tree
- * node will be a TEST node, no matter what. So assert that. */
switch (stnode_type_id(st_node)) {
case STTYPE_TEST:
check_test(dfw, st_node);
break;
+ case STTYPE_ARITHMETIC:
+ check_arithmetic_operation(dfw, st_node, FT_NONE);
+ break;
default:
- ws_assert_not_reached();
+ check_exists(dfw, st_node);
}
}
diff --git a/epan/dfilter/sttype-test.c b/epan/dfilter/sttype-test.c
index 9e08de8374..13c0040ee3 100644
--- a/epan/dfilter/sttype-test.c
+++ b/epan/dfilter/sttype-test.c
@@ -70,9 +70,6 @@ test_todisplay(test_op_t op)
const char *s = "<notset>";
switch(op) {
- case TEST_OP_EXISTS:
- s = "<exists>";
- break;
case TEST_OP_NOT:
s = "!";
break;
@@ -125,9 +122,6 @@ test_todisplay(test_op_t op)
case OP_MODULO:
s = "%";
break;
- case TEST_OP_NOTZERO:
- s = "<notzero>";
- break;
case TEST_OP_CONTAINS:
s = "contains";
break;
@@ -150,9 +144,6 @@ test_todebug(test_op_t op)
const char *s = "<notset>";
switch(op) {
- case TEST_OP_EXISTS:
- s = "TEST_EXISTS";
- break;
case TEST_OP_NOT:
s = "TEST_NOT";
break;
@@ -207,9 +198,6 @@ test_todebug(test_op_t op)
case OP_MODULO:
s = "OP_MODULO";
break;
- case TEST_OP_NOTZERO:
- s = "TEST_NOTZERO";
- break;
case TEST_OP_CONTAINS:
s = "TEST_CONTAINS";
break;
@@ -246,9 +234,7 @@ num_operands(test_op_t op)
switch(op) {
case TEST_OP_UNINITIALIZED:
break;
- case TEST_OP_EXISTS:
case TEST_OP_NOT:
- case TEST_OP_NOTZERO:
case OP_UNARY_MINUS:
return 1;
case TEST_OP_AND:
diff --git a/epan/dfilter/syntax-tree.h b/epan/dfilter/syntax-tree.h
index 3fa27841d1..d7bdce55d5 100644
--- a/epan/dfilter/syntax-tree.h
+++ b/epan/dfilter/syntax-tree.h
@@ -39,7 +39,6 @@ typedef enum {
typedef enum {
TEST_OP_UNINITIALIZED,
- TEST_OP_EXISTS,
TEST_OP_NOT,
TEST_OP_AND,
TEST_OP_OR,
@@ -58,7 +57,6 @@ typedef enum {
OP_MULTIPLY,
OP_DIVIDE,
OP_MODULO,
- TEST_OP_NOTZERO,
TEST_OP_CONTAINS,
TEST_OP_MATCHES,
TEST_OP_IN