GOptionContext test: free all arguments, not just the remaining ones
[glib.git] / glib / tests / option-context.c
blob20b1ee327c843b36b141f015358cc7f0194cce4a
1 /* Unit tests for GOptionContext
2 * Copyright (C) 2007 Openismus GmbH
3 * Authors: Mathias Hasselmann
5 * This work is provided "as is"; redistribution and modification
6 * in whole or in part, in any medium, physical or electronic is
7 * permitted without restriction.
9 * This work is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * In no event shall the authors or contributors be liable for any
14 * direct, indirect, incidental, special, exemplary, or consequential
15 * damages (including, but not limited to, procurement of substitute
16 * goods or services; loss of use, data, or profits; or business
17 * interruption) however caused and on any theory of liability, whether
18 * in contract, strict liability, or tort (including negligence or
19 * otherwise) arising in any way out of the use of this software, even
20 * if advised of the possibility of such damage.
23 #include <glib.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <locale.h>
30 static void
31 group_captions (void)
33 gchar *help_variants[] = { "--help", "--help-all", "--help-test" };
35 GOptionEntry main_entries[] = {
36 { "main-switch", 0, 0,
37 G_OPTION_ARG_NONE, NULL,
38 "A switch that is in the main group", NULL },
39 { NULL }
42 GOptionEntry group_entries[] = {
43 { "test-switch", 0, 0,
44 G_OPTION_ARG_NONE, NULL,
45 "A switch that is in the test group", NULL },
46 { NULL }
49 gint i, j;
51 g_test_bug ("504142");
53 for (i = 0; i < 4; ++i)
55 gboolean have_main_entries = (0 != (i & 1));
56 gboolean have_test_entries = (0 != (i & 2));
58 GOptionContext *options;
59 GOptionGroup *group = NULL;
61 options = g_option_context_new (NULL);
63 if (have_main_entries)
64 g_option_context_add_main_entries (options, main_entries, NULL);
65 if (have_test_entries)
67 group = g_option_group_new ("test", "Test Options",
68 "Show all test options",
69 NULL, NULL);
70 g_option_context_add_group (options, group);
71 g_option_group_add_entries (group, group_entries);
74 for (j = 0; j < G_N_ELEMENTS (help_variants); ++j)
76 GTestTrapFlags trap_flags = 0;
77 gchar *args[3];
79 args[0] = __FILE__;
80 args[1] = help_variants[j];
81 args[2] = NULL;
83 if (!g_test_verbose ())
84 trap_flags |= G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR;
86 g_test_message ("test setup: args='%s', main-entries=%d, test-entries=%d",
87 args[1], have_main_entries, have_test_entries);
89 if (g_test_trap_fork (0, trap_flags))
91 gchar **argv = args;
92 gint argc = 2;
93 GError *error = NULL;
95 g_setenv ("LANG", "C", TRUE);
97 g_option_context_parse (options, &argc, &argv, &error);
98 g_option_context_free (options);
99 exit(0);
101 else
103 gboolean expect_main_description = FALSE;
104 gboolean expect_main_switch = FALSE;
106 gboolean expect_test_description = FALSE;
107 gboolean expect_test_switch = FALSE;
108 gboolean expect_test_group = FALSE;
110 g_test_trap_assert_passed ();
111 g_test_trap_assert_stderr ("");
113 switch (j)
115 case 0:
116 g_assert_cmpstr ("--help", ==, args[1]);
117 expect_main_switch = have_main_entries;
118 expect_test_group = have_test_entries;
119 break;
121 case 1:
122 g_assert_cmpstr ("--help-all", ==, args[1]);
123 expect_main_switch = have_main_entries;
124 expect_test_switch = have_test_entries;
125 expect_test_group = have_test_entries;
126 break;
128 case 2:
129 g_assert_cmpstr ("--help-test", ==, args[1]);
130 expect_test_switch = have_test_entries;
131 break;
133 default:
134 g_assert_not_reached ();
135 break;
138 expect_main_description |= expect_main_switch;
139 expect_test_description |= expect_test_switch;
141 if (expect_main_description)
142 g_test_trap_assert_stdout ("*Application Options*");
143 else
144 g_test_trap_assert_stdout_unmatched ("*Application Options*");
145 if (expect_main_switch)
146 g_test_trap_assert_stdout ("*--main-switch*");
147 else
148 g_test_trap_assert_stdout_unmatched ("*--main-switch*");
150 if (expect_test_description)
151 g_test_trap_assert_stdout ("*Test Options*");
152 else
153 g_test_trap_assert_stdout_unmatched ("*Test Options*");
154 if (expect_test_switch)
155 g_test_trap_assert_stdout ("*--test-switch*");
156 else
157 g_test_trap_assert_stdout_unmatched ("*--test-switch*");
159 if (expect_test_group)
160 g_test_trap_assert_stdout ("*--help-test*");
161 else
162 g_test_trap_assert_stdout_unmatched ("*--help-test*");
166 g_option_context_free (options);
170 int error_test1_int;
171 char *error_test2_string;
172 gboolean error_test3_boolean;
174 int arg_test1_int;
175 gchar *arg_test2_string;
176 gchar *arg_test3_filename;
177 gdouble arg_test4_double;
178 gdouble arg_test5_double;
179 gint64 arg_test6_int64;
180 gint64 arg_test6_int64_2;
182 gchar *callback_test1_string;
183 int callback_test2_int;
185 gchar *callback_test_optional_string;
186 gboolean callback_test_optional_boolean;
188 gchar **array_test1_array;
190 gboolean ignore_test1_boolean;
191 gboolean ignore_test2_boolean;
192 gchar *ignore_test3_string;
194 static gchar **
195 split_string (const char *str, int *argc)
197 gchar **argv;
198 int len;
200 argv = g_strsplit (str, " ", 0);
202 for (len = 0; argv[len] != NULL; len++);
204 if (argc)
205 *argc = len;
207 return argv;
210 static gchar *
211 join_stringv (int argc, char **argv)
213 int i;
214 GString *str;
216 str = g_string_new (NULL);
218 for (i = 0; i < argc; i++)
220 g_string_append (str, argv[i]);
222 if (i < argc - 1)
223 g_string_append_c (str, ' ');
226 return g_string_free (str, FALSE);
229 /* Performs a shallow copy */
230 static char **
231 copy_stringv (char **argv, int argc)
233 return g_memdup (argv, sizeof (char *) * (argc + 1));
236 static void
237 check_identical_stringv (gchar **before, gchar **after)
239 guint i;
241 /* Not only is it the same string... */
242 for (i = 0; before[i] != NULL; i++)
243 g_assert_cmpstr (before[i], ==, after[i]);
245 /* ... it is actually the same pointer */
246 for (i = 0; before[i] != NULL; i++)
247 g_assert (before[i] == after[i]);
249 g_assert (after[i] == NULL);
253 static gboolean
254 error_test1_pre_parse (GOptionContext *context,
255 GOptionGroup *group,
256 gpointer data,
257 GError **error)
259 g_assert (error_test1_int == 0x12345678);
261 return TRUE;
264 static gboolean
265 error_test1_post_parse (GOptionContext *context,
266 GOptionGroup *group,
267 gpointer data,
268 GError **error)
270 g_assert (error_test1_int == 20);
272 /* Set an error in the post hook */
273 g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
275 return FALSE;
278 static void
279 error_test1 (void)
281 GOptionContext *context;
282 gboolean retval;
283 GError *error = NULL;
284 gchar **argv;
285 gchar **argv_copy;
286 int argc;
287 GOptionGroup *main_group;
288 GOptionEntry entries [] =
289 { { "test", 0, 0, G_OPTION_ARG_INT, &error_test1_int, NULL, NULL },
290 { NULL } };
292 error_test1_int = 0x12345678;
294 context = g_option_context_new (NULL);
295 g_option_context_add_main_entries (context, entries, NULL);
297 /* Set pre and post parse hooks */
298 main_group = g_option_context_get_main_group (context);
299 g_option_group_set_parse_hooks (main_group,
300 error_test1_pre_parse, error_test1_post_parse);
302 /* Now try parsing */
303 argv = split_string ("program --test 20", &argc);
304 argv_copy = copy_stringv (argv, argc);
306 retval = g_option_context_parse (context, &argc, &argv, &error);
307 g_assert (retval == FALSE);
308 g_assert (error != NULL);
309 /* An error occurred, so argv has not been changed */
310 check_identical_stringv (argv_copy, argv);
311 g_clear_error (&error);
313 /* On failure, values should be reset */
314 g_assert (error_test1_int == 0x12345678);
316 g_strfreev (argv_copy);
317 g_free (argv);
318 g_option_context_free (context);
321 static gboolean
322 error_test2_pre_parse (GOptionContext *context,
323 GOptionGroup *group,
324 gpointer data,
325 GError **error)
327 g_assert (strcmp (error_test2_string, "foo") == 0);
329 return TRUE;
332 static gboolean
333 error_test2_post_parse (GOptionContext *context,
334 GOptionGroup *group,
335 gpointer data,
336 GError **error)
338 g_assert (strcmp (error_test2_string, "bar") == 0);
340 /* Set an error in the post hook */
341 g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
343 return FALSE;
346 static void
347 error_test2 (void)
349 GOptionContext *context;
350 gboolean retval;
351 GError *error = NULL;
352 gchar **argv;
353 gchar **argv_copy;
354 int argc;
355 GOptionGroup *main_group;
356 GOptionEntry entries [] =
357 { { "test", 0, 0, G_OPTION_ARG_STRING, &error_test2_string, NULL, NULL },
358 { NULL } };
360 error_test2_string = "foo";
362 context = g_option_context_new (NULL);
363 g_option_context_add_main_entries (context, entries, NULL);
365 /* Set pre and post parse hooks */
366 main_group = g_option_context_get_main_group (context);
367 g_option_group_set_parse_hooks (main_group,
368 error_test2_pre_parse, error_test2_post_parse);
370 /* Now try parsing */
371 argv = split_string ("program --test bar", &argc);
372 argv_copy = copy_stringv (argv, argc);
373 retval = g_option_context_parse (context, &argc, &argv, &error);
375 g_assert (retval == FALSE);
376 g_assert (error != NULL);
377 check_identical_stringv (argv_copy, argv);
378 g_clear_error (&error);
380 g_assert (strcmp (error_test2_string, "foo") == 0);
382 g_strfreev (argv_copy);
383 g_free (argv);
384 g_option_context_free (context);
387 static gboolean
388 error_test3_pre_parse (GOptionContext *context,
389 GOptionGroup *group,
390 gpointer data,
391 GError **error)
393 g_assert (!error_test3_boolean);
395 return TRUE;
398 static gboolean
399 error_test3_post_parse (GOptionContext *context,
400 GOptionGroup *group,
401 gpointer data,
402 GError **error)
404 g_assert (error_test3_boolean);
406 /* Set an error in the post hook */
407 g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
409 return FALSE;
412 static void
413 error_test3 (void)
415 GOptionContext *context;
416 gboolean retval;
417 GError *error = NULL;
418 gchar **argv;
419 gchar **argv_copy;
420 int argc;
421 GOptionGroup *main_group;
422 GOptionEntry entries [] =
423 { { "test", 0, 0, G_OPTION_ARG_NONE, &error_test3_boolean, NULL, NULL },
424 { NULL } };
426 error_test3_boolean = FALSE;
428 context = g_option_context_new (NULL);
429 g_option_context_add_main_entries (context, entries, NULL);
431 /* Set pre and post parse hooks */
432 main_group = g_option_context_get_main_group (context);
433 g_option_group_set_parse_hooks (main_group,
434 error_test3_pre_parse, error_test3_post_parse);
436 /* Now try parsing */
437 argv = split_string ("program --test", &argc);
438 argv_copy = copy_stringv (argv, argc);
439 retval = g_option_context_parse (context, &argc, &argv, &error);
441 g_assert (retval == FALSE);
442 g_assert (error != NULL);
443 check_identical_stringv (argv_copy, argv);
444 g_clear_error (&error);
446 g_assert (!error_test3_boolean);
448 g_strfreev (argv_copy);
449 g_free (argv);
450 g_option_context_free (context);
453 static void
454 arg_test1 (void)
456 GOptionContext *context;
457 gboolean retval;
458 GError *error = NULL;
459 gchar **argv;
460 gchar **argv_copy;
461 int argc;
462 GOptionEntry entries [] =
463 { { "test", 0, 0, G_OPTION_ARG_INT, &arg_test1_int, NULL, NULL },
464 { NULL } };
466 context = g_option_context_new (NULL);
467 g_option_context_add_main_entries (context, entries, NULL);
469 /* Now try parsing */
470 argv = split_string ("program --test 20 --test 30", &argc);
471 argv_copy = copy_stringv (argv, argc);
473 retval = g_option_context_parse (context, &argc, &argv, &error);
474 g_assert_no_error (error);
475 g_assert (retval);
477 /* Last arg specified is the one that should be stored */
478 g_assert (arg_test1_int == 30);
480 /* We free all of the strings in a copy of argv, because now argv is a
481 * subset - some have been removed in-place
483 g_strfreev (argv_copy);
484 g_free (argv);
485 g_option_context_free (context);
488 static void
489 arg_test2 (void)
491 GOptionContext *context;
492 gboolean retval;
493 GError *error = NULL;
494 gchar **argv;
495 gchar **argv_copy;
496 int argc;
497 GOptionEntry entries [] =
498 { { "test", 0, 0, G_OPTION_ARG_STRING, &arg_test2_string, NULL, NULL },
499 { NULL } };
501 context = g_option_context_new (NULL);
502 g_option_context_add_main_entries (context, entries, NULL);
504 /* Now try parsing */
505 argv = split_string ("program --test foo --test bar", &argc);
506 argv_copy = copy_stringv (argv, argc);
508 retval = g_option_context_parse (context, &argc, &argv, &error);
509 g_assert_no_error (error);
510 g_assert (retval);
512 /* Last arg specified is the one that should be stored */
513 g_assert (strcmp (arg_test2_string, "bar") == 0);
515 g_free (arg_test2_string);
517 g_strfreev (argv_copy);
518 g_free (argv);
519 g_option_context_free (context);
522 static void
523 arg_test3 (void)
525 GOptionContext *context;
526 gboolean retval;
527 GError *error = NULL;
528 gchar **argv;
529 gchar **argv_copy;
530 int argc;
531 GOptionEntry entries [] =
532 { { "test", 0, 0, G_OPTION_ARG_FILENAME, &arg_test3_filename, NULL, NULL },
533 { NULL } };
535 context = g_option_context_new (NULL);
536 g_option_context_add_main_entries (context, entries, NULL);
538 /* Now try parsing */
539 argv = split_string ("program --test foo.txt", &argc);
540 argv_copy = copy_stringv (argv, argc);
542 retval = g_option_context_parse (context, &argc, &argv, &error);
543 g_assert_no_error (error);
544 g_assert (retval);
546 /* Last arg specified is the one that should be stored */
547 g_assert (strcmp (arg_test3_filename, "foo.txt") == 0);
549 g_free (arg_test3_filename);
551 g_strfreev (argv_copy);
552 g_free (argv);
553 g_option_context_free (context);
557 static void
558 arg_test4 (void)
560 GOptionContext *context;
561 gboolean retval;
562 GError *error = NULL;
563 gchar **argv_copy;
564 gchar **argv;
565 int argc;
566 GOptionEntry entries [] =
567 { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test4_double, NULL, NULL },
568 { NULL } };
570 context = g_option_context_new (NULL);
571 g_option_context_add_main_entries (context, entries, NULL);
573 /* Now try parsing */
574 argv = split_string ("program --test 20.0 --test 30.03", &argc);
575 argv_copy = copy_stringv (argv, argc);
577 retval = g_option_context_parse (context, &argc, &argv, &error);
578 g_assert_no_error (error);
579 g_assert (retval);
581 /* Last arg specified is the one that should be stored */
582 g_assert (arg_test4_double == 30.03);
584 g_strfreev (argv_copy);
585 g_free (argv);
586 g_option_context_free (context);
589 static void
590 arg_test5 (void)
592 GOptionContext *context;
593 gboolean retval;
594 GError *error = NULL;
595 gchar **argv;
596 gchar **argv_copy;
597 int argc;
598 char *old_locale, *current_locale;
599 const char *locale = "de_DE";
600 GOptionEntry entries [] =
601 { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test5_double, NULL, NULL },
602 { NULL } };
604 context = g_option_context_new (NULL);
605 g_option_context_add_main_entries (context, entries, NULL);
607 /* Now try parsing */
608 argv = split_string ("program --test 20,0 --test 30,03", &argc);
609 argv_copy = copy_stringv (argv, argc);
611 /* set it to some locale that uses commas instead of decimal points */
613 old_locale = g_strdup (setlocale (LC_NUMERIC, locale));
614 current_locale = setlocale (LC_NUMERIC, NULL);
615 if (strcmp (current_locale, locale) != 0)
617 fprintf (stderr, "Cannot set locale to %s, skipping\n", locale);
618 goto cleanup;
621 retval = g_option_context_parse (context, &argc, &argv, &error);
622 g_assert_no_error (error);
623 g_assert (retval);
625 /* Last arg specified is the one that should be stored */
626 g_assert (arg_test5_double == 30.03);
628 cleanup:
629 setlocale (LC_NUMERIC, old_locale);
630 g_free (old_locale);
632 g_strfreev (argv_copy);
633 g_free (argv);
634 g_option_context_free (context);
637 static void
638 arg_test6 (void)
640 GOptionContext *context;
641 gboolean retval;
642 GError *error = NULL;
643 gchar **argv;
644 gchar **argv_copy;
645 int argc;
646 GOptionEntry entries [] =
647 { { "test", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64, NULL, NULL },
648 { "test2", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64_2, NULL, NULL },
649 { NULL } };
651 context = g_option_context_new (NULL);
652 g_option_context_add_main_entries (context, entries, NULL);
654 /* Now try parsing */
655 argv = split_string ("program --test 4294967297 --test 4294967296 --test2 0xfffffffff", &argc);
656 argv_copy = copy_stringv (argv, argc);
658 retval = g_option_context_parse (context, &argc, &argv, &error);
659 g_assert_no_error (error);
660 g_assert (retval);
662 /* Last arg specified is the one that should be stored */
663 g_assert (arg_test6_int64 == G_GINT64_CONSTANT(4294967296));
664 g_assert (arg_test6_int64_2 == G_GINT64_CONSTANT(0xfffffffff));
666 g_strfreev (argv_copy);
667 g_free (argv);
668 g_option_context_free (context);
671 static gboolean
672 callback_parse1 (const gchar *option_name, const gchar *value,
673 gpointer data, GError **error)
675 callback_test1_string = g_strdup (value);
676 return TRUE;
679 static void
680 callback_test1 (void)
682 GOptionContext *context;
683 gboolean retval;
684 GError *error = NULL;
685 gchar **argv;
686 gchar **argv_copy;
687 int argc;
688 GOptionEntry entries [] =
689 { { "test", 0, 0, G_OPTION_ARG_CALLBACK, callback_parse1, NULL, NULL },
690 { NULL } };
692 context = g_option_context_new (NULL);
693 g_option_context_add_main_entries (context, entries, NULL);
695 /* Now try parsing */
696 argv = split_string ("program --test foo.txt", &argc);
697 argv_copy = copy_stringv (argv, argc);
699 retval = g_option_context_parse (context, &argc, &argv, &error);
700 g_assert_no_error (error);
701 g_assert (retval);
703 g_assert (strcmp (callback_test1_string, "foo.txt") == 0);
705 g_free (callback_test1_string);
707 g_strfreev (argv_copy);
708 g_free (argv);
709 g_option_context_free (context);
712 static gboolean
713 callback_parse2 (const gchar *option_name, const gchar *value,
714 gpointer data, GError **error)
716 callback_test2_int++;
717 return TRUE;
720 static void
721 callback_test2 (void)
723 GOptionContext *context;
724 gboolean retval;
725 GError *error = NULL;
726 gchar **argv;
727 gchar **argv_copy;
728 int argc;
729 GOptionEntry entries [] =
730 { { "test", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_parse2, NULL, NULL },
731 { NULL } };
733 context = g_option_context_new (NULL);
734 g_option_context_add_main_entries (context, entries, NULL);
736 /* Now try parsing */
737 argv = split_string ("program --test --test", &argc);
738 argv_copy = copy_stringv (argv, argc);
740 retval = g_option_context_parse (context, &argc, &argv, &error);
741 g_assert_no_error (error);
742 g_assert (retval);
744 g_assert (callback_test2_int == 2);
746 g_strfreev (argv_copy);
747 g_free (argv);
748 g_option_context_free (context);
751 static gboolean
752 callback_parse_optional (const gchar *option_name, const gchar *value,
753 gpointer data, GError **error)
755 callback_test_optional_boolean = TRUE;
756 if (value)
757 callback_test_optional_string = g_strdup (value);
758 else
759 callback_test_optional_string = NULL;
760 return TRUE;
763 static void
764 callback_test_optional_1 (void)
766 GOptionContext *context;
767 gboolean retval;
768 GError *error = NULL;
769 gchar **argv;
770 gchar **argv_copy;
771 int argc;
772 GOptionEntry entries [] =
773 { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
774 callback_parse_optional, NULL, NULL },
775 { NULL } };
777 context = g_option_context_new (NULL);
778 g_option_context_add_main_entries (context, entries, NULL);
780 /* Now try parsing */
781 argv = split_string ("program --test foo.txt", &argc);
782 argv_copy = copy_stringv (argv, argc);
784 retval = g_option_context_parse (context, &argc, &argv, &error);
785 g_assert_no_error (error);
786 g_assert (retval);
788 g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
790 g_assert (callback_test_optional_boolean);
792 g_free (callback_test_optional_string);
794 g_strfreev (argv_copy);
795 g_free (argv);
796 g_option_context_free (context);
799 static void
800 callback_test_optional_2 (void)
802 GOptionContext *context;
803 gboolean retval;
804 GError *error = NULL;
805 gchar **argv;
806 gchar **argv_copy;
807 int argc;
808 GOptionEntry entries [] =
809 { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
810 callback_parse_optional, NULL, NULL },
811 { NULL } };
813 context = g_option_context_new (NULL);
814 g_option_context_add_main_entries (context, entries, NULL);
816 /* Now try parsing */
817 argv = split_string ("program --test", &argc);
818 argv_copy = copy_stringv (argv, argc);
820 retval = g_option_context_parse (context, &argc, &argv, &error);
821 g_assert_no_error (error);
822 g_assert (retval);
824 g_assert (callback_test_optional_string == NULL);
826 g_assert (callback_test_optional_boolean);
828 g_free (callback_test_optional_string);
830 g_strfreev (argv_copy);
831 g_free (argv);
832 g_option_context_free (context);
835 static void
836 callback_test_optional_3 (void)
838 GOptionContext *context;
839 gboolean retval;
840 GError *error = NULL;
841 gchar **argv_copy;
842 gchar **argv;
843 int argc;
844 GOptionEntry entries [] =
845 { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
846 callback_parse_optional, NULL, NULL },
847 { NULL } };
849 context = g_option_context_new (NULL);
850 g_option_context_add_main_entries (context, entries, NULL);
852 /* Now try parsing */
853 argv = split_string ("program -t foo.txt", &argc);
854 argv_copy = copy_stringv (argv, argc);
856 retval = g_option_context_parse (context, &argc, &argv, &error);
857 g_assert_no_error (error);
858 g_assert (retval);
860 g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
862 g_assert (callback_test_optional_boolean);
864 g_free (callback_test_optional_string);
866 g_strfreev (argv_copy);
867 g_free (argv);
868 g_option_context_free (context);
872 static void
873 callback_test_optional_4 (void)
875 GOptionContext *context;
876 gboolean retval;
877 GError *error = NULL;
878 gchar **argv;
879 gchar **argv_copy;
880 int argc;
881 GOptionEntry entries [] =
882 { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
883 callback_parse_optional, NULL, NULL },
884 { NULL } };
886 context = g_option_context_new (NULL);
887 g_option_context_add_main_entries (context, entries, NULL);
889 /* Now try parsing */
890 argv = split_string ("program -t", &argc);
891 argv_copy = copy_stringv (argv, argc);
893 retval = g_option_context_parse (context, &argc, &argv, &error);
894 g_assert_no_error (error);
895 g_assert (retval);
897 g_assert (callback_test_optional_string == NULL);
899 g_assert (callback_test_optional_boolean);
901 g_free (callback_test_optional_string);
903 g_strfreev (argv_copy);
904 g_free (argv);
905 g_option_context_free (context);
908 static void
909 callback_test_optional_5 (void)
911 GOptionContext *context;
912 gboolean dummy;
913 gboolean retval;
914 GError *error = NULL;
915 gchar **argv;
916 gchar **argv_copy;
917 int argc;
918 GOptionEntry entries [] =
919 { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
920 { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
921 callback_parse_optional, NULL, NULL },
922 { NULL } };
924 context = g_option_context_new (NULL);
925 g_option_context_add_main_entries (context, entries, NULL);
927 /* Now try parsing */
928 argv = split_string ("program --test --dummy", &argc);
929 argv_copy = copy_stringv (argv, argc);
931 retval = g_option_context_parse (context, &argc, &argv, &error);
932 g_assert_no_error (error);
933 g_assert (retval);
935 g_assert (callback_test_optional_string == NULL);
937 g_assert (callback_test_optional_boolean);
939 g_free (callback_test_optional_string);
941 g_strfreev (argv_copy);
942 g_free (argv);
943 g_option_context_free (context);
946 static void
947 callback_test_optional_6 (void)
949 GOptionContext *context;
950 gboolean dummy;
951 gboolean retval;
952 GError *error = NULL;
953 gchar **argv;
954 gchar **argv_copy;
955 int argc;
956 GOptionEntry entries [] =
957 { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
958 { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
959 callback_parse_optional, NULL, NULL },
960 { NULL } };
962 context = g_option_context_new (NULL);
963 g_option_context_add_main_entries (context, entries, NULL);
965 /* Now try parsing */
966 argv = split_string ("program -t -d", &argc);
967 argv_copy = copy_stringv (argv, argc);
969 retval = g_option_context_parse (context, &argc, &argv, &error);
970 g_assert_no_error (error);
971 g_assert (retval);
973 g_assert (callback_test_optional_string == NULL);
975 g_assert (callback_test_optional_boolean);
977 g_free (callback_test_optional_string);
979 g_strfreev (argv_copy);
980 g_free (argv);
981 g_option_context_free (context);
984 static void
985 callback_test_optional_7 (void)
987 GOptionContext *context;
988 gboolean dummy;
989 gboolean retval;
990 GError *error = NULL;
991 gchar **argv;
992 gchar **argv_copy;
993 int argc;
994 GOptionEntry entries [] =
995 { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
996 { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
997 callback_parse_optional, NULL, NULL },
998 { NULL } };
1000 context = g_option_context_new (NULL);
1001 g_option_context_add_main_entries (context, entries, NULL);
1003 /* Now try parsing */
1004 argv = split_string ("program -td", &argc);
1005 argv_copy = copy_stringv (argv, argc);
1007 retval = g_option_context_parse (context, &argc, &argv, &error);
1008 g_assert_no_error (error);
1009 g_assert (retval);
1011 g_assert (callback_test_optional_string == NULL);
1013 g_assert (callback_test_optional_boolean);
1015 g_free (callback_test_optional_string);
1017 g_strfreev (argv_copy);
1018 g_free (argv);
1019 g_option_context_free (context);
1022 static void
1023 callback_test_optional_8 (void)
1025 GOptionContext *context;
1026 gboolean dummy;
1027 gboolean retval;
1028 GError *error = NULL;
1029 gchar **argv;
1030 gchar **argv_copy;
1031 int argc;
1032 GOptionEntry entries [] =
1033 { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
1034 { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
1035 callback_parse_optional, NULL, NULL },
1036 { NULL } };
1038 context = g_option_context_new (NULL);
1039 g_option_context_add_main_entries (context, entries, NULL);
1041 /* Now try parsing */
1042 argv = split_string ("program -dt foo.txt", &argc);
1043 argv_copy = copy_stringv (argv, argc);
1045 retval = g_option_context_parse (context, &argc, &argv, &error);
1046 g_assert_no_error (error);
1047 g_assert (retval);
1049 g_assert (callback_test_optional_string);
1051 g_assert (callback_test_optional_boolean);
1053 g_free (callback_test_optional_string);
1055 g_strfreev (argv_copy);
1056 g_free (argv);
1057 g_option_context_free (context);
1060 static void
1061 callback_test_optional_9 (void)
1063 GOptionContext *context;
1064 gboolean retval;
1065 GError *error = NULL;
1066 gchar **argv;
1067 gchar **argv_copy;
1068 int argc;
1069 gchar *string = NULL;
1070 GOptionEntry entries [] =
1071 { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING,
1072 &string, NULL, NULL },
1073 { NULL } };
1075 context = g_option_context_new (NULL);
1076 g_option_context_add_main_entries (context, entries, NULL);
1078 /* Now try parsing */
1079 argv = split_string ("program -t", &argc);
1080 argv_copy = copy_stringv (argv, argc);
1082 retval = g_option_context_parse (context, &argc, &argv, &error);
1083 g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1084 g_assert (!retval);
1085 g_assert (string == NULL);
1086 check_identical_stringv (argv_copy, argv);
1088 g_error_free (error);
1089 g_strfreev (argv_copy);
1090 g_free (argv);
1091 g_option_context_free (context);
1094 static void
1095 callback_test_optional_10 (void)
1097 GOptionContext *context;
1098 gboolean retval;
1099 GError *error = NULL;
1100 gchar **argv;
1101 gchar **argv_copy;
1102 int argc;
1103 gchar *string = NULL;
1104 GOptionEntry entries [] =
1105 { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING,
1106 &string, NULL, NULL },
1107 { NULL } };
1109 context = g_option_context_new (NULL);
1110 g_option_context_add_main_entries (context, entries, NULL);
1112 /* Now try parsing */
1113 argv = split_string ("program --test", &argc);
1114 argv_copy = copy_stringv (argv, argc);
1116 retval = g_option_context_parse (context, &argc, &argv, &error);
1117 g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1118 g_assert (!retval);
1119 g_assert (string == NULL);
1120 check_identical_stringv (argv_copy, argv);
1122 g_error_free (error);
1123 g_strfreev (argv_copy);
1124 g_free (argv);
1125 g_option_context_free (context);
1128 static GPtrArray *callback_remaining_args;
1129 static gboolean
1130 callback_remaining_test1_callback (const gchar *option_name, const gchar *value,
1131 gpointer data, GError **error)
1133 g_ptr_array_add (callback_remaining_args, g_strdup (value));
1134 return TRUE;
1137 static void
1138 callback_remaining_test1 (void)
1140 GOptionContext *context;
1141 gboolean retval;
1142 GError *error = NULL;
1143 gchar **argv;
1144 gchar **argv_copy;
1145 int argc;
1146 GOptionEntry entries [] =
1147 { { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_CALLBACK, callback_remaining_test1_callback, NULL, NULL },
1148 { NULL } };
1150 callback_remaining_args = g_ptr_array_new ();
1151 context = g_option_context_new (NULL);
1152 g_option_context_add_main_entries (context, entries, NULL);
1154 /* Now try parsing */
1155 argv = split_string ("program foo.txt blah.txt", &argc);
1156 argv_copy = copy_stringv (argv, argc);
1158 retval = g_option_context_parse (context, &argc, &argv, &error);
1159 g_assert_no_error (error);
1160 g_assert (retval);
1162 g_assert (callback_remaining_args->len == 2);
1163 g_assert (strcmp (callback_remaining_args->pdata[0], "foo.txt") == 0);
1164 g_assert (strcmp (callback_remaining_args->pdata[1], "blah.txt") == 0);
1166 g_ptr_array_foreach (callback_remaining_args, (GFunc) g_free, NULL);
1167 g_ptr_array_free (callback_remaining_args, TRUE);
1169 g_strfreev (argv_copy);
1170 g_free (argv);
1171 g_option_context_free (context);
1174 static gboolean
1175 callback_error (const gchar *option_name, const gchar *value,
1176 gpointer data, GError **error)
1178 g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "42");
1179 return FALSE;
1182 static void
1183 callback_returns_false (void)
1185 GOptionContext *context;
1186 gboolean retval;
1187 GError *error = NULL;
1188 gchar **argv;
1189 gchar **argv_copy;
1190 int argc;
1191 GOptionEntry entries [] =
1192 { { "error", 0, 0, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1193 { "error-no-arg", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1194 { "error-optional-arg", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1195 { NULL } };
1197 context = g_option_context_new (NULL);
1198 g_option_context_add_main_entries (context, entries, NULL);
1200 /* Now try parsing */
1201 argv = split_string ("program --error value", &argc);
1202 argv_copy = copy_stringv (argv, argc);
1204 retval = g_option_context_parse (context, &argc, &argv, &error);
1205 g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1206 g_assert (retval == FALSE);
1207 check_identical_stringv (argv_copy, argv);
1209 g_option_context_free (context);
1210 g_clear_error (&error);
1211 g_strfreev (argv_copy);
1212 g_free (argv);
1214 /* And again, this time with a no-arg variant */
1215 context = g_option_context_new (NULL);
1216 g_option_context_add_main_entries (context, entries, NULL);
1218 argv = split_string ("program --error-no-arg", &argc);
1219 argv_copy = copy_stringv (argv, argc);
1221 retval = g_option_context_parse (context, &argc, &argv, &error);
1222 g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1223 g_assert (retval == FALSE);
1224 check_identical_stringv (argv_copy, argv);
1226 g_option_context_free (context);
1227 g_clear_error (&error);
1228 g_strfreev (argv_copy);
1229 g_free (argv);
1231 /* And again, this time with a optional arg variant, with argument */
1232 context = g_option_context_new (NULL);
1233 g_option_context_add_main_entries (context, entries, NULL);
1235 argv = split_string ("program --error-optional-arg value", &argc);
1236 argv_copy = copy_stringv (argv, argc);
1238 retval = g_option_context_parse (context, &argc, &argv, &error);
1239 g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1240 g_assert (retval == FALSE);
1241 check_identical_stringv (argv_copy, argv);
1243 g_option_context_free (context);
1244 g_clear_error (&error);
1245 g_strfreev (argv_copy);
1246 g_free (argv);
1248 /* And again, this time with a optional arg variant, without argument */
1249 context = g_option_context_new (NULL);
1250 g_option_context_add_main_entries (context, entries, NULL);
1252 argv = split_string ("program --error-optional-arg", &argc);
1253 argv_copy = copy_stringv (argv, argc);
1255 retval = g_option_context_parse (context, &argc, &argv, &error);
1256 g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1257 g_assert (retval == FALSE);
1258 check_identical_stringv (argv_copy, argv);
1260 g_option_context_free (context);
1261 g_clear_error (&error);
1262 g_strfreev (argv_copy);
1263 g_free (argv);
1267 static void
1268 ignore_test1 (void)
1270 GOptionContext *context;
1271 gboolean retval;
1272 GError *error = NULL;
1273 gchar **argv, **argv_copy;
1274 int argc;
1275 gchar *arg;
1276 GOptionEntry entries [] =
1277 { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1278 { NULL } };
1280 context = g_option_context_new (NULL);
1281 g_option_context_set_ignore_unknown_options (context, TRUE);
1282 g_option_context_add_main_entries (context, entries, NULL);
1284 /* Now try parsing */
1285 argv = split_string ("program --test --hello", &argc);
1286 argv_copy = copy_stringv (argv, argc);
1288 retval = g_option_context_parse (context, &argc, &argv, &error);
1289 g_assert_no_error (error);
1290 g_assert (retval);
1292 /* Check array */
1293 arg = join_stringv (argc, argv);
1294 g_assert (strcmp (arg, "program --hello") == 0);
1296 g_free (arg);
1297 g_strfreev (argv_copy);
1298 g_free (argv);
1299 g_option_context_free (context);
1302 static void
1303 ignore_test2 (void)
1305 GOptionContext *context;
1306 gboolean retval;
1307 GError *error = NULL;
1308 gchar **argv;
1309 gchar **argv_copy;
1310 int argc;
1311 gchar *arg;
1312 GOptionEntry entries [] =
1313 { { "test", 't', 0, G_OPTION_ARG_NONE, &ignore_test2_boolean, NULL, NULL },
1314 { NULL } };
1316 context = g_option_context_new (NULL);
1317 g_option_context_set_ignore_unknown_options (context, TRUE);
1318 g_option_context_add_main_entries (context, entries, NULL);
1320 /* Now try parsing */
1321 argv = split_string ("program -test", &argc);
1322 argv_copy = copy_stringv (argv, argc);
1324 retval = g_option_context_parse (context, &argc, &argv, &error);
1325 g_assert_no_error (error);
1326 g_assert (retval);
1328 /* Check array */
1329 arg = join_stringv (argc, argv);
1330 g_assert (strcmp (arg, "program -es") == 0);
1332 g_free (arg);
1333 g_strfreev (argv_copy);
1334 g_free (argv);
1335 g_option_context_free (context);
1338 static void
1339 ignore_test3 (void)
1341 GOptionContext *context;
1342 gboolean retval;
1343 GError *error = NULL;
1344 gchar **argv, **argv_copy;
1345 int argc;
1346 gchar *arg;
1347 GOptionEntry entries [] =
1348 { { "test", 0, 0, G_OPTION_ARG_STRING, &ignore_test3_string, NULL, NULL },
1349 { NULL } };
1351 context = g_option_context_new (NULL);
1352 g_option_context_set_ignore_unknown_options (context, TRUE);
1353 g_option_context_add_main_entries (context, entries, NULL);
1355 /* Now try parsing */
1356 argv = split_string ("program --test foo --hello", &argc);
1357 argv_copy = copy_stringv (argv, argc);
1359 retval = g_option_context_parse (context, &argc, &argv, &error);
1360 g_assert_no_error (error);
1361 g_assert (retval);
1363 /* Check array */
1364 arg = join_stringv (argc, argv);
1365 g_assert (strcmp (arg, "program --hello") == 0);
1367 g_assert (strcmp (ignore_test3_string, "foo") == 0);
1368 g_free (ignore_test3_string);
1370 g_free (arg);
1371 g_strfreev (argv_copy);
1372 g_free (argv);
1373 g_option_context_free (context);
1376 void
1377 static array_test1 (void)
1379 GOptionContext *context;
1380 gboolean retval;
1381 GError *error = NULL;
1382 gchar **argv;
1383 gchar **argv_copy;
1384 int argc;
1385 GOptionEntry entries [] =
1386 { { "test", 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1387 { NULL } };
1389 context = g_option_context_new (NULL);
1390 g_option_context_add_main_entries (context, entries, NULL);
1392 /* Now try parsing */
1393 argv = split_string ("program --test foo --test bar", &argc);
1394 argv_copy = copy_stringv (argv, argc);
1396 retval = g_option_context_parse (context, &argc, &argv, &error);
1397 g_assert_no_error (error);
1398 g_assert (retval);
1400 /* Check array */
1401 g_assert (strcmp (array_test1_array[0], "foo") == 0);
1402 g_assert (strcmp (array_test1_array[1], "bar") == 0);
1403 g_assert (array_test1_array[2] == NULL);
1405 g_strfreev (array_test1_array);
1407 g_strfreev (argv_copy);
1408 g_free (argv);
1409 g_option_context_free (context);
1412 static void
1413 add_test1 (void)
1415 GOptionContext *context;
1417 GOptionEntry entries1 [] =
1418 { { "test1", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
1419 { NULL } };
1420 GOptionEntry entries2 [] =
1421 { { "test2", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
1422 { NULL } };
1424 context = g_option_context_new (NULL);
1425 g_option_context_add_main_entries (context, entries1, NULL);
1426 g_option_context_add_main_entries (context, entries2, NULL);
1428 g_option_context_free (context);
1431 static void
1432 empty_test2 (void)
1434 GOptionContext *context;
1436 context = g_option_context_new (NULL);
1437 g_option_context_parse (context, NULL, NULL, NULL);
1439 g_option_context_free (context);
1442 static void
1443 empty_test3 (void)
1445 GOptionContext *context;
1446 gint argc;
1447 gchar **argv;
1449 argc = 0;
1450 argv = NULL;
1452 context = g_option_context_new (NULL);
1453 g_option_context_parse (context, &argc, &argv, NULL);
1455 g_option_context_free (context);
1458 /* check that non-option arguments are left in argv by default */
1459 static void
1460 rest_test1 (void)
1462 GOptionContext *context;
1463 gboolean retval;
1464 GError *error = NULL;
1465 gchar **argv;
1466 gchar **argv_copy;
1467 int argc;
1468 GOptionEntry entries [] = {
1469 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1470 { NULL }
1473 context = g_option_context_new (NULL);
1474 g_option_context_add_main_entries (context, entries, NULL);
1476 /* Now try parsing */
1477 argv = split_string ("program foo --test bar", &argc);
1478 argv_copy = copy_stringv (argv, argc);
1480 retval = g_option_context_parse (context, &argc, &argv, &error);
1481 g_assert_no_error (error);
1482 g_assert (retval);
1484 /* Check array */
1485 g_assert (ignore_test1_boolean);
1486 g_assert (strcmp (argv[0], "program") == 0);
1487 g_assert (strcmp (argv[1], "foo") == 0);
1488 g_assert (strcmp (argv[2], "bar") == 0);
1489 g_assert (argv[3] == NULL);
1491 g_strfreev (argv_copy);
1492 g_free (argv);
1493 g_option_context_free (context);
1496 /* check that -- works */
1497 static void
1498 rest_test2 (void)
1500 GOptionContext *context;
1501 gboolean retval;
1502 GError *error = NULL;
1503 gchar **argv;
1504 gchar **argv_copy;
1505 int argc;
1506 GOptionEntry entries [] = {
1507 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1508 { NULL }
1511 context = g_option_context_new (NULL);
1512 g_option_context_add_main_entries (context, entries, NULL);
1514 /* Now try parsing */
1515 argv = split_string ("program foo --test -- -bar", &argc);
1516 argv_copy = copy_stringv (argv, argc);
1518 retval = g_option_context_parse (context, &argc, &argv, &error);
1519 g_assert_no_error (error);
1520 g_assert (retval);
1522 /* Check array */
1523 g_assert (ignore_test1_boolean);
1524 g_assert (strcmp (argv[0], "program") == 0);
1525 g_assert (strcmp (argv[1], "foo") == 0);
1526 g_assert (strcmp (argv[2], "--") == 0);
1527 g_assert (strcmp (argv[3], "-bar") == 0);
1528 g_assert (argv[4] == NULL);
1530 g_strfreev (argv_copy);
1531 g_free (argv);
1532 g_option_context_free (context);
1535 /* check that -- stripping works */
1536 static void
1537 rest_test2a (void)
1539 GOptionContext *context;
1540 gboolean retval;
1541 GError *error = NULL;
1542 gchar **argv;
1543 gchar **argv_copy;
1544 int argc;
1545 GOptionEntry entries [] = {
1546 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1547 { NULL }
1550 context = g_option_context_new (NULL);
1551 g_option_context_add_main_entries (context, entries, NULL);
1553 /* Now try parsing */
1554 argv = split_string ("program foo --test -- bar", &argc);
1555 argv_copy = copy_stringv (argv, argc);
1557 retval = g_option_context_parse (context, &argc, &argv, &error);
1558 g_assert_no_error (error);
1559 g_assert (retval);
1561 /* Check array */
1562 g_assert (ignore_test1_boolean);
1563 g_assert (strcmp (argv[0], "program") == 0);
1564 g_assert (strcmp (argv[1], "foo") == 0);
1565 g_assert (strcmp (argv[2], "bar") == 0);
1566 g_assert (argv[3] == NULL);
1568 g_strfreev (argv_copy);
1569 g_free (argv);
1570 g_option_context_free (context);
1573 static void
1574 rest_test2b (void)
1576 GOptionContext *context;
1577 gboolean retval;
1578 GError *error = NULL;
1579 gchar **argv;
1580 gchar **argv_copy;
1581 int argc;
1582 GOptionEntry entries [] = {
1583 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1584 { NULL }
1587 context = g_option_context_new (NULL);
1588 g_option_context_set_ignore_unknown_options (context, TRUE);
1589 g_option_context_add_main_entries (context, entries, NULL);
1591 /* Now try parsing */
1592 argv = split_string ("program foo --test -bar --", &argc);
1593 argv_copy = copy_stringv (argv, argc);
1595 retval = g_option_context_parse (context, &argc, &argv, &error);
1596 g_assert_no_error (error);
1597 g_assert (retval);
1599 /* Check array */
1600 g_assert (ignore_test1_boolean);
1601 g_assert (strcmp (argv[0], "program") == 0);
1602 g_assert (strcmp (argv[1], "foo") == 0);
1603 g_assert (strcmp (argv[2], "-bar") == 0);
1604 g_assert (argv[3] == NULL);
1606 g_strfreev (argv_copy);
1607 g_free (argv);
1608 g_option_context_free (context);
1611 static void
1612 rest_test2c (void)
1614 GOptionContext *context;
1615 gboolean retval;
1616 GError *error = NULL;
1617 gchar **argv;
1618 gchar **argv_copy;
1619 int argc;
1620 GOptionEntry entries [] = {
1621 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1622 { NULL }
1625 context = g_option_context_new (NULL);
1626 g_option_context_add_main_entries (context, entries, NULL);
1628 /* Now try parsing */
1629 argv = split_string ("program --test foo -- bar", &argc);
1630 argv_copy = copy_stringv (argv, argc);
1632 retval = g_option_context_parse (context, &argc, &argv, &error);
1633 g_assert_no_error (error);
1634 g_assert (retval);
1636 /* Check array */
1637 g_assert (ignore_test1_boolean);
1638 g_assert (strcmp (argv[0], "program") == 0);
1639 g_assert (strcmp (argv[1], "foo") == 0);
1640 g_assert (strcmp (argv[2], "bar") == 0);
1641 g_assert (argv[3] == NULL);
1643 g_strfreev (argv_copy);
1644 g_free (argv);
1645 g_option_context_free (context);
1648 static void
1649 rest_test2d (void)
1651 GOptionContext *context;
1652 gboolean retval;
1653 GError *error = NULL;
1654 gchar **argv;
1655 gchar **argv_copy;
1656 int argc;
1657 GOptionEntry entries [] = {
1658 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1659 { NULL }
1662 context = g_option_context_new (NULL);
1663 g_option_context_add_main_entries (context, entries, NULL);
1665 /* Now try parsing */
1666 argv = split_string ("program --test -- -bar", &argc);
1667 argv_copy = copy_stringv (argv, argc);
1669 retval = g_option_context_parse (context, &argc, &argv, &error);
1670 g_assert_no_error (error);
1671 g_assert (retval);
1673 /* Check array */
1674 g_assert (ignore_test1_boolean);
1675 g_assert (strcmp (argv[0], "program") == 0);
1676 g_assert (strcmp (argv[1], "--") == 0);
1677 g_assert (strcmp (argv[2], "-bar") == 0);
1678 g_assert (argv[3] == NULL);
1680 g_strfreev (argv_copy);
1681 g_free (argv);
1682 g_option_context_free (context);
1686 /* check that G_OPTION_REMAINING collects non-option arguments */
1687 static void
1688 rest_test3 (void)
1690 GOptionContext *context;
1691 gboolean retval;
1692 GError *error = NULL;
1693 gchar **argv;
1694 gchar **argv_copy;
1695 int argc;
1696 GOptionEntry entries [] = {
1697 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1698 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1699 { NULL }
1702 context = g_option_context_new (NULL);
1703 g_option_context_add_main_entries (context, entries, NULL);
1705 /* Now try parsing */
1706 argv = split_string ("program foo --test bar", &argc);
1707 argv_copy = copy_stringv (argv, argc);
1709 retval = g_option_context_parse (context, &argc, &argv, &error);
1710 g_assert_no_error (error);
1711 g_assert (retval);
1713 /* Check array */
1714 g_assert (ignore_test1_boolean);
1715 g_assert (strcmp (array_test1_array[0], "foo") == 0);
1716 g_assert (strcmp (array_test1_array[1], "bar") == 0);
1717 g_assert (array_test1_array[2] == NULL);
1719 g_strfreev (array_test1_array);
1721 g_strfreev (argv_copy);
1722 g_free (argv);
1723 g_option_context_free (context);
1727 /* check that G_OPTION_REMAINING and -- work together */
1728 static void
1729 rest_test4 (void)
1731 GOptionContext *context;
1732 gboolean retval;
1733 GError *error = NULL;
1734 gchar **argv;
1735 gchar **argv_copy;
1736 int argc;
1737 GOptionEntry entries [] = {
1738 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1739 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1740 { NULL }
1743 context = g_option_context_new (NULL);
1744 g_option_context_add_main_entries (context, entries, NULL);
1746 /* Now try parsing */
1747 argv = split_string ("program foo --test -- -bar", &argc);
1748 argv_copy = copy_stringv (argv, argc);
1750 retval = g_option_context_parse (context, &argc, &argv, &error);
1751 g_assert_no_error (error);
1752 g_assert (retval);
1754 /* Check array */
1755 g_assert (ignore_test1_boolean);
1756 g_assert (strcmp (array_test1_array[0], "foo") == 0);
1757 g_assert (strcmp (array_test1_array[1], "-bar") == 0);
1758 g_assert (array_test1_array[2] == NULL);
1760 g_strfreev (array_test1_array);
1762 g_strfreev (argv_copy);
1763 g_free (argv);
1764 g_option_context_free (context);
1767 /* test that G_OPTION_REMAINING works with G_OPTION_ARG_FILENAME_ARRAY */
1768 static void
1769 rest_test5 (void)
1771 GOptionContext *context;
1772 gboolean retval;
1773 GError *error = NULL;
1774 gchar **argv;
1775 gchar **argv_copy;
1776 int argc;
1777 GOptionEntry entries [] = {
1778 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1779 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &array_test1_array, NULL, NULL },
1780 { NULL }
1783 context = g_option_context_new (NULL);
1784 g_option_context_add_main_entries (context, entries, NULL);
1786 /* Now try parsing */
1787 argv = split_string ("program foo --test bar", &argc);
1788 argv_copy = copy_stringv (argv, argc);
1790 retval = g_option_context_parse (context, &argc, &argv, &error);
1791 g_assert_no_error (error);
1792 g_assert (retval);
1794 /* Check array */
1795 g_assert (ignore_test1_boolean);
1796 g_assert (strcmp (array_test1_array[0], "foo") == 0);
1797 g_assert (strcmp (array_test1_array[1], "bar") == 0);
1798 g_assert (array_test1_array[2] == NULL);
1800 g_strfreev (array_test1_array);
1802 g_strfreev (argv_copy);
1803 g_free (argv);
1804 g_option_context_free (context);
1807 static void
1808 unknown_short_test (void)
1810 GOptionContext *context;
1811 gboolean retval;
1812 GError *error = NULL;
1813 gchar **argv;
1814 gchar **argv_copy;
1815 int argc;
1816 GOptionEntry entries [] = { { NULL } };
1818 g_test_bug ("166609");
1820 context = g_option_context_new (NULL);
1821 g_option_context_add_main_entries (context, entries, NULL);
1823 /* Now try parsing */
1824 argv = split_string ("program -0", &argc);
1825 argv_copy = copy_stringv (argv, argc);
1827 retval = g_option_context_parse (context, &argc, &argv, &error);
1828 g_assert (!retval);
1829 g_assert (error != NULL);
1830 g_clear_error (&error);
1832 g_strfreev (argv_copy);
1833 g_free (argv);
1834 g_option_context_free (context);
1837 /* test that lone dashes are treated as non-options */
1838 static void
1839 lonely_dash_test (void)
1841 GOptionContext *context;
1842 gboolean retval;
1843 GError *error = NULL;
1844 gchar **argv;
1845 gchar **argv_copy;
1846 int argc;
1848 g_test_bug ("168008");
1850 context = g_option_context_new (NULL);
1852 /* Now try parsing */
1853 argv = split_string ("program -", &argc);
1854 argv_copy = copy_stringv (argv, argc);
1856 retval = g_option_context_parse (context, &argc, &argv, &error);
1857 g_assert_no_error (error);
1858 g_assert (retval);
1860 g_assert (argv[1] && strcmp (argv[1], "-") == 0);
1862 g_strfreev (argv_copy);
1863 g_free (argv);
1864 g_option_context_free (context);
1867 static void
1868 missing_arg_test (void)
1870 GOptionContext *context;
1871 gboolean retval;
1872 GError *error = NULL;
1873 gchar **argv;
1874 gchar **argv_copy;
1875 int argc;
1876 gchar *arg = NULL;
1877 GOptionEntry entries [] =
1878 { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1879 { NULL } };
1881 g_test_bug ("305576");
1883 context = g_option_context_new (NULL);
1884 g_option_context_add_main_entries (context, entries, NULL);
1886 /* Now try parsing */
1887 argv = split_string ("program --test", &argc);
1888 argv_copy = copy_stringv (argv, argc);
1890 retval = g_option_context_parse (context, &argc, &argv, &error);
1891 g_assert (retval == FALSE);
1892 g_assert (error != NULL);
1893 /* An error occurred, so argv has not been changed */
1894 check_identical_stringv (argv_copy, argv);
1895 g_clear_error (&error);
1897 g_strfreev (argv_copy);
1898 g_free (argv);
1900 /* Try parsing again */
1901 argv = split_string ("program -t", &argc);
1902 argv_copy = copy_stringv (argv, argc);
1904 retval = g_option_context_parse (context, &argc, &argv, &error);
1905 g_assert (retval == FALSE);
1906 g_assert (error != NULL);
1907 /* An error occurred, so argv has not been changed */
1908 check_identical_stringv (argv_copy, argv);
1909 g_clear_error (&error);
1911 g_strfreev (argv_copy);
1912 g_free (argv);
1913 g_option_context_free (context);
1916 static gchar *test_arg;
1918 static gboolean cb (const gchar *option_name,
1919 const gchar *value,
1920 gpointer data,
1921 GError **error)
1923 test_arg = g_strdup (value);
1924 return TRUE;
1927 static void
1928 dash_arg_test (void)
1930 GOptionContext *context;
1931 gboolean retval;
1932 GError *error = NULL;
1933 gchar **argv;
1934 gchar **argv_copy;
1935 int argc;
1936 gboolean argb = FALSE;
1937 GOptionEntry entries [] =
1938 { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, cb, NULL, NULL },
1939 { "three", '3', 0, G_OPTION_ARG_NONE, &argb, NULL, NULL },
1940 { NULL } };
1942 g_test_bug ("577638");
1944 context = g_option_context_new (NULL);
1945 g_option_context_add_main_entries (context, entries, NULL);
1947 /* Now try parsing */
1948 argv = split_string ("program --test=-3", &argc);
1949 argv_copy = copy_stringv (argv, argc);
1951 test_arg = NULL;
1952 error = NULL;
1953 retval = g_option_context_parse (context, &argc, &argv, &error);
1954 g_assert (retval);
1955 g_assert_no_error (error);
1956 g_assert_cmpstr (test_arg, ==, "-3");
1958 g_strfreev (argv_copy);
1959 g_free (argv);
1960 g_free (test_arg);
1961 test_arg = NULL;
1963 /* Try parsing again */
1964 argv = split_string ("program --test -3", &argc);
1965 argv_copy = copy_stringv (argv, argc);
1967 error = NULL;
1968 retval = g_option_context_parse (context, &argc, &argv, &error);
1969 g_assert_no_error (error);
1970 g_assert (retval);
1971 g_assert_cmpstr (test_arg, ==, NULL);
1973 g_option_context_free (context);
1974 g_strfreev (argv_copy);
1975 g_free (argv);
1978 static void
1979 test_basic (void)
1981 GOptionContext *context;
1982 gchar *arg = NULL;
1983 GOptionEntry entries [] =
1984 { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1985 { NULL } };
1987 context = g_option_context_new (NULL);
1988 g_option_context_add_main_entries (context, entries, NULL);
1990 g_assert (g_option_context_get_help_enabled (context));
1991 g_assert (!g_option_context_get_ignore_unknown_options (context));
1992 g_assert_cmpstr (g_option_context_get_summary (context), ==, NULL);
1993 g_assert_cmpstr (g_option_context_get_description (context), ==, NULL);
1995 g_option_context_set_help_enabled (context, FALSE);
1996 g_option_context_set_ignore_unknown_options (context, TRUE);
1997 g_option_context_set_summary (context, "summary");
1998 g_option_context_set_description(context, "description");
2000 g_assert (!g_option_context_get_help_enabled (context));
2001 g_assert (g_option_context_get_ignore_unknown_options (context));
2002 g_assert_cmpstr (g_option_context_get_summary (context), ==, "summary");
2003 g_assert_cmpstr (g_option_context_get_description (context), ==, "description");
2005 g_option_context_free (context);
2008 static void
2009 test_main_group (void)
2011 GOptionContext *context;
2012 GOptionGroup *group;
2014 context = g_option_context_new (NULL);
2015 g_assert (g_option_context_get_main_group (context) == NULL);
2016 group = g_option_group_new ("name", "description", "hlep", NULL, NULL);
2017 g_option_context_add_group (context, group);
2018 g_assert (g_option_context_get_main_group (context) == NULL);
2019 group = g_option_group_new ("name", "description", "hlep", NULL, NULL);
2020 g_option_context_set_main_group (context, group);
2021 g_assert (g_option_context_get_main_group (context) == group);
2023 g_option_context_free (context);
2026 static gboolean error_func_called = FALSE;
2028 static void
2029 error_func (GOptionContext *context,
2030 GOptionGroup *group,
2031 gpointer data,
2032 GError **error)
2034 g_assert_cmpint (GPOINTER_TO_INT(data), ==, 1234);
2035 error_func_called = TRUE;
2038 static void
2039 test_error_hook (void)
2041 GOptionContext *context;
2042 gchar *arg = NULL;
2043 GOptionEntry entries [] =
2044 { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
2045 { NULL } };
2046 GOptionGroup *group;
2047 gchar **argv;
2048 gchar **argv_copy;
2049 gint argc;
2050 gboolean retval;
2051 GError *error = NULL;
2053 context = g_option_context_new (NULL);
2054 group = g_option_group_new ("name", "description", "hlep", GINT_TO_POINTER(1234), NULL);
2055 g_option_group_add_entries (group, entries);
2056 g_option_context_set_main_group (context, group);
2057 g_option_group_set_error_hook (g_option_context_get_main_group (context),
2058 error_func);
2060 argv = split_string ("program --test", &argc);
2061 argv_copy = copy_stringv (argv, argc);
2063 retval = g_option_context_parse (context, &argc, &argv, &error);
2064 g_assert (retval == FALSE);
2065 g_assert (error != NULL);
2066 /* An error occurred, so argv has not been changed */
2067 check_identical_stringv (argv_copy, argv);
2068 g_clear_error (&error);
2070 g_assert (error_func_called);
2072 g_strfreev (argv_copy);
2073 g_free (argv);
2074 g_option_context_free (context);
2077 static void
2078 flag_reverse_string (void)
2080 if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
2082 GOptionContext *context;
2083 gchar *arg = NULL;
2084 GOptionEntry entries [] =
2085 { { "test", 't', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_STRING, &arg, NULL, NULL },
2086 { NULL } };
2087 gchar **argv;
2088 gint argc;
2089 gboolean retval;
2090 GError *error = NULL;
2092 context = g_option_context_new (NULL);
2093 g_option_context_add_main_entries (context, entries, NULL);
2095 argv = split_string ("program --test bla", &argc);
2097 retval = g_option_context_parse (context, &argc, &argv, &error);
2098 g_assert (retval == FALSE);
2099 g_clear_error (&error);
2100 g_strfreev (argv);
2101 g_option_context_free (context);
2102 exit (0);
2104 g_test_trap_assert_failed ();
2105 g_test_trap_assert_stderr ("*ignoring reverse flag*");
2108 static void
2109 flag_optional_int (void)
2111 if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
2113 GOptionContext *context;
2114 gint arg = 0;
2115 GOptionEntry entries [] =
2116 { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &arg, NULL, NULL },
2117 { NULL } };
2118 gchar **argv;
2119 gint argc;
2120 gboolean retval;
2121 GError *error = NULL;
2123 context = g_option_context_new (NULL);
2124 g_option_context_add_main_entries (context, entries, NULL);
2126 argv = split_string ("program --test 5", &argc);
2128 retval = g_option_context_parse (context, &argc, &argv, &error);
2129 g_assert (retval == FALSE);
2130 g_clear_error (&error);
2131 g_strfreev (argv);
2132 g_option_context_free (context);
2133 exit (0);
2135 g_test_trap_assert_failed ();
2136 g_test_trap_assert_stderr ("*ignoring no-arg, optional-arg or filename flags*");
2139 main (int argc,
2140 char *argv[])
2142 g_test_init (&argc, &argv, NULL);
2144 g_test_bug_base ("http://bugzilla.gnome.org/");
2146 g_test_add_func ("/option/basic", test_basic);
2147 g_test_add_func ("/option/group/captions", group_captions);
2148 g_test_add_func ("/option/group/main", test_main_group);
2149 g_test_add_func ("/option/group/error-hook", test_error_hook);
2151 /* Test that restoration on failure works */
2152 g_test_add_func ("/option/restoration/int", error_test1);
2153 g_test_add_func ("/option/restoration/string", error_test2);
2154 g_test_add_func ("/option/restoration/boolean", error_test3);
2156 /* Test that special argument parsing works */
2157 g_test_add_func ("/option/arg/repetition/int", arg_test1);
2158 g_test_add_func ("/option/arg/repetition/string", arg_test2);
2159 g_test_add_func ("/option/arg/repetition/filename", arg_test3);
2160 g_test_add_func ("/option/arg/repetition/double", arg_test4);
2161 g_test_add_func ("/option/arg/repetition/locale", arg_test5);
2162 g_test_add_func ("/option/arg/repetition/int64", arg_test6);
2164 /* Test string arrays */
2165 g_test_add_func ("/option/arg/array/string", array_test1);
2167 /* Test callback args */
2168 g_test_add_func ("/option/arg/callback/string", callback_test1);
2169 g_test_add_func ("/option/arg/callback/count", callback_test2);
2171 /* Test optional arg flag for callback */
2172 g_test_add_func ("/option/arg/callback/optional1", callback_test_optional_1);
2173 g_test_add_func ("/option/arg/callback/optional2", callback_test_optional_2);
2174 g_test_add_func ("/option/arg/callback/optional3", callback_test_optional_3);
2175 g_test_add_func ("/option/arg/callback/optional4", callback_test_optional_4);
2176 g_test_add_func ("/option/arg/callback/optional5", callback_test_optional_5);
2177 g_test_add_func ("/option/arg/callback/optional6", callback_test_optional_6);
2178 g_test_add_func ("/option/arg/callback/optional7", callback_test_optional_7);
2179 g_test_add_func ("/option/arg/callback/optional8", callback_test_optional_8);
2181 /* Test callback with G_OPTION_REMAINING */
2182 g_test_add_func ("/option/arg/remaining/callback", callback_remaining_test1);
2184 /* Test callbacks which return FALSE */
2185 g_test_add_func ("/option/arg/remaining/callback-false", callback_returns_false);
2187 /* Test ignoring options */
2188 g_test_add_func ("/option/arg/ignore/long", ignore_test1);
2189 g_test_add_func ("/option/arg/ignore/short", ignore_test2);
2190 g_test_add_func ("/option/arg/ignore/arg", ignore_test3);
2191 g_test_add_func ("/option/context/add", add_test1);
2193 /* Test parsing empty args */
2194 /* Note there used to be an empty1 here, but it effectively moved
2195 * to option-argv0.c.
2197 g_test_add_func ("/option/context/empty2", empty_test2);
2198 g_test_add_func ("/option/context/empty3", empty_test3);
2200 /* Test handling of rest args */
2201 g_test_add_func ("/option/arg/rest/non-option", rest_test1);
2202 g_test_add_func ("/option/arg/rest/separator1", rest_test2);
2203 g_test_add_func ("/option/arg/rest/separator2", rest_test2a);
2204 g_test_add_func ("/option/arg/rest/separator3", rest_test2b);
2205 g_test_add_func ("/option/arg/rest/separator4", rest_test2c);
2206 g_test_add_func ("/option/arg/rest/separator5", rest_test2d);
2207 g_test_add_func ("/option/arg/remaining/non-option", rest_test3);
2208 g_test_add_func ("/option/arg/remaining/separator", rest_test4);
2209 g_test_add_func ("/option/arg/remaining/array", rest_test5);
2211 /* Test some invalid flag combinations */
2212 g_test_add_func ("/option/arg/reverse-string", flag_reverse_string);
2213 g_test_add_func ("/option/arg/optional-int", flag_optional_int);
2215 /* regression tests for individual bugs */
2216 g_test_add_func ("/option/bug/unknown-short", unknown_short_test);
2217 g_test_add_func ("/option/bug/lonely-dash", lonely_dash_test);
2218 g_test_add_func ("/option/bug/missing-arg", missing_arg_test);
2219 g_test_add_func ("/option/bug/dash-arg", dash_arg_test);
2221 return g_test_run();