From 636fa4640d84eaa5da369d02db27fdc38321ed4b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 28 Nov 2008 05:17:27 +0000 Subject: [PATCH] Fix an issue with callbacks that return FALSE. svn path=/trunk/; revision=7684 --- ChangeLog | 11 +++++++ glib/goption.c | 7 ++-- glib/tests/option-context.c | 79 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index eb8c726..22a412e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-11-28 Matthias Clasen + + 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 Bug 559413 – g_option_group_set_error_hook docs buglet diff --git a/glib/goption.c b/glib/goption.c index b45e5f4..906fc19 100644 --- a/glib/goption.c +++ b/glib/goption.c @@ -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 { diff --git a/glib/tests/option-context.c b/glib/tests/option-context.c index f7ec209..913ad5c 100644 --- a/glib/tests/option-context.c +++ b/glib/tests/option-context.c @@ -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); -- 2.7.4