aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dfilter
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>2001-02-27 19:23:30 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>2001-02-27 19:23:30 +0000
commit2a50f8af4f18dab44ee5414aa2c47fef3ab18e9d (patch)
tree9fba9ac63ac5a5f60b1519bb9bcf76112e1fbd78 /epan/dfilter
parenta954a9d276678fb6ff357ffa7be0a1609415fc0d (diff)
Add Ed Warnicke's drange code to the new dfilter system.
Not supported yet: [i-j] (offset-offset) Supported: [i] index [i:j] offset:length [:j] 0:offset [i:] offset:end [x,y] concatenation of slices svn path=/trunk/; revision=3080
Diffstat (limited to 'epan/dfilter')
-rw-r--r--epan/dfilter/Makefile.am5
-rw-r--r--epan/dfilter/Makefile.nmake4
-rw-r--r--epan/dfilter/dfvm.c23
-rw-r--r--epan/dfilter/dfvm.h7
-rw-r--r--epan/dfilter/drange.c188
-rw-r--r--epan/dfilter/drange.h92
-rw-r--r--epan/dfilter/gencode.c10
-rw-r--r--epan/dfilter/grammar.lemon88
-rw-r--r--epan/dfilter/scanner.l71
-rw-r--r--epan/dfilter/semcheck.c306
-rw-r--r--epan/dfilter/sttype-integer.c42
-rw-r--r--epan/dfilter/sttype-range.c116
-rw-r--r--epan/dfilter/sttype-range.h20
-rw-r--r--epan/dfilter/syntax-tree.c23
-rw-r--r--epan/dfilter/syntax-tree.h14
15 files changed, 729 insertions, 280 deletions
diff --git a/epan/dfilter/Makefile.am b/epan/dfilter/Makefile.am
index 2b3ad99b68..9f34939e1c 100644
--- a/epan/dfilter/Makefile.am
+++ b/epan/dfilter/Makefile.am
@@ -1,6 +1,6 @@
# Makefile.am
#
-# $Id: Makefile.am,v 1.6 2001/02/26 23:56:59 guy Exp $
+# $Id: Makefile.am,v 1.7 2001/02/27 19:23:28 gram Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@@ -40,6 +40,8 @@ libdfilter_a_SOURCES = \
dfilter-int.h \
dfvm.c \
dfvm.h \
+ drange.c \
+ drange.h \
gencode.c \
gencode.h \
glib-util.c \
@@ -49,6 +51,7 @@ libdfilter_a_SOURCES = \
scanner.c \
semcheck.c \
semcheck.h \
+ sttype-integer.c \
sttype-pointer.c \
sttype-range.c \
sttype-range.h \
diff --git a/epan/dfilter/Makefile.nmake b/epan/dfilter/Makefile.nmake
index 2bc20038aa..cb4f7586b8 100644
--- a/epan/dfilter/Makefile.nmake
+++ b/epan/dfilter/Makefile.nmake
@@ -17,11 +17,13 @@ CFLAGS=/MT /DHAVE_CONFIG_H /I. /I.. /I..\.. /I$(LEMON) \
OBJECTS = \
dfilter.obj \
dfvm.obj \
+ drange.obj \
gencode.obj \
glib-util.obj \
grammar.obj \
scanner.obj \
semcheck.obj \
+ sttype-integer.obj \
sttype-pointer.obj \
sttype-range.obj \
sttype-string.obj \
@@ -36,8 +38,6 @@ dfilter.lib : $(OBJECTS)
clean:
rm -f $(OBJECTS) scanner.c grammar.c grammar.h grammar.out dfilter.lib
-
-
scanner.c : scanner.l
$(LEX) -Pdf_ -oscanner.c scanner.l
diff --git a/epan/dfilter/dfvm.c b/epan/dfilter/dfvm.c
index b5c4e40453..6f2f2b9942 100644
--- a/epan/dfilter/dfvm.c
+++ b/epan/dfilter/dfvm.c
@@ -1,5 +1,5 @@
/*
- * $Id: dfvm.c,v 1.2 2001/02/01 20:31:18 gram Exp $
+ * $Id: dfvm.c,v 1.3 2001/02/27 19:23:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -37,7 +37,6 @@ dfvm_insn_new(dfvm_opcode_t op)
insn->arg1 = NULL;
insn->arg2 = NULL;
insn->arg3 = NULL;
- insn->arg4 = NULL;
return insn;
}
@@ -53,9 +52,6 @@ dfvm_insn_free(dfvm_insn_t *insn)
if (insn->arg3) {
dfvm_value_free(insn->arg3);
}
- if (insn->arg4) {
- dfvm_value_free(insn->arg4);
- }
g_free(insn);
}
@@ -78,6 +74,9 @@ dfvm_value_free(dfvm_value_t *v)
case FVALUE:
fvalue_free(v->value.fvalue);
break;
+ case DRANGE:
+ drange_free(v->value.drange);
+ break;
default:
/* nothing */
;
@@ -125,11 +124,9 @@ dfvm_dump(FILE *f, GPtrArray *insns)
break;
case MK_RANGE:
- fprintf(f, "%05d MK_RANGE\t\treg#%d[%d:%d] -> reg#%d\n",
+ fprintf(f, "%05d MK_RANGE\t\treg#%d[?] -> reg#%d\n",
id,
arg1->value.numeric,
- arg3->value.numeric,
- arg4->value.numeric,
arg2->value.numeric);
break;
@@ -275,7 +272,7 @@ free_register_overhead(dfilter_t* df)
* to make a new list of fvalue_t's (which are ranges, or byte-slices),
* and puts the new list into a new register. */
static void
-mk_range(dfilter_t *df, int from_reg, int to_reg, int start, int end)
+mk_range(dfilter_t *df, int from_reg, int to_reg, drange *drange)
{
GList *from_list, *to_list;
fvalue_t *old_fv, *new_fv;
@@ -285,8 +282,8 @@ mk_range(dfilter_t *df, int from_reg, int to_reg, int start, int end)
while (from_list) {
old_fv = from_list->data;
- new_fv = fvalue_slice(old_fv, start, end);
- /* Assert there because semcheck.c should have
+ new_fv = fvalue_slice(old_fv, drange);
+ /* Assert here because semcheck.c should have
* already caught the cases in which a slice
* cannot be made. */
g_assert(new_fv);
@@ -309,7 +306,6 @@ dfvm_apply(dfilter_t *df, tvbuff_t *tvb, proto_tree *tree)
dfvm_value_t *arg1;
dfvm_value_t *arg2;
dfvm_value_t *arg3;
- dfvm_value_t *arg4;
g_assert(tvb);
g_assert(tree);
@@ -348,10 +344,9 @@ dfvm_apply(dfilter_t *df, tvbuff_t *tvb, proto_tree *tree)
case MK_RANGE:
arg3 = insn->arg3;
- arg4 = insn->arg4;
mk_range(df,
arg1->value.numeric, arg2->value.numeric,
- arg3->value.numeric, arg4->value.numeric);
+ arg3->value.drange);
break;
case ANY_EQ:
diff --git a/epan/dfilter/dfvm.h b/epan/dfilter/dfvm.h
index 7af61fe8c4..c4b00c655c 100644
--- a/epan/dfilter/dfvm.h
+++ b/epan/dfilter/dfvm.h
@@ -1,5 +1,5 @@
/*
- * $Id: dfvm.h,v 1.2 2001/02/01 20:31:18 gram Exp $
+ * $Id: dfvm.h,v 1.3 2001/02/27 19:23:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -28,6 +28,7 @@
#include "proto.h"
#include "dfilter-int.h"
#include "syntax-tree.h"
+#include "drange.h"
typedef enum {
EMPTY,
@@ -35,7 +36,8 @@ typedef enum {
FIELD_ID,
INSN_NUMBER,
REGISTER,
- INTEGER
+ INTEGER,
+ DRANGE
} dfvm_value_type_t;
typedef struct {
@@ -44,6 +46,7 @@ typedef struct {
union {
fvalue_t *fvalue;
guint32 numeric;
+ drange *drange;
} value;
} dfvm_value_t;
diff --git a/epan/dfilter/drange.c b/epan/dfilter/drange.c
new file mode 100644
index 0000000000..f0cedfe22e
--- /dev/null
+++ b/epan/dfilter/drange.c
@@ -0,0 +1,188 @@
+/* drange.c
+ * Routines for providing general range support to the dfilter library
+ *
+ * $Id: drange.c,v 1.1 2001/02/27 19:23:28 gram Exp $
+ *
+ * Copyright (c) 2000 by Ed Warnicke <hagbard@physics.rutgers.edu>
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs
+ * Copyright 1999 Gerald Combs
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "drange.h"
+
+/* drange_node constructor */
+drange_node*
+drange_node_new(void)
+{
+ drange_node* new_range_node;
+
+ new_range_node = g_malloc(sizeof(drange_node));
+ new_range_node->offset = 0;
+ new_range_node->length = 0;
+ new_range_node->to_the_end = FALSE;
+ return new_range_node;
+}
+
+/* drange_node destructor */
+void
+drange_node_free(drange_node* drnode)
+{
+ g_free(drnode);
+}
+
+/* drange_node accessors */
+gint
+drange_node_get_offset(drange_node* drnode)
+{
+ return drnode->offset;
+}
+
+gint
+drange_node_get_length(drange_node* drnode)
+{
+ return drnode->length;
+}
+
+gboolean
+drange_node_get_to_the_end(drange_node* drnode)
+{
+ return drnode->to_the_end;
+}
+
+/* drange_node mutators */
+void
+drange_node_set_offset(drange_node* drnode, gint offset)
+{
+ drnode->offset = offset;
+}
+
+void
+drange_node_set_length(drange_node* drnode, gint length)
+{
+ drnode->length = length;
+ drnode->to_the_end = FALSE;
+}
+
+void
+drange_node_set_to_the_end(drange_node* drnode, gboolean to_the_end)
+{
+ drnode->to_the_end = to_the_end;
+}
+
+/* drange constructor */
+drange*
+drange_new(void)
+{
+ drange* new_drange;
+ new_drange = g_malloc(sizeof(drange));
+ new_drange->range_list = NULL;
+ new_drange->has_total_length = TRUE;
+ new_drange->total_length = 0;
+ new_drange->min_offset = G_MAXINT;
+ new_drange->max_offset = G_MININT;
+ return new_drange;
+}
+
+static void
+drange_append_wrapper(gpointer data, gpointer user_data)
+{
+ drange_node *drnode = data;
+ drange *dr = user_data;
+
+ drange_append_drange_node(dr, drnode);
+}
+
+drange*
+drange_new_from_list(GSList *list)
+{
+ drange *new_drange;
+
+ new_drange = drange_new();
+ g_slist_foreach(list, drange_append_wrapper, new_drange);
+ return new_drange;
+}
+
+
+static void
+drange_node_free_wrapper(gpointer data, gpointer userdata)
+{
+ g_free(data);
+}
+
+/* drange destructor */
+void
+drange_free(drange* dr)
+{
+ drange_node_free_list(dr->range_list);
+ g_free(dr);
+}
+
+/* Call drange_node destructor on all list items */
+void
+drange_node_free_list(GSList* list)
+{
+ g_slist_foreach(list, drange_node_free_wrapper, NULL);
+}
+
+/* drange accessors */
+gboolean drange_has_total_length(drange* dr){ return dr->has_total_length; }
+gint drange_get_total_length(drange* dr) { return dr->total_length; }
+gint drange_get_min_offset(drange* dr) { return dr->min_offset; }
+gint drange_get_max_offset(drange* dr) { return dr->max_offset; }
+
+static void
+update_drange_with_node(drange *dr, drange_node *drnode)
+{
+ if(drnode->to_the_end){
+ dr->has_total_length = FALSE;
+ }
+ else if(dr->has_total_length){
+ dr->total_length += drnode->length;
+ }
+ if(drnode->offset < dr->min_offset){
+ dr->min_offset = drnode->offset;
+ }
+ if(drnode->offset > dr->max_offset){
+ dr->max_offset = drnode->offset;
+ }
+}
+
+/* drange mutators */
+void
+drange_prepend_drange_node(drange* dr, drange_node* drnode)
+{
+ if(drnode != NULL){
+ dr->range_list = g_slist_prepend(dr->range_list,drnode);
+ update_drange_with_node(dr, drnode);
+ }
+}
+
+void
+drange_append_drange_node(drange* dr, drange_node* drnode)
+{
+ if(drnode != NULL){
+ dr->range_list = g_slist_append(dr->range_list,drnode);
+ update_drange_with_node(dr, drnode);
+ }
+}
+
+void
+drange_foreach_drange_node(drange* dr, GFunc func, gpointer funcdata)
+{
+ g_slist_foreach(dr->range_list,func,funcdata);
+}
diff --git a/epan/dfilter/drange.h b/epan/dfilter/drange.h
new file mode 100644
index 0000000000..f02684c476
--- /dev/null
+++ b/epan/dfilter/drange.h
@@ -0,0 +1,92 @@
+/* drange.h
+ * Routines for providing general range support to the dfilter library
+ *
+ * $Id: drange.h,v 1.1 2001/02/27 19:23:28 gram Exp $
+ *
+ * Copyright (c) 2000 by Ed Warnicke <hagbard@physics.rutgers.edu>
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs
+ * Copyright 1999 Gerald Combs
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __DRANGE_H__
+#define __DRANGE_H__
+
+#include <glib.h>
+
+/* Please don't directly manipulate these structs. Please use
+ * the methods provided. If you REALLY can't do what you need to
+ * do with the methods provided please write new methods that do
+ * what you need, put them into the drange object here, and limit
+ * your direct manipulation of the drange and drange_node structs to
+ * here.
+ */
+
+typedef struct _drange_node {
+ gint offset;
+ gint length;
+ gboolean to_the_end;
+} drange_node;
+
+typedef struct _drange {
+ GSList* range_list;
+ gboolean has_total_length;
+ gint total_length;
+ gint min_offset;
+ gint max_offset;
+} drange;
+
+/* drange_node constructor */
+drange_node* drange_node_new();
+
+/* drange_node destructor */
+void drange_node_free(drange_node* drnode);
+
+/* Call drange_node destructor on all list items */
+void drange_node_free_list(GSList* list);
+
+/* drange_node accessors */
+gint drange_node_get_offset(drange_node* drnode);
+gint drange_node_get_length(drange_node* drnode);
+gboolean drange_node_get_to_the_end(drange_node* drnode);
+
+/* drange_node mutators */
+void drange_node_set_offset(drange_node* drnode, gint offset);
+void drange_node_set_length(drange_node* drnode, gint length);
+void drange_node_set_to_the_end(drange_node* drnode, gboolean to_the_end);
+
+/* drange constructor */
+drange* drange_new();
+drange* drange_new_from_list(GSList *list);
+
+/* drange destructor, only use this if you used drange_new() to creat
+ * the drange
+ */
+void drange_free(drange* dr);
+
+/* drange accessors */
+gboolean drange_has_total_length(drange* dr);
+gint drange_get_total_length(drange* dr);
+gint drange_get_min_offset(drange* dr);
+gint drange_get_max_offset(drange* dr);
+
+/* drange mutators */
+void drange_append_drange_node(drange* dr, drange_node* drnode);
+void drange_prepend_drange_node(drange* dr, drange_node* drnode);
+void drange_foreach_drange_node(drange* dr, GFunc func, gpointer funcdata);
+
+#endif /* ! __DRANGE_H__ */
diff --git a/epan/dfilter/gencode.c b/epan/dfilter/gencode.c
index 7c2ab1224d..cf3e1d5787 100644
--- a/epan/dfilter/gencode.c
+++ b/epan/dfilter/gencode.c
@@ -1,5 +1,5 @@
/*
- * $Id: gencode.c,v 1.2 2001/02/11 03:12:46 gram Exp $
+ * $Id: gencode.c,v 1.3 2001/02/27 19:23:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -129,13 +129,11 @@ dfw_append_mk_range(dfwork_t *dfw, stnode_t *node)
val->value.numeric = reg;
insn->arg2 = val;
- val = dfvm_value_new(INTEGER);
- val->value.numeric = sttype_range_start(node);
+ val = dfvm_value_new(DRANGE);
+ val->value.drange = sttype_range_drange(node);
insn->arg3 = val;
- val = dfvm_value_new(INTEGER);
- val->value.numeric = sttype_range_end(node);
- insn->arg4 = val;
+ sttype_range_remove_drange(node);
dfw_append_insn(dfw, insn);
diff --git a/epan/dfilter/grammar.lemon b/epan/dfilter/grammar.lemon
index 8072458ab7..b6001789cd 100644
--- a/epan/dfilter/grammar.lemon
+++ b/epan/dfilter/grammar.lemon
@@ -1,4 +1,4 @@
-/* $Id: grammar.lemon,v 1.1 2001/02/01 20:21:18 gram Exp $ */
+/* $Id: grammar.lemon,v 1.2 2001/02/27 19:23:28 gram Exp $ */
%include {
#ifdef HAVE_CONFIG_H
@@ -9,6 +9,7 @@
#include "syntax-tree.h"
#include "sttype-range.h"
#include "sttype-test.h"
+#include "drange.h"
/*extern char *df_text;*/
@@ -44,6 +45,12 @@
%type range {stnode_t*}
%destructor range {stnode_free($$);}
+%type drnode {drange_node*}
+%destructor drnode {drange_node_free($$);}
+
+%type drnode_list {GSList*}
+%destructor drnode_list {drange_node_free_list($$);}
+
/* This is called as soon as a syntax error happens. After that,
any "error" symbols are shifted, if possible. */
%syntax_error {
@@ -66,6 +73,10 @@ any "error" symbols are shifted, if possible. */
dfilter_fail("The string \"%s\" was unexpected in this context.",
stnode_data(TOKEN));
break;
+ case STTYPE_INTEGER:
+ dfilter_fail("The integer %u was unexpected in this context.",
+ stnode_value(TOKEN));
+ break;
case STTYPE_FIELD:
hfinfo = stnode_data(TOKEN);
dfilter_fail("Syntax error near \"%s\".", hfinfo->abbrev);
@@ -143,29 +154,82 @@ entity(E) ::= FIELD(F). { E = F; }
entity(E) ::= STRING(S). { E = S; }
entity(E) ::= range(R). { E = R; }
-range(R) ::= FIELD(F) LBRACKET STRING(X) COLON STRING(Y) RBRACKET.
+
+/* Ranges */
+range(R) ::= FIELD(F) LBRACKET drnode_list(L) RBRACKET.
{
R = stnode_new(STTYPE_RANGE, NULL);
- sttype_range_set(R, F, X, Y);
+ sttype_range_set(R, F, L);
+
+ /* Delete the list, but not the drange_nodes that
+ * the list contains. */
+ g_slist_free(L);
}
-range(R) ::= FIELD(F) LBRACKET STRING(X) COLON RBRACKET.
+drnode_list(L) ::= drnode(D).
{
- R = stnode_new(STTYPE_RANGE, NULL);
- sttype_range_set(R, F, X, NULL);
+ L = g_slist_append(NULL, D);
}
-range(R) ::= FIELD(F) LBRACKET COLON STRING(Y) RBRACKET.
+drnode_list(L) ::= drnode_list(P) COMMA drnode(D).
{
- R = stnode_new(STTYPE_RANGE, NULL);
- sttype_range_set(R, F, NULL, Y);
+ L = g_slist_append(P, D);
}
-range(R) ::= FIELD(F) LBRACKET STRING(Y) RBRACKET.
+/* x:y is offset:length */
+drnode(D) ::= INTEGER(X) COLON INTEGER(Y).
{
- R = stnode_new(STTYPE_RANGE, NULL);
- sttype_range_set1(R, F, Y);
+ D = drange_node_new();
+ drange_node_set_offset(D, stnode_value(X));
+ drange_node_set_length(D, stnode_value(Y));
+
+ stnode_free(X);
+ stnode_free(Y);
+}
+
+/* x,y == offset:(offset-1)
+drnode(D) ::= INTEGER(X) HYPHEN INTEGER(Y).
+{
+ D = drange_node_new();
+ drange_node_set_offset(D, stnode_value(X));
+ drange_node_set_length(D, stnode_value(Y));
+
+ stnode_free(X);
+ stnode_free(Y);
}
+*/
+
+/* :y == from start to offset */
+drnode(D) ::= COLON INTEGER(Y).
+{
+ D = drange_node_new();
+ drange_node_set_offset(D, 0);
+ drange_node_set_length(D, stnode_value(Y));
+
+ stnode_free(Y);
+}
+
+/* x: from offset to end */
+drnode(D) ::= INTEGER(X) COLON.
+{
+ D = drange_node_new();
+ drange_node_set_offset(D, stnode_value(X));
+ drange_node_set_to_the_end(D, TRUE);
+
+ stnode_free(X);
+}
+
+/* x == x:1 */
+drnode(D) ::= INTEGER(X).
+{
+ D = drange_node_new();
+ drange_node_set_offset(D, stnode_value(X));
+ drange_node_set_length(D, 1);
+
+ stnode_free(X);
+}
+
+
/* Relational tests */
relation_test(T) ::= entity(E) rel_op2(O) entity(F).
diff --git a/epan/dfilter/scanner.l b/epan/dfilter/scanner.l
index 43bcba55c7..71c5cc0a80 100644
--- a/epan/dfilter/scanner.l
+++ b/epan/dfilter/scanner.l
@@ -1,6 +1,6 @@
%{
/*
- * $Id: scanner.l,v 1.2 2001/02/01 20:31:18 gram Exp $
+ * $Id: scanner.l,v 1.3 2001/02/27 19:23:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -26,6 +26,9 @@
#include "config.h"
#endif
+#include <stdlib.h>
+#include <errno.h>
+
#include "glib-util.h"
#include "dfilter-int.h"
#include "syntax-tree.h"
@@ -40,8 +43,10 @@
/*#undef YY_NO_UNPUT*/
-int set_lval(int token, gpointer data);
-int simple(int token);
+static int set_lval(int token, gpointer data);
+static int set_lval_int(int token, char *s);
+static int simple(int token);
+static gboolean str_to_guint32(char *s, guint32* pint);
%}
@@ -88,12 +93,13 @@ VARCHARS [[:alnum:]_]
}
<RANGE>[+-]?[[:digit:]]+ {
- return set_lval(TOKEN_STRING, g_strdup(yytext));
+ return set_lval_int(TOKEN_INTEGER, yytext);
}
<RANGE>[+-]?0x[[:xdigit:]]+ {
- return set_lval(TOKEN_STRING, g_strdup(yytext));
+ return set_lval_int(TOKEN_INTEGER, yytext);
}
<RANGE>":" return simple(TOKEN_COLON);
+<RANGE>"," return simple(TOKEN_COMMA);
<RANGE>"]" {
BEGIN(INITIAL);
@@ -126,7 +132,7 @@ VARCHARS [[:alnum:]_]
%%
-int
+static int
simple(int token)
{
switch (token) {
@@ -135,6 +141,7 @@ simple(int token)
case TOKEN_LBRACKET:
case TOKEN_RBRACKET:
case TOKEN_COLON:
+ case TOKEN_COMMA:
case TOKEN_TEST_EQ:
case TOKEN_TEST_NE:
case TOKEN_TEST_GT:
@@ -151,7 +158,7 @@ simple(int token)
return token;
}
-int
+static int
set_lval(int token, gpointer data)
{
sttype_id_t type_id = STTYPE_UNINITIALIZED;
@@ -171,4 +178,54 @@ set_lval(int token, gpointer data)
return token;
}
+static int
+set_lval_int(int token, char *s)
+{
+ sttype_id_t type_id = STTYPE_UNINITIALIZED;
+ guint32 val;
+
+ if (!str_to_guint32(s, &val)) {
+ return 0;
+ }
+
+ switch (token) {
+ case TOKEN_INTEGER:
+ type_id = STTYPE_INTEGER;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ stnode_init_int(df_lval, type_id, val);
+ return token;
+}
+
+
+static gboolean
+str_to_guint32(char *s, guint32* pint)
+{
+ char *endptr;
+ guint32 integer;
+
+ integer = strtoul(s, &endptr, 0);
+
+ if (endptr == s || *endptr != '\0') {
+ /* This isn't a valid number. */
+ dfilter_fail("\"%s\" is not a valid number.", s);
+ return FALSE;
+ }
+ if (errno == ERANGE) {
+ if (integer == ULONG_MAX) {
+ dfilter_fail("\"%s\" causes an integer overflow.", s);
+ }
+ else {
+ dfilter_fail("\"%s\" is not an integer.", s);
+ }
+ return FALSE;
+ }
+
+ *pint = integer;
+ return TRUE;
+}
+
#include <lemonflex-tail.inc>
diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c
index 24096ec694..ba272ff660 100644
--- a/epan/dfilter/semcheck.c
+++ b/epan/dfilter/semcheck.c
@@ -1,5 +1,5 @@
/*
- * $Id: semcheck.c,v 1.2 2001/02/01 20:31:18 gram Exp $
+ * $Id: semcheck.c,v 1.3 2001/02/27 19:23:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -240,9 +240,8 @@ is_bytes_type(enum ftenum type)
return FALSE;
}
-/* This could really be split up... it's too big. */
static void
-check_relation(dfwork_t *dfw, FtypeCanFunc can_func, stnode_t *st_node,
+check_relation_LHS_FIELD(dfwork_t *dfw, FtypeCanFunc can_func, stnode_t *st_node,
stnode_t *st_arg1, stnode_t *st_arg2)
{
stnode_t *new_st;
@@ -251,169 +250,224 @@ check_relation(dfwork_t *dfw, FtypeCanFunc can_func, stnode_t *st_node,
ftenum_t ftype1, ftype2;
fvalue_t *fvalue;
char *s;
+ drange_node *rn;
type1 = stnode_type_id(st_arg1);
type2 = stnode_type_id(st_arg2);
- if (type1 == STTYPE_FIELD) {
- hfinfo1 = stnode_data(st_arg1);
- ftype1 = hfinfo1->type;
- if (!can_func(ftype1)) {
- dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
- hfinfo1->abbrev, ftype_pretty_name(ftype1));
- THROW(TypeError);
- }
+ hfinfo1 = stnode_data(st_arg1);
+ ftype1 = hfinfo1->type;
+ if (!can_func(ftype1)) {
+ dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
+ hfinfo1->abbrev, ftype_pretty_name(ftype1));
+ THROW(TypeError);
+ }
- if (type2 == STTYPE_FIELD) {
- hfinfo2 = stnode_data(st_arg2);
- ftype2 = hfinfo2->type;
- if (!compatible_ftypes(ftype1, ftype2)) {
- dfilter_fail("%s and %s are not of compatible types.",
- hfinfo1->abbrev, hfinfo2->abbrev);
- THROW(TypeError);
- }
- /* Do this check even though you'd think that if
- * they're compatible, then can_func() would pass. */
- if (!can_func(ftype2)) {
- dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
- hfinfo2->abbrev, ftype_pretty_name(ftype2));
- THROW(TypeError);
- }
- }
- else if (type2 == STTYPE_STRING) {
- s = stnode_data(st_arg2);
- fvalue = fvalue_from_string(ftype1, s, dfilter_fail);
- if (!fvalue) {
- /* check value_string */
- fvalue = mk_fvalue_from_val_string(hfinfo1, s);
- if (!fvalue) {
- THROW(TypeError);
- }
- }
+ if (type2 == STTYPE_FIELD) {
+ hfinfo2 = stnode_data(st_arg2);
+ ftype2 = hfinfo2->type;
- new_st = stnode_new(STTYPE_FVALUE, fvalue);
- sttype_test_set2_args(st_node, st_arg1, new_st);
- stnode_free(st_arg2);
- }
- else if (type2 == STTYPE_RANGE) {
- if (!is_bytes_type(ftype1)) {
- if (!ftype_can_slice(ftype1)) {
- dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
- hfinfo1->abbrev,
- ftype_pretty_name(ftype1));
- THROW(TypeError);
- }
-
- /* Convert entire field to bytes */
- new_st = stnode_new(STTYPE_RANGE, NULL);
-
- /* st_arg1 is freed in this step */
- sttype_range_set(new_st, st_arg1, NULL, NULL);
-
- sttype_test_set2_args(st_node, new_st, st_arg2);
- }
+ if (!compatible_ftypes(ftype1, ftype2)) {
+ dfilter_fail("%s and %s are not of compatible types.",
+ hfinfo1->abbrev, hfinfo2->abbrev);
+ THROW(TypeError);
}
- else {
- g_assert_not_reached();
+ /* Do this check even though you'd think that if
+ * they're compatible, then can_func() would pass. */
+ if (!can_func(ftype2)) {
+ dfilter_fail("%s (type=%s) cannot participate in specified comparison.",
+ hfinfo2->abbrev, ftype_pretty_name(ftype2));
+ THROW(TypeError);
}
}
- else if (type1 == STTYPE_STRING) {
-
- if (type2 == STTYPE_FIELD) {
- hfinfo2 = stnode_data(st_arg2);
- ftype2 = hfinfo2->type;
-
- s = stnode_data(st_arg1);
- fvalue = fvalue_from_string(ftype2, s, dfilter_fail);
+ else if (type2 == STTYPE_STRING) {
+ s = stnode_data(st_arg2);
+ fvalue = fvalue_from_string(ftype1, s, dfilter_fail);
+ if (!fvalue) {
+ /* check value_string */
+ fvalue = mk_fvalue_from_val_string(hfinfo1, s);
if (!fvalue) {
- /* check value_string */
- fvalue = mk_fvalue_from_val_string(hfinfo2, s);
- if (!fvalue) {
- THROW(TypeError);
- }
+ THROW(TypeError);
+ }
+ }
+
+ new_st = stnode_new(STTYPE_FVALUE, fvalue);
+ sttype_test_set2_args(st_node, st_arg1, new_st);
+ stnode_free(st_arg2);
+ }
+ else if (type2 == STTYPE_RANGE) {
+ if (!is_bytes_type(ftype1)) {
+ if (!ftype_can_slice(ftype1)) {
+ dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
+ hfinfo1->abbrev,
+ ftype_pretty_name(ftype1));
+ THROW(TypeError);
}
- new_st = stnode_new(STTYPE_FVALUE, fvalue);
+ /* Convert entire field to bytes */
+ new_st = stnode_new(STTYPE_RANGE, NULL);
+
+ rn = drange_node_new();
+ drange_node_set_offset(rn, 0);
+ drange_node_set_to_the_end(rn, TRUE);
+ /* st_arg1 is freed in this step */
+ sttype_range_set1(new_st, st_arg1, rn);
+
sttype_test_set2_args(st_node, new_st, st_arg2);
- stnode_free(st_arg1);
- }
- else if (type2 == STTYPE_STRING) {
- /* Well now that's silly... */
- dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.",
- stnode_data(st_arg1),
- stnode_data(st_arg2));
- THROW(TypeError);
}
- else if (type2 == STTYPE_RANGE) {
- s = stnode_data(st_arg1);
- fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
+ }
+ else {
+ g_assert_not_reached();
+ }
+}
+
+static void
+check_relation_LHS_STRING(dfwork_t *dfw, FtypeCanFunc can_func, stnode_t *st_node,
+ stnode_t *st_arg1, stnode_t *st_arg2)
+{
+ stnode_t *new_st;
+ sttype_id_t type1, type2;
+ header_field_info *hfinfo2;
+ ftenum_t ftype2;
+ fvalue_t *fvalue;
+ char *s;
+
+ type1 = stnode_type_id(st_arg1);
+ type2 = stnode_type_id(st_arg2);
+
+ if (type2 == STTYPE_FIELD) {
+ hfinfo2 = stnode_data(st_arg2);
+ ftype2 = hfinfo2->type;
+
+ s = stnode_data(st_arg1);
+ fvalue = fvalue_from_string(ftype2, s, dfilter_fail);
+ if (!fvalue) {
+ /* check value_string */
+ fvalue = mk_fvalue_from_val_string(hfinfo2, s);
if (!fvalue) {
THROW(TypeError);
}
- new_st = stnode_new(STTYPE_FVALUE, fvalue);
- sttype_test_set2_args(st_node, new_st, st_arg2);
- stnode_free(st_arg1);
}
- else {
- g_assert_not_reached();
- }
- }
- else if (type1 == STTYPE_RANGE) {
- hfinfo1 = sttype_range_hfinfo(st_arg1);
- ftype1 = hfinfo1->type;
- if (!ftype_can_slice(ftype1)) {
- dfilter_fail("\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
- hfinfo1->abbrev, ftype_pretty_name(ftype1));
+ new_st = stnode_new(STTYPE_FVALUE, fvalue);
+ sttype_test_set2_args(st_node, new_st, st_arg2);
+ stnode_free(st_arg1);
+ }
+ else if (type2 == STTYPE_STRING) {
+ /* Well now that's silly... */
+ dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.",
+ stnode_data(st_arg1),
+ stnode_data(st_arg2));
+ THROW(TypeError);
+ }
+ else if (type2 == STTYPE_RANGE) {
+ s = stnode_data(st_arg1);
+ fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
+ if (!fvalue) {
THROW(TypeError);
}
+ new_st = stnode_new(STTYPE_FVALUE, fvalue);
+ sttype_test_set2_args(st_node, new_st, st_arg2);
+ stnode_free(st_arg1);
+ }
+ else {
+ g_assert_not_reached();
+ }
+}
+static void
+check_relation_LHS_RANGE(dfwork_t *dfw, FtypeCanFunc can_func, stnode_t *st_node,
+ stnode_t *st_arg1, stnode_t *st_arg2)
+{
+ stnode_t *new_st;
+ sttype_id_t type1, type2;
+ header_field_info *hfinfo1, *hfinfo2;
+ ftenum_t ftype1, ftype2;
+ fvalue_t *fvalue;
+ char *s;
+ drange_node *rn;
- if (type2 == STTYPE_FIELD) {
- hfinfo2 = sttype_range_hfinfo(st_arg2);
- ftype2 = hfinfo2->type;
+ type1 = stnode_type_id(st_arg1);
+ type2 = stnode_type_id(st_arg2);
+ hfinfo1 = sttype_range_hfinfo(st_arg1);
+ ftype1 = hfinfo1->type;
- if (!is_bytes_type(ftype2)) {
- if (!ftype_can_slice(ftype2)) {
- dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
- hfinfo2->abbrev,
- ftype_pretty_name(ftype2));
- THROW(TypeError);
- }
+ if (!ftype_can_slice(ftype1)) {
+ dfilter_fail("\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
+ hfinfo1->abbrev, ftype_pretty_name(ftype1));
+ THROW(TypeError);
+ }
- /* Convert entire field to bytes */
- new_st = stnode_new(STTYPE_RANGE, NULL);
- /* st_arg2 is freed in this step */
- sttype_range_set(new_st, st_arg2, NULL, NULL);
+ if (type2 == STTYPE_FIELD) {
+ hfinfo2 = sttype_range_hfinfo(st_arg2);
+ ftype2 = hfinfo2->type;
- sttype_test_set2_args(st_node, st_arg1, new_st);
- }
- }
- else if (type2 == STTYPE_STRING) {
- s = stnode_data(st_arg2);
- fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
- if (!fvalue) {
+ if (!is_bytes_type(ftype2)) {
+ if (!ftype_can_slice(ftype2)) {
+ dfilter_fail("\"%s\" is a %s and cannot be converted into a sequence of bytes.",
+ hfinfo2->abbrev,
+ ftype_pretty_name(ftype2));
THROW(TypeError);
}
- new_st = stnode_new(STTYPE_FVALUE, fvalue);
+
+ /* Convert entire field to bytes */
+ new_st = stnode_new(STTYPE_RANGE, NULL);
+
+ rn = drange_node_new();
+ drange_node_set_offset(rn, 0);
+ drange_node_set_to_the_end(rn, TRUE);
+ /* st_arg2 is freed in this step */
+ sttype_range_set1(new_st, st_arg2, rn);
+
sttype_test_set2_args(st_node, st_arg1, new_st);
- stnode_free(st_arg2);
- }
- else if (type2 == STTYPE_RANGE) {
- /* XXX - check lengths of both ranges */
}
- else {
- g_assert_not_reached();
+ }
+ else if (type2 == STTYPE_STRING) {
+ s = stnode_data(st_arg2);
+ fvalue = fvalue_from_string(FT_BYTES, s, dfilter_fail);
+ if (!fvalue) {
+ THROW(TypeError);
}
+ new_st = stnode_new(STTYPE_FVALUE, fvalue);
+ sttype_test_set2_args(st_node, st_arg1, new_st);
+ stnode_free(st_arg2);
+ }
+ else if (type2 == STTYPE_RANGE) {
+ /* XXX - check lengths of both ranges */
}
else {
g_assert_not_reached();
}
}
+
+static void
+check_relation(dfwork_t *dfw, FtypeCanFunc can_func, stnode_t *st_node,
+ stnode_t *st_arg1, stnode_t *st_arg2)
+{
+ switch (stnode_type_id(st_arg1)) {
+ case STTYPE_FIELD:
+ check_relation_LHS_FIELD(dfw, can_func, st_node, st_arg1, st_arg2);
+ break;
+ case STTYPE_STRING:
+ check_relation_LHS_STRING(dfw, can_func, st_node, st_arg1, st_arg2);
+ break;
+ case STTYPE_RANGE:
+ check_relation_LHS_RANGE(dfw, can_func, st_node, st_arg1, st_arg2);
+ break;
+
+ case STTYPE_UNINITIALIZED:
+ case STTYPE_TEST:
+ case STTYPE_INTEGER:
+ case STTYPE_FVALUE:
+ case STTYPE_NUM_TYPES:
+ g_assert_not_reached();
+ }
+}
+
static void
check_test(dfwork_t *dfw, stnode_t *st_node)
{
diff --git a/epan/dfilter/sttype-integer.c b/epan/dfilter/sttype-integer.c
new file mode 100644
index 0000000000..68ac0db987
--- /dev/null
+++ b/epan/dfilter/sttype-integer.c
@@ -0,0 +1,42 @@
+/*
+ * $Id: sttype-integer.c,v 1.1 2001/02/27 19:23:28 gram Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * Copyright 2001 Gerald Combs
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ftypes/ftypes.h"
+#include "syntax-tree.h"
+
+void
+sttype_register_integer(void)
+{
+ static sttype_t integer_type = {
+ STTYPE_INTEGER,
+ "INTEGER",
+ NULL,
+ NULL,
+ };
+
+ sttype_register(&integer_type);
+}
diff --git a/epan/dfilter/sttype-range.c b/epan/dfilter/sttype-range.c
index e21e52a99d..1195223eb1 100644
--- a/epan/dfilter/sttype-range.c
+++ b/epan/dfilter/sttype-range.c
@@ -1,5 +1,5 @@
/*
- * $Id: sttype-range.c,v 1.2 2001/02/01 20:31:18 gram Exp $
+ * $Id: sttype-range.c,v 1.3 2001/02/27 19:23:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -30,18 +30,16 @@
#include "config.h"
#endif
-#include <stdlib.h>
-#include <errno.h>
+#include <glib.h>
+
#include "proto.h"
+#include "drange.h"
#include "sttype-range.h"
typedef struct {
guint32 magic;
header_field_info *hfinfo;
- gint start;
- gint end;
- char *start_error;
- char *end_error;
+ drange *drange;
} range_t;
#define RANGE_MAGIC 0xec0990ce
@@ -57,10 +55,7 @@ range_new(gpointer junk)
range->magic = RANGE_MAGIC;
range->hfinfo = NULL;
- range->start = 0;
- range->end = -1;
- range->start_error = NULL;
- range->end_error = NULL;
+ range->drange = NULL;
return (gpointer) range;
}
@@ -71,38 +66,29 @@ range_free(gpointer value)
range_t *range = value;
assert_magic(range, RANGE_MAGIC);
- if (range->start_error)
- g_free(range->start_error);
- if (range->end_error)
- g_free(range->end_error);
+ if (range->drange)
+ drange_free(range->drange);
g_free(range);
}
-static gint
-string_to_gint(char *s, gboolean *success)
+void
+sttype_range_remove_drange(stnode_t *node)
{
- char *endptr;
- gint val;
-
- *success = TRUE;
- val = strtol(s, &endptr, 0);
+ range_t *range;
- if (endptr == s || *endptr != '\0') {
- *success = FALSE;
- }
- else if (errno == ERANGE) {
- *success = FALSE;
- }
+ range = stnode_data(node);
+ assert_magic(range, RANGE_MAGIC);
- return val;
+ range->drange = NULL;
}
-static void
-range_set(stnode_t *node, stnode_t *field, char *start, char *end)
+
+/* Set a range */
+void
+sttype_range_set(stnode_t *node, stnode_t *field, GSList* drange_list)
{
range_t *range;
- gboolean success;
range = stnode_data(node);
assert_magic(range, RANGE_MAGIC);
@@ -110,75 +96,17 @@ range_set(stnode_t *node, stnode_t *field, char *start, char *end)
range->hfinfo = stnode_data(field);
stnode_free(field);
- if (start) {
- range->start = string_to_gint(start, &success);
- if (!success) {
- /* Save the error-causing string for later reporting */
- range->start_error = g_strdup(start);
- }
- }
- else {
- range->start = 0;
- }
-
- if (end) {
- range->end = string_to_gint(end, &success);
-
- if (!success) {
- /* Save the error-causing string for later reporting */
- range->end_error = g_strdup(end);
- }
- }
- else {
- range->end = G_MAXINT;
- }
+ range->drange = drange_new_from_list(drange_list);
}
void
-sttype_range_set(stnode_t *node, stnode_t *field, stnode_t *start, stnode_t *end)
+sttype_range_set1(stnode_t *node, stnode_t *field, drange_node *rn)
{
- char *start_str, *end_str;
-
- if (start) {
- start_str = stnode_data(start);
- }
- else {
- start_str = NULL;
- }
-
- if (end) {
- end_str = stnode_data(end);
- }
- else {
- end_str = NULL;
- }
-
- range_set(node, field, start_str, end_str);
-
- if (start)
- stnode_free(start);
- if (end)
- stnode_free(end);
+ sttype_range_set(node, field, g_slist_append(NULL, rn));
}
-void
-sttype_range_set1(stnode_t *node, stnode_t *field, stnode_t *offset)
-{
- char *offset_str;
-
- g_assert(offset);
-
- offset_str = stnode_data(offset);
- range_set(node, field, offset_str, "1");
- stnode_free(offset);
-}
-
-
STTYPE_ACCESSOR(header_field_info*, range, hfinfo, RANGE_MAGIC)
-STTYPE_ACCESSOR(gint, range, start, RANGE_MAGIC)
-STTYPE_ACCESSOR(gint, range, end, RANGE_MAGIC)
-STTYPE_ACCESSOR(char*, range, start_error, RANGE_MAGIC)
-STTYPE_ACCESSOR(char*, range, end_error, RANGE_MAGIC)
+STTYPE_ACCESSOR(drange*, range, drange, RANGE_MAGIC)
void
diff --git a/epan/dfilter/sttype-range.h b/epan/dfilter/sttype-range.h
index 34b654f4e9..b5d91f1cac 100644
--- a/epan/dfilter/sttype-range.h
+++ b/epan/dfilter/sttype-range.h
@@ -1,5 +1,5 @@
/*
- * $Id: sttype-range.h,v 1.2 2001/02/01 20:31:18 gram Exp $
+ * $Id: sttype-range.h,v 1.3 2001/02/27 19:23:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -25,19 +25,21 @@
#define STTYPE_RANGE_H
#include "syntax-tree.h"
+#include "drange.h"
STTYPE_ACCESSOR_PROTOTYPE(header_field_info*, range, hfinfo)
-STTYPE_ACCESSOR_PROTOTYPE(gint, range, start)
-STTYPE_ACCESSOR_PROTOTYPE(gint, range, end)
-STTYPE_ACCESSOR_PROTOTYPE(char*, range, start_error)
-STTYPE_ACCESSOR_PROTOTYPE(char*, range, end_error)
+STTYPE_ACCESSOR_PROTOTYPE(drange*, range, drange)
-/* Set a range, [x:y], [:y], [x:] */
+/* Set a range */
void
-sttype_range_set(stnode_t *node, stnode_t *field, stnode_t *start, stnode_t *end);
+sttype_range_set(stnode_t *node, stnode_t *field, GSList* drange_list);
-/* Set a single-byte lookup, [x] */
void
-sttype_range_set1(stnode_t *node, stnode_t *field, stnode_t *offset);
+sttype_range_set1(stnode_t *node, stnode_t *field, drange_node *rn);
+
+/* Clear the 'drange' variable to remove responsibility for
+ * freeing it. */
+void
+sttype_range_remove_drange(stnode_t *node);
#endif
diff --git a/epan/dfilter/syntax-tree.c b/epan/dfilter/syntax-tree.c
index cbe85ba3fb..dafe440cc9 100644
--- a/epan/dfilter/syntax-tree.c
+++ b/epan/dfilter/syntax-tree.c
@@ -1,5 +1,5 @@
/*
- * $Id: syntax-tree.c,v 1.2 2001/02/01 20:31:18 gram Exp $
+ * $Id: syntax-tree.c,v 1.3 2001/02/27 19:23:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -31,6 +31,7 @@
static sttype_t* type_list[STTYPE_NUM_TYPES];
/* These are the sttype_t registration function prototypes. */
+void sttype_register_integer(void);
void sttype_register_pointer(void);
void sttype_register_range(void);
void sttype_register_string(void);
@@ -43,6 +44,7 @@ void sttype_register_test(void);
void
sttype_init(void)
{
+ sttype_register_integer();
sttype_register_pointer();
sttype_register_range();
sttype_register_string();
@@ -141,6 +143,13 @@ stnode_init(stnode_t *node, sttype_id_t type_id, gpointer data)
}
void
+stnode_init_int(stnode_t *node, sttype_id_t type_id, guint32 value)
+{
+ stnode_init(node, type_id, NULL);
+ node->value = value;
+}
+
+void
stnode_free(stnode_t *node)
{
assert_magic(node, STNODE_MAGIC);
@@ -179,8 +188,12 @@ gpointer
stnode_data(stnode_t *node)
{
assert_magic(node, STNODE_MAGIC);
- if (node)
- return node->data;
- else
- return NULL;
+ return node->data;
+}
+
+guint32
+stnode_value(stnode_t *node)
+{
+ assert_magic(node, STNODE_MAGIC);
+ return node->value;
}
diff --git a/epan/dfilter/syntax-tree.h b/epan/dfilter/syntax-tree.h
index 13a77024d6..d496d25e84 100644
--- a/epan/dfilter/syntax-tree.h
+++ b/epan/dfilter/syntax-tree.h
@@ -1,5 +1,5 @@
/*
- * $Id: syntax-tree.h,v 1.2 2001/02/01 20:31:18 gram Exp $
+ * $Id: syntax-tree.h,v 1.3 2001/02/27 19:23:28 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -33,6 +33,7 @@ typedef enum {
STTYPE_STRING,
STTYPE_FIELD,
STTYPE_FVALUE,
+ STTYPE_INTEGER,
STTYPE_RANGE,
STTYPE_NUM_TYPES
} sttype_id_t;
@@ -53,8 +54,11 @@ typedef struct {
typedef struct {
guint32 magic;
sttype_t *type;
- gpointer data;
+ /* This could be made an enum, but I haven't
+ * set aside to time to do so. */
+ gpointer data;
+ guint32 value;
} stnode_t;
void
@@ -73,6 +77,9 @@ void
stnode_init(stnode_t *node, sttype_id_t type_id, gpointer data);
void
+stnode_init_int(stnode_t *node, sttype_id_t type_id, guint32 value);
+
+void
stnode_free(stnode_t *node);
const char*
@@ -84,6 +91,9 @@ stnode_type_id(stnode_t *node);
gpointer
stnode_data(stnode_t *node);
+guint32
+stnode_value(stnode_t *node);
+
#define assert_magic(obj, mnum) \
g_assert((obj)); \
if ((obj)->magic != (mnum)) { \