new goption flag G_OPTION_FLAG_OPTIONAL ARG
- From: Pawel Sliwowski <open list gmail com>
- To: GTK Devel <gtk-devel-list gnome org>
- Subject: new goption flag G_OPTION_FLAG_OPTIONAL ARG
- Date: Thu, 23 Jun 2005 23:08:16 +0000
I was wondering if we could add a new goption flag
G_OPTION_FLAG_OPTIONAL_ARG. This flag would only apply to
G_OPTION_ARG_CALLBACK like the other new flags, but allows the argument
to be optional. So this allows the switch to collect data and act like a
boolean. This is useful when you want a default action to be taken if no
argument is given.
2005-06-23 Pawel Sliwowski <open list gmail com>
* glib/goption.h:
* glib/goption.c: Add G_OPTION_FLAG_OPTIONAL_ARG to
allow greater control of G_OPTION_ARG_CALLBACK options.
* tests/option-test.c: test optional arg flag
2005-06-23 Pawel Sliwowski <open.list at gmail.com>
* glib/tmpl/option.sgml (GOptionFlags): document
G_OPTION_FLAG_OPTIONAL_ARG
? tests/hum
Index: docs/reference/glib/tmpl/option.sgml
===================================================================
RCS file: /cvs/gnome/glib/docs/reference/glib/tmpl/option.sgml,v
retrieving revision 1.10
diff -u -r1.10 option.sgml
--- docs/reference/glib/tmpl/option.sgml 18 Jun 2005 04:55:26 -0000 1.10
+++ docs/reference/glib/tmpl/option.sgml 24 Jun 2005 03:38:54 -0000
@@ -272,7 +272,10 @@
@G_OPTION_FLAG_FILENAME: For options of the %G_OPTION_ARG_CALLBACK
kind, this flag indicates that the argument should be passed to the
callback in the GLib filename encoding rather than UTF-8. Since 2.8
-
+ G_OPTION_FLAG_OPTIONAL_ARG: For options of the %G_OPTION_ARG_CALLBACK
+ kind, this flag indicates that the argument supply is optional. If no argument
+ is given then data of %GOptionParseFunc will be set to NULL. Since 2.8
+
<!-- ##### MACRO G_OPTION_REMAINING ##### -->
<para>
If a long option in the main group has this name, it is not treated as a
Index: glib/goption.c
===================================================================
RCS file: /cvs/gnome/glib/glib/goption.c,v
retrieving revision 1.43
diff -u -r1.43 goption.c
--- glib/goption.c 22 Jun 2005 17:09:31 -0000 1.43
+++ glib/goption.c 24 Jun 2005 03:38:55 -0000
@@ -37,6 +37,9 @@
((entry)->arg == G_OPTION_ARG_CALLBACK && \
((entry)->flags & G_OPTION_FLAG_NO_ARG)))
+#define OPTIONAL_ARG(entry) ((entry)->arg == G_OPTION_ARG_CALLBACK && \
+ (entry)->flags & G_OPTION_FLAG_OPTIONAL_ARG)
+
typedef struct
{
GOptionArg arg_type;
@@ -728,7 +731,7 @@
case G_OPTION_ARG_STRING:
{
gchar *data;
-
+
data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
if (!data)
@@ -747,7 +750,7 @@
case G_OPTION_ARG_STRING_ARRAY:
{
gchar *data;
-
+
data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
if (!data)
@@ -853,13 +856,15 @@
{
gchar *data;
gboolean retval;
-
- if (entry->flags & G_OPTION_FLAG_NO_ARG)
+
+ if (!value && entry->flags & G_OPTION_FLAG_OPTIONAL_ARG)
+ data = NULL;
+ else if (entry->flags & G_OPTION_FLAG_NO_ARG)
data = NULL;
else if (entry->flags & G_OPTION_FLAG_FILENAME)
{
#ifdef G_OS_WIN32
- data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
+ data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
#else
data = g_strdup (value);
#endif
@@ -867,7 +872,8 @@
else
data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
- if (!(entry->flags & G_OPTION_FLAG_NO_ARG) && !data)
+ if (!((entry->flags & G_OPTION_FLAG_NO_ARG) || (entry->flags & G_OPTION_FLAG_OPTIONAL_ARG))
+ && !data)
return FALSE;
retval = (* (GOptionArgFunc) entry->arg_data) (option_name, data, group->user_data, error);
@@ -929,9 +935,39 @@
if (index < *argc - 1)
{
- value = (*argv)[index + 1];
- add_pending_null (context, &((*argv)[index + 1]), NULL);
- *new_index = index + 1;
+ if (!OPTIONAL_ARG(&group->entries[j]))
+ {
+ value = (*argv)[index + 1];
+ add_pending_null (context, &((*argv)[index + 1]), NULL);
+ *new_index = index+1;
+ }
+ else
+ {
+ if (strncmp ((*argv)[index + 1],"-",1) == 0)
+ {
+ gboolean retval;
+ retval = parse_arg (context, group, &group->entries[j],
+ NULL, option_name, error);
+ *parsed = TRUE;
+ g_free (option_name);
+ return retval;
+ }
+ else
+ {
+ value = (*argv)[index + 1];
+ add_pending_null (context, &((*argv)[index + 1]), NULL);
+ *new_index = index + 1;
+ }
+ }
+ }
+ else if (index >= *argc - 1 && OPTIONAL_ARG(&group->entries[j]))
+ {
+ gboolean retval;
+ retval = parse_arg (context, group, &group->entries[j],
+ NULL, option_name, error);
+ *parsed = TRUE;
+ g_free (option_name);
+ return retval;
}
else
{
@@ -1002,11 +1038,42 @@
if (arg[len] == '=')
value = arg + len + 1;
- else if (*index < *argc - 1)
+ else if (*index < *argc - 1)
{
- value = (*argv)[*index + 1];
- add_pending_null (context, &((*argv)[*index + 1]), NULL);
- (*index)++;
+ if (!(group->entries[j].flags & G_OPTION_FLAG_OPTIONAL_ARG))
+ {
+ value = (*argv)[*index + 1];
+ add_pending_null (context, &((*argv)[*index + 1]), NULL);
+ (*index)++;
+ }
+ else
+ {
+ if (strncmp ((*argv)[*index + 1],"-",1) == 0)
+ {
+ gboolean retval;
+ retval = parse_arg (context, group, &group->entries[j],
+ NULL, option_name, error);
+ *parsed = TRUE;
+ g_free (option_name);
+ return retval;
+ }
+ else
+ {
+ value = (*argv)[*index + 1];
+ add_pending_null (context, &((*argv)[*index + 1]), NULL);
+ (*index)++;
+ }
+ }
+ }
+ else if (*index >= *argc - 1 &&
+ group->entries[j].flags & G_OPTION_FLAG_OPTIONAL_ARG)
+ {
+ gboolean retval;
+ retval = parse_arg (context, group, &group->entries[j],
+ NULL, option_name, error);
+ *parsed = TRUE;
+ g_free (option_name);
+ return retval;
}
else
{
@@ -1025,7 +1092,7 @@
g_free (option_name);
*parsed = TRUE;
- }
+ }
}
}
Index: glib/goption.h
===================================================================
RCS file: /cvs/gnome/glib/glib/goption.h,v
retrieving revision 1.9
diff -u -r1.9 goption.h
--- glib/goption.h 18 Jun 2005 04:55:25 -0000 1.9
+++ glib/goption.h 24 Jun 2005 03:38:55 -0000
@@ -32,11 +32,12 @@
typedef enum
{
- G_OPTION_FLAG_HIDDEN = 1 << 0,
- G_OPTION_FLAG_IN_MAIN = 1 << 1,
- G_OPTION_FLAG_REVERSE = 1 << 2,
- G_OPTION_FLAG_NO_ARG = 1 << 3,
- G_OPTION_FLAG_FILENAME = 1 << 4
+ G_OPTION_FLAG_HIDDEN = 1 << 0,
+ G_OPTION_FLAG_IN_MAIN = 1 << 1,
+ G_OPTION_FLAG_REVERSE = 1 << 2,
+ G_OPTION_FLAG_NO_ARG = 1 << 3,
+ G_OPTION_FLAG_FILENAME = 1 << 4,
+ G_OPTION_FLAG_OPTIONAL_ARG = 1 << 5
} GOptionFlags;
typedef enum
Index: tests/option-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/option-test.c,v
retrieving revision 1.13
diff -u -r1.13 option-test.c
--- tests/option-test.c 18 Jun 2005 04:55:26 -0000 1.13
+++ tests/option-test.c 24 Jun 2005 03:38:55 -0000
@@ -12,6 +12,9 @@
gchar *callback_test1_string;
gboolean callback_test2_int;
+gchar *callback_test_optional_string;
+gboolean callback_test_optional_boolean;
+
gchar **array_test1_array;
gboolean ignore_test1_boolean;
@@ -399,6 +402,80 @@
g_option_context_free (context);
}
+static gboolean
+callback_parse_optional (const gchar *option_name, const gchar *value,
+ gpointer data, GError **error)
+{
+ callback_test_optional_boolean = TRUE;
+ if (value)
+ callback_test_optional_string = g_strdup (value);
+ else
+ callback_test_optional_string = NULL;
+ return TRUE;
+}
+
+void
+callback_test_optional_1 (void)
+{
+ GOptionContext *context;
+ gboolean retval;
+ GError *error = NULL;
+ gchar **argv;
+ int argc;
+ GOptionEntry entries [] =
+ { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, callback_parse_optional, 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 --test foo.txt", &argc);
+
+ retval = g_option_context_parse (context, &argc, &argv, &error);
+ g_assert (retval);
+
+ g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
+
+ g_assert (callback_test_optional_boolean);
+
+ g_free (callback_test_optional_string);
+
+ g_strfreev (argv);
+ g_option_context_free (context);
+}
+
+void
+callback_test_optional_2 (void)
+{
+ GOptionContext *context;
+ gboolean retval;
+ GError *error = NULL;
+ gchar **argv;
+ int argc;
+ GOptionEntry entries [] =
+ { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, callback_parse_optional, 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 --test", &argc);
+
+ retval = g_option_context_parse (context, &argc, &argv, &error);
+ g_assert (retval);
+
+ g_assert (callback_test_optional_string == NULL);
+
+ g_assert (callback_test_optional_boolean);
+
+ g_free (callback_test_optional_string);
+
+ g_strfreev (argv);
+ g_option_context_free (context);
+}
+
void
ignore_test1 (void)
{
@@ -1016,6 +1093,10 @@
callback_test1 ();
callback_test2 ();
+ /* Test optional arg flag for callback */
+ callback_test_optional_1 ();
+ callback_test_optional_2 ();
+
/* Test ignoring options */
ignore_test1 ();
ignore_test2 ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]