mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-04 06:43:07 +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>
|
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.
|
* glib/goption.c: Add documentation.
|
||||||
|
|
||||||
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
@ -1,5 +1,16 @@
|
|||||||
2004-10-29 Matthias Clasen <mclasen@redhat.com>
|
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.
|
* glib/goption.c: Add documentation.
|
||||||
|
|
||||||
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
@ -1,5 +1,16 @@
|
|||||||
2004-10-29 Matthias Clasen <mclasen@redhat.com>
|
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.
|
* glib/goption.c: Add documentation.
|
||||||
|
|
||||||
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
@ -1,5 +1,16 @@
|
|||||||
2004-10-29 Matthias Clasen <mclasen@redhat.com>
|
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.
|
* glib/goption.c: Add documentation.
|
||||||
|
|
||||||
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
@ -1,5 +1,16 @@
|
|||||||
2004-10-29 Matthias Clasen <mclasen@redhat.com>
|
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.
|
* glib/goption.c: Add documentation.
|
||||||
|
|
||||||
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
2004-10-28 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
@ -19,9 +19,11 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "goption.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "galias.h"
|
#include "galias.h"
|
||||||
|
|
||||||
|
#include "goption.h"
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include "gi18n.h"
|
#include "gi18n.h"
|
||||||
|
|
||||||
@ -148,8 +150,9 @@ g_option_context_new (const gchar *parameter_string)
|
|||||||
*
|
*
|
||||||
* Since: 2.6
|
* Since: 2.6
|
||||||
*/
|
*/
|
||||||
void g_option_context_free (GOptionContext *context) {
|
void g_option_context_free (GOptionContext *context)
|
||||||
g_return_if_fail (context != NULL);
|
{
|
||||||
|
g_return_if_fail (context != NULL);
|
||||||
|
|
||||||
g_list_foreach (context->groups, (GFunc)g_option_group_free, NULL);
|
g_list_foreach (context->groups, (GFunc)g_option_group_free, NULL);
|
||||||
g_list_free (context->groups);
|
g_list_free (context->groups);
|
||||||
@ -404,6 +407,9 @@ print_help (GOptionContext *context,
|
|||||||
/* Then we go through the entries */
|
/* Then we go through the entries */
|
||||||
for (i = 0; i < group->n_entries; i++)
|
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);
|
len = g_utf8_strlen (group->entries[i].long_name, -1);
|
||||||
|
|
||||||
if (group->entries[i].short_name)
|
if (group->entries[i].short_name)
|
||||||
@ -862,6 +868,40 @@ parse_long_option (GOptionContext *context,
|
|||||||
return TRUE;
|
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
|
static void
|
||||||
free_changes_list (GOptionContext *context,
|
free_changes_list (GOptionContext *context,
|
||||||
gboolean revert)
|
gboolean revert)
|
||||||
@ -1004,12 +1044,14 @@ g_option_context_parse (GOptionContext *context,
|
|||||||
|
|
||||||
if (argc && argv)
|
if (argc && argv)
|
||||||
{
|
{
|
||||||
|
gboolean stop_parsing = FALSE;
|
||||||
|
|
||||||
for (i = 1; i < *argc; i++)
|
for (i = 1; i < *argc; i++)
|
||||||
{
|
{
|
||||||
gchar *arg;
|
gchar *arg;
|
||||||
gboolean parsed = FALSE;
|
gboolean parsed = FALSE;
|
||||||
|
|
||||||
if ((*argv)[i][0] == '-')
|
if ((*argv)[i][0] == '-' && !stop_parsing)
|
||||||
{
|
{
|
||||||
if ((*argv)[i][1] == '-')
|
if ((*argv)[i][1] == '-')
|
||||||
{
|
{
|
||||||
@ -1021,7 +1063,8 @@ g_option_context_parse (GOptionContext *context,
|
|||||||
if (*arg == 0)
|
if (*arg == 0)
|
||||||
{
|
{
|
||||||
add_pending_null (context, &((*argv)[i]), NULL);
|
add_pending_null (context, &((*argv)[i]), NULL);
|
||||||
break;
|
stop_parsing = TRUE;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle help options */
|
/* Handle help options */
|
||||||
@ -1167,6 +1210,15 @@ g_option_context_parse (GOptionContext *context,
|
|||||||
goto fail;
|
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 */
|
/* Call post-parse hooks */
|
||||||
@ -1204,7 +1256,10 @@ g_option_context_parse (GOptionContext *context,
|
|||||||
{
|
{
|
||||||
k -= i;
|
k -= i;
|
||||||
for (j = i + k; j < *argc; j++)
|
for (j = i + k; j < *argc; j++)
|
||||||
(*argv)[j-k] = (*argv)[j];
|
{
|
||||||
|
(*argv)[j-k] = (*argv)[j];
|
||||||
|
(*argv)[j] = NULL;
|
||||||
|
}
|
||||||
*argc -= k;
|
*argc -= k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1415,7 +1470,7 @@ g_option_group_set_translate_func (GOptionGroup *group,
|
|||||||
|
|
||||||
group->translate_func = func;
|
group->translate_func = func;
|
||||||
group->translate_data = data;
|
group->translate_data = data;
|
||||||
group->translate_notify = notify;
|
group->translate_notify = destroy_notify;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
|
@ -87,6 +87,8 @@ struct _GOptionEntry
|
|||||||
const gchar *arg_description;
|
const gchar *arg_description;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define G_OPTION_REMAINING ""
|
||||||
|
|
||||||
GOptionContext *g_option_context_new (const gchar *parameter_string);
|
GOptionContext *g_option_context_new (const gchar *parameter_string);
|
||||||
void g_option_context_free (GOptionContext *context);
|
void g_option_context_free (GOptionContext *context);
|
||||||
void g_option_context_set_help_enabled (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);
|
const gchar *domain);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __G_OPTION_H__ */
|
#endif /* __G_OPTION_H__ */
|
||||||
|
@ -524,6 +524,184 @@ empty_test3 (void)
|
|||||||
g_option_context_free (context);
|
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
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -555,5 +733,12 @@ main (int argc, char **argv)
|
|||||||
empty_test2 ();
|
empty_test2 ();
|
||||||
empty_test3 ();
|
empty_test3 ();
|
||||||
|
|
||||||
|
/* Test handling of rest args */
|
||||||
|
rest_test1 ();
|
||||||
|
rest_test2 ();
|
||||||
|
rest_test3 ();
|
||||||
|
rest_test4 ();
|
||||||
|
rest_test5 ();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user