Fix an issue with callbacks that return FALSE.
authorMatthias Clasen <matthiasc@src.gnome.org>
Fri, 28 Nov 2008 05:17:27 +0000 (05:17 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Fri, 28 Nov 2008 05:17:27 +0000 (05:17 +0000)
svn path=/trunk/; revision=7684

ChangeLog
glib/goption.c
glib/tests/option-context.c

index eb8c726..22a412e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2008-11-28  Matthias Clasen  <mclasen@redhat.com>
+
+       Bug 562378 – callback return value not respected for callback option
+       with no arg
+
+       * glib/goption.c (parse_long_option): Return the parse_arg return
+       value even for no-arg callbacks. Patch by Christian Persch
+
+       * glib/tests/option-context.c: Add a test for a callback which
+       returns FALSE.
+
 2008-11-23  Christian Persch  <chpe@gnome.org>
 
        Bug 559413 – g_option_group_set_error_hook docs buglet
index b45e5f4..906fc19 100644 (file)
@@ -1303,14 +1303,17 @@ parse_long_option (GOptionContext *context,
          strcmp (arg, group->entries[j].long_name) == 0)
        {
          gchar *option_name;
+         gboolean retval;
 
          option_name = g_strconcat ("--", group->entries[j].long_name, NULL);
-         parse_arg (context, group, &group->entries[j],
-                    NULL, option_name, error);
+         retval = parse_arg (context, group, &group->entries[j],
+                             NULL, option_name, error);
          g_free(option_name);
          
          add_pending_null (context, &((*argv)[*index]), NULL);
          *parsed = TRUE;
+
+         return retval;
        }
       else
        {
index f7ec209..913ad5c 100644 (file)
@@ -1025,6 +1025,82 @@ callback_remaining_test1 (void)
   g_option_context_free (context);
 }
 
+static gboolean
+callback_error (const gchar *option_name, const gchar *value,
+                gpointer data, GError **error)
+{
+  g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "42");
+  return FALSE;
+}
+
+static void
+callback_returns_false (void)
+{
+  GOptionContext *context;
+  gboolean retval;
+  GError *error = NULL;
+  gchar **argv;
+  int argc;
+  GOptionEntry entries [] =
+    { { "error", 0, 0, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
+      { "error-no-arg", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
+      { "error-optional-arg", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
+      { NULL } };
+
+  context = g_option_context_new (NULL);
+  g_option_context_add_main_entries (context, entries, NULL);
+
+  /* Now try parsing */
+  argv = split_string ("program --error value", &argc);
+  
+  retval = g_option_context_parse (context, &argc, &argv, &error);
+  g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
+  g_assert (retval == FALSE);
+
+  g_option_context_free (context);
+  g_clear_error (&error);
+
+  /* And again, this time with a no-arg variant */
+  context = g_option_context_new (NULL);
+  g_option_context_add_main_entries (context, entries, NULL);
+
+  argv = split_string ("program --error-no-arg", &argc);
+  
+  retval = g_option_context_parse (context, &argc, &argv, &error);
+  g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
+  g_assert (retval == FALSE);
+
+  g_option_context_free (context);
+  g_clear_error (&error);
+
+  /* And again, this time with a optional arg variant, with argument */
+  context = g_option_context_new (NULL);
+  g_option_context_add_main_entries (context, entries, NULL);
+
+  argv = split_string ("program --error-optional-arg value", &argc);
+  
+  retval = g_option_context_parse (context, &argc, &argv, &error);
+  g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
+  g_assert (retval == FALSE);
+
+  g_option_context_free (context);
+  g_clear_error (&error);
+
+  /* And again, this time with a optional arg variant, without argument */
+  context = g_option_context_new (NULL);
+  g_option_context_add_main_entries (context, entries, NULL);
+
+  argv = split_string ("program --error-optional-arg", &argc);
+  
+  retval = g_option_context_parse (context, &argc, &argv, &error);
+  g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
+  g_assert (retval == FALSE);
+
+  g_option_context_free (context);
+  g_clear_error (&error);
+}
+
+
 void
 ignore_test1 (void)
 {
@@ -1683,6 +1759,9 @@ main (int   argc,
   /* Test callback with G_OPTION_REMAINING */
   g_test_add_func ("/arg/remaining/callback", callback_remaining_test1);
   
+  /* Test callbacks which return FALSE */
+  g_test_add_func ("/arg/remaining/callback-false", callback_returns_false);
+  
   /* Test ignoring options */
   g_test_add_func ("/arg/ignore/long", ignore_test1);
   g_test_add_func ("/arg/ignore/short", ignore_test2);