diff options
-rw-r--r-- | epan/dfilter/Makefile.am | 6 | ||||
-rw-r--r-- | epan/dfilter/Makefile.nmake | 7 | ||||
-rw-r--r-- | epan/dfilter/dfilter-macro.c | 374 | ||||
-rw-r--r-- | epan/dfilter/dfilter-macro.h | 19 | ||||
-rw-r--r-- | epan/dfilter/dfilter.c | 6 | ||||
-rw-r--r-- | epan/dfilter/dfilter_macro_load.l | 136 |
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**) ¯os, + &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; -} |