Prefs: replace preference type 'bitmap' values with enum

The preference types (PREF_*) are #defined as bitmap values. However
these values are mutually exclusive. For instance, if a preference
type is a PREF_UINT it can't be a PREF_STRING also. In many places a
switch statement is used to select the handling for the particular
preference type, reinforcing the idea of distinct values, rather than
being a bitmap.

The only exception is PREF_OBSOLETE, which can be added to the type
value. This causes several complications. Before any switch statement
the PREF_OBSOLETE bit has to be removed from the type. In other places
this aspect is totally overlooked, and the type value is regarded
distinct, rather than a bitmap. Somehow the code skirts the issue?

With this change the bitmap values are replaced with a dedicated enum,
while the preference, just like the modules, gets a distinct boolean
'obsolete' field. This removes the need for bitmap manipulations
before using a switch statement, and makes the direct comparison of
preference type values actually work. Where required, checks for
obsolete are added.

This also allows the definitions for Lua preferences to be aligned
with epan. Even though the Lua code comment mentioned PREF_OBSOLETE,
this is not actually supported there.
This commit is contained in:
Jaap Keuter 2025-04-07 18:01:04 +02:00 committed by John Thacker
parent 7a63a37e0e
commit c0bb27ed29
10 changed files with 419 additions and 440 deletions

View File

@ -83,33 +83,34 @@ struct pref_custom_cbs {
pref_custom_to_str_cb to_str_cb;
};
/**
* PREF_OBSOLETE is used for preferences that a module used to support
* but no longer supports; we give different error messages for them.
*/
#define PREF_UINT (1u << 0)
#define PREF_BOOL (1u << 1)
#define PREF_ENUM (1u << 2)
#define PREF_STRING (1u << 3)
#define PREF_RANGE (1u << 4)
#define PREF_STATIC_TEXT (1u << 5)
#define PREF_UAT (1u << 6)
#define PREF_SAVE_FILENAME (1u << 7)
#define PREF_COLOR (1u << 8) /* XXX - These are only supported for "internal" (non-protocol) */
#define PREF_CUSTOM (1u << 9) /* use and not as a generic protocol preference */
#define PREF_OBSOLETE (1u << 10)
#define PREF_DIRNAME (1u << 11)
// Was PREF_DECODE_AS_UINT (1u << 12)
#define PREF_DECODE_AS_RANGE (1u << 13) /* XXX - Internal use only, not a generic protocol preference */
#define PREF_OPEN_FILENAME (1u << 14)
#define PREF_PASSWORD (1u << 15) /* like string, but never saved to prefs file */
/**
* Dedicated to TCP PROTOCOL for handling manual SEQ interpretation,
* and allow users manage the sender traffic ambiguities
*/
#define PREF_PROTO_TCP_SNDAMB_ENUM (1u << 16)
typedef enum {
PREF_UINT,
PREF_BOOL,
PREF_ENUM,
PREF_STRING,
PREF_RANGE,
PREF_STATIC_TEXT,
PREF_UAT,
PREF_SAVE_FILENAME,
PREF_COLOR, // (1)
PREF_CUSTOM, // (1)
PREF_DIRNAME,
PREF_DECODE_AS_RANGE, // (2)
PREF_OPEN_FILENAME,
PREF_PASSWORD, // (3)
PREF_PROTO_TCP_SNDAMB_ENUM, // (4)
PREF_DISSECTOR // (5)
} pref_type_e;
#define PREF_DISSECTOR (1u << 17) /* like string, but with dissector name syntax check */
/*
* (1) These are only supported for "internal" (non-protocol) use
* and not as a generic protocol preference.
* (2) Internal use only, not a generic protocol preference.
* (3) Like string, but never saved to prefs file.
* (4) Dedicated to TCP PROTOCOL for handling manual SEQ interpretation,
* and allow users manage the sender traffic ambiguities
* (5) Like string, but with dissector name syntax check.
*/
/* read_prefs_file: read in a generic config file and do a callback to */
/* pref_set_pair_fct() for every key/value pair found */

View File

