aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2017-01-07 08:52:23 -0500
committerAnders Broman <a.broman58@gmail.com>2017-01-22 10:43:57 +0000
commit21a3b8cc71ac127e21375c62e0a738db8f3ea286 (patch)
tree5295e34869b8968b328fbf197815ae3d168e0d5e /epan
parent76cf1d0b0a0b804b24bea6afb4a4620a1607b144 (diff)
Internalize struct preference
Move "struct preference" into prefs.c, essentially creating a "private" structure to handle preferences. The 2 motivating factors were: 1. Better memory management so that clients/users of API don't have to worry about it. 2. Hide the ugliness of the union stuff and make it transparent to the API. A few bugs related to preference <-> Decode As integration were fixed while in the neighborhood. Change-Id: I509b9a236235d066b139c98222b701475e0ed365 Reviewed-on: https://code.wireshark.org/review/19578 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r--epan/decode_as.c38
-rw-r--r--epan/dissectors/packet-megaco.c2
-rw-r--r--epan/prefs-int.h117
-rw-r--r--epan/prefs.c557
-rw-r--r--epan/show_exception.c2
5 files changed, 589 insertions, 127 deletions
diff --git a/epan/decode_as.c b/epan/decode_as.c
index f7da809294..da78564b3d 100644
--- a/epan/decode_as.c
+++ b/epan/decode_as.c
@@ -152,13 +152,14 @@ static GSList *dissector_reset_list = NULL;
*/
static prefs_set_pref_e
read_set_decode_as_entries(gchar *key, const gchar *value,
- void *user_data _U_,
+ void *user_data,
gboolean return_range_errors _U_)
{
gchar *values[4] = {NULL, NULL, NULL, NULL};
gchar delimiter[4] = {',', ',', ',','\0'};
gchar *pch;
guint i, j;
+ GHashTable* processed_entries = (GHashTable*)user_data;
dissector_table_t sub_dissectors;
prefs_set_pref_e retval = PREFS_SET_OK;
gboolean is_valid = FALSE;
@@ -182,6 +183,7 @@ read_set_decode_as_entries(gchar *key, const gchar *value,
ftenum_t selector_type;
pref_t* pref_value;
module_t *module;
+ const char* proto_name;
selector_type = dissector_table_get_type(sub_dissectors);
@@ -207,26 +209,21 @@ read_set_decode_as_entries(gchar *key, const gchar *value,
}
/* Now apply the value data back to dissector table preference */
- module = prefs_find_module(proto_get_protocol_filter_name(dissector_handle_get_protocol_index(handle)));
+ proto_name = proto_get_protocol_filter_name(dissector_handle_get_protocol_index(handle));
+ module = prefs_find_module(proto_name);
pref_value = prefs_find_preference(module, values[0]);
if (pref_value != NULL) {
- switch(pref_value->type)
- {
- case PREF_DECODE_AS_UINT:
- /* This doesn't support multiple values for a dissector in Decode As because the
- preference only supports a single value. This leads to a "last port for
- dissector in Decode As wins" */
- *pref_value->varp.uint = (guint)long_value;
- module->prefs_changed = TRUE;
- break;
- case PREF_DECODE_AS_RANGE:
- prefs_range_add_value(pref_value, (guint)long_value);
- module->prefs_changed = TRUE;
- break;
- default:
- /* XXX - Worth asserting over? */
- break;
+ gboolean replace = FALSE;
+ if (g_hash_table_lookup(processed_entries, proto_name) == NULL) {
+ /* First decode as entry for this protocol, ranges may be replaced */
+ replace = TRUE;
+
+ /* Remember we've processed this protocol */
+ g_hash_table_insert(processed_entries, (gpointer)proto_name, (gpointer)proto_name);
}
+
+ prefs_add_decode_as_value(pref_value, (guint)long_value, replace);
+ module->prefs_changed = TRUE;
}
}
@@ -260,7 +257,10 @@ load_decode_as_entries(void)
daf_path = get_persconffile_path(DECODE_AS_ENTRIES_FILE_NAME, TRUE);
if ((daf = ws_fopen(daf_path, "r")) != NULL) {
- read_prefs_file(daf_path, daf, read_set_decode_as_entries, NULL);
+ /* Store saved entries for better range processing */
+ GHashTable* processed_entries = g_hash_table_new(g_str_hash, g_str_equal);
+ read_prefs_file(daf_path, daf, read_set_decode_as_entries, processed_entries);
+ g_hash_table_destroy(processed_entries);
fclose(daf);
}
g_free(daf_path);
diff --git a/epan/dissectors/packet-megaco.c b/epan/dissectors/packet-megaco.c
index ae55aafb24..c58e96cb37 100644
--- a/epan/dissectors/packet-megaco.c
+++ b/epan/dissectors/packet-megaco.c
@@ -325,7 +325,7 @@ megacostat_filtercheck(const char *opt_arg _U_, const char **filter _U_, char**
return;
}
- if (!*megaco_ctx_track->varp.boolp || !*h248_ctx_track->varp.boolp) {
+ if (!prefs_get_bool_value(megaco_ctx_track, pref_current) || !prefs_get_bool_value(h248_ctx_track, pref_current)) {
*err = g_strdup_printf("Track Context option at Protocols -> MEGACO and Protocols -> H248 preferences\n"
"has to be set to true to enable measurement of service response times.\n");
}
diff --git a/epan/prefs-int.h b/epan/prefs-int.h
index c678ffa1dd..a5e713b1e1 100644
--- a/epan/prefs-int.h
+++ b/epan/prefs-int.h
@@ -116,57 +116,6 @@ typedef enum {
GUI_QT
} gui_type_t;
-/** Struct to hold preference data */
-struct preference {
- const char *name; /**< name of preference */
- const char *title; /**< title to use in GUI */
- const char *description; /**< human-readable description of preference */
- int ordinal; /**< ordinal number of this preference */
- int type; /**< type of that preference */
- gui_type_t gui; /**< type of the GUI (QT, GTK or both) the preference is registered for */
- union { /* The Qt preference code assumes that these will all be pointers (and unique) */
- guint *uint;
- gboolean *boolp;
- gint *enump;
- char **string;
- range_t **range;
- struct epan_uat* uat;
- color_t *colorp;
- GList** list;
- } varp; /**< pointer to variable storing the value */
- union {
- guint uint;
- gboolean boolval;
- gint enumval;
- char *string;
- range_t *range;
- color_t color;
- GList* list;
- } stashed_val; /**< original value, when editing from the GUI */
- union {
- guint uint;
- gboolean boolval;
- gint enumval;
- char *string;
- range_t *range;
- color_t color;
- GList* list;
- } default_val; /**< the default value of the preference */
- union {
- guint base; /**< input/output base, for PREF_UINT */
- guint32 max_value; /**< maximum value of a range */
- struct {
- const enum_val_t *enumvals; /**< list of name & values */
- gboolean radio_buttons; /**< TRUE if it should be shown as
- radio buttons rather than as an
- option menu or combo box in
- the preferences tab */
- } enum_info; /**< for PREF_ENUM */
- } info; /**< display/text file information */
- struct pref_custom_cbs custom_cbs; /**< for PREF_CUSTOM */
- void *control; /**< handle for GUI control for this preference. GTK+ only? */
-};
-
/* read_prefs_file: read in a generic config file and do a callback to */
/* pref_set_pair_fct() for every key/value pair found */
/**
@@ -178,27 +127,35 @@ struct preference {
*/
typedef prefs_set_pref_e (*pref_set_pair_cb) (gchar *key, const gchar *value, void *private_data, gboolean return_range_errors);
-/** Set the value of a string-like preference. */
WS_DLL_PUBLIC
-void
-prefs_set_string_like_value(pref_t *pref, const gchar *value, gboolean *changed);
+const char* prefs_get_description(pref_t *pref);
-/** Set the value of a range preference. Return FALSE on error, TRUE otherwise. */
WS_DLL_PUBLIC
-gboolean
-prefs_set_range_value(pref_t *pref, const gchar *value, gboolean *changed);
+const char* prefs_get_title(pref_t *pref);
WS_DLL_PUBLIC
-gboolean
-prefs_set_stashed_range_value(pref_t *pref, const gchar *value);
+const char* prefs_get_name(pref_t *pref);
WS_DLL_PUBLIC
-gboolean
-prefs_set_stashed_range(pref_t *pref, range_t *value);
+int prefs_get_type(pref_t *pref);
WS_DLL_PUBLIC
-range_t *
-prefs_get_stashed_range(pref_t *pref);
+gui_type_t prefs_get_gui_type(pref_t *pref);
+
+WS_DLL_PUBLIC guint32 prefs_get_max_value(pref_t *pref);
+
+// GTK only
+WS_DLL_PUBLIC void* prefs_get_control(pref_t *pref);
+WS_DLL_PUBLIC void prefs_set_control(pref_t *pref, void* control);
+WS_DLL_PUBLIC int prefs_get_ordinal(pref_t *pref);
+
+WS_DLL_PUBLIC
+gboolean prefs_set_range_value_work(pref_t *pref, const gchar *value,
+ gboolean return_range_errors, gboolean *changed);
+
+WS_DLL_PUBLIC
+gboolean
+prefs_set_stashed_range_value(pref_t *pref, const gchar *value);
/** Add a range value of a range preference. */
WS_DLL_PUBLIC
@@ -210,10 +167,36 @@ WS_DLL_PUBLIC
void
prefs_range_remove_value(pref_t *pref, guint32 val);
-/** Set the value of an enum preference. */
-WS_DLL_PUBLIC
-void
-prefs_set_enum_value(pref_t *pref, const gchar *value, gboolean *changed);
+
+WS_DLL_PUBLIC gboolean prefs_set_bool_value(pref_t *pref, gboolean value, pref_source_t source);
+WS_DLL_PUBLIC gboolean prefs_get_bool_value(pref_t *pref, pref_source_t source);
+WS_DLL_PUBLIC void prefs_invert_bool_value(pref_t *pref, pref_source_t source);
+
+WS_DLL_PUBLIC gboolean prefs_set_uint_value(pref_t *pref, guint value, pref_source_t source);
+WS_DLL_PUBLIC guint prefs_get_uint_base(pref_t *pref);
+WS_DLL_PUBLIC guint prefs_get_uint_value_real(pref_t *pref, pref_source_t source);
+
+
+WS_DLL_PUBLIC gboolean prefs_set_enum_value(pref_t *pref, gint value, pref_source_t source);
+WS_DLL_PUBLIC gint prefs_get_enum_value(pref_t *pref, pref_source_t source);
+WS_DLL_PUBLIC const enum_val_t* prefs_get_enumvals(pref_t *pref);
+WS_DLL_PUBLIC gboolean prefs_get_enum_radiobuttons(pref_t *pref);
+
+WS_DLL_PUBLIC gboolean prefs_set_color_value(pref_t *pref, color_t value, pref_source_t source);
+WS_DLL_PUBLIC color_t* prefs_get_color_value(pref_t *pref, pref_source_t source);
+
+WS_DLL_PUBLIC gboolean prefs_set_string_value(pref_t *pref, const char* value, pref_source_t source);
+WS_DLL_PUBLIC char* prefs_get_string_value(pref_t *pref, pref_source_t source);
+
+WS_DLL_PUBLIC struct epan_uat* prefs_get_uat_value(pref_t *pref);
+
+WS_DLL_PUBLIC gboolean prefs_set_range_value(pref_t *pref, range_t *value, pref_source_t source);
+WS_DLL_PUBLIC range_t* prefs_get_range_value_real(pref_t *pref, pref_source_t source);
+
+WS_DLL_PUBLIC gboolean prefs_add_decode_as_value(pref_t *pref, guint value, gboolean replace);
+WS_DLL_PUBLIC gboolean prefs_remove_decode_as_value(pref_t *pref, guint value, gboolean set_default);
+
+WS_DLL_PUBLIC void reset_pref(pref_t *pref);
/** read the preferences file (or similar) and call the callback
* function to set each key/value pair found
diff --git a/epan/prefs.c b/epan/prefs.c
index 0fb1a311e2..b1528d7cf8 100644
--- a/epan/prefs.c
+++ b/epan/prefs.c
@@ -204,6 +204,102 @@ static const enum_val_t gui_packet_list_elide_mode[] = {
{NULL, NULL, -1}
};
+/** Struct to hold preference data */
+struct preference {
+ const char *name; /**< name of preference */
+ const char *title; /**< title to use in GUI */
+ const char *description; /**< human-readable description of preference */
+ int ordinal; /**< ordinal number of this preference */
+ int type; /**< type of that preference */
+ gui_type_t gui; /**< type of the GUI (QT, GTK or both) the preference is registered for */
+ union { /* The Qt preference code assumes that these will all be pointers (and unique) */
+ guint *uint;
+ gboolean *boolp;
+ gint *enump;
+ char **string;
+ range_t **range;
+ struct epan_uat* uat;
+ color_t *colorp;
+ GList** list;
+ } varp; /**< pointer to variable storing the value */
+ union {
+ guint uint;
+ gboolean boolval;
+ gint enumval;
+ char *string;
+ range_t *range;
+ color_t color;
+ GList* list;
+ } stashed_val; /**< original value, when editing from the GUI */
+ union {
+ guint uint;
+ gboolean boolval;
+ gint enumval;
+ char *string;
+ range_t *range;
+ color_t color;
+ GList* list;
+ } default_val; /**< the default value of the preference */
+ union {
+ guint base; /**< input/output base, for PREF_UINT */
+ guint32 max_value; /**< maximum value of a range */
+ struct {
+ const enum_val_t *enumvals; /**< list of name & values */
+ gboolean radio_buttons; /**< TRUE if it should be shown as
+ radio buttons rather than as an
+ option menu or combo box in
+ the preferences tab */
+ } enum_info; /**< for PREF_ENUM */
+ } info; /**< display/text file information */
+ struct pref_custom_cbs custom_cbs; /**< for PREF_CUSTOM */
+ void *control; /**< handle for GUI control for this preference. GTK+ only? */
+};
+
+const char* prefs_get_description(pref_t *pref)
+{
+ return pref->description;
+}
+
+const char* prefs_get_title(pref_t *pref)
+{
+ return pref->title;
+}
+
+int prefs_get_type(pref_t *pref)
+{
+ return pref->type;
+}
+
+gui_type_t prefs_get_gui_type(pref_t *pref)
+{
+ return pref->gui;
+}
+
+const char* prefs_get_name(pref_t *pref)
+{
+ return pref->name;
+}
+
+guint32 prefs_get_max_value(pref_t *pref)
+{
+ return pref->info.max_value;
+}
+
+void* prefs_get_control(pref_t *pref)
+{
+ return pref->control;
+}
+
+void prefs_set_control(pref_t *pref, void* control)
+{
+ pref->control = control;
+}
+
+int prefs_get_ordinal(pref_t *pref)
+{
+ return pref->ordinal;
+}
+
/*
* List of all modules with preference settings.
*/
@@ -1036,6 +1132,78 @@ prefs_register_bool_preference(module_t *module, const char *name,
preference->default_val.boolval = *var;
}
+gboolean prefs_set_bool_value(pref_t *pref, gboolean value, pref_source_t source)
+{
+ gboolean changed = FALSE;
+
+ switch (source)
+ {
+ case pref_default:
+ if (pref->default_val.boolval != value) {
+ pref->default_val.boolval = value;
+ changed = TRUE;
+ }
+ break;
+ case pref_stashed:
+ if (pref->stashed_val.boolval != value) {
+ pref->stashed_val.boolval = value;
+ changed = TRUE;
+ }
+ break;
+ case pref_current:
+ if (*pref->varp.boolp != value) {
+ *pref->varp.boolp = value;
+ changed = TRUE;
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ return changed;
+}
+
+void prefs_invert_bool_value(pref_t *pref, pref_source_t source)
+{
+ switch (source)
+ {
+ case pref_default:
+ pref->default_val.boolval = !pref->default_val.boolval;
+ break;
+ case pref_stashed:
+ pref->stashed_val.boolval = !pref->stashed_val.boolval;
+ break;
+ case pref_current:
+ *pref->varp.boolp = !(*pref->varp.boolp);
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+}
+
+gboolean prefs_get_bool_value(pref_t *pref, pref_source_t source)
+{
+ switch (source)
+ {
+ case pref_default:
+ return pref->default_val.boolval;
+ break;
+ case pref_stashed:
+ return pref->stashed_val.boolval;
+ break;
+ case pref_current:
+ return *pref->varp.boolp;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ return FALSE;
+}
+
/*
* Register a preference with an enumerated value.
*/
@@ -1055,6 +1223,69 @@ prefs_register_enum_preference(module_t *module, const char *name,
preference->info.enum_info.radio_buttons = radio_buttons;
}
+gboolean prefs_set_enum_value(pref_t *pref, gint value, pref_source_t source)
+{
+ gboolean changed = FALSE;
+
+ switch (source)
+ {
+ case pref_default:
+ if (pref->default_val.enumval != value) {
+ pref->default_val.enumval = value;
+ changed = TRUE;
+ }
+ break;
+ case pref_stashed:
+ if (pref->stashed_val.enumval != value) {
+ pref->stashed_val.enumval = value;
+ changed = TRUE;
+ }
+ break;
+ case pref_current:
+ if (*pref->varp.enump != value) {
+ *pref->varp.enump = value;
+ changed = TRUE;
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ return changed;
+}
+
+gint prefs_get_enum_value(pref_t *pref, pref_source_t source)
+{
+ switch (source)
+ {
+ case pref_default:
+ return pref->default_val.enumval;
+ break;
+ case pref_stashed:
+ return pref->stashed_val.enumval;
+ break;
+ case pref_current:
+ return *pref->varp.enump;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ return 0;
+}
+
+const enum_val_t* prefs_get_enumvals(pref_t *pref)
+{
+ return pref->info.enum_info.enumvals;
+}
+
+gboolean prefs_get_enum_radiobuttons(pref_t *pref)
+{
+ return pref->info.enum_info.radio_buttons;
+}
+
static void
register_string_like_preference(module_t *module, const char *name,
const char *title, const char *description,
@@ -1097,18 +1328,70 @@ register_string_like_preference(module_t *module, const char *name,
/*
* For use by UI code that sets preferences.
*/
-void
-prefs_set_string_like_value(pref_t *pref, const gchar *value, gboolean *changed)
+gboolean
+prefs_set_string_value(pref_t *pref, const char* value, pref_source_t source)
{
- if (*pref->varp.string) {
- if (strcmp(*pref->varp.string, value) != 0) {
- *changed = TRUE;
- g_free(*pref->varp.string);
+ gboolean changed = FALSE;
+
+ switch (source)
+ {
+ case pref_default:
+ if (*pref->default_val.string) {
+ if (strcmp(pref->default_val.string, value) != 0) {
+ changed = TRUE;
+ g_free(pref->default_val.string);
+ pref->default_val.string = g_strdup(value);
+ }
+ } else if (value) {
+ pref->default_val.string = g_strdup(value);
+ }
+ break;
+ case pref_stashed:
+ if (pref->stashed_val.string) {
+ if (strcmp(pref->stashed_val.string, value) != 0) {
+ changed = TRUE;
+ g_free(pref->stashed_val.string);
+ pref->stashed_val.string = g_strdup(value);
+ }
+ } else if (value) {
+ pref->stashed_val.string = g_strdup(value);
+ }
+ break;
+ case pref_current:
+ if (*pref->varp.string) {
+ if (strcmp(*pref->varp.string, value) != 0) {
+ changed = TRUE;
+ g_free(*pref->varp.string);
+ *pref->varp.string = g_strdup(value);
+ }
+ } else if (value) {
*pref->varp.string = g_strdup(value);
}
- } else if (value) {
- *pref->varp.string = g_strdup(value);
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ return changed;
+}
+
+char* prefs_get_string_value(pref_t *pref, pref_source_t source)
+{
+ switch (source)
+ {
+ case pref_default:
+ return pref->default_val.string;
+ case pref_stashed:
+ return pref->stashed_val.string;
+ case pref_current:
+ return *pref->varp.string;
+ default:
+ g_assert_not_reached();
+ break;
}
+
+ return NULL;
}
/*
@@ -1201,7 +1484,7 @@ prefs_register_range_preference(module_t *module, const char *name,
description, var, max_value, PREF_RANGE);
}
-static gboolean
+gboolean
prefs_set_range_value_work(pref_t *pref, const gchar *value,
gboolean return_range_errors, gboolean *changed)
{
@@ -1226,12 +1509,6 @@ prefs_set_range_value_work(pref_t *pref, const gchar *value,
* For use by UI code that sets preferences.
*/
gboolean
-prefs_set_range_value(pref_t *pref, const gchar *value, gboolean *changed)
-{
- return prefs_set_range_value_work(pref, value, TRUE, changed);
-}
-
-gboolean
prefs_set_stashed_range_value(pref_t *pref, const gchar *value)
{
range_t *newrange;
@@ -1251,22 +1528,64 @@ prefs_set_stashed_range_value(pref_t *pref, const gchar *value)
}
-gboolean
-prefs_set_stashed_range(pref_t *pref, range_t *value)
+gboolean prefs_set_range_value(pref_t *pref, range_t *value, pref_source_t source)
{
- if (!ranges_are_equal(pref->stashed_val.range, value)) {
- wmem_free(wmem_epan_scope(), pref->stashed_val.range);
- pref->stashed_val.range = range_copy(wmem_epan_scope(), value);
- return TRUE;
+ gboolean changed = FALSE;
+
+ switch (source)
+ {
+ case pref_default:
+ if (!ranges_are_equal(pref->default_val.range, value)) {
+ wmem_free(wmem_epan_scope(), pref->default_val.range);
+ pref->default_val.range = range_copy(wmem_epan_scope(), value);
+ changed = TRUE;
+ }
+ break;
+ case pref_stashed:
+ if (!ranges_are_equal(pref->stashed_val.range, value)) {
+ wmem_free(wmem_epan_scope(), pref->stashed_val.range);
+ pref->stashed_val.range = range_copy(wmem_epan_scope(), value);
+ changed = TRUE;
+ }
+ break;
+ case pref_current:
+ if (!ranges_are_equal(*pref->varp.range, value)) {
+ wmem_free(wmem_epan_scope(), *pref->varp.range);
+ *pref->varp.range = range_copy(wmem_epan_scope(), value);
+ changed = TRUE;
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ break;
}
- return FALSE;
+ return changed;
+}
+
+range_t* prefs_get_range_value_real(pref_t *pref, pref_source_t source)
+{
+ switch (source)
+ {
+ case pref_default:
+ return pref->default_val.range;
+ case pref_stashed:
+ return pref->stashed_val.range;
+ break;
+ case pref_current:
+ return *pref->varp.range;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ return NULL;
}
-range_t *
-prefs_get_stashed_range(pref_t *pref)
+range_t* prefs_get_range_value(const char *module_name, const char* pref_name)
{
- return pref->stashed_val.range;
+ return prefs_get_range_value_real(prefs_find_preference(prefs_find_module(module_name), pref_name), pref_current);
}
void
@@ -1326,6 +1645,11 @@ prefs_register_uat_preference_qt(module_t *module, const char *name,
preference->gui = GUI_QT;
}
+struct epan_uat* prefs_get_uat_value(pref_t *pref)
+{
+ return pref->varp.uat;
+}
+
/*
* Register a color preference.
*/
@@ -1340,6 +1664,64 @@ prefs_register_color_preference(module_t *module, const char *name,
preference->default_val.color = *color;
}
+gboolean prefs_set_color_value(pref_t *pref, color_t value, pref_source_t source)
+{
+ gboolean changed = FALSE;
+
+ switch (source)
+ {
+ case pref_default:
+ if ((pref->default_val.color.red != value.red) &&
+ (pref->default_val.color.green != value.green) &&
+ (pref->default_val.color.blue != value.blue)) {
+ changed = TRUE;
+ pref->default_val.color = value;
+ }
+ break;
+ case pref_stashed:
+ if ((pref->stashed_val.color.red != value.red) &&
+ (pref->stashed_val.color.green != value.green) &&
+ (pref->stashed_val.color.blue != value.blue)) {
+ changed = TRUE;
+ pref->stashed_val.color = value;
+ }
+ break;
+ case pref_current:
+ if ((pref->varp.colorp->red != value.red) &&
+ (pref->varp.colorp->green != value.green) &&
+ (pref->varp.colorp->blue != value.blue)) {
+ changed = TRUE;
+ *pref->varp.colorp = value;
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ return changed;
+}
+
+color_t* prefs_get_color_value(pref_t *pref, pref_source_t source)
+{
+ switch (source)
+ {
+ case pref_default:
+ return &pref->default_val.color;
+ case pref_stashed:
+ return &pref->stashed_val.color;
+ break;
+ case pref_current:
+ return pref->varp.colorp;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ return NULL;
+}
+
/*
* Register a "custom" preference with a list.
* XXX - This should be temporary until we can find a better way
@@ -1405,6 +1787,58 @@ void prefs_register_decode_as_preference(module_t *module, const char *name,
preference->info.base = 10;
}
+gboolean prefs_add_decode_as_value(pref_t *pref, guint value, gboolean replace)
+{
+ switch(pref->type)
+ {
+ case PREF_DECODE_AS_UINT:
+ /* This doesn't support multiple values for a dissector in Decode As because the
+ preference only supports a single value. This leads to a "last port for
+ dissector in Decode As wins" */
+ *pref->varp.uint = value;
+ break;
+ case PREF_DECODE_AS_RANGE:
+ if (replace)
+ {
+ /* If range has single value, replace it */
+ if (((*pref->varp.range)->nranges == 1) &&
+ ((*pref->varp.range)->ranges[0].low == (*pref->varp.range)->ranges[0].high)) {
+ wmem_free(wmem_epan_scope(), *pref->varp.range);
+ *pref->varp.range = range_empty(wmem_epan_scope());
+ }
+ }
+
+ prefs_range_add_value(pref, value);
+ break;
+ default:
+ /* XXX - Worth asserting over? */
+ break;
+ }
+
+ return TRUE;
+}
+
+gboolean prefs_remove_decode_as_value(pref_t *pref, guint value, gboolean set_default)
+{
+ switch(pref->type)
+ {
+ case PREF_DECODE_AS_UINT:
+ if (set_default) {
+ *pref->varp.uint = pref->default_val.uint;
+ } else {
+ *pref->varp.uint = 0;
+ }
+ break;
+ case PREF_DECODE_AS_RANGE:
+ prefs_range_remove_value(pref, value);
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
/*
* Register a preference that used to be supported but no longer is.
*/
@@ -1920,7 +2354,7 @@ column_hidden_set_cb(pref_t* pref, const gchar* value, gboolean* changed)
fmt_data *cfmt;
pref_t *format_pref;
- prefs_set_string_like_value(pref, value, changed);
+ (*changed) |= prefs_set_string_value(pref, value, pref_current);
/*
* Set the "visible" flag for the existing columns; we need to
@@ -2433,8 +2867,7 @@ capture_column_to_str_cb(pref_t* pref, gboolean default_val)
static prefs_set_pref_e
colorized_frame_set_cb(pref_t* pref, const gchar* value, gboolean* changed)
{
- prefs_set_string_like_value(pref, value, changed);
-
+ (*changed) |= prefs_set_string_value(pref, value, pref_current);
return PREFS_SET_OK;
}
@@ -3604,7 +4037,7 @@ pre_init_prefs(void)
/*
* Reset a single dissector preference.
*/
-static void
+void
reset_pref(pref_t *pref)
{
int type;
@@ -4153,20 +4586,66 @@ prefs_set_pref(char *prefarg)
return ret;
}
-guint prefs_get_uint_value(const char *module_name, const char* pref_name)
+guint prefs_get_uint_value_real(pref_t *pref, pref_source_t source)
{
- pref_t *pref = prefs_find_preference(prefs_find_module(module_name), pref_name);
- g_assert(pref != NULL);
+ switch (source)
+ {
+ case pref_default:
+ return pref->default_val.uint;
+ break;
+ case pref_stashed:
+ return pref->stashed_val.uint;
+ break;
+ case pref_current:
+ return *pref->varp.uint;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
- return *pref->varp.uint;
+ return 0;
}
-range_t* prefs_get_range_value(const char *module_name, const char* pref_name)
+guint prefs_get_uint_value(const char *module_name, const char* pref_name)
+{
+ return prefs_get_uint_value_real(prefs_find_preference(prefs_find_module(module_name), pref_name), pref_current);
+}
+
+gboolean prefs_set_uint_value(pref_t *pref, guint value, pref_source_t source)
{
- pref_t *pref = prefs_find_preference(prefs_find_module(module_name), pref_name);
- g_assert(pref != NULL);
+ gboolean changed = FALSE;
+ switch (source)
+ {
+ case pref_default:
+ if (pref->default_val.uint != value) {
+ pref->default_val.uint = value;
+ changed = TRUE;
+ }
+ break;
+ case pref_stashed:
+ if (pref->stashed_val.uint != value) {
+ pref->stashed_val.uint = value;
+ changed = TRUE;
+ }
+ break;
+ case pref_current:
+ if (*pref->varp.uint != value) {
+ *pref->varp.uint = value;
+ changed = TRUE;
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ return changed;
+}
- return *pref->varp.range;
+guint prefs_get_uint_base(pref_t *pref)
+{
+ return pref->info.base;
}
/*
@@ -4693,7 +5172,7 @@ deprecated_port_pref(gchar *pref_name, const gchar *value)
pref = prefs_find_preference(module, port_range_prefs[i].table_name);
if (pref != NULL)
{
- if (!prefs_set_range_value(pref, value, &module->prefs_changed))
+ if (!prefs_set_range_value_work(pref, value, TRUE, &module->prefs_changed))
{
return FALSE; /* number was bad */
}
@@ -5253,7 +5732,7 @@ set_pref(gchar *pref_name, const gchar *value, void *private_data _U_,
case PREF_STRING:
case PREF_FILENAME:
case PREF_DIRNAME:
- prefs_set_string_like_value(pref, value, &containing_module->prefs_changed);
+ containing_module->prefs_changed |= prefs_set_string_value(pref, value, pref_current);
break;
case PREF_RANGE:
diff --git a/epan/show_exception.c b/epan/show_exception.c
index aa037fc275..6b65dff300 100644
--- a/epan/show_exception.c
+++ b/epan/show_exception.c
@@ -100,7 +100,7 @@ show_exception(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
pref_t *display_pref = prefs_find_preference(frame_module, "disable_packet_size_limited_in_summary");
if (display_pref)
{
- if (*display_pref->varp.boolp)
+ if (prefs_get_bool_value(display_pref, pref_current))
display_info = FALSE;
}
}