summaryrefslogtreecommitdiff
path: root/epan
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2007-02-03 14:25:02 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2007-02-03 14:25:02 +0000
commitd70a58f881e34d3a83533236d0fe74e425a0700f (patch)
tree683c63d63061635121c0893a08d8320a910299da /epan
parent009d38e6a0accceef00a1209cfe7f6708e8b30ee (diff)
downloadwireshark-d70a58f881e34d3a83533236d0fe74e425a0700f.tar.gz
second iteration:
* fields of an uat table now are passed using an array of uat_filed_t * field callbacks take two more userdata arguments * add some macros to define uat field callbacks. * uats can be registered as preferences for a specific protocol - the preference widget is a button that opens the uat's window * dfilter-macro => reflect changes to API svn path=/trunk/; revision=20695
Diffstat (limited to 'epan')
-rw-r--r--epan/dfilter/dfilter-macro.c81
-rw-r--r--epan/prefs-int.h2
-rw-r--r--epan/prefs.c25
-rw-r--r--epan/prefs.h10
-rw-r--r--epan/uat-int.h28
-rw-r--r--epan/uat.c231
-rw-r--r--epan/uat.h231
-rw-r--r--epan/uat_load.l43
8 files changed, 391 insertions, 260 deletions
diff --git a/epan/dfilter/dfilter-macro.c b/epan/dfilter/dfilter-macro.c
index 944400f77a..9e01cec70d 100644
--- a/epan/dfilter/dfilter-macro.c
+++ b/epan/dfilter/dfilter-macro.c
@@ -165,13 +165,14 @@ gchar* dfilter_macro_apply(const gchar* text, guint depth, gchar** error) {
#define FGS(n) if (n) g_string_free(n,TRUE); n = NULL
-#define FREE_ALL() do { \
- FGS(name); \
- FGS(arg); \
- if (args) { \
- while(args->len) { void* p = g_ptr_array_remove_index_fast(args,0); if (p) g_free(p); } \
- g_ptr_array_free(args,TRUE); \
- args = NULL; } } while(0)
+#define FREE_ALL() \
+ do { \
+ FGS(name); \
+ FGS(arg); \
+ if (args) { \
+ while(args->len) { void* p = g_ptr_array_remove_index_fast(args,0); if (p) g_free(p); } \
+ g_ptr_array_free(args,TRUE); \
+ args = NULL; } } while(0)
*error = NULL;
out = g_string_sized_new(64);
@@ -443,7 +444,8 @@ static void* macro_copy(void* dest, const void* orig, unsigned len _U_) {
return d;
}
-gboolean macro_name_chk(void* r _U_, const char* in_name, unsigned name_len, char** error) {
+
+gboolean macro_name_chk(void* r _U_, const char* in_name, unsigned name_len, void* u1 _U_, void* u2 _U_, char** error) {
guint i;
for (i=0; i < name_len; i++) {
@@ -453,54 +455,19 @@ gboolean macro_name_chk(void* r _U_, const char* in_name, unsigned name_len, cha
}
}
- return TRUE;
+ return i > 0 ? TRUE : FALSE;
}
-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->name);
- 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;
-}
+UAT_CSTRING_CB_DEF(macro,name,dfilter_macro_t)
+UAT_CSTRING_CB_DEF(macro,text,dfilter_macro_t)
void dfilter_macro_init(void) {
- char* error = NULL;
+ static uat_field_t uat_fields[] = {
+ UAT_FLD_CSTRING_OTHER(macro,name,macro_name_chk),
+ UAT_FLD_CSTRING_ISPRINT(macro,text),
+ UAT_END_FIELDS
+ };
+
dfilter_macro_uat = uat_new("Display Filter Macros",
sizeof(dfilter_macro_t),
DFILTER_MACRO_FILENAME,
@@ -509,15 +476,7 @@ void dfilter_macro_init(void) {
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_MACRO_FILENAME "':\n%s",error);
- }
-
+ uat_fields);
}
void dfilter_macro_get_uat(void** p) {
diff --git a/epan/prefs-int.h b/epan/prefs-int.h
index 508e637188..547ae36742 100644
--- a/epan/prefs-int.h
+++ b/epan/prefs-int.h
@@ -56,6 +56,7 @@ typedef enum {
PREF_STRING,
PREF_RANGE,
PREF_STATIC_TEXT,
+ PREF_UAT,
PREF_OBSOLETE
} pref_type_t;
@@ -71,6 +72,7 @@ struct preference {
gint *enump;
const char **string;
range_t **range;
+ void* uat;
} varp; /* pointer to variable storing the value */
union {
guint uint;
diff --git a/epan/prefs.c b/epan/prefs.c
index 434ed00d7e..309d876567 100644
--- a/epan/prefs.c
+++ b/epan/prefs.c
@@ -48,6 +48,7 @@
#include <wiretap/file_util.h>
#include <epan/prefs-int.h>
+#include <epan/uat-int.h>
/* Internal functions */
static module_t *prefs_register_module_or_subtree(module_t *parent,
@@ -639,6 +640,24 @@ void prefs_register_static_text_preference(module_t *module, const char *name,
}
/*
+ * Register a uat 'preference'. It adds a button that opens the uat's window in the
+ * preferences tab of the module.
+ */
+extern void prefs_register_uat_preference(module_t *module,
+ const char *name,
+ const char *title,
+ const char *description,
+ void* uat) {
+
+ pref_t* preference = register_preference(module, name, title, description, PREF_UAT);
+
+ preference->varp.uat = uat;
+
+}
+
+
+
+/*
* Register a preference that used to be supported but no longer is.
*/
void
@@ -941,6 +960,8 @@ init_prefs(void) {
if (prefs_initialized)
return;
+ uat_load_all();
+
prefs.pr_format = PR_FMT_TEXT;
prefs.pr_dest = PR_DEST_CMD;
prefs.pr_file = g_strdup("wireshark.out");
@@ -1103,7 +1124,7 @@ read_prefs(int *gpf_errno_return, int *gpf_read_errno_return,
FILE *pf;
init_prefs();
-
+
/*
* If we don't already have the pathname of the global preferences
* file, construct it. Then, in either case, try to open the file.
@@ -2133,6 +2154,7 @@ set_pref(gchar *pref_name, gchar *value, void *private_data _U_)
}
case PREF_STATIC_TEXT:
+ case PREF_UAT:
{
break;
}
@@ -2248,6 +2270,7 @@ write_pref(gpointer data, gpointer user_data)
}
case PREF_STATIC_TEXT:
+ case PREF_UAT:
{
/* Nothing to do */
break;
diff --git a/epan/prefs.h b/epan/prefs.h
index 1aa0751b25..52e1adeff0 100644
--- a/epan/prefs.h
+++ b/epan/prefs.h
@@ -314,6 +314,16 @@ extern void prefs_register_static_text_preference(module_t *module, const char *
const char *title, const char *description);
/*
+ * Register a uat 'preference'. It adds a button that opens the uat's window in the
+ * preferences tab of the module.
+ */
+extern void prefs_register_uat_preference(module_t *module,
+ const char *name,
+ const char* title,
+ const char *description,
+ void* uat);
+
+/*
* Register a preference that used to be supported but no longer is.
*/
extern void prefs_register_obsolete_preference(module_t *module,
diff --git a/epan/uat-int.h b/epan/uat-int.h
index 4f9b8a48f7..060b3f7df7 100644
--- a/epan/uat-int.h
+++ b/epan/uat-int.h
@@ -39,19 +39,11 @@ typedef struct _uat_rep_t uat_rep_t;
typedef void (*uat_rep_fld_free_cb_t)(uat_fld_rep_t*);
typedef void (*uat_rep_free_cb_t)(uat_rep_t*);
-typedef struct _uat_fld_t {
- char* name;
- uat_text_mode_t mode;
- uat_fld_chk_cb_t chk_cb;
- uat_fld_set_cb_t set_cb;
- uat_fld_tostr_cb_t tostr_cb;
-
+typedef struct _fld_data_t {
guint colnum;
uat_fld_rep_t* rep;
uat_rep_fld_free_cb_t free_rep;
-
- struct _uat_fld_t* next;
-} uat_fld_t;
+} fld_data_t;
struct _uat_t {
char* name;
@@ -63,23 +55,31 @@ struct _uat_t {
uat_update_cb_t update_cb;
uat_free_cb_t free_cb;
- uat_fld_t* fields;
+ uat_field_t* fields;
guint ncols;
GArray* user_data;
- gboolean finalized;
uat_rep_t* rep;
uat_rep_free_cb_t free_rep;
};
gchar* uat_get_actual_filename(uat_t* uat, gboolean for_writing);
+
void uat_init(void);
+
void uat_reset(void);
+
void* uat_add_record(uat_t*, const void* orig_rec_ptr);
+
void uat_remove_record_idx(uat_t*, guint rec_idx);
+
void uat_destroy(uat_t*);
-gboolean uat_save(uat_t* dt, char** error);
-gboolean uat_load(uat_t* dt, char** error);
+
+gboolean uat_save(uat_t* , char** );
+
+gboolean uat_load(uat_t* , char** );
+
+void uat_load_all(void);
#define UAT_UPDATE(uat) do { *((uat)->user_ptr) = (void*)((uat)->user_data->data); *((uat)->nrows_p) = (uat)->user_data->len; } while(0)
#define UAT_INDEX_PTR(uat,idx) (uat->user_data->data + (uat->record_size * (idx)))
diff --git a/epan/uat.c b/epan/uat.c
index e22b924b94..d886e0b589 100644
--- a/epan/uat.c
+++ b/epan/uat.c
@@ -39,7 +39,9 @@
#include <glib.h>
#include <epan/emem.h>
+#include <epan/report_err.h>
#include <epan/filesystem.h>
+#include <epan/packet.h>
#include "uat-int.h"
@@ -49,128 +51,60 @@ void uat_init(void) {
all_uats = g_ptr_array_new();
}
-uat_t* uat_start(const char* name,
- size_t size,
- char* filename,
- void** data_ptr,
- guint* num_items_ptr,
- uat_copy_cb_t copy_cb,
- uat_update_cb_t update_cb,
- uat_free_cb_t free_cb) {
-
+uat_t* uat_new(const char* name,
+ size_t size,
+ char* filename,
+ void** data_ptr,
+ guint* numitems_ptr,
+ uat_copy_cb_t copy_cb,
+ uat_update_cb_t update_cb,
+ uat_free_cb_t free_cb,
+ uat_field_t* flds_array) {
uat_t* uat = g_malloc(sizeof(uat_t));
-
+ guint i;
+
if (!all_uats)
all_uats = g_ptr_array_new();
g_ptr_array_add(all_uats,uat);
- g_assert(name && size && filename && data_ptr && num_items_ptr);
+ g_assert(name && size && filename && data_ptr && numitems_ptr);
uat->name = g_strdup(name);
uat->record_size = size;
uat->filename = g_strdup(filename);
uat->user_ptr = data_ptr;
- uat->nrows_p = num_items_ptr;
+ uat->nrows_p = numitems_ptr;
uat->copy_cb = copy_cb;
uat->update_cb = update_cb;
uat->free_cb = free_cb;
-
- uat->fields = NULL;
- uat->ncols = 0;
+ uat->fields = flds_array;
uat->user_data = g_array_new(FALSE,FALSE,uat->record_size);
- uat->finalized = FALSE;
uat->rep = NULL;
uat->free_rep = NULL;
- return uat;
-}
-
-void uat_add_field(uat_t* uat,
- const char* name,
- uat_text_mode_t mode,
- uat_fld_chk_cb_t chk_cb,
- uat_fld_set_cb_t set_cb,
- uat_fld_tostr_cb_t tostr_cb) {
-
- uat_fld_t* f = g_malloc(sizeof(uat_fld_t));
-
- g_assert( name && set_cb && tostr_cb && (! uat->finalized )
- && (mode == PT_TXTMOD_STRING || mode == PT_TXTMOD_HEXBYTES) );
+ for (i=0;flds_array[i].name;i++) {
+ fld_data_t* f = g_malloc(sizeof(fld_data_t));
- f->name = g_strdup(name);
- f->mode = mode;
- f->chk_cb = chk_cb;
- f->set_cb = set_cb;
- f->tostr_cb = tostr_cb;
-
- f->rep = NULL;
- f->free_rep = NULL;
- f->colnum = uat->ncols;
- f->next = NULL;
-
- uat->ncols++;
-
- if (uat->fields) {
- uat_fld_t* c;
- for (c = uat->fields; c->next; c = c->next) ;
- c->next = f;
- } else {
- uat->fields = f;
- }
-}
-
-void uat_finalize(uat_t* uat) {
- UAT_UPDATE(uat);
- uat->finalized = TRUE;
-}
-
-uat_t* uat_new(const char* uat_name,
- size_t size,
- char* filename,
- void** data_ptr,
- guint* numitems_ptr,
- uat_copy_cb_t copy_cb,
- uat_update_cb_t update_cb,
- uat_free_cb_t free_cb,
- char** error,
- ...) {
- uat_t* uat = uat_start(uat_name, size, filename, data_ptr, numitems_ptr, copy_cb, update_cb, free_cb);
- va_list ap;
- char* name;
- uat_text_mode_t mode;
- uat_fld_chk_cb_t chk_cb;
- uat_fld_set_cb_t set_cb;
- uat_fld_tostr_cb_t tostr_cb;
- va_start(ap,error);
-
- name = va_arg(ap,char*);
-
- do {
- mode = va_arg(ap,uat_text_mode_t);
- chk_cb = va_arg(ap,uat_fld_chk_cb_t);
- set_cb = va_arg(ap,uat_fld_set_cb_t);
- tostr_cb = va_arg(ap,uat_fld_tostr_cb_t);
-
- uat_add_field(uat, name, mode, chk_cb, set_cb, tostr_cb);
+ f->colnum = i+1;
+ f->rep = NULL;
+ f->free_rep = NULL;
- name = va_arg(ap,char*);
- } while (name);
+ flds_array[i].priv = f;
+ }
- va_end(ap);
+ uat->ncols = i;
- uat_finalize(uat);
- uat_load(uat,error);
+ *data_ptr = NULL;
+ *numitems_ptr = 0;
return uat;
}
void* uat_add_record(uat_t* uat, const void* data) {
void* rec;
-
- g_assert( uat->finalized );
-
+
g_array_append_vals (uat->user_data, data, 1);
rec = uat->user_data->data + (uat->record_size * (uat->user_data->len-1));
@@ -179,7 +113,6 @@ void* uat_add_record(uat_t* uat, const void* data) {
uat->copy_cb(rec, data, uat->record_size);
}
-
UAT_UPDATE(uat);
return rec;
@@ -187,19 +120,22 @@ void* uat_add_record(uat_t* uat, const void* data) {
void uat_remove_record_idx(uat_t* uat, guint idx) {
- g_assert( uat->finalized && idx < uat->user_data->len);
+ g_assert( idx < uat->user_data->len );
+ if (uat->free_cb) {
+ uat->free_cb(UAT_INDEX_PTR(uat,idx));
+ }
+
g_array_remove_index(uat->user_data, idx);
UAT_UPDATE(uat);
}
-
gchar* uat_get_actual_filename(uat_t* uat, gboolean for_writing) {
gchar* pers_fname = get_persconffile_path(uat->filename,for_writing);
-
- if (! (file_exists(pers_fname) || for_writing) ) {
+
+ if (! for_writing ) {
gchar* data_fname = get_datafile_path(uat->filename);
if (file_exists(data_fname)) {
@@ -207,14 +143,18 @@ gchar* uat_get_actual_filename(uat_t* uat, gboolean for_writing) {
}
}
+ if ((! file_exists(pers_fname) ) && (! for_writing ) ) {
+ return NULL;
+ }
+
return pers_fname;
}
-static void putfld(FILE* fp, void* rec, uat_fld_t* f) {
+static void putfld(FILE* fp, void* rec, uat_field_t* f) {
guint fld_len;
char* fld_ptr;
- f->tostr_cb(rec,&fld_ptr,&fld_len);
+ f->cb.tostr(rec,&fld_ptr,&fld_len,f->cbdata.tostr,f->fld_data);
switch(f->mode){
case PT_TXTMOD_STRING: {
@@ -254,9 +194,12 @@ static void putfld(FILE* fp, void* rec, uat_fld_t* f) {
gboolean uat_save(uat_t* uat, char** error) {
guint i;
gchar* fname = uat_get_actual_filename(uat,TRUE);
- FILE* fp = fopen(fname,"w");
+ FILE* fp;
+ if (! fname ) return FALSE;
+ fp = fopen(fname,"w");
+
if (!fp) {
*error = ep_strdup_printf("uat_save: error opening '%s': %s",fname,strerror(errno));
return FALSE;
@@ -266,18 +209,17 @@ gboolean uat_save(uat_t* uat, char** error) {
for ( i = 0 ; i < uat->user_data->len ; i++ ) {
void* rec = uat->user_data->data + (uat->record_size * i);
- uat_fld_t* f;
-
+ uat_field_t* f;
+ guint j;
+
f = uat->fields;
- putfld(fp, rec, f);
- while (( f = f->next )) {
- fputs(",",fp);
- putfld(fp, rec, f);
+ for( j=0 ; j < uat->ncols ; j++ ) {
+ putfld(fp, rec, &(f[j]));
+ fputs((j == uat->ncols - 1) ? "\n" : "," ,fp);
}
- fputs("\n",fp);
}
fclose(fp);
@@ -286,6 +228,7 @@ gboolean uat_save(uat_t* uat, char** error) {
}
void uat_destroy(uat_t* uat) {
+ /* XXX still missing a destructor */
g_ptr_array_remove(all_uats,uat);
}
@@ -303,7 +246,6 @@ void* uat_se_dup(uat_t* uat, guint* len_p) {
}
void uat_cleanup(void) {
-
while( all_uats->len ) {
uat_destroy((uat_t*)all_uats->pdata);
}
@@ -311,3 +253,74 @@ void uat_cleanup(void) {
g_ptr_array_free(all_uats,TRUE);
}
+void uat_load_all(void) {
+ guint i;
+ gchar* err;
+
+ for (i=0; i < all_uats->len; i++) {
+ uat_t* u = g_ptr_array_index(all_uats,i);
+ err = NULL;
+
+ uat_load(u, &err);
+
+ if (err) {
+ report_failure("Error loading table '%s': %s",u->name,err);
+ }
+ }
+}
+
+gboolean uat_fld_chk_str(void* u1 _U_, const char* strptr, unsigned len _U_, void* u2 _U_, void* u3 _U_, char** err) {
+ if (strptr == NULL) {
+ *err = "NULL pointer";
+ return FALSE;
+ }
+
+ *err = NULL;
+ return TRUE;
+}
+
+gboolean uat_fld_chk_proto(void* u1 _U_, const char* strptr, unsigned len, void* u2 _U_, void* u3 _U_, char** err) {
+ char* name = ep_strndup(strptr,len);
+ g_strdown(name);
+ g_strchug(name);
+ if (find_dissector(name)) {
+ *err = NULL;
+ return TRUE;
+ } else {
+ *err = "dissector not found";
+ return FALSE;
+ }
+}
+
+gboolean uat_fld_chk_num_dec(void* u1 _U_, const char* strptr, unsigned len, void* u2 _U_, void* u3 _U_, char** err) {
+ char* str = ep_strndup(strptr,len);
+ long i = strtol(str,&str,10);
+
+ if ( ( i == 0) && (errno == ERANGE || errno == EINVAL) ) {
+ *err = strerror(errno);
+ return FALSE;
+ }
+
+ *err = NULL;
+ return TRUE;
+}
+
+gboolean uat_fld_chk_num_hex(void* u1 _U_, const char* strptr, unsigned len, void* u2 _U_, void* u3 _U_, char** err) {
+ char* str = ep_strndup(strptr,len);
+ long i = strtol(str,&str,16);
+
+ if ( ( i == 0) && (errno == ERANGE || errno == EINVAL) ) {
+ *err = strerror(errno);
+ return FALSE;
+ }
+
+ *err = NULL;
+ return TRUE;
+}
+
+CHK_STR_IS_DEF(isprint)
+CHK_STR_IS_DEF(isalpha)
+CHK_STR_IS_DEF(isalnum)
+CHK_STR_IS_DEF(isdigit)
+CHK_STR_IS_DEF(isxdigit)
+
diff --git a/epan/uat.h b/epan/uat.h
index c028e7ed4c..8c37561938 100644
--- a/epan/uat.h
+++ b/epan/uat.h
@@ -53,7 +53,6 @@
/* obscure data type to handle an uat */
typedef struct _uat_t uat_t;
-
/********************************************
* Callbacks:
* these instruct uat on how to deal with user info and data in records
@@ -103,9 +102,9 @@ typedef void (*uat_update_cb_t)(void* , char** );
* it will return FALSE and may set *error to inform the user on what's
* wrong with the given input
* optional, if not given any input is considered OK and the set cb will be called
- * chk(record, ptr, len, &error)
+ * chk(record, ptr, len, chk_data, fld_data, &error)
*/
-typedef gboolean (*uat_fld_chk_cb_t)(void*, const char*, unsigned, char**);
+typedef gboolean (*uat_fld_chk_cb_t)(void*, const char*, unsigned, void*, void*, char**);
/*
* Set Field CB
@@ -115,19 +114,16 @@ typedef gboolean (*uat_fld_chk_cb_t)(void*, const char*, unsigned, char**);
* it will return FALSE and may set *error to inform the user on what's
* wrong with the given input
* it is mandatory
- * set(record, ptr, len)
+ * set(record, ptr, len, set_data, fld_data)
*/
-typedef void (*uat_fld_set_cb_t)(void*, const char*, unsigned);
+typedef void (*uat_fld_set_cb_t)(void*, const char*, unsigned, void*, void*);
/*
* given a record returns a string representation of the field
* mandatory
- * tostr(record, &ptr, &len)
+ * tostr(record, &out_ptr, &out_len, tostr_data, fld_data)
*/
-typedef void (*uat_fld_tostr_cb_t)(void*, char**, unsigned*);
-
-
-
+typedef void (*uat_fld_tostr_cb_t)(void*, char**, unsigned*, void*, void*);
/***********
* Text Mode
@@ -174,6 +170,36 @@ typedef enum _uat_text_mode_t {
*/
} uat_text_mode_t;
+/*
+ * Fields
+ *
+ *
+ */
+typedef struct _uat_field_t {
+ const char* name;
+ uat_text_mode_t mode;
+
+ struct {
+ uat_fld_chk_cb_t chk;
+ uat_fld_set_cb_t set;
+ uat_fld_tostr_cb_t tostr;
+ } cb;
+
+ struct {
+ void* chk;
+ void* set;
+ void* tostr;
+ } cbdata;
+
+ void* fld_data;
+
+ struct _fld_data_t* priv;
+} uat_field_t;
+
+#define FLDFILL NULL
+#define UAT_END_FIELDS {0,PT_TXTMOD_NONE,{0,0,0},{0,0,0},0,FLDFILL}
+
+
/*
* uat_new()
@@ -196,18 +222,6 @@ typedef enum _uat_text_mode_t {
*
* free_cb: will be called to destroy a struct in the dataset
*
- *
- * followed by a list of N quintuplets terminated by a NULL, each quituplet has:
- *
- * field_name: a string with the name of the field ([a-zA-Z0-9_-]+)
- *
- * field_mode: see comments for enum _uat_text_mode_t below
- *
- * field_chk_cb: a function that given a string will check the given value
- *
- * field_set_cb: a function that given a string will set the value in the data structure
- *
- * field_tostr_cb: a function that given a record generates a string,len pair representing this file
*
*/
uat_t* uat_new(const char* name,
@@ -218,40 +232,8 @@ uat_t* uat_new(const char* name,
uat_copy_cb_t copy_cb,
uat_update_cb_t update_cb,
uat_free_cb_t free_cb,
- char** error,
- ...);
-
-
-/*
- * uat_start()
- * as uat_new() but leaves the dyntable without fields
- */
-uat_t* uat_start(const char* name,
- size_t size,
- char* filename,
- void** data_ptr,
- guint* num_items,
- uat_copy_cb_t copy_cb,
- uat_update_cb_t update_cb,
- uat_free_cb_t free_cb);
-
-/*
- * uat_add_field()
- * adds a field to a uat created with uat_start(),
- * see uat_new() for description of arguments
- */
-void uat_add_field(uat_t*,
- const char* name,
- uat_text_mode_t mode,
- uat_fld_chk_cb_t chk_cb,
- uat_fld_set_cb_t set_cb,
- uat_fld_tostr_cb_t tostr_cb);
+ uat_field_t* flds_array);
-/*
- * uat_finalize()
- * once fields have been added it makes the uat usable, leaves it locked.
- */
-void uat_finalize(uat_t*);
/*
* uat_dup()
@@ -263,5 +245,144 @@ void uat_finalize(uat_t*);
void* uat_dup(uat_t*, guint* len_p); /* to be freed */
void* uat_se_dup(uat_t*, guint* len_p);
+/*
+ * Some common uat_fld_chk_cbs
+ */
+gboolean uat_fld_chk_str(void*, const char*, unsigned, void*,void*, char** err);
+gboolean uat_fld_chk_proto(void*, const char*, unsigned, void*,void*, char** err);
+gboolean uat_fld_chk_num_dec(void*, const char*, unsigned, void*, void*, char** err);
+gboolean uat_fld_chk_num_hex(void*, const char*, unsigned, void*, void*, char** err);
+
+#define CHK_STR_IS_DECL(what) \
+gboolean uat_fld_chk_str_ ## what (void*, const char*, unsigned, void*, void*, char**)
+
+/* Some strings entirely made of ... already declared */
+CHK_STR_IS_DECL(isprint);
+CHK_STR_IS_DECL(isalpha);
+CHK_STR_IS_DECL(isalnum);
+CHK_STR_IS_DECL(isdigit);
+CHK_STR_IS_DECL(isxdigit);
+
+#define CHK_STR_IS_DEF(what) \
+gboolean uat_fld_chk_str_ ## what (void* u1 _U_, const char* strptr, unsigned len, void* u2 _U_, void* u3 _U_, char** err) { \
+ guint i; for (i=0;i<len;i++) { \
+ char c = strptr[i]; \
+ if (! what(c)) { \
+ *err = ep_strdup_printf("invalid char pos=%d value=%.2x",i,c); return FALSE; } } \
+ *err = NULL; return TRUE; }
+
+
+/*
+ * Macros
+ * to define basic uat_fld_set_cbs, uat_fld_tostr_cbs
+ * for those elements in uat_field_t array
+ */
+
+/*
+ * CSTRING macros,
+ * a simple c-string contained in (((rec_t*)rec)->(field_name))
+ */
+#define UAT_CSTRING_CB_DEF(basename,field_name,rec_t) \
+static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, void* u1 _U_, void* u2 _U_) {\
+ if ((((rec_t*)rec)->field_name)) g_free((((rec_t*)rec)->field_name)); \
+ (((rec_t*)rec)->field_name) = g_strndup(buf,len); } \
+static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, void* u1 _U_, void* u2 _U_) {\
+ if (((rec_t*)rec)->field_name ) { \
+ *out_ptr = (((rec_t*)rec)->field_name); *out_len = strlen((((rec_t*)rec)->field_name)); \
+ } else { \
+ *out_ptr = ""; *out_len = 0; } }
+
+#define UAT_FLD_CSTRING(basename,field_name) \
+ {#field_name, PT_TXTMOD_STRING,{uat_fld_chk_str,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{NULL,NULL,NULL},NULL,FLDFILL}
+
+#define UAT_FLD_CSTRING_ISPRINT(basename,field_name) \
+ {#field_name, PT_TXTMOD_STRING,{uat_fld_chk_str_isprint,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{NULL,NULL,NULL},NULL,FLDFILL}
+
+#define UAT_FLD_CSTRING_OTHER(basename,field_name,chk) \
+ {#field_name, PT_TXTMOD_STRING,{ chk ,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{NULL,NULL,NULL},NULL,FLDFILL}
+
+
+/*
+ * BUFFER macros,
+ * a buffer_ptr contained in (((rec_t*)rec)->(field_name))
+ * and its len in (((rec_t*)rec)->(len_name))
+ * XXX: UNTESTED
+ */
+#define UAT_BUFFER_CB_DEF(field_name,len_name,rec_t,ptr_element,len_element) \
+static void basename ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, void* u1 _U_, void* u2 _U_) {\
+ if ((((rec_t*)rec)->(field_name))) g_free((((rec_t*)rec)->(field_name))); \
+ (((rec_t*)rec)->(field_name)) = g_memdup(buf,len); \
+ (((rec_t*)rec)->(len_name)) = len; \ } \
+static void basename ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, void* u1 _U_, void* u2 _U_) {\
+ *out_ptr = ep_memdup(((rec_t*)rec)->(field_name),((rec_t*)rec)->(len_name)); \
+ *len_ptr = (((rec_t*)rec)->(len_name)); }
+
+#define UAT_FLD_BUFFER(basename,field_name) \
+ {#field_name, PT_TXTMOD_HEXBYTES,{NULL,basename ## field_name ## _set_cb,basename ## field_name ## _tostr_cb},{NULL,NULL,NULL},NULL,FLDFILL}
+
+
+/*
+ * DEC Macros,
+ * a decimal number contained in
+ */
+#define UAT_DEC_CB_DEF(basename,field_name,rec_t) \
+static void basename ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, void* u1 _U_, void* u2 _U_) {\
+ ((rec_t*)rec)->(field_name) = strtol(buf,end,10); } \
+static void basename ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, void* u1 _U_, void* u2 _U_) {\
+ *out_ptr = ep_strdup_printf("%d",((rec_t*)rec)->(field_name)); \
+ *out_len = strlen(*out_ptr); }
+
+#define UAT_FLD_DEC(basename,field_name) \
+ {#field_name, PT_TXTMOD_STRING,{uat_fld_chk_num_dec,basename ## field_name ## _set_cb,basename ## field_name ## _tostr_cb},{NULL,NULL,NULL},NULL,FLDFILL}
+
+
+/*
+ * HEX Macros,
+ * an hexadecimal number contained in
+ */
+#define UAT_HEX_CB_DEF(basename,field_name,rec_t) \
+static void basename ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, void* u1 _U_, void* u2 _U_) {\
+ ((rec_t*)rec)->(field_name) = strtol(buf,end,16); } \
+static void basename ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, void* u1 _U_, void* u2 _U_) {\
+ *out_ptr = ep_strdup_printf("%x",((rec_t*)rec)->(field_name)); \
+ *out_len = strlen(*out_ptr); }
+
+#define UAT_FLD_HEX(basename,field_name) \
+{#field_name, PT_TXTMOD_STRING,{uat_fld_chk_num_hex,basename ## field_name ## _set_cb,basename ## field_name ## _tostr_cb},{NULL,NULL,NULL},NULL,FLDFILL}
+
+
+/*
+ * ENUM macros
+ * enum_t: name = ((enum_t*)ptr)->strptr
+ * value = ((enum_t*)ptr)->value
+ * rec_t:
+ * value
+ */
+#define UAT_SET_ENUM_DEF(basename,field_name,rec_t,enum_t,default) \
+void static void basename ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, void* enum, void* u2 _U_) {\
+ char* str = ep_strndup(buf,len); \
+ for(;((enum_t*)enum)->strptr;((enum_t*)enum)++) { \
+ if (g_strequal(((enum_t*)enum)->strptr,str)) { \
+ ((rec_t*)rec)->(field_name) = ((enum_t*)enum)->value; return; } } \
+ (rec_t*)rec)->(field_name) = default; \
+}
+
+#define UAT_TOSTR_ENUM_DEF(basename,field_name,rec_t,enum_t) {\
+static void basename ## field_name ## _tostr_cb(void* rec, char** out_ptr, unsigned* out_len, void* enum, void* u2 _U_) {\
+ for(;((enum_t*)enum)->strptr;((enum_t*)enum)++) { \
+ if ( ((enum_t*)enum)->value == ((rec_t*)rec)->(field_name) ) { \
+ *out_str = ((enum_t*)enum)->strptr; \
+ *out_len = strlen(*out_ptr); } } }
+
+
+#define UAT_FLD_ENUM(basename,field_name,enum_t,enum) \
+ {#field_name, PT_TXTMOD_STRING,{uat_fld_chk_enum,basename ## field_name ## _set_cb,basename ## field_name ## _tostr_cb},{&(enum),&(enum),&(enum)},NULL,FLDFILL}
+
+
+
+
+
+
+
#endif
diff --git a/epan/uat_load.l b/epan/uat_load.l
index 2408b04d08..2e2a0b511a 100644
--- a/epan/uat_load.l
+++ b/epan/uat_load.l
@@ -48,9 +48,9 @@
#include <epan/emem.h>
#include "uat-int.h"
-
+
static uat_t* uat;
- static uat_fld_t* uat_fld;
+ static guint colnum;
static gchar* ptr;
static guint len;
static gchar* error;
@@ -63,13 +63,14 @@
#define SET_FIELD() \
{ gchar* err; \
- if (uat_fld->chk_cb) { \
- if ( ! uat_fld->chk_cb(record, ptr, len, &err) ) { \
+ if (uat->fields[colnum].cb.chk) { \
+ if ( ! uat->fields[colnum].cb.chk(record, ptr, len, uat->fields[colnum].cbdata.chk,uat->fields[colnum].fld_data, &err) ) { \
ERROR(("%s",err)); \
}\
}\
- uat_fld->set_cb(record, ptr, len);\
+ uat->fields[colnum].cb.set(record, ptr, len,uat->fields[colnum].cbdata.chk,uat->fields[colnum].fld_data);\
g_free(ptr);\
+ colnum++; \
} while(0)
#ifdef DEBUG_UAT_LOAD
@@ -96,7 +97,7 @@ comment #[^\n]*\n
<START_OF_LINE>{newline} ;
<START_OF_LINE>{comment} ;
<NEXT_FIELD>{newline} {
- ERROR(("expecting %s field in previuos line",uat_fld->name));
+ ERROR(("expecting %s field in previuos line",uat->fields[colnum].name));
BEGIN START_OF_LINE;
}
@@ -104,7 +105,7 @@ comment #[^\n]*\n
ptr = undquote(yytext,yyleng,&len);
- if (uat_fld->next) {
+ if (colnum < uat->ncols - 1) {
DUMP("quoted_str->s");
BEGIN SEPARATOR;
} else {
@@ -117,10 +118,10 @@ comment #[^\n]*\n
ptr = unbinstring(yytext,yyleng,&len);
if (!ptr) {
- ERROR(("uneven hexstring for field %s",uat_fld->name));
+ ERROR(("uneven hexstring for field %s",uat->fields[colnum].name));
}
- if ( uat_fld->next ) {
+ if ( colnum < uat->ncols - 1 ) {
DUMP("binstring->s");
BEGIN SEPARATOR;
} else {
@@ -135,7 +136,7 @@ comment #[^\n]*\n
SET_FIELD();
- if ( ! (uat_fld = uat_fld->next) ) {
+ if ( colnum >= uat->ncols ) {
ERROR(("more fields than required"));
}
@@ -143,12 +144,12 @@ comment #[^\n]*\n
}
<SEPARATOR>{newline} {
- ERROR(("expecting field %s in previuos line",uat_fld->name));
+ ERROR(("expecting field %s in previuos line",uat->fields[colnum].name));
BEGIN START_OF_LINE;
}
<SEPARATOR>. {
- ERROR(("unexpected char while looking for field %s",uat_fld->name));
+ ERROR(("unexpected char while looking for field %s",uat->fields[colnum].name));
BEGIN ERRORED;
}
@@ -166,7 +167,7 @@ comment #[^\n]*\n
SET_FIELD();
rec = uat_add_record(uat, record);
-
+
if (uat->update_cb)
uat->update_cb(rec,&err);
@@ -174,7 +175,7 @@ comment #[^\n]*\n
ERROR(("%s",err));
}
- uat_fld = uat->fields;
+ colnum = 0;;
ptr = NULL;
len = 0;
memset(record,0,uat->record_size);
@@ -333,19 +334,21 @@ done:
gboolean uat_load(uat_t* uat_in, char** err) {
gchar* fname = uat_get_actual_filename(uat_in, FALSE);
-
- g_assert(uat_in->finalized);
-
+
uat = uat_in;
-
- ;
+
+ if (!fname) {
+ UAT_UPDATE(uat);
+ return TRUE;
+ }
+
if (!(yyin = fopen(fname,"r"))) {
*err = strerror(errno);
return FALSE;
}
error = NULL;
- uat_fld = uat->fields;
+ colnum = 0;
record = g_malloc0(uat->record_size);
BEGIN START_OF_LINE;