@ -75,10 +75,6 @@ static unsigned prefs_module_list_foreach(wmem_tree_t *module_list, module_cb ca
void *user_data, bool skip_obsolete);
static int find_val_for_string(const char *needle, const enum_val_t *haystack, int default_value);
#define IS_PREF_OBSOLETE(p) ((p) & PREF_OBSOLETE)
#define SET_PREF_OBSOLETE(p) ((p) |= PREF_OBSOLETE)
#define RESET_PREF_OBSOLETE(p) ((p) &= ~PREF_OBSOLETE)
#define PF_NAME "preferences"
#define OLD_GPF_NAME "wireshark.conf" /* old name for global preferences file */
@ -223,7 +219,8 @@ struct 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 */
pref_type_e type; /**< type of that preference */
bool obsolete; /**< obsolete preference flag */
unsigned int effect_flags; /**< Flags of types effected by preference (PREF_TYPE_DISSECTION, PREF_EFFECT_CAPTURE, etc).
Flags must be non-zero to ensure saving to disk */
union { /* The Qt preference code assumes that these will all be pointers (and unique) */
@ -347,12 +344,8 @@ static void
free_pref(void *data, void *user_data _U_)
{
pref_t *pref = (pref_t *)data;
int type = pref->type;
/* we reset the PREF_OBSOLETE bit in order to allow the original preference to be freed */
RESET_PREF_OBSOLETE(type);
switch (type) {
switch (pref->type) {
case PREF_BOOL:
case PREF_ENUM:
case PREF_UINT:
@ -995,7 +988,7 @@ prefs_find_module_alias(const char *name)
*/
static pref_t *
register_preference(module_t *module, const char *name, const char *title,
const char *description, int type)
const char *description, pref_type_e type, bool obsolete)
{
pref_t *preference;
const char *p;
@ -1006,6 +999,7 @@ register_preference(module_t *module, const char *name, const char *title,
preference->title = title;
preference->description = description;
preference->type = type;
preference->obsolete = obsolete;
/* Default to module's preference effects */
preference->effect_flags = module->effect_flags;
@ -1037,7 +1031,7 @@ register_preference(module_t *module, const char *name, const char *title,
if (prefs_find_preference(module, name) != NULL)
ws_error("Preference %s has already been registered", name);
if ((!IS_PREF_OBSOLETE(type)) &&
if ((!preference->obsolete) &&
/* Don't compare if it's a subtree */
(module->name != NULL)) {
/*
@ -1199,7 +1193,7 @@ prefs_register_uint_preference(module_t *module, const char *name,
pref_t *preference;
preference = register_preference(module, name, title, description,
PREF_UINT);
PREF_UINT, false);
preference->varp.uint = var;
preference->default_val.uint = *var;
ws_assert(base > 0 && base != 1 && base < 37);
@ -1224,7 +1218,7 @@ prefs_register_uint_custom_preference(module_t *module, const char *name,
pref_t *preference;
preference = register_preference(module, name, title, description,
PREF_CUSTOM);
PREF_CUSTOM, false);
preference->custom_cbs = *custom_cbs;
preference->varp.uint = var;
@ -1242,7 +1236,7 @@ prefs_register_bool_preference(module_t *module, const char *name,
pref_t *preference;
preference = register_preference(module, name, title, description,
PREF_BOOL);
PREF_BOOL, false);
preference->varp.boolp = var;
preference->default_val.boolval = *var;
}
@ -1344,7 +1338,7 @@ prefs_register_enum_preference(module_t *module, const char *name,
preference = register_preference(module, name, title, description,
PREF_ENUM);
PREF_ENUM, false);
preference->varp.enump = var;
preference->default_val.enumval = *var;
preference->info.enum_info.enumvals = enumvals;
@ -1433,14 +1427,14 @@ prefs_set_custom_value(pref_t *pref, const char *value, pref_source_t source _U_
static void
register_string_like_preference(module_t *module, const char *name,
const char *title, const char *description,
char **var, int type,
char **var, pref_type_e type,
struct pref_custom_cbs* custom_cbs,
bool free_tmp)
{
pref_t *pref;
char *tmp;
pref = register_preference(module, name, title, description, type);
pref = register_preference(module, name, title, description, type, false);
/*
* String preference values should be non-null (as you can't
@ -1605,11 +1599,11 @@ DIAG_ON(cast-qual)
static pref_t*
prefs_register_range_preference_common(module_t *module, const char *name,
const char *title, const char *description,
range_t **var, uint32_t max_value, int type)
range_t **var, uint32_t max_value, pref_type_e type)
{
pref_t *preference;
preference = register_preference(module, name, title, description, type);
preference = register_preference(module, name, title, description, type, false);
preference->info.max_value = max_value;
/*
@ -1808,7 +1802,7 @@ prefs_register_static_text_preference(module_t *module, const char *name,
const char *title,
const char *description)
{
register_preference(module, name, title, description, PREF_STATIC_TEXT);
register_preference(module, name, title, description, PREF_STATIC_TEXT, false);
}
/*
@ -1820,7 +1814,7 @@ prefs_register_uat_preference(module_t *module, const char *name,
const char *title, const char *description,
uat_t* uat)
{
pref_t* preference = register_preference(module, name, title, description, PREF_UAT);
pref_t* preference = register_preference(module, name, title, description, PREF_UAT, false);
preference->varp.uat = uat;
}
@ -1838,7 +1832,7 @@ prefs_register_color_preference(module_t *module, const char *name,
const char *title, const char *description,
color_t *color)
{
pref_t* preference = register_preference(module, name, title, description, PREF_COLOR);
pref_t* preference = register_preference(module, name, title, description, PREF_COLOR, false);
preference->varp.colorp = color;
preference->default_val.color = *color;
@ -1914,7 +1908,7 @@ prefs_register_list_custom_preference(module_t *module, const char *name,
pref_custom_list_init_cb init_cb,
GList** list)
{
pref_t* preference = register_preference(module, name, title, description, PREF_CUSTOM);
pref_t* preference = register_preference(module, name, title, description, PREF_CUSTOM, false);
preference->custom_cbs = *custom_cbs;
init_cb(preference, list);
@ -1929,7 +1923,7 @@ prefs_register_custom_preference(module_t *module, const char *name,
struct pref_custom_cbs* custom_cbs,
void **custom_data _U_)
{
pref_t* preference = register_preference(module, name, title, description, PREF_CUSTOM);
pref_t* preference = register_preference(module, name, title, description, PREF_CUSTOM, false);
preference->custom_cbs = *custom_cbs;
/* XXX - wait until we can handle void** pointers
@ -1957,7 +1951,7 @@ prefs_register_custom_preference_TCP_Analysis(module_t *module, const char *name
pref_t *preference;
preference = register_preference(module, name, title, description,
PREF_PROTO_TCP_SNDAMB_ENUM);
PREF_PROTO_TCP_SNDAMB_ENUM, false);
preference->varp.enump = var;
preference->default_val.enumval = *var;
preference->stashed_val.list = NULL;
@ -2056,7 +2050,13 @@ bool prefs_remove_decode_as_value(pref_t *pref, unsigned value, bool set_default
void
prefs_register_obsolete_preference(module_t *module, const char *name)
{
register_preference(module, name, NULL, NULL, PREF_OBSOLETE);
register_preference(module, name, NULL, NULL, PREF_STATIC_TEXT, true);
}
bool
prefs_is_preference_obsolete(pref_t *pref)
{
return pref->obsolete;
}
void
@ -2071,6 +2071,8 @@ prefs_set_preference_effect_fields(module_t *module, const char *name)
unsigned
pref_stash(pref_t *pref, void *unused _U_)
{
ws_assert(!pref->obsolete);
switch (pref->type) {
case PREF_UINT:
@ -2111,7 +2113,7 @@ pref_stash(pref_t *pref, void *unused _U_)
case PREF_PROTO_TCP_SNDAMB_ENUM:
break;
case PREF_OBSOLETE:
default:
ws_assert_not_reached();
break;
}
@ -2125,6 +2127,8 @@ pref_unstash(pref_t *pref, void *unstash_data_p)
dissector_table_t sub_dissectors = NULL;
dissector_handle_t handle = NULL;
ws_assert(!pref->obsolete);
/* Revert the preference to its saved value. */
switch (pref->type) {
@ -2259,7 +2263,7 @@ pref_unstash(pref_t *pref, void *unstash_data_p)
case PREF_CUSTOM:
break;
case PREF_OBSOLETE:
default:
ws_assert_not_reached();
break;
}
@ -2268,6 +2272,9 @@ pref_unstash(pref_t *pref, void *unstash_data_p)
void
reset_stashed_pref(pref_t *pref) {
ws_assert(!pref->obsolete);
switch (pref->type) {
case PREF_UINT:
@ -2314,7 +2321,7 @@ reset_stashed_pref(pref_t *pref) {
case PREF_CUSTOM:
break;
case PREF_OBSOLETE:
default:
ws_assert_not_reached();
break;
}
@ -2323,6 +2330,8 @@ reset_stashed_pref(pref_t *pref) {
unsigned
pref_clean_stash(pref_t *pref, void *unused _U_)
{
ws_assert(!pref->obsolete);
switch (pref->type) {
case PREF_UINT:
@ -2367,7 +2376,7 @@ pref_clean_stash(pref_t *pref, void *unused _U_)
}
break;
case PREF_OBSOLETE:
default:
ws_assert_not_reached();
break;
}
@ -2390,7 +2399,7 @@ prefs_pref_foreach(module_t *module, pref_cb callback, void *user_data)
for (elem = g_list_first(module->prefs); elem != NULL; elem = g_list_next(elem)) {
pref = (pref_t *)elem->data;
if (IS_PREF_OBSOLETE(pref->type)) {
if (!pref || pref->obsolete) {
/*
* This preference is no longer supported; it's
* not a real preference, so we don't call the
@ -4517,23 +4526,18 @@ pre_init_prefs(void)
void
reset_pref(pref_t *pref)
{
int type;
if (!pref) return;
type = pref->type;
/*
* This preference is no longer supported; it's not a
* real preference, so we don't reset it (i.e., we
* treat it as if it weren't found in the list of
* preferences, and we weren't called in the first place).
*/
if (IS_PREF_OBSOLETE(type))
if (pref->obsolete)
return;
else
RESET_PREF_OBSOLETE(type);
switch (type) {
switch (pref->type) {
case PREF_UINT:
*pref->varp.uint = pref->default_val.uint;
@ -5891,7 +5895,6 @@ set_pref(char *pref_name, const char *value, void *private_data,
static bool filter_enabled = false;
module_t *module, *containing_module, *target_module;
pref_t *pref;
int type;
bool converted_pref = false;
target_module = (module_t*)private_data;
@ -6375,12 +6378,8 @@ set_pref(char *pref_name, const char *value, void *private_data,
return PREFS_SET_OK;
}
type = pref->type;
if (IS_PREF_OBSOLETE(type)) {
if (pref->obsolete)
return PREFS_SET_OBSOLETE; /* no such preference any more */
} else {
RESET_PREF_OBSOLETE(type);
}
if (converted_pref) {
ws_warning("Preference \"%s\" has been converted to \"%s.%s\"\n"
@ -6388,7 +6387,7 @@ set_pref(char *pref_name, const char *value, void *private_data,
pref_name, module->name ? module->name : module->parent->name, prefs_get_name(pref));
}
switch (type) {
switch (pref->type) {
case PREF_UINT:
if (!ws_basestrtou32(value, NULL, &uval, pref->info.base))
@ -6542,21 +6541,15 @@ const char *
prefs_pref_type_name(pref_t *pref)
{
const char *type_name = "[Unknown]";
int type;
if (!pref) {
return type_name; /* ...or maybe assert? */
}
type = pref->type;
if (IS_PREF_OBSOLETE(type)) {
if (pref->obsolete) {
type_name = "Obsolete";
} else {
RESET_PREF_OBSOLETE(type);
}
switch (type) {
switch (pref->type) {
case PREF_UINT:
switch (pref->info.base) {
@ -6631,6 +6624,8 @@ prefs_pref_type_name(pref_t *pref)
type_name = "Dissector";
break;
}
}
return type_name;
}
@ -6684,21 +6679,15 @@ char *
prefs_pref_type_description(pref_t *pref)
{
const char *type_desc = "An unknown preference type";
int type;
if (!pref) {
return ws_strdup_printf("%s.", type_desc); /* ...or maybe assert? */
}
type = pref->type;
if (IS_PREF_OBSOLETE(type)) {
if (pref->obsolete) {
type_desc = "An obsolete preference";
} else {
RESET_PREF_OBSOLETE(type);
}
switch (type) {
switch (pref->type) {
case PREF_UINT:
switch (pref->info.base) {
@ -6802,23 +6791,21 @@ prefs_pref_type_description(pref_t *pref)
default:
break;
}
}
return g_strdup(type_desc);
}
bool
prefs_pref_is_default(pref_t *pref)
{
int type;
if (!pref) return false;
type = pref->type;
if (IS_PREF_OBSOLETE(type)) {
if (pref->obsolete) {
return false;
} else {
RESET_PREF_OBSOLETE(type);
}
switch (type) {
switch (pref->type) {
case PREF_UINT:
if (pref->default_val.uint == *pref->varp.uint)
@ -6872,16 +6859,17 @@ prefs_pref_is_default(pref_t *pref)
/* ws_assert_not_reached(); */
break;
}
return false;
}
char *
prefs_pref_to_str(pref_t *pref, pref_source_t source) {
prefs_pref_to_str(pref_t *pref, pref_source_t source)
{
const char *pref_text = "[Unknown]";
void *valp; /* pointer to preference value */
color_t *pref_color;
char *tmp_value, *ret_value;
int type;
if (!pref) {
return g_strdup(pref_text);
@ -6907,14 +6895,10 @@ prefs_pref_to_str(pref_t *pref, pref_source_t source) {
return g_strdup(pref_text);
}
type = pref->type;
if (IS_PREF_OBSOLETE(type)) {
if (pref->obsolete) {
pref_text = "[Obsolete]";
} else {
RESET_PREF_OBSOLETE(type);
}
switch (type) {
switch (pref->type) {
case PREF_UINT:
{
@ -7003,6 +6987,8 @@ prefs_pref_to_str(pref_t *pref, pref_source_t source) {
default:
break;
}
}
return g_strdup(pref_text);
}
@ -7016,11 +7002,8 @@ write_pref(void *data, void *user_data)
write_pref_arg_t *arg = (write_pref_arg_t *)user_data;
char **desc_lines;
int i;
int type;
type = pref->type;
if (IS_PREF_OBSOLETE(type)) {
if (!pref || pref->obsolete) {
/*
* This preference is no longer supported; it's not a
* real preference, so we don't write it out (i.e., we
@ -7028,11 +7011,9 @@ write_pref(void *data, void *user_data)
* preferences, and we weren't called in the first place).
*/
return;
} else {
RESET_PREF_OBSOLETE(type);
}
switch (type) {
switch (pref->type) {
case PREF_STATIC_TEXT:
case PREF_UAT:
@ -7115,7 +7096,6 @@ count_non_uat_pref(void *data, void *user_data)
switch (pref->type)
{
case PREF_UAT:
case PREF_OBSOLETE:
case PREF_DECODE_AS_RANGE:
case PREF_PROTO_TCP_SNDAMB_ENUM:
//These types are not written in preference file

View File

@ -938,6 +938,15 @@ char *prefs_pref_type_description(pref_t *pref);
WS_DLL_PUBLIC
char *prefs_pref_to_str(pref_t *pref, pref_source_t source);
/** Fetch whether a preference is marked obsolete.
*
* @param pref A preference.
*
* @return A boolean indication the obsolesence of the preference.
*/
WS_DLL_PUBLIC
bool prefs_is_preference_obsolete(pref_t *pref);
/**
* Read the preferences file, fill in "prefs", and return a pointer to it.
* If we got an error (other than "it doesn't exist") we report it through

View File

@ -41,6 +41,7 @@
#include <epan/uat-int.h>
#include <epan/uat.h>
#include <epan/prefs.h>
#include <epan/prefs-int.h>
#include <epan/proto.h>
#include <epan/epan_dissect.h>
#include <epan/tap.h>
@ -168,26 +169,11 @@ typedef struct _wslua_expert_field_t {
int severity;
} wslua_expert_field_t;
/**
* PREF_OBSOLETE is used for preferences that a module used to support
* but no longer supports; we give different error messages for them.
*/
typedef enum {
PREF_UINT,
PREF_BOOL,
PREF_ENUM,
PREF_STRING,
PREF_RANGE,
PREF_STATIC_TEXT,
PREF_UAT,
PREF_OBSOLETE
} pref_type_t;
typedef struct _wslua_pref_t {
char* name;
char* label;
char* desc;
pref_type_t type;
pref_type_e type;
union {
bool b;
unsigned u;

View File

@ -256,7 +256,7 @@ static uat_field_t* get_uat_flds_array(lua_State *L, int idx, char * uat_filenam
return ret;
}
static int new_pref(lua_State* L, pref_type_t type) {
static int new_pref(lua_State* L, pref_type_e type) {
const char* label = luaL_optstring(L,1,NULL);
const char* descr = luaL_optstring(L,3,"");

View File

@ -5435,6 +5435,7 @@ sharkd_session_process_dumpconf_cb(pref_t *pref, void *d)
snprintf(json_pref_key, sizeof(json_pref_key), "%s.%s", data->module->name, pref_name);
sharkd_json_object_open(json_pref_key);
if (!prefs_is_preference_obsolete(pref)) {
switch (prefs_get_type(pref))
{
case PREF_UINT:
@ -5517,10 +5518,10 @@ sharkd_session_process_dumpconf_cb(pref_t *pref, void *d)
case PREF_COLOR:
case PREF_CUSTOM:
case PREF_STATIC_TEXT:
case PREF_OBSOLETE:
/* TODO */
break;
}
}
#if 0
sharkd_json_value_string("t", prefs_get_title(pref));

View File

@ -274,7 +274,7 @@ fill_prefs(module_t *module, void *root_ptr)
for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = gxx_list_next(pref_l)) {
pref_t *pref = gxx_list_data(pref_t *, pref_l);
if (prefs_get_type(pref) == PREF_OBSOLETE || prefs_get_type(pref) == PREF_STATIC_TEXT)
if (prefs_is_preference_obsolete(pref) || (prefs_get_type(pref) == PREF_STATIC_TEXT))
continue;
const char *type_name = prefs_pref_type_name(pref);
@ -329,7 +329,7 @@ void PrefsModel::populate()
root_->prependChild(special_item);
}
QString PrefsModel::typeToString(int type)
QString PrefsModel::typeToString(PrefsModelType type)
{
QString typeStr;
@ -349,7 +349,7 @@ QString PrefsModel::typeToString(int type)
return typeStr;
}
QString PrefsModel::typeToHelp(int type)
QString PrefsModel::typeToHelp(PrefsModelType type)
{
QString helpStr;

View File

@ -57,8 +57,8 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
static QString typeToString(int type);
static QString typeToHelp(int type);
static QString typeToString(PrefsModelType type);
static QString typeToHelp(PrefsModelType type);
private:
void populate();

View File

@ -51,7 +51,7 @@ module_prefs_unstash(module_t *module, void *data)
for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = gxx_list_next(pref_l)) {
pref_t *pref = gxx_list_data(pref_t *, pref_l);
if (prefs_get_type(pref) == PREF_OBSOLETE || prefs_get_type(pref) == PREF_STATIC_TEXT) continue;
if (prefs_is_preference_obsolete(pref) || prefs_get_type(pref) == PREF_STATIC_TEXT) continue;
unstashed_data.module = module;
pref_unstash(pref, &unstashed_data);
@ -75,7 +75,7 @@ module_prefs_clean_stash(module_t *module, void *)
for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = gxx_list_next(pref_l)) {
pref_t *pref = gxx_list_data(pref_t *, pref_l);
if (prefs_get_type(pref) == PREF_OBSOLETE || prefs_get_type(pref) == PREF_STATIC_TEXT) continue;
if (prefs_is_preference_obsolete(pref) || prefs_get_type(pref) == PREF_STATIC_TEXT) continue;
pref_clean_stash(pref, Q_NULLPTR);
}

View File

@ -234,6 +234,9 @@ void ProtocolPreferencesMenu::setModule(const QString module_name)
void ProtocolPreferencesMenu::addMenuItem(preference *pref)
{
if (prefs_is_preference_obsolete(pref))
return;
switch (prefs_get_type(pref)) {
case PREF_BOOL:
{
@ -284,7 +287,6 @@ void ProtocolPreferencesMenu::addMenuItem(preference *pref)
}
case PREF_CUSTOM:
case PREF_STATIC_TEXT:
case PREF_OBSOLETE:
break;
case PREF_PROTO_TCP_SNDAMB_ENUM:
{