forked from osmocom/wireshark
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
This commit is contained in:
parent
009d38e6a0
commit
d70a58f881
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
25
epan/prefs.c
25
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,
|
||||
|
@ -638,6 +639,24 @@ void prefs_register_static_text_preference(module_t *module, const char *name,
|
|||
register_preference(module, name, title, description, PREF_STATIC_TEXT);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
|
10
epan/prefs.h
10
epan/prefs.h
|
@ -313,6 +313,16 @@ extern void prefs_register_range_preference(module_t *module, const char *name,
|
|||
extern void prefs_register_static_text_preference(module_t *module, const char *name,
|
||||
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.
|
||||
*/
|
||||
|
|
|
@ -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)))
|
||||
|
|
251
epan/uat.c
251
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,83 +51,7 @@ 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 = g_malloc(sizeof(uat_t));
|
||||
|
||||
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);
|
||||
|
||||
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->copy_cb = copy_cb;
|
||||
uat->update_cb = update_cb;
|
||||
uat->free_cb = free_cb;
|
||||
|
||||
uat->fields = NULL;
|
||||
uat->ncols = 0;
|
||||
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) );
|
||||
|
||||
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,
|
||||
uat_t* uat_new(const char* name,
|
||||
size_t size,
|
||||
char* filename,
|
||||
void** data_ptr,
|
||||
|
@ -133,44 +59,52 @@ uat_t* uat_new(const char* uat_name,
|
|||
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);
|
||||
uat_field_t* flds_array) {
|
||||
uat_t* uat = g_malloc(sizeof(uat_t));
|
||||
guint i;
|
||||
|
||||
name = va_arg(ap,char*);
|
||||
if (!all_uats)
|
||||
all_uats = g_ptr_array_new();
|
||||
|
||||
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);
|
||||
g_ptr_array_add(all_uats,uat);
|
||||
|
||||
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 = numitems_ptr;
|
||||
uat->copy_cb = copy_cb;
|
||||
uat->update_cb = update_cb;
|
||||
uat->free_cb = free_cb;
|
||||
uat->fields = flds_array;
|
||||
uat->user_data = g_array_new(FALSE,FALSE,uat->record_size);
|
||||
uat->rep = NULL;
|
||||
uat->free_rep = NULL;
|
||||
|
||||
for (i=0;flds_array[i].name;i++) {
|
||||
fld_data_t* f = g_malloc(sizeof(fld_data_t));
|
||||
|
||||
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)
|
||||
|
||||
|
|
231
epan/uat.h
231
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,41 +232,9 @@ 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_field_t* flds_array);
|
||||
|
||||
|
||||
/*
|
||||
* 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_finalize()
|
||||
* once fields have been added it makes the uat usable, leaves it locked.
|
||||
*/
|
||||
void uat_finalize(uat_t*);
|
||||
|
||||
/*
|
||||
* uat_dup()
|
||||
* uat_se_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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
121
gtk/uat_gui.c
121
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue