Check the values of the protocol preferences before fetching them; if
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 12 Oct 2004 03:13:17 +0000 (03:13 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 12 Oct 2004 03:13:17 +0000 (03:13 +0000)
any are not valid, pop up an alert box and don't dismiss the preferences
dialog.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@12269 f5534014-38df-0310-8fa8-9805f1628bb7

epan/prefs.c
epan/prefs.h
gtk/prefs_dlg.c

index a2b77bdace8cb979c72f46b19491bf7df2c188e1..1def43c8446a94448512ecf6267b3073645708db 100644 (file)
@@ -316,43 +316,39 @@ find_module(const char *name)
        return (module_t *) list_entry->data;
 }
 
-typedef struct {
-       module_cb callback;
-       gpointer user_data;
-} module_cb_arg_t;
-
-static void
-do_module_callback(gpointer data, gpointer user_data)
-{
-       module_t *module = data;
-       module_cb_arg_t *arg = user_data;
-
-       if (!module->obsolete)
-               (*arg->callback)(module, arg->user_data);
-}
-
 /*
  * Call a callback function, with a specified argument, for each module
  * in a list of modules.  If the list is NULL, searches the top-level
- * list in the display tree of modules.
+ * list in the display tree of modules.  If any callback returns a
+ * non-zero value, we stop and return that value, otherwise we
+ * return 0.
  *
  * Ignores "obsolete" modules; their sole purpose is to allow old
  * preferences for dissectors that no longer have preferences to be
  * silently ignored in preference files.  Does not ignore subtrees,
  * as this can be used when walking the display tree of modules.
  */
-void
+guint
 prefs_module_list_foreach(GList *module_list, module_cb callback,
     gpointer user_data)
 {
-       module_cb_arg_t arg;
+       GList *elem;
+       module_t *module;
+       guint ret;
 
        if (module_list == NULL)
                module_list = top_level_modules;
 
-       arg.callback = callback;
-       arg.user_data = user_data;
-       g_list_foreach(module_list, do_module_callback, &arg);
+       for (elem = g_list_first(module_list); elem != NULL;
+           elem = g_list_next(elem)) {
+               module = elem->data;
+               if (!module->obsolete) {
+                       ret = (*callback)(module, user_data);
+                       if (ret != 0)
+                               return ret;
+               }
+       }
+       return 0;
 }
 
 /*
@@ -363,10 +359,10 @@ prefs_module_list_foreach(GList *module_list, module_cb callback,
  * preferences for dissectors that no longer have preferences to be
  * silently ignored in preference files.
  */
-void
+guint
 prefs_modules_foreach(module_cb callback, gpointer user_data)
 {
-       prefs_module_list_foreach(modules, callback, user_data);
+       return prefs_module_list_foreach(modules, callback, user_data);
 }
 
 static void
index 8f2c274fc1eadaacb5848e9e81b442eace151bb3..5a6f589a4b9e82046d6f26b2d26ba31e2408171e 100644 (file)
@@ -196,7 +196,7 @@ extern module_t *prefs_register_protocol_obsolete(int id);
 /*
  * Callback function for module list scanners.
  */
-typedef void (*module_cb)(module_t *module, gpointer user_data);
+typedef guint (*module_cb)(module_t *module, gpointer user_data);
 
 /*
  * Call a callback function, with a specified argument, for each module
@@ -208,7 +208,7 @@ typedef void (*module_cb)(module_t *module, gpointer user_data);
  * silently ignored in preference files.  Does not ignore subtrees,
  * as this can be used when walking the display tree of modules.
  */
-extern void prefs_module_list_foreach(GList *module_list, module_cb callback,
+extern guint prefs_module_list_foreach(GList *module_list, module_cb callback,
     gpointer user_data);
 
 /*
@@ -219,7 +219,7 @@ extern void prefs_module_list_foreach(GList *module_list, module_cb callback,
  * preferences for dissectors that no longer have preferences to be
  * silently ignored in preference files.
  */
-extern void prefs_modules_foreach(module_cb callback, gpointer user_data);
+extern guint prefs_modules_foreach(module_cb callback, gpointer user_data);
 
 /*
  * Call the "apply" callback function for each module if any of its
index d52e3a8ff24c8d053134c9a2daa78d3a6de63fe0..cf329a052480e5e0a5d80828aa8912654aad5187 100644 (file)
@@ -213,7 +213,7 @@ pref_show(pref_t *pref, gpointer user_data)
 
 #define MAX_TREE_NODE_NAME_LEN 64
 /* show prefs page for each registered module (protocol) */
-static void
+static guint
 module_prefs_show(module_t *module, gpointer user_data)
 {
   struct ct_struct *cts = user_data;
@@ -243,7 +243,7 @@ module_prefs_show(module_t *module, gpointer user_data)
        * nothing under it that will be displayed, don't put it into
        * the window.
        */
-      return;
+      return 0;
     }
   }
 
@@ -334,6 +334,8 @@ module_prefs_show(module_t *module, gpointer user_data)
     /* Show 'em what we got */
     gtk_widget_show_all(main_vb);
   }
+
+  return 0;
 }
 
 
@@ -852,6 +854,53 @@ create_preference_entry(GtkWidget *main_tb, int table_position,
        return entry;
 }
 
+static guint
+pref_check(pref_t *pref, gpointer user_data)
+{
+  const char *str_val;
+  char *p;
+  guint uval;
+  pref_t **badpref = user_data;
+
+  /* Fetch the value of the preference, and check whether it's valid. */
+  switch (pref->type) {
+
+  case PREF_UINT:
+    str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
+    uval = strtoul(str_val, &p, pref->info.base);
+    if (p == str_val || *p != '\0') {
+      *badpref = pref;
+      return PREFS_SET_SYNTAX_ERR;     /* number was bad */
+    }
+    break;
+
+  case PREF_BOOL:
+    /* Value can't be bad. */
+    break;
+
+  case PREF_ENUM:
+    /* Value can't be bad. */
+    break;
+
+  case PREF_STRING:
+    /* Value can't be bad. */
+    break;
+
+  case PREF_OBSOLETE:
+    g_assert_not_reached();
+    break;
+  }
+  return 0;
+}
+
+static guint
+module_prefs_check(module_t *module, gpointer user_data)
+{
+  /* For all preferences in this module, fetch its value from this
+     module's notebook page and check whether it's valid. */
+  return prefs_pref_foreach(module, pref_check, user_data);
+}
+
 static guint
 pref_fetch(pref_t *pref, gpointer user_data)
 {
@@ -918,7 +967,7 @@ pref_fetch(pref_t *pref, gpointer user_data)
   return 0;
 }
 
-static void
+static guint
 module_prefs_fetch(module_t *module, gpointer user_data)
 {
   gboolean *must_redissect_p = user_data;
@@ -933,6 +982,8 @@ module_prefs_fetch(module_t *module, gpointer user_data)
      could cause packets to be dissected differently. */
   if (module->prefs_changed)
     *must_redissect_p = TRUE;
+
+  return 0;    /* keep fetching module preferences */
 }
 
 static guint
@@ -963,19 +1014,40 @@ pref_clean(pref_t *pref, gpointer user_data _U_)
   return 0;
 }
 
-static void
+static guint
 module_prefs_clean(module_t *module, gpointer user_data _U_)
 {
   /* For all preferences in this module, clean up any cruft allocated for
      use by the GUI code. */
   prefs_pref_foreach(module, pref_clean, NULL);
+  return 0;    /* keep cleaning modules */
 }
 
-
 /* fetch all pref values from all pages */
-static void
+static gboolean
 prefs_main_fetch_all(GtkWidget *dlg, gboolean *must_redissect)
 {
+  pref_t *badpref;
+
+  /* First, check that the values are all valid. */
+  /* XXX - check the non-registered preferences too */
+  switch (prefs_modules_foreach(module_prefs_check, (gpointer)&badpref)) {
+
+  case PREFS_SET_SYNTAX_ERR:
+    switch (badpref->type) {
+
+    case PREF_UINT:
+      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                    "The value for \"%s\" is not a valid number.",
+                    badpref->title);
+      return FALSE;
+
+    default:
+      g_assert_not_reached();
+      break;
+    }
+  }
+
   /* Fetch the preferences (i.e., make sure all the values set in all of
      the preferences panes have been copied to "prefs" and the registered
      preferences). */
@@ -998,8 +1070,9 @@ prefs_main_fetch_all(GtkWidget *dlg, gboolean *must_redissect)
   nameres_prefs_fetch(OBJECT_GET_DATA(dlg, E_NAMERES_PAGE_KEY));
 
   prefs_modules_foreach(module_prefs_fetch, must_redissect);
-}
 
+  return TRUE;
+}
 
 /* apply all pref values to the real world */
 static void
@@ -1066,7 +1139,8 @@ prefs_main_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
 {
   gboolean must_redissect = FALSE;
 
-  prefs_main_fetch_all(parent_w, &must_redissect);
+  if (!prefs_main_fetch_all(parent_w, &must_redissect))
+    return; /* Errors in some preference setting */
 
   prefs_main_apply_all(parent_w);
 
@@ -1084,7 +1158,8 @@ prefs_main_apply_cb(GtkWidget *apply_bt _U_, gpointer parent_w)
 {
   gboolean must_redissect = FALSE;
 
-  prefs_main_fetch_all(parent_w, &must_redissect);
+  if (!prefs_main_fetch_all(parent_w, &must_redissect))
+    return; /* Errors in some preference setting */
 
   prefs_main_apply_all(parent_w);
 
@@ -1102,7 +1177,8 @@ prefs_main_save_cb(GtkWidget *save_bt _U_, gpointer parent_w)
   char *pf_dir_path;
   char *pf_path;
 
-  prefs_main_fetch_all(parent_w, &must_redissect);
+  if (!prefs_main_fetch_all(parent_w, &must_redissect))
+    return; /* Errors in some preference setting */
 
   /* Create the directory that holds personal configuration files, if
      necessary.  */
@@ -1188,7 +1264,7 @@ pref_revert(pref_t *pref, gpointer user_data)
   return 0;
 }
 
-static void
+static guint
 module_prefs_revert(module_t *module, gpointer user_data)
 {
   gboolean *must_redissect_p = user_data;
@@ -1204,6 +1280,7 @@ module_prefs_revert(module_t *module, gpointer user_data)
      could cause packets to be dissected differently. */
   if (module->prefs_changed)
     *must_redissect_p = TRUE;
+  return 0;    /* keep processing modules */
 }
 
 /* cancel button pressed, revert prefs to saved and exit dialog */
@@ -1256,14 +1333,17 @@ struct properties_data {
   module_t *module;
 };
 
-static void
+static guint
 module_search_properties(module_t *module, gpointer user_data)
 {
   struct properties_data *p = (struct properties_data *)user_data;
 
   /* If this module has the specified title, remember it. */
-  if (strcmp(module->title, p->title) == 0)
+  if (strcmp(module->title, p->title) == 0) {
     p->module = module;
+    return 1;  /* stops the search */
+  }
+  return 0;
 }
 
 void