diff options
-rw-r--r-- | epan/dfilter/dfilter-macro.c | 81 | ||||
-rw-r--r-- | epan/prefs-int.h | 2 | ||||
-rw-r--r-- | epan/prefs.c | 25 | ||||
-rw-r--r-- | epan/prefs.h | 10 | ||||
-rw-r--r-- | epan/uat-int.h | 28 | ||||
-rw-r--r-- | epan/uat.c | 231 | ||||
-rw-r--r-- | epan/uat.h | 231 | ||||
-rw-r--r-- | epan/uat_load.l | 43 | ||||
-rw-r--r-- | gtk/macros_dlg.c | 2 | ||||
-rw-r--r-- | gtk/prefs_dlg.c | 46 | ||||
-rw-r--r-- | gtk/uat_gui.c | 119 | ||||
-rw-r--r-- | gtk/uat_gui.h | 4 |
12 files changed, 506 insertions, 316 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; diff --git a/gtk/macros_dlg.c b/gtk/macros_dlg.c index 44759bd657..6050572c74 100644 --- a/gtk/macros_dlg.c +++ b/gtk/macros_dlg.c @@ -34,7 +34,7 @@ #include "macros_dlg.h" void macros_dialog_cb(GtkWidget *w _U_, gpointer data _U_) { - uat_t* dfmuat; + void* dfmuat; dfilter_macro_get_uat(&dfmuat); uat_window(dfmuat); } diff --git a/gtk/prefs_dlg.c b/gtk/prefs_dlg.c index 890462c08f..da16a45ed5 100644 --- a/gtk/prefs_dlg.c +++ b/gtk/prefs_dlg.c @@ -51,6 +51,7 @@ #include "compat_macros.h" #include "help_dlg.h" #include "keys.h" +#include "uat_gui.h" #include <epan/prefs-int.h> @@ -77,6 +78,8 @@ static void prefs_tree_select_cb(GtkCTree *, GtkCTreeNode *, gint, #else static void prefs_tree_select_cb(GtkTreeSelection *, gpointer); #endif +static GtkWidget* create_preference_uat(GtkWidget*, int, const gchar*, const gchar *, void*); + #define E_PREFSW_SCROLLW_KEY "prefsw_scrollw" #define E_PREFSW_TREE_KEY "prefsw_tree" @@ -237,6 +240,14 @@ pref_show(pref_t *pref, gpointer user_data) break; } + case PREF_UAT: + { + pref->control = create_preference_uat(main_tb, pref->ordinal, + label_string, pref->description, + pref->varp.uat); + break; + } + case PREF_OBSOLETE: g_assert_not_reached(); break; @@ -940,6 +951,35 @@ create_preference_static_text(GtkWidget *main_tb, int table_position, return label; } +static GtkWidget * +create_preference_uat(GtkWidget *main_tb, + int table_position, + const gchar *label_text, + const gchar *tooltip_text, + void* uat) +{ + GtkTooltips *tooltips; + GtkWidget *button = NULL; + + tooltips = OBJECT_GET_DATA(main_tb, E_TOOLTIPS_KEY); + + set_option_label(main_tb, table_position, label_text, tooltip_text, + tooltips); + + button = BUTTON_NEW_FROM_STOCK(WIRESHARK_STOCK_EDIT); + + SIGNAL_CONNECT(button, "clicked", uat_window_cb, uat); + + gtk_table_attach_defaults(GTK_TABLE(main_tb), button, 1, 2, + table_position, table_position+1); + if (tooltip_text != NULL && tooltips != NULL) + gtk_tooltips_set_tip(tooltips, button, tooltip_text, NULL); + gtk_widget_show(button); + + return button; +} + + static guint pref_check(pref_t *pref, gpointer user_data) { @@ -987,7 +1027,8 @@ pref_check(pref_t *pref, gpointer user_data) } break; - case PREF_STATIC_TEXT: + case PREF_STATIC_TEXT: + case PREF_UAT: /* Value can't be bad. */ break; @@ -1090,6 +1131,7 @@ pref_fetch(pref_t *pref, gpointer user_data) } case PREF_STATIC_TEXT: + case PREF_UAT: break; case PREF_OBSOLETE: @@ -1208,6 +1250,7 @@ pref_clean(pref_t *pref, gpointer user_data _U_) break; case PREF_STATIC_TEXT: + case PREF_UAT: break; case PREF_OBSOLETE: @@ -1541,6 +1584,7 @@ pref_revert(pref_t *pref, gpointer user_data) break; case PREF_STATIC_TEXT: + case PREF_UAT: break; case PREF_OBSOLETE: diff --git a/gtk/uat_gui.c b/gtk/uat_gui.c index 51842e15e0..8ac8f241ed 100644 --- a/gtk/uat_gui.c +++ b/gtk/uat_gui.c @@ -91,15 +91,16 @@ struct _uat_dlg_data { static void append_row(uat_t* uat, guint idx) { GPtrArray* a = g_ptr_array_new(); void* rec = UAT_INDEX_PTR(uat,idx); - uat_fld_t* f; + uat_field_t* f = uat->fields; guint rownum; - + guint colnum; + gtk_clist_freeze(GTK_CLIST(uat->rep->clist)); - for ( f = uat->fields; f ; f = f->next ) { + for ( colnum = 0; colnum < uat->ncols; colnum++ ) { guint len; char* ptr; - f->tostr_cb(rec,&ptr,&len); + f[colnum].cb.tostr(rec,&ptr,&len,f[colnum].cbdata.tostr,f[colnum].fld_data); g_ptr_array_add(a,ptr); } @@ -113,15 +114,16 @@ static void append_row(uat_t* uat, guint idx) { static void reset_row(uat_t* uat, guint idx) { void* rec = UAT_INDEX_PTR(uat,idx); - uat_fld_t* f; + uat_field_t* f = uat->fields; + guint colnum; gtk_clist_freeze(GTK_CLIST(uat->rep->clist)); - - for ( f = uat->fields; f ; f = f->next ) { + + for ( colnum = 0; colnum < uat->ncols; colnum++ ) { guint len; char* ptr; - f->tostr_cb(rec,&ptr,&len); - gtk_clist_set_text(GTK_CLIST(uat->rep->clist), idx, f->colnum, ptr); + f[colnum].cb.tostr(rec,&ptr,&len,f[colnum].cbdata.tostr,f[colnum].fld_data); + gtk_clist_set_text(GTK_CLIST(uat->rep->clist), idx, colnum, ptr); } gtk_clist_thaw(GTK_CLIST(uat->rep->clist)); @@ -131,23 +133,23 @@ static void reset_row(uat_t* uat, guint idx) { static gboolean uat_dlg_cb(GtkWidget *win _U_, gpointer user_data) { struct _uat_dlg_data* dd = user_data; - uat_fld_t* fld; + guint ncols = dd->uat->ncols; + uat_field_t* f = dd->uat->fields; char* err = NULL; - guint i; - - for (fld = dd->uat->fields, i = 0; fld ; fld = fld->next, i++) { - GtkWidget* entry = g_ptr_array_index(dd->entries,i); - const gchar* text = gtk_entry_get_text(GTK_ENTRY(entry)); + guint colnum; + + for ( colnum = 0; colnum < ncols; colnum++ ) { + const gchar* text = gtk_entry_get_text(GTK_ENTRY(g_ptr_array_index(dd->entries,colnum))); unsigned len = strlen(text); - if (fld->chk_cb) { - if (! fld->chk_cb(dd->rec,text,len,&err)) { - err = ep_strdup_printf("error in field '%s': %s",fld->name,err); + if (f[colnum].cb.chk) { + if (! f[colnum].cb.chk(dd->rec, text, len, f[colnum].cbdata.tostr, f[colnum].fld_data, &err)) { + err = ep_strdup_printf("error in field '%s': %s",f[colnum].name,err); goto on_failure; } } - fld->set_cb(dd->rec,text,len); + f[colnum].cb.set(dd->rec,text,len, f[colnum].cbdata.tostr, f[colnum].fld_data); } if (dd->uat->update_cb) { @@ -157,16 +159,19 @@ static gboolean uat_dlg_cb(GtkWidget *win _U_, gpointer user_data) { err = ep_strdup_printf("error updating record: %s",err); goto on_failure; } - - if (dd->is_new) { - uat_add_record(dd->uat, dd->rec); - - if (dd->uat->free_cb) { - dd->uat->free_cb(dd->rec); - } + } + + if (dd->is_new) { + void* rec_tmp = dd->rec; + dd->rec = uat_add_record(dd->uat, dd->rec); + + if (dd->uat->free_cb) { + dd->uat->free_cb(rec_tmp); } + + g_free(rec_tmp); } - + uat_save(dd->uat,&err); if (err) { @@ -180,7 +185,6 @@ static gboolean uat_dlg_cb(GtkWidget *win _U_, gpointer user_data) { reset_row(dd->uat,dd->row); } - if (dd->is_new) g_free(dd->rec); g_ptr_array_free(dd->entries,TRUE); window_destroy(GTK_WIDGET(dd->win)); @@ -201,7 +205,7 @@ static gboolean uat_cancel_dlg_cb(GtkWidget *win _U_, gpointer user_data) { if (dd->is_new) g_free(dd->rec); g_ptr_array_free(dd->entries,TRUE); window_destroy(GTK_WIDGET(dd->win)); - + g_free(dd); return TRUE; } @@ -209,8 +213,8 @@ static gboolean uat_cancel_dlg_cb(GtkWidget *win _U_, gpointer user_data) { static void uat_dialog(uat_t* uat, gint row) { GtkWidget *win, *main_tb, *main_vb, *bbox, *bt_cancel, *bt_ok; struct _uat_dlg_data* dd = g_malloc(sizeof(struct _uat_dlg_data)); - uat_fld_t* fld; - int i = 0; + uat_field_t* f = uat->fields; + guint colnum; dd->entries = g_ptr_array_new(); dd->win = dlg_window_new(uat->name); @@ -237,28 +241,27 @@ static void uat_dialog(uat_t* uat, gint row) { gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10); gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15); - for (fld = uat->fields; fld ; fld = fld->next) { + for ( colnum = 0; colnum < uat->ncols; colnum++ ) { GtkWidget *entry, *label; - label = gtk_label_new(fld->name); + label = gtk_label_new(f[colnum].name); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 0, 1, i+1, i + 2); + gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 0, 1, colnum+1, colnum + 2); gtk_widget_show(label); entry = gtk_entry_new(); g_ptr_array_add(dd->entries,entry); - gtk_table_attach_defaults(GTK_TABLE(main_tb), entry, 1, 2, i+1, i + 2); + gtk_table_attach_defaults(GTK_TABLE(main_tb), entry, 1, 2, colnum+1, colnum + 2); gtk_widget_show(entry); if (! dd->is_new) { gchar* text; unsigned len; - fld->tostr_cb(dd->rec,&text,&len); + f[colnum].cb.tostr(dd->rec,&text,&len, f[colnum].cbdata.tostr, f[colnum].fld_data); gtk_entry_set_text(GTK_ENTRY(entry),text); } - i++; } bbox = dlg_button_row_new(GTK_STOCK_CANCEL,GTK_STOCK_OK, NULL); @@ -285,8 +288,17 @@ struct _uat_del { static void uat_del_cb(GtkButton *button _U_, gpointer u) { struct _uat_del* ud = u; + char* err = NULL; + uat_remove_record_idx(ud->uat, ud->idx); gtk_clist_remove(GTK_CLIST(ud->uat->rep->clist),ud->idx); + + uat_save(ud->uat,&err); + + if (err) { + report_failure("an error happened while saving %s: %s",ud->uat->name,err); + } + window_destroy(GTK_WIDGET(ud->win)); window_present(GTK_WIDGET(ud->uat->rep->window)); g_free(ud); @@ -301,8 +313,8 @@ static void uat_cancel_del_cb(GtkButton *button _U_, gpointer u) { static void uat_del_dlg(uat_t* uat, int idx) { GtkWidget *win, *main_tb, *main_vb, *bbox, *bt_cancel, *bt_ok; - uat_fld_t* fld; - int i = 0; + uat_field_t* f = uat->fields; + guint colnum; void* rec = UAT_INDEX_PTR(uat,idx); struct _uat_del* ud = g_malloc(sizeof(struct _uat_del)); @@ -326,26 +338,24 @@ static void uat_del_dlg(uat_t* uat, int idx) { gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10); gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15); - for (fld = uat->fields; fld ; fld = fld->next) { + for ( colnum = 0; colnum < uat->ncols; colnum++ ) { GtkWidget *label; gchar* text; unsigned len; - fld->tostr_cb(rec,&text,&len); + f[colnum].cb.tostr(rec,&text,&len, f[colnum].cbdata.tostr, f[colnum].fld_data); - label = gtk_label_new(fld->name); + label = gtk_label_new(f[colnum].name); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 0, 1, i+1, i + 2); + gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 0, 1, colnum+1, colnum + 2); gtk_widget_show(label); label = gtk_label_new(text); gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 1, 2, i+1, i + 2); + gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 1, 2, colnum+1, colnum + 2); gtk_widget_show(label); - - i++; - } + } bbox = dlg_button_row_new(GTK_STOCK_CANCEL,GTK_STOCK_DELETE, NULL); gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0); @@ -404,10 +414,12 @@ static void free_rep(GtkWindow *win _U_, uat_t* uat) { } -GtkWidget* uat_window(uat_t* uat) { +GtkWidget* uat_window(void* u) { + uat_t* uat = u; + uat_field_t* f = uat->fields; uat_rep_t* rep; - uat_fld_t* f; guint i; + guint colnum; if (uat->rep) { window_present(uat->rep->window); @@ -440,9 +452,9 @@ GtkWidget* uat_window(uat_t* uat) { rep->clist = gtk_clist_new(uat->ncols); - for ( f = uat->fields; f ; f = f->next ) { - gtk_clist_set_column_title(GTK_CLIST(rep->clist), f->colnum, f->name); - gtk_clist_set_column_auto_resize(GTK_CLIST(rep->clist), f->colnum, TRUE); + for ( colnum = 0; colnum < uat->ncols; colnum++ ) { + gtk_clist_set_column_title(GTK_CLIST(rep->clist), colnum, f[colnum].name); + gtk_clist_set_column_auto_resize(GTK_CLIST(rep->clist), colnum, TRUE); } gtk_clist_column_titles_show(GTK_CLIST(rep->clist)); @@ -514,3 +526,6 @@ GtkWidget* uat_window(uat_t* uat) { return rep->window; } +void uat_window_cb(GtkWidget* u _U_, void* uat) { + uat_window(uat); +} diff --git a/gtk/uat_gui.h b/gtk/uat_gui.h index 13f934a579..8daf274847 100644 --- a/gtk/uat_gui.h +++ b/gtk/uat_gui.h @@ -29,8 +29,8 @@ #ifndef _UAT_GUI_H_ #define _UAT_GUI_H_ -#include <epan/uat.h> -GtkWidget* uat_window(uat_t*); +GtkWidget* uat_window(void*); +void uat_window_cb(GtkWidget* unused, void* uat); #endif |