mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-02 13:53:06 +02:00
Add tests for the handling of non-option arguments, "--" and
2004-10-29 Matthias Clasen <mclasen@redhat.com> * tests/option-test.c: Add tests for the handling of non-option arguments, "--" and G_OPTION_REMAINING. * glib/goption.[hc]: #define G_OPTION_REMAINING, which is a special long option name, which can be used for an option in the main group which collects the non-option arguments. It must be of type G_OPTION_ARG_STRING_ARRAY or G_OPTION_ARG_FILENAME_ARRAY. If the main group doesn't contain an option whose name is G_OPTION_REMAINING, the non-option arguments are left behind in argv as before.
This commit is contained in:
parent
a0e217e94a
commit
a9fa61a13e
11
ChangeLog
11
ChangeLog
@ -1,5 +1,16 @@
|
||||
2004-10-29 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* tests/option-test.c: Add tests for the handling of
|
||||
non-option arguments, "--" and G_OPTION_REMAINING.
|
||||
|
||||
* glib/goption.[hc]: #define G_OPTION_REMAINING, which is
|
||||
a special long option name, which can be used for an option
|
||||
in the main group which collects the non-option arguments.
|
||||
It must be of type G_OPTION_ARG_STRING_ARRAY or
|
||||
G_OPTION_ARG_FILENAME_ARRAY. If the main group doesn't contain
|
||||
an option whose name is G_OPTION_REMAINING, the non-option
|
||||
arguments are left behind in argv as before.
|
||||
|
||||
* glib/goption.c: Add documentation.
|
||||
|
||||
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
||||
|
@ -1,5 +1,16 @@
|
||||
2004-10-29 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* tests/option-test.c: Add tests for the handling of
|
||||
non-option arguments, "--" and G_OPTION_REMAINING.
|
||||
|
||||
* glib/goption.[hc]: #define G_OPTION_REMAINING, which is
|
||||
a special long option name, which can be used for an option
|
||||
in the main group which collects the non-option arguments.
|
||||
It must be of type G_OPTION_ARG_STRING_ARRAY or
|
||||
G_OPTION_ARG_FILENAME_ARRAY. If the main group doesn't contain
|
||||
an option whose name is G_OPTION_REMAINING, the non-option
|
||||
arguments are left behind in argv as before.
|
||||
|
||||
* glib/goption.c: Add documentation.
|
||||
|
||||
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
||||
|
@ -1,5 +1,16 @@
|
||||
2004-10-29 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* tests/option-test.c: Add tests for the handling of
|
||||
non-option arguments, "--" and G_OPTION_REMAINING.
|
||||
|
||||
* glib/goption.[hc]: #define G_OPTION_REMAINING, which is
|
||||
a special long option name, which can be used for an option
|
||||
in the main group which collects the non-option arguments.
|
||||
It must be of type G_OPTION_ARG_STRING_ARRAY or
|
||||
G_OPTION_ARG_FILENAME_ARRAY. If the main group doesn't contain
|
||||
an option whose name is G_OPTION_REMAINING, the non-option
|
||||
arguments are left behind in argv as before.
|
||||
|
||||
* glib/goption.c: Add documentation.
|
||||
|
||||
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
||||
|
@ -1,5 +1,16 @@
|
||||
2004-10-29 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* tests/option-test.c: Add tests for the handling of
|
||||
non-option arguments, "--" and G_OPTION_REMAINING.
|
||||
|
||||
* glib/goption.[hc]: #define G_OPTION_REMAINING, which is
|
||||
a special long option name, which can be used for an option
|
||||
in the main group which collects the non-option arguments.
|
||||
It must be of type G_OPTION_ARG_STRING_ARRAY or
|
||||
G_OPTION_ARG_FILENAME_ARRAY. If the main group doesn't contain
|
||||
an option whose name is G_OPTION_REMAINING, the non-option
|
||||
arguments are left behind in argv as before.
|
||||
|
||||
* glib/goption.c: Add documentation.
|
||||
|
||||
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
||||
|
@ -1,5 +1,16 @@
|
||||
2004-10-29 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* tests/option-test.c: Add tests for the handling of
|
||||
non-option arguments, "--" and G_OPTION_REMAINING.
|
||||
|
||||
* glib/goption.[hc]: #define G_OPTION_REMAINING, which is
|
||||
a special long option name, which can be used for an option
|
||||
in the main group which collects the non-option arguments.
|
||||
It must be of type G_OPTION_ARG_STRING_ARRAY or
|
||||
G_OPTION_ARG_FILENAME_ARRAY. If the main group doesn't contain
|
||||
an option whose name is G_OPTION_REMAINING, the non-option
|
||||
arguments are left behind in argv as before.
|
||||
|
||||
* glib/goption.c: Add documentation.
|
||||
|
||||
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
||||
|
@ -19,9 +19,11 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "goption.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "galias.h"
|
||||
|
||||
#include "goption.h"
|
||||
#include "glib.h"
|
||||
#include "gi18n.h"
|
||||
|
||||
@ -148,8 +150,9 @@ g_option_context_new (const gchar *parameter_string)
|
||||
*
|
||||
* Since: 2.6
|
||||
*/
|
||||
void g_option_context_free (GOptionContext *context) {
|
||||
g_return_if_fail (context != NULL);
|
||||
void g_option_context_free (GOptionContext *context)
|
||||
{
|
||||
g_return_if_fail (context != NULL);
|
||||
|
||||
g_list_foreach (context->groups, (GFunc)g_option_group_free, NULL);
|
||||
g_list_free (context->groups);
|
||||
@ -404,6 +407,9 @@ print_help (GOptionContext *context,
|
||||
/* Then we go through the entries */
|
||||
for (i = 0; i < group->n_entries; i++)
|
||||
{
|
||||
if (group->entries[i].flags & G_OPTION_FLAG_HIDDEN)
|
||||
continue;
|
||||
|
||||
len = g_utf8_strlen (group->entries[i].long_name, -1);
|
||||
|
||||
if (group->entries[i].short_name)
|
||||
@ -862,6 +868,40 @@ parse_long_option (GOptionContext *context,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_remaining_arg (GOptionContext *context,
|
||||
GOptionGroup *group,
|
||||
gint *index,
|
||||
gint *argc,
|
||||
gchar ***argv,
|
||||
GError **error,
|
||||
gboolean *parsed)
|
||||
{
|
||||
gint j;
|
||||
|
||||
for (j = 0; j < group->n_entries; j++)
|
||||
{
|
||||
if (*index >= *argc)
|
||||
return TRUE;
|
||||
|
||||
if (group->entries[j].long_name[0])
|
||||
continue;
|
||||
|
||||
g_return_val_if_fail (group->entries[j].arg == G_OPTION_ARG_STRING_ARRAY ||
|
||||
group->entries[j].arg == G_OPTION_ARG_FILENAME_ARRAY, FALSE);
|
||||
|
||||
add_pending_null (context, &((*argv)[*index]), NULL);
|
||||
|
||||
if (!parse_arg (context, group, &group->entries[j], (*argv)[*index], "", error))
|
||||
return FALSE;
|
||||
|
||||
*parsed = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
free_changes_list (GOptionContext *context,
|
||||
gboolean revert)
|
||||
@ -1004,12 +1044,14 @@ g_option_context_parse (GOptionContext *context,
|
||||
|
||||
if (argc && argv)
|
||||
{
|
||||
gboolean stop_parsing = FALSE;
|
||||
|
||||
for (i = 1; i < *argc; i++)
|
||||
{
|
||||
gchar *arg;
|
||||
gboolean parsed = FALSE;
|
||||
|
||||
if ((*argv)[i][0] == '-')
|
||||
if ((*argv)[i][0] == '-' && !stop_parsing)
|
||||
{
|
||||
if ((*argv)[i][1] == '-')
|
||||
{
|
||||
@ -1021,7 +1063,8 @@ g_option_context_parse (GOptionContext *context,
|
||||
if (*arg == 0)
|
||||
{
|
||||
add_pending_null (context, &((*argv)[i]), NULL);
|
||||
break;
|
||||
stop_parsing = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle help options */
|
||||
@ -1167,6 +1210,15 @@ g_option_context_parse (GOptionContext *context,
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Collect remaining args */
|
||||
if (context->main_group &&
|
||||
!parse_remaining_arg (context, context->main_group, &i,
|
||||
argc, argv, error, &parsed))
|
||||
goto fail;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Call post-parse hooks */
|
||||
@ -1204,7 +1256,10 @@ g_option_context_parse (GOptionContext *context,
|
||||
{
|
||||
k -= i;
|
||||
for (j = i + k; j < *argc; j++)
|
||||
(*argv)[j-k] = (*argv)[j];
|
||||
{
|
||||
(*argv)[j-k] = (*argv)[j];
|
||||
(*argv)[j] = NULL;
|
||||
}
|
||||
*argc -= k;
|
||||
}
|
||||
}
|
||||
@ -1415,7 +1470,7 @@ g_option_group_set_translate_func (GOptionGroup *group,
|
||||
|
||||
group->translate_func = func;
|
||||
group->translate_data = data;
|
||||
group->translate_notify = notify;
|
||||
group->translate_notify = destroy_notify;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
|
@ -87,6 +87,8 @@ struct _GOptionEntry
|
||||
const gchar *arg_description;
|
||||
};
|
||||
|
||||
#define G_OPTION_REMAINING ""
|
||||
|
||||
GOptionContext *g_option_context_new (const gchar *parameter_string);
|
||||
void g_option_context_free (GOptionContext *context);
|
||||
void g_option_context_set_help_enabled (GOptionContext *context,
|
||||
@ -132,9 +134,6 @@ void g_option_group_set_translation_domain (GOptionGroup *group,
|
||||
const gchar *domain);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_OPTION_H__ */
|
||||
|
@ -524,6 +524,184 @@ empty_test3 (void)
|
||||
g_option_context_free (context);
|
||||
}
|
||||
|
||||
/* check that non-option arguments are left in argv by default */
|
||||
void
|
||||
rest_test1 (void)
|
||||
{
|
||||
GOptionContext *context;
|
||||
gboolean retval;
|
||||
GError *error = NULL;
|
||||
gchar **argv;
|
||||
int argc;
|
||||
GOptionEntry entries [] = {
|
||||
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, 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 foo --test bar", &argc);
|
||||
|
||||
retval = g_option_context_parse (context, &argc, &argv, &error);
|
||||
g_assert (retval);
|
||||
|
||||
/* Check array */
|
||||
g_assert (ignore_test1_boolean);
|
||||
g_assert (strcmp (argv[0], "program") == 0);
|
||||
g_assert (strcmp (argv[1], "foo") == 0);
|
||||
g_assert (strcmp (argv[2], "bar") == 0);
|
||||
g_assert (argv[3] == NULL);
|
||||
|
||||
g_strfreev (argv);
|
||||
g_option_context_free (context);
|
||||
}
|
||||
|
||||
/* check that -- works */
|
||||
void
|
||||
rest_test2 (void)
|
||||
{
|
||||
GOptionContext *context;
|
||||
gboolean retval;
|
||||
GError *error = NULL;
|
||||
gchar **argv;
|
||||
int argc;
|
||||
GOptionEntry entries [] = {
|
||||
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, 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 foo --test -- -bar", &argc);
|
||||
|
||||
retval = g_option_context_parse (context, &argc, &argv, &error);
|
||||
g_assert (retval);
|
||||
|
||||
/* Check array */
|
||||
g_assert (ignore_test1_boolean);
|
||||
g_assert (strcmp (argv[0], "program") == 0);
|
||||
g_assert (strcmp (argv[1], "foo") == 0);
|
||||
g_assert (strcmp (argv[2], "-bar") == 0);
|
||||
g_assert (argv[3] == NULL);
|
||||
|
||||
g_strfreev (argv);
|
||||
g_option_context_free (context);
|
||||
}
|
||||
|
||||
/* check that G_OPTION_REMAINING collects non-option arguments */
|
||||
void
|
||||
rest_test3 (void)
|
||||
{
|
||||
GOptionContext *context;
|
||||
gboolean retval;
|
||||
GError *error = NULL;
|
||||
gchar **argv;
|
||||
int argc;
|
||||
GOptionEntry entries [] = {
|
||||
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
|
||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, 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 foo --test bar", &argc);
|
||||
|
||||
retval = g_option_context_parse (context, &argc, &argv, &error);
|
||||
g_assert (retval);
|
||||
|
||||
/* Check array */
|
||||
g_assert (ignore_test1_boolean);
|
||||
g_assert (strcmp (array_test1_array[0], "foo") == 0);
|
||||
g_assert (strcmp (array_test1_array[1], "bar") == 0);
|
||||
g_assert (array_test1_array[2] == NULL);
|
||||
|
||||
g_strfreev (array_test1_array);
|
||||
|
||||
g_strfreev (argv);
|
||||
g_option_context_free (context);
|
||||
}
|
||||
|
||||
|
||||
/* check that G_OPTION_REMAINING and -- work together */
|
||||
void
|
||||
rest_test4 (void)
|
||||
{
|
||||
GOptionContext *context;
|
||||
gboolean retval;
|
||||
GError *error = NULL;
|
||||
gchar **argv;
|
||||
int argc;
|
||||
GOptionEntry entries [] = {
|
||||
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
|
||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, 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 foo --test -- -bar", &argc);
|
||||
|
||||
retval = g_option_context_parse (context, &argc, &argv, &error);
|
||||
g_assert (retval);
|
||||
|
||||
/* Check array */
|
||||
g_assert (ignore_test1_boolean);
|
||||
g_assert (strcmp (array_test1_array[0], "foo") == 0);
|
||||
g_assert (strcmp (array_test1_array[1], "-bar") == 0);
|
||||
g_assert (array_test1_array[2] == NULL);
|
||||
|
||||
g_strfreev (array_test1_array);
|
||||
|
||||
g_strfreev (argv);
|
||||
g_option_context_free (context);
|
||||
}
|
||||
|
||||
/* test that G_OPTION_REMAINING works with G_OPTION_ARG_FILENAME_ARRAY */
|
||||
void
|
||||
rest_test5 (void)
|
||||
{
|
||||
GOptionContext *context;
|
||||
gboolean retval;
|
||||
GError *error = NULL;
|
||||
gchar **argv;
|
||||
int argc;
|
||||
GOptionEntry entries [] = {
|
||||
{ "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
|
||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &array_test1_array, 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 foo --test bar", &argc);
|
||||
|
||||
retval = g_option_context_parse (context, &argc, &argv, &error);
|
||||
g_assert (retval);
|
||||
|
||||
/* Check array */
|
||||
g_assert (ignore_test1_boolean);
|
||||
g_assert (strcmp (array_test1_array[0], "foo") == 0);
|
||||
g_assert (strcmp (array_test1_array[1], "bar") == 0);
|
||||
g_assert (array_test1_array[2] == NULL);
|
||||
|
||||
g_strfreev (array_test1_array);
|
||||
|
||||
g_strfreev (argv);
|
||||
g_option_context_free (context);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@ -555,5 +733,12 @@ main (int argc, char **argv)
|
||||
empty_test2 ();
|
||||
empty_test3 ();
|
||||
|
||||
/* Test handling of rest args */
|
||||
rest_test1 ();
|
||||
rest_test2 ();
|
||||
rest_test3 ();
|
||||
rest_test4 ();
|
||||
rest_test5 ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user