From 1b7f5d9f798634770656a82aaa2df30f7f01a9b0 Mon Sep 17 00:00:00 2001 From: Michael Mann Date: Thu, 22 Jun 2017 11:34:48 -0400 Subject: Convert filter expressions preference data to a UAT. The filter expressions data was shoved into the preference file in a very loose, non-arrayed form. It's much easier to manage in code (and for users in a separate file) as a UAT. The GTK GUI was hacked to use the existing UAT dialog rather than rewrite the pref_filter_expressions.c to support a UAT. Should be okay since it's deprecated. Change-Id: I688cebb4b7b6594878c1398365e79a205f1902d9 Ping-Bug: 13814 Reviewed-on: https://code.wireshark.org/review/22354 Reviewed-by: Peter Wu Petri-Dish: Peter Wu Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann --- epan/filter_expressions.c | 114 +++++++++++++++++++++++++++++++--------------- epan/filter_expressions.h | 26 ++++------- epan/prefs.c | 66 ++++++++++++++++----------- epan/prefs.h | 1 - 4 files changed, 128 insertions(+), 79 deletions(-) (limited to 'epan') diff --git a/epan/filter_expressions.c b/epan/filter_expressions.c index bf5a29033a..048bad65bd 100644 --- a/epan/filter_expressions.c +++ b/epan/filter_expressions.c @@ -22,64 +22,106 @@ #include "config.h" -#include -#include #include #include +#include +#include #include "epan/filter_expressions.h" -static struct filter_expression *_filter_expression_head = NULL; -struct filter_expression **pfilter_expression_head = &_filter_expression_head; +/* UAT variables */ +static uat_t *display_filter_macro_uat = NULL; +static filter_expression_t *display_filter_macros = NULL; +static guint num_display_filter_macros = 0; + +/* Field callbacks. */ +UAT_BOOL_CB_DEF(display_filter_macro_uat, enabled, filter_expression_t) +UAT_CSTRING_CB_DEF(display_filter_macro_uat, label, filter_expression_t) +UAT_DISPLAY_FILTER_CB_DEF(display_filter_macro_uat, expression, filter_expression_t) /* * Create a new filter_expression and add it to the end of the list * of filter_expressions. */ -struct filter_expression * +filter_expression_t* filter_expression_new(const gchar *label, const gchar *expr, const gboolean enabled) { - struct filter_expression *expression; - struct filter_expression *prev; - - expression = (struct filter_expression *)g_malloc0(sizeof(struct filter_expression)); - expression->label = g_strdup(label); - expression->expression = g_strdup(expr); - expression->enabled = enabled; - - /* Add it at the end so the button order is always the same*/ - if (*pfilter_expression_head == NULL) { - _filter_expression_head = expression; - } else { - prev = *pfilter_expression_head; - while (prev->next != NULL) - prev = prev->next; - prev->next = expression; - expression->filter_index = prev->filter_index + 1; - } + filter_expression_t expression; - return(expression); + //UAT does the allocation of memory before copying structure + memset(&expression, 0, sizeof(expression)); + expression.label = g_strdup(label); + expression.expression = g_strdup(expr); + expression.enabled = enabled; + + /* XXX - This is just returned to make GTK GUI work. */ + return (filter_expression_t*)uat_add_record(display_filter_macro_uat, &expression, TRUE); } -void -filter_expression_init(void) +void filter_expression_iterate_expressions(wmem_foreach_func func, void* user_data) { - prefs.filter_expressions = pfilter_expression_head; + guint i; + + for (i = 0; i < num_display_filter_macros; i++) + { + func(NULL, &display_filter_macros[i], user_data); + } } -void -filter_expression_free(struct filter_expression *list_head) -{ - if (list_head == NULL) - return; - filter_expression_free(list_head->next); - g_free(list_head->label); - g_free(list_head->expression); - g_free(list_head); +static void display_filter_free_cb(void*r) { + filter_expression_t* rec = (filter_expression_t*)r; + + g_free(rec->label); + g_free(rec->expression); +} + +static void* display_filter_copy_cb(void* n, const void* o, size_t siz _U_) { + filter_expression_t* new_record = (filter_expression_t*)n; + const filter_expression_t* old_record = (const filter_expression_t*)o; + + new_record->button = old_record->button; + new_record->label = g_strdup(old_record->label); + new_record->expression = g_strdup(old_record->expression); + + new_record->enabled = old_record->enabled; + + return new_record; } +static uat_field_t display_filter_uat_flds[] = { + UAT_FLD_BOOL(display_filter_macro_uat, enabled, "Enabled", + "Checked to add display filter button to toolbar"), + UAT_FLD_CSTRING(display_filter_macro_uat, label, "Button Label", + "Name of the display filter button"), + UAT_FLD_DISPLAY_FILTER(display_filter_macro_uat, expression, "Filter Expression", + "Filter expression to be applied by the button"), + UAT_END_FIELDS +}; + +void filter_expression_register_uat(module_t* pref_module) +{ + display_filter_macro_uat = uat_new("Display expressions", + sizeof(filter_expression_t), /* record size */ + "dfilter_buttons", /* filename */ + TRUE, /* from_profile */ + &display_filter_macros, /* data_ptr */ + &num_display_filter_macros, /* numitems_ptr */ + 0, /* Doesn't not explicitly effect dissection */ + NULL, /* help */ + display_filter_copy_cb, /* copy callback */ + NULL, /* update callback */ + display_filter_free_cb, /* free callback */ + NULL, /* post update callback */ + NULL, /* reset callback */ + display_filter_uat_flds); /* UAT field definitions */ + + prefs_register_uat_preference(pref_module, "expressions", + "Display filter expressions", + "Macros for display filters", + display_filter_macro_uat); +} /* diff --git a/epan/filter_expressions.h b/epan/filter_expressions.h index a5042fff09..a9af58860a 100644 --- a/epan/filter_expressions.h +++ b/epan/filter_expressions.h @@ -25,6 +25,9 @@ #include "ws_symbol_export.h" +#include +#include + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -33,19 +36,15 @@ extern "C" { * Filter expressions. */ -struct filter_expression { - gpointer button; /* Filter toolbar */ +typedef struct filter_expression { + gpointer button; /* Filter toolbar (GTK only) */ gchar *label; gchar *expression; - gint filter_index; gboolean enabled; /* Can be set to FALSE by Preferences Dialog */ - gboolean deleted; /* Can be set to TRUE by Preferences Dialog (GTK+ only) */ - - struct filter_expression *next; -}; +} filter_expression_t; -WS_DLL_PUBLIC struct filter_expression **pfilter_expression_head; +WS_DLL_PUBLIC void filter_expression_iterate_expressions(wmem_foreach_func func, void* user_data); /** Create a filter expression * @@ -55,16 +54,11 @@ WS_DLL_PUBLIC struct filter_expression **pfilter_expression_head; * @return A newly allocated and initialized struct filter_expression. */ WS_DLL_PUBLIC -struct filter_expression *filter_expression_new(const gchar *label, +filter_expression_t *filter_expression_new(const gchar *label, const gchar *expr, const gboolean enabled); -void filter_expression_init(void); - -/** Clear the filter expression list. - * Frees each item in the list. Caller should set list_head to NULL afterward. - */ -WS_DLL_PUBLIC -void filter_expression_free(struct filter_expression *list_head); +/* Keep the UAT structure local to the filter_expressions */ +void filter_expression_register_uat(module_t* pref_module); #ifdef __cplusplus } diff --git a/epan/prefs.c b/epan/prefs.c index 854fba53c8..a63223b221 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -3356,6 +3356,14 @@ prefs_register_modules(void) "Look for dissectors that left some bytes undecoded (debug)", &prefs.incomplete_dissectors_check_debug); + /* Display filter Expressions + * This used to be an array of individual fields that has now been + * converted to a UAT. Just make it part of the GUI category even + * though the name of the preference will never be seen in preference + * file + */ + filter_expression_register_uat(gui_module); + /* Capture * These are preferences that can be read/written using the * preference module API. These preferences still use their own @@ -3890,8 +3898,6 @@ init_prefs(void) prefs_register_modules(); - filter_expression_init(); - prefs_initialized = TRUE; } @@ -4206,12 +4212,6 @@ prefs_reset(void) */ oids_cleanup(); - /* - * Free the filter expression list. - */ - filter_expression_free(*pfilter_expression_head); - *pfilter_expression_head = NULL; - /* * Reset the non-dissector preferences. */ @@ -5299,6 +5299,8 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_, pref_t *pref; int type; + //The PRS_GUI field names are here for backwards compatibility + //display filters have been converted to a UAT. if (strcmp(pref_name, PRS_GUI_FILTER_LABEL) == 0) { filter_label = g_strdup(value); } else if (strcmp(pref_name, PRS_GUI_FILTER_ENABLED) == 0) { @@ -6370,6 +6372,35 @@ write_pref(gpointer data, gpointer user_data) } +static void +count_non_uat_pref(gpointer data, gpointer user_data) +{ + pref_t *pref = (pref_t *)data; + int *arg = (int *)user_data; + + switch (pref->type) + { + case PREF_UAT: + case PREF_OBSOLETE: + case PREF_DECODE_AS_UINT: + case PREF_DECODE_AS_RANGE: + //These types are not written in preference file + break; + default: + (*arg)++; + break; + } +} + +static int num_non_uat_prefs(module_t *module) +{ + int num = 0; + + g_list_foreach(module->prefs, count_non_uat_pref, &num); + + return num; +} + /* * Write out all preferences for a module. */ @@ -6387,7 +6418,7 @@ write_module_prefs(module_t *module, gpointer user_data) /* Write a header for the main modules and GUI sub-modules */ if (((module->parent == NULL) || (module->parent == gui_module)) && ((prefs_module_has_submodules(module)) || - (module->numprefs > 0) || + (num_non_uat_prefs(module) > 0) || (module->name == NULL))) { if ((module->name == NULL) && (module->parent != NULL)) { fprintf(gui_pref_arg->pf, "\n####### %s: %s ########\n", module->parent->title, module->title); @@ -6457,23 +6488,6 @@ write_prefs(char **pf_path_return) write_module_prefs(gui_module, &write_gui_pref_info); - { - struct filter_expression *fe = *(struct filter_expression **)prefs.filter_expressions; - - if (fe != NULL) - fprintf(pf, "\n####### Filter Expressions ########\n\n"); - - while (fe != NULL) { - if (fe->deleted == FALSE) { - fprintf(pf, "%s: %s\n", PRS_GUI_FILTER_LABEL, fe->label); - fprintf(pf, "%s: %s\n", PRS_GUI_FILTER_ENABLED, - fe->enabled == TRUE ? "TRUE" : "FALSE"); - fprintf(pf, "%s: %s\n", PRS_GUI_FILTER_EXPR, fe->expression); - } - fe = fe->next; - } - } - write_gui_pref_info.is_gui_module = FALSE; prefs_modules_foreach_submodules(NULL, write_module_prefs, &write_gui_pref_info); diff --git a/epan/prefs.h b/epan/prefs.h index 96546a188a..eba5e65fbb 100644 --- a/epan/prefs.h +++ b/epan/prefs.h @@ -220,7 +220,6 @@ typedef struct _e_prefs { gboolean display_byte_fields_with_spaces; gboolean enable_incomplete_dissectors_check; gboolean incomplete_dissectors_check_debug; - gpointer filter_expressions;/* Actually points to &head */ gboolean gui_update_enabled; software_update_channel_e gui_update_channel; gint gui_update_interval; -- cgit v1.2.1