aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dfilter/Makefile.am6
-rw-r--r--epan/dfilter/Makefile.nmake7
-rw-r--r--epan/dfilter/dfilter-macro.c374
-rw-r--r--epan/dfilter/dfilter-macro.h19
-rw-r--r--epan/dfilter/dfilter.c6
-rw-r--r--epan/dfilter/dfilter_macro_load.l136
6 files changed, 241 insertions, 307 deletions
diff --git a/epan/dfilter/Makefile.am b/epan/dfilter/Makefile.am
index dd4658915a..a6a6e07515 100644
--- a/epan/dfilter/Makefile.am
+++ b/epan/dfilter/Makefile.am
@@ -35,7 +35,6 @@ DISTCLEANFILES = \
MAINTAINERCLEANFILES = \
dfilter-macro.c \
- dfilter_macro_load.c \
Makefile.in \
grammar.c \
grammar.h \
@@ -50,7 +49,6 @@ libdfilter_la_SOURCES = \
dfilter-int.h \
dfilter-macro.h \
dfilter-macro.c \
- dfilter_macro_load.c \
dfunctions.c \
dfunctions.h \
dfvm.c \
@@ -79,14 +77,10 @@ libdfilter_la_SOURCES = \
syntax-tree.h
EXTRA_DIST = \
- dfilter_macro_load.l \
grammar.lemon \
scanner.l \
Makefile.nmake
-dfilter_macro_load.c : dfilter_macro_load.l
- $(LEX) -Pdf_ -odfilter_macro_load.c $(srcdir)/dfilter_macro_load.l
-
scanner.c : scanner.l
@if [ ! -x "$(LEX)" ]; then \
echo "Neither lex nor flex was found"; \
diff --git a/epan/dfilter/Makefile.nmake b/epan/dfilter/Makefile.nmake
index ae07e87dd1..e7b47cc74a 100644
--- a/epan/dfilter/Makefile.nmake
+++ b/epan/dfilter/Makefile.nmake
@@ -21,7 +21,6 @@ CVARSDLL=-DWIN32 -DNULL=0 -D_MT -D_DLL
OBJECTS = \
dfilter.obj \
dfilter-macro.obj \
- dfilter_macro_load.obj \
dfunctions.obj \
dfvm.obj \
drange.obj \
@@ -61,14 +60,10 @@ clean:
# the same for now.
#
distclean: clean
- rm -f scanner.c grammar.c grammar.h grammar.out dfilter_macro_load.c
+ rm -f scanner.c grammar.c grammar.h grammar.out
maintainer-clean: distclean
-
-dfilter_macro_load.c : dfilter_macro_load.l
- $(LEX) -Pdf_ -odfilter_macro_load.c dfilter_macro_load.l
-
scanner.c : scanner.l
$(LEX) -Pdf_ -oscanner.c scanner.l
diff --git a/epan/dfilter/dfilter-macro.c b/epan/dfilter/dfilter-macro.c
index 4445b0e960..244565c589 100644
--- a/epan/dfilter/dfilter-macro.c
+++ b/epan/dfilter/dfilter-macro.c
@@ -35,14 +35,22 @@
#include "dfilter.h"
#include "dfilter-macro.h"
#include <epan/emem.h>
+#include <epan/uat.h>
+#include <epan/report_err.h>
-dfilter_macro_t* macros = NULL;
+#if 0
+#define DUMP_MACROS
+#endif
-void dfilter_macro_foreach(dfilter_macro_cb_t cb, void* data) {
- dfilter_macro_t* c;
+static uat_t* dfilter_macro_uat = NULL;
+static dfilter_macro_t* macros = NULL;
+static guint num_macros;
- for (c = macros; c; c = c->next) {
- cb(c,data);
+void dfilter_macro_foreach(dfilter_macro_cb_t cb, void* data) {
+ guint i;
+
+ for (i = 0; i < num_macros; i++) {
+ cb(&(macros[i]),data);
}
return;
}
@@ -73,8 +81,8 @@ static void macro_dump(dfilter_macro_t* m _U_, void* ud _U_) {
gchar** part = m->parts;
int* args_pos = m->args_pos;
- printf("\n->%s\t%s\t%d\n\t'%s'\n",
- m->name, m->text, m->argc, *(part++));
+ printf("\n->%s\t%s\t%d [%d]\n\t'%s'\n",
+ m->name, m->text, m->argc, m->usable, *(part++));
while (*part) {
printf("\t$%d '%s'\n",*args_pos,*part);
@@ -91,23 +99,28 @@ void dfilter_macro_dump(void) {
#endif
}
-gchar* dfilter_macro_resolve(gchar* name, gchar** args, gchar** error) {
+static gchar* dfilter_macro_resolve(gchar* name, gchar** args, gchar** error) {
GString* text;
int argc = 0;
- dfilter_macro_t* m;
+ dfilter_macro_t* m = NULL;
int* arg_pos_p;
gchar** parts;
gchar* ret;
-
- for (m = macros; m; m = m->next) {
- if ( g_str_equal(m->name,name) ) break;
+ guint i;
+
+ for (i = 0; i < num_macros; i++) {
+ dfilter_macro_t* c = &(macros[i]);
+ if ( c->usable && g_str_equal(c->name,name) ) {
+ m = c;
+ break;
+ }
}
-
+
if (!m) {
*error = ep_strdup_printf("macro '%s' does not exist", name);
return NULL;
}
-
+
if (args) {
while(args[argc]) argc++;
}
@@ -117,10 +130,10 @@ gchar* dfilter_macro_resolve(gchar* name, gchar** args, gchar** error) {
name, m->argc, argc);
return NULL;
}
-
+
arg_pos_p = m->args_pos;
parts = m->parts;
-
+
text = g_string_new(*(parts++));
while (*parts) {
@@ -130,133 +143,13 @@ gchar* dfilter_macro_resolve(gchar* name, gchar** args, gchar** error) {
}
ret = ep_strdup(text->str);
-
- g_string_free(text,TRUE);
-
- return ret;
-}
-
-void dfilter_macro_add(const gchar* name, const gchar* text, gchar** error) {
- dfilter_macro_t* m;
- GPtrArray* parts;
- GArray* args_pos;
- const gchar* r;
- gchar* w;
- gchar* part;
- int argc = 0;
-
- *error = NULL;
-
- for (m = macros; m; m = m->next) {
- if ( g_str_equal(m->name,name) ) {
- *error = ep_strdup_printf("macro '%s' exists already", name);
- return;
- }
- }
-
- m = g_malloc(sizeof(dfilter_macro_t));
- m->name = g_strdup(name);
- m->text = g_strdup(text);
-
- parts = g_ptr_array_new();
- args_pos = g_array_new(FALSE,FALSE,sizeof(int));
-
- m->priv = part = w = g_strdup(text);
- r = text;
- g_ptr_array_add(parts,part);
-
- do {
-
- switch (*r) {
- default:
- *(w++) = *(r++);
- break;
- case '\0':
- *(w++) = *(r++);
- goto done;
- case '\\':
- *(w++) = *(++r);
- r++;
- break;
- case '$': {
- int cnt = 0;
- int arg_pos = 0;
- do {
- char c = *(r+1);
- if (c >= '0' && c <= '9') {
- cnt++;
- r++;
- arg_pos *= 10;
- arg_pos += c - '0';
- } else {
- break;
- }
- } while(1);
-
- if (cnt) {
- *(w++) = '\0';
- r++;
- argc = argc < arg_pos ? arg_pos : argc;
- arg_pos--;
- g_array_append_val(args_pos,arg_pos);
- g_ptr_array_add(parts,w);
- } else {
- *(w++) = *(r++);
- }
- break;
- }
- }
-
- } while(1);
-
-done:
- g_ptr_array_add(parts,NULL);
- m->parts = (gchar**)parts->pdata;
- m->args_pos = (int*)args_pos->data;
-
- g_ptr_array_free(parts,FALSE);
- g_array_free(args_pos,FALSE);
-
- m->argc = argc;
- m->next = macros;
- macros = m;
-
- return;
-}
-
-void dfilter_macro_remove(const gchar* name, gchar** error) {
- dfilter_macro_t* m;
- dfilter_macro_t* p = NULL;
-
- for (m = macros; m; m = m->next) {
- if ( g_str_equal(m->name,name) ) {
- p = m;
- break;
- }
- }
-
- if (!m) {
- *error = ep_strdup_printf("macro '%s' does not exist", name);
- return;
- }
-
- if (p) {
- p->next = m->next;
- } else {
- macros = m->next;
- }
+ g_string_free(text,TRUE);
- g_free(m->name);
- g_free(m->text);
- g_free(m->priv);
- g_free(m->parts);
- g_free(m->args_pos);
- g_free(m);
+ return ret;
}
-
gchar* dfilter_macro_apply(const gchar* text, guint depth, gchar** error) {
enum { OUTSIDE, STARTING, NAME, ARGS } state = OUTSIDE;
GString* out;
@@ -425,3 +318,208 @@ on_error:
return NULL;
}
}
+
+static void macro_update(void* mp, gchar** error) {
+ dfilter_macro_t* m = mp;
+ GPtrArray* parts;
+ GArray* args_pos;
+ const gchar* r;
+ gchar* w;
+ gchar* part;
+ int argc = 0;
+ guint i;
+
+ *error = NULL;
+
+ for (i = 0; i < num_macros; i++) {
+ if (m == &(macros[i])) continue;
+
+ if ( g_str_equal(m->name,macros[i].name) ) {
+ *error = ep_strdup_printf("macro '%s' exists already", m->name);
+ m->usable = FALSE;
+ return;
+ }
+ }
+
+ parts = g_ptr_array_new();
+ args_pos = g_array_new(FALSE,FALSE,sizeof(int));
+
+ m->priv = part = w = g_strdup(m->text);
+ r = m->text;
+ g_ptr_array_add(parts,part);
+
+ do {
+
+ switch (*r) {
+ default:
+ *(w++) = *(r++);
+ break;
+ case '\0':
+ *(w++) = *(r++);
+ goto done;
+ case '\\':
+ *(w++) = *(++r);
+ r++;
+ break;
+ case '$': {
+ int cnt = 0;
+ int arg_pos = 0;
+ do {
+ char c = *(r+1);
+ if (c >= '0' && c <= '9') {
+ cnt++;
+ r++;
+ arg_pos *= 10;
+ arg_pos += c - '0';
+ } else {
+ break;
+ }
+ } while(1);
+
+ if (cnt) {
+ *(w++) = '\0';
+ r++;
+ argc = argc < arg_pos ? arg_pos : argc;
+ arg_pos--;
+ g_array_append_val(args_pos,arg_pos);
+ g_ptr_array_add(parts,w);
+ } else {
+ *(w++) = *(r++);
+ }
+ break;
+ }
+ }
+
+ } while(1);
+
+done:
+ g_ptr_array_add(parts,NULL);
+
+ if (m->parts) g_free(m->parts);
+
+ m->parts = (gchar**)parts->pdata;
+
+ if (m->args_pos) g_free(m->args_pos);
+
+ m->args_pos = (int*)args_pos->data;
+
+ g_ptr_array_free(parts,FALSE);
+ g_array_free(args_pos,FALSE);
+
+ m->argc = argc;
+
+ m->usable = TRUE;
+
+ return;
+}
+
+static void macro_free(void* r) {
+ dfilter_macro_t* m = r;
+
+ g_free(m->name);
+ g_free(m->text);
+ g_free(m->priv);
+ g_free(m->parts);
+ g_free(m->args_pos);
+}
+
+static void* macro_copy(void* dest, const void* orig, unsigned len _U_) {
+ dfilter_macro_t* d = dest;
+ const dfilter_macro_t* m = orig;
+ guint nparts = 0;
+
+ d->name = g_strdup(m->name);
+ d->text = g_strdup(m->text);
+ d->usable = m->usable;
+
+ if (m->parts) {
+ do nparts++; while (m->parts[nparts]);
+ d->priv = g_strdup(m->priv);
+ d->parts = g_memdup(m->parts,nparts*sizeof(void*));
+ d->args_pos = g_memdup(m->args_pos,(--nparts)*sizeof(int));
+ }
+
+
+ return d;
+}
+
+gboolean macro_name_chk(void* r _U_, const char* in_name, unsigned name_len, char** error) {
+ guint i;
+
+ for (i=0; i < name_len; i++) {
+ if (!(in_name[i] == '_' || isalnum(in_name[i]) ) ) {
+ *error = "invalid char in name";
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void macro_name_set(void* r, const char* in_name, unsigned len) {
+ dfilter_macro_t* m = r;
+ char* name = g_malloc(len+1);
+ memcpy(name,in_name,len);
+ name[len] = '\0';
+ g_free(m->text);
+ m->name = name;
+}
+
+static void macro_name_tostr(void* r, char** out_name, unsigned* out_len) {
+ dfilter_macro_t* m = r;
+ *out_len = strlen(m->name);
+ *out_name = m->name;
+}
+
+gboolean macro_text_chk(void* r _U_, const char* in_name, unsigned name_len, char** error) {
+ guint i;
+
+ for (i=0; i < name_len; i++) {
+ if (! isprint(in_name[i]) ) {
+ *error = "invalid char in text";
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void macro_text_set(void* r, const char* in_name, unsigned len) {
+ dfilter_macro_t* m = r;
+ char* text = g_malloc(len+1);
+ memcpy(text,in_name,len);
+ text[len] = '\0';
+ g_free(m->text);
+ m->text = text;
+}
+
+static void macro_text_tostr(void* r, char** out_name, unsigned* out_len) {
+ dfilter_macro_t* m = r;
+ *out_len = strlen(m->text);
+ *out_name = m->text;
+}
+
+void dfilter_macro_init(void) {
+ char* error = NULL;
+ dfilter_macro_uat = uat_new("Display Filter Macros",
+ sizeof(dfilter_macro_t),
+ "dfilter_macros",
+ (void**) &macros,
+ &num_macros,
+ macro_copy,
+ macro_update,
+ macro_free,
+ &error,
+ "name", PT_TXTMOD_STRING, macro_name_chk, macro_name_set, macro_name_tostr,
+ "text", PT_TXTMOD_STRING, macro_text_chk, macro_text_set, macro_text_tostr,
+ NULL );
+
+ if(error) {
+ report_failure("error while loading dfilter_macros:\n%s",error);
+ }
+
+#ifdef DUMP_MACROS
+ dfilter_macro_dump();
+#endif
+
+}
diff --git a/epan/dfilter/dfilter-macro.h b/epan/dfilter/dfilter-macro.h
index 11fd6b8a7d..bc43e69637 100644
--- a/epan/dfilter/dfilter-macro.h
+++ b/epan/dfilter/dfilter-macro.h
@@ -30,36 +30,23 @@
typedef struct _dfilter_macro_t {
gchar* name; /* the macro id */
gchar* text; /* raw data from file */
+ gboolean usable; /* macro is usable */
gchar** parts; /* various segments of text between insertion targets */
int* args_pos; /* what's to be inserted */
int argc; /* the expected number of arguments */
void* priv; /* a copy of text that contains every c-string in parts */
- struct _dfilter_macro_t* next; /* in macros list */
} dfilter_macro_t;
/* loop over the macros list */
typedef void (*dfilter_macro_cb_t)(dfilter_macro_t*, void*);
void dfilter_macro_foreach(dfilter_macro_cb_t, void*);
-/* add a macro to the list, text s raw text from file */
-void dfilter_macro_add(const gchar* name, const gchar* text, gchar** error);
-
-/* remove a macro from the list */
-void dfilter_macro_remove(const gchar* name, gchar** error);
-
-/* loads the macros from file in userdir or else datadir */
-gboolean dfilter_macro_load(gchar** error);
-
-/* save the macro list to file */
-void dfilter_macro_save(const gchar* filename, gchar** error);
-
/* dumps the macros in the list (debug info, not formated as in the macros file) */
void dfilter_macro_dump(void);
-/* given a macro_name and its arguments returns an ep_allocated string */
-gchar* dfilter_macro_resolve(gchar* macro_name, gchar** macro_args, gchar** error);
-
/* applies all macros to the given text and returns the resulting string or NULL on failure */
gchar* dfilter_macro_apply(const gchar* text, guint depth, gchar** error);
+void dfilter_macro_init(void);
+
#endif /* _DFILTER_MACRO_H */
diff --git a/epan/dfilter/dfilter.c b/epan/dfilter/dfilter.c
index 06a9dd55a2..8ad6061c53 100644
--- a/epan/dfilter/dfilter.c
+++ b/epan/dfilter/dfilter.c
@@ -94,11 +94,7 @@ dfilter_init(void)
/* Initialize the syntax-tree sub-sub-system */
sttype_init();
- if ( ! dfilter_macro_load(&err) ) {
- if (err) {
- report_failure("%s",err);
- }
- }
+ dfilter_macro_init();
}
/* Clean-up the dfilter module */
diff --git a/epan/dfilter/dfilter_macro_load.l b/epan/dfilter/dfilter_macro_load.l
deleted file mode 100644
index d5ec376c7f..0000000000
--- a/epan/dfilter/dfilter_macro_load.l
+++ /dev/null
@@ -1,136 +0,0 @@
-%option never-interactive
-%option prefix="dfml_"
-%option outfile="dfilter_macro_load.c"
-%option nounput
-%option noyywrap
-%{
-/* dfilter_macro_load.l
- *
- * $Id$
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.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 <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include "dfilter-int.h"
-#include "dfilter.h"
-#include "dfilter-macro.h"
-#include <epan/emem.h>
-#include <epan/filesystem.h>
-
- static char* macro_name;
- static char* macro_body;
- static gchar* err;
- static const gchar* fname;
- static int linenum;
-
-%}
-name [a-zA-Z][-_[:alnum:]]*
-colon ":"
-body [^\r\n]+
-nl [\r]?\n
-ws [:blank:]+
-
-%START GET_NAME GET_COLON GET_BODY GET_NL
-%%
-<GET_NAME>[:blank:]*[\r]?\n ; /* ignore empty lines*/
-
-<GET_NAME>{name} { macro_name = ep_strdup(yytext); BEGIN GET_COLON; }
-<GET_NAME>{ws} ;
-<GET_NAME>. {
- err = ep_strdup_printf("%s:%d: unexpected char at: '%s'", fname, linenum, yytext);
- yyterminate();
-}
-
-<GET_COLON>{colon} { BEGIN GET_BODY; };
-<GET_COLON>{ws} ;
-<GET_COLON>. {
- err = ep_strdup_printf("%s:%d: unexpected char at: '%s'", fname, linenum, yytext);
- yyterminate();
-}
-
-<GET_BODY>{body} { macro_body = ep_strdup(yytext); BEGIN GET_NL; }
-<GET_BODY>{nl} {
- err = ep_strdup_printf("%s:%d: empty body", fname, linenum);
- yyterminate();
-}
-
-<GET_NL>{nl} {
- dfilter_macro_add(macro_name, macro_body, &err);
- if (err) yyterminate();
- BEGIN GET_NAME;
-}
-<GET_NL><<EOF>> {
- dfilter_macro_add(macro_name, macro_body, &err);
- if (err) yyterminate();
- return 1;
-}
-
-%%
-
-gboolean dfilter_macro_load(gchar** error) {
-
- linenum = 1;
- macro_name = NULL;
- macro_body = NULL;
- err = NULL;
- *error = NULL;
-
- fname = get_persconffile_path(DFILTER_MACRO_FILENAME,FALSE);
-
- yyin = fopen(fname,"r");
-
- if (!yyin) {
- if(errno != ENOENT) {
- *error = ep_strdup_printf("Could not open file: '%s', error: %s\n", fname, strerror(errno));
- return FALSE;
- }
-
- fname = get_datafile_path(DFILTER_MACRO_FILENAME);
-
- yyin = fopen(fname,"r");
-
- if (!yyin) {
- if(errno != ENOENT) {
- *error = ep_strdup_printf("Could not open file: '%s', error: %s\n", fname, strerror(errno));
- return FALSE;
- } else {
- return TRUE;
- }
- }
- }
-
- BEGIN GET_NAME;
-
- yylex();
-
- if (err) {
- *error = err;
- return FALSE;
- }
-
- return TRUE;
-}