nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /* Unit tests for GOptionContext
2 * Copyright (C) 2007 Openismus GmbH
3 * Authors: Mathias Hasselmann
4 *
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.
8 *
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.
12 *
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.
21 */
22  
23 #include <glib.h>
24  
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <locale.h>
29  
30 static GOptionEntry main_entries[] = {
31 { "main-switch", 0, 0,
32 G_OPTION_ARG_NONE, NULL,
33 "A switch that is in the main group", NULL },
34 { NULL }
35 };
36  
37 static GOptionEntry group_entries[] = {
38 { "test-switch", 0, 0,
39 G_OPTION_ARG_NONE, NULL,
40 "A switch that is in the test group", NULL },
41 { NULL }
42 };
43  
44 static GOptionContext *
45 make_options (int test_number)
46 {
47 GOptionContext *options;
48 GOptionGroup *group = NULL;
49 gboolean have_main_entries = (0 != (test_number & 1));
50 gboolean have_test_entries = (0 != (test_number & 2));
51  
52 options = g_option_context_new (NULL);
53  
54 if (have_main_entries)
55 g_option_context_add_main_entries (options, main_entries, NULL);
56 if (have_test_entries)
57 {
58 group = g_option_group_new ("test", "Test Options",
59 "Show all test options",
60 NULL, NULL);
61 g_option_context_add_group (options, group);
62 g_option_group_add_entries (group, group_entries);
63 }
64  
65 return options;
66 }
67  
68 static void
69 print_help (GOptionContext *options, gchar **argv)
70 {
71 gint argc = 3;
72 GError *error = NULL;
73  
74 g_option_context_parse (options, &argc, &argv, &error);
75 g_option_context_free (options);
76 exit(0);
77 }
78  
79 static void
80 test_group_captions_help (gconstpointer test_number)
81 {
82 GOptionContext *options;
83 gchar *argv[] = { __FILE__, "--help", NULL };
84  
85 options = make_options (GPOINTER_TO_INT (test_number));
86 print_help (options, argv);
87 }
88  
89 static void
90 test_group_captions_help_all (gconstpointer test_number)
91 {
92 GOptionContext *options;
93 gchar *argv[] = { __FILE__, "--help-all", NULL };
94  
95 options = make_options (GPOINTER_TO_INT (test_number));
96 print_help (options, argv);
97 }
98  
99 static void
100 test_group_captions_help_test (gconstpointer test_number)
101 {
102 GOptionContext *options;
103 gchar *argv[] = { __FILE__, "--help-test", NULL };
104  
105 options = make_options (GPOINTER_TO_INT (test_number));
106 print_help (options, argv);
107 }
108  
109 static void
110 test_group_captions (void)
111 {
112 const gchar *test_name_base[] = { "help", "help-all", "help-test" };
113 gchar *test_name;
114 gint i, j;
115  
116 g_test_bug ("504142");
117  
118 for (i = 0; i < 4; ++i)
119 {
120 gboolean have_main_entries = (0 != (i & 1));
121 gboolean have_test_entries = (0 != (i & 2));
122  
123 for (j = 0; j < G_N_ELEMENTS (test_name_base); ++j)
124 {
125 GTestSubprocessFlags trap_flags = 0;
126 gboolean expect_main_description = FALSE;
127 gboolean expect_main_switch = FALSE;
128 gboolean expect_test_description = FALSE;
129 gboolean expect_test_switch = FALSE;
130 gboolean expect_test_group = FALSE;
131  
132 if (g_test_verbose ())
133 trap_flags |= G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR;
134  
135 test_name = g_strdup_printf ("/option/group/captions/subprocess/%s-%d",
136 test_name_base[j], i);
137 g_test_trap_subprocess (test_name, 0, trap_flags);
138 g_free (test_name);
139 g_test_trap_assert_passed ();
140 g_test_trap_assert_stderr ("");
141  
142 switch (j)
143 {
144 case 0:
145 g_assert_cmpstr ("help", ==, test_name_base[j]);
146 expect_main_switch = have_main_entries;
147 expect_test_group = have_test_entries;
148 break;
149  
150 case 1:
151 g_assert_cmpstr ("help-all", ==, test_name_base[j]);
152 expect_main_switch = have_main_entries;
153 expect_test_switch = have_test_entries;
154 expect_test_group = have_test_entries;
155 break;
156  
157 case 2:
158 g_assert_cmpstr ("help-test", ==, test_name_base[j]);
159 expect_test_switch = have_test_entries;
160 break;
161  
162 default:
163 g_assert_not_reached ();
164 break;
165 }
166  
167 expect_main_description |= expect_main_switch;
168 expect_test_description |= expect_test_switch;
169  
170 if (expect_main_description)
171 g_test_trap_assert_stdout ("*Application Options*");
172 else
173 g_test_trap_assert_stdout_unmatched ("*Application Options*");
174 if (expect_main_switch)
175 g_test_trap_assert_stdout ("*--main-switch*");
176 else
177 g_test_trap_assert_stdout_unmatched ("*--main-switch*");
178  
179 if (expect_test_description)
180 g_test_trap_assert_stdout ("*Test Options*");
181 else
182 g_test_trap_assert_stdout_unmatched ("*Test Options*");
183 if (expect_test_switch)
184 g_test_trap_assert_stdout ("*--test-switch*");
185 else
186 g_test_trap_assert_stdout_unmatched ("*--test-switch*");
187  
188 if (expect_test_group)
189 g_test_trap_assert_stdout ("*--help-test*");
190 else
191 g_test_trap_assert_stdout_unmatched ("*--help-test*");
192 }
193 }
194 }
195  
196 int error_test1_int;
197 char *error_test2_string;
198 gboolean error_test3_boolean;
199  
200 int arg_test1_int;
201 gchar *arg_test2_string;
202 gchar *arg_test3_filename;
203 gdouble arg_test4_double;
204 gdouble arg_test5_double;
205 gint64 arg_test6_int64;
206 gint64 arg_test6_int64_2;
207  
208 gchar *callback_test1_string;
209 int callback_test2_int;
210  
211 gchar *callback_test_optional_string;
212 gboolean callback_test_optional_boolean;
213  
214 gchar **array_test1_array;
215  
216 gboolean ignore_test1_boolean;
217 gboolean ignore_test2_boolean;
218 gchar *ignore_test3_string;
219  
220 static gchar **
221 split_string (const char *str, int *argc)
222 {
223 gchar **argv;
224 int len;
225  
226 argv = g_strsplit (str, " ", 0);
227  
228 for (len = 0; argv[len] != NULL; len++);
229  
230 if (argc)
231 *argc = len;
232  
233 return argv;
234 }
235  
236 static gchar *
237 join_stringv (int argc, char **argv)
238 {
239 int i;
240 GString *str;
241  
242 str = g_string_new (NULL);
243  
244 for (i = 0; i < argc; i++)
245 {
246 g_string_append (str, argv[i]);
247  
248 if (i < argc - 1)
249 g_string_append_c (str, ' ');
250 }
251  
252 return g_string_free (str, FALSE);
253 }
254  
255 /* Performs a shallow copy */
256 static char **
257 copy_stringv (char **argv, int argc)
258 {
259 return g_memdup (argv, sizeof (char *) * (argc + 1));
260 }
261  
262 static void
263 check_identical_stringv (gchar **before, gchar **after)
264 {
265 guint i;
266  
267 /* Not only is it the same string... */
268 for (i = 0; before[i] != NULL; i++)
269 g_assert_cmpstr (before[i], ==, after[i]);
270  
271 /* ... it is actually the same pointer */
272 for (i = 0; before[i] != NULL; i++)
273 g_assert (before[i] == after[i]);
274  
275 g_assert (after[i] == NULL);
276 }
277  
278  
279 static gboolean
280 error_test1_pre_parse (GOptionContext *context,
281 GOptionGroup *group,
282 gpointer data,
283 GError **error)
284 {
285 g_assert (error_test1_int == 0x12345678);
286  
287 return TRUE;
288 }
289  
290 static gboolean
291 error_test1_post_parse (GOptionContext *context,
292 GOptionGroup *group,
293 gpointer data,
294 GError **error)
295 {
296 g_assert (error_test1_int == 20);
297  
298 /* Set an error in the post hook */
299 g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
300  
301 return FALSE;
302 }
303  
304 static void
305 error_test1 (void)
306 {
307 GOptionContext *context;
308 gboolean retval;
309 GError *error = NULL;
310 gchar **argv;
311 gchar **argv_copy;
312 int argc;
313 GOptionGroup *main_group;
314 GOptionEntry entries [] =
315 { { "test", 0, 0, G_OPTION_ARG_INT, &error_test1_int, NULL, NULL },
316 { NULL } };
317  
318 error_test1_int = 0x12345678;
319  
320 context = g_option_context_new (NULL);
321 g_option_context_add_main_entries (context, entries, NULL);
322  
323 /* Set pre and post parse hooks */
324 main_group = g_option_context_get_main_group (context);
325 g_option_group_set_parse_hooks (main_group,
326 error_test1_pre_parse, error_test1_post_parse);
327  
328 /* Now try parsing */
329 argv = split_string ("program --test 20", &argc);
330 argv_copy = copy_stringv (argv, argc);
331  
332 retval = g_option_context_parse (context, &argc, &argv, &error);
333 g_assert (retval == FALSE);
334 g_assert (error != NULL);
335 /* An error occurred, so argv has not been changed */
336 check_identical_stringv (argv_copy, argv);
337 g_clear_error (&error);
338  
339 /* On failure, values should be reset */
340 g_assert (error_test1_int == 0x12345678);
341  
342 g_strfreev (argv_copy);
343 g_free (argv);
344 g_option_context_free (context);
345 }
346  
347 static gboolean
348 error_test2_pre_parse (GOptionContext *context,
349 GOptionGroup *group,
350 gpointer data,
351 GError **error)
352 {
353 g_assert (strcmp (error_test2_string, "foo") == 0);
354  
355 return TRUE;
356 }
357  
358 static gboolean
359 error_test2_post_parse (GOptionContext *context,
360 GOptionGroup *group,
361 gpointer data,
362 GError **error)
363 {
364 g_assert (strcmp (error_test2_string, "bar") == 0);
365  
366 /* Set an error in the post hook */
367 g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
368  
369 return FALSE;
370 }
371  
372 static void
373 error_test2 (void)
374 {
375 GOptionContext *context;
376 gboolean retval;
377 GError *error = NULL;
378 gchar **argv;
379 gchar **argv_copy;
380 int argc;
381 GOptionGroup *main_group;
382 GOptionEntry entries [] =
383 { { "test", 0, 0, G_OPTION_ARG_STRING, &error_test2_string, NULL, NULL },
384 { NULL } };
385  
386 error_test2_string = "foo";
387  
388 context = g_option_context_new (NULL);
389 g_option_context_add_main_entries (context, entries, NULL);
390  
391 /* Set pre and post parse hooks */
392 main_group = g_option_context_get_main_group (context);
393 g_option_group_set_parse_hooks (main_group,
394 error_test2_pre_parse, error_test2_post_parse);
395  
396 /* Now try parsing */
397 argv = split_string ("program --test bar", &argc);
398 argv_copy = copy_stringv (argv, argc);
399 retval = g_option_context_parse (context, &argc, &argv, &error);
400  
401 g_assert (retval == FALSE);
402 g_assert (error != NULL);
403 check_identical_stringv (argv_copy, argv);
404 g_clear_error (&error);
405  
406 g_assert (strcmp (error_test2_string, "foo") == 0);
407  
408 g_strfreev (argv_copy);
409 g_free (argv);
410 g_option_context_free (context);
411 }
412  
413 static gboolean
414 error_test3_pre_parse (GOptionContext *context,
415 GOptionGroup *group,
416 gpointer data,
417 GError **error)
418 {
419 g_assert (!error_test3_boolean);
420  
421 return TRUE;
422 }
423  
424 static gboolean
425 error_test3_post_parse (GOptionContext *context,
426 GOptionGroup *group,
427 gpointer data,
428 GError **error)
429 {
430 g_assert (error_test3_boolean);
431  
432 /* Set an error in the post hook */
433 g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
434  
435 return FALSE;
436 }
437  
438 static void
439 error_test3 (void)
440 {
441 GOptionContext *context;
442 gboolean retval;
443 GError *error = NULL;
444 gchar **argv;
445 gchar **argv_copy;
446 int argc;
447 GOptionGroup *main_group;
448 GOptionEntry entries [] =
449 { { "test", 0, 0, G_OPTION_ARG_NONE, &error_test3_boolean, NULL, NULL },
450 { NULL } };
451  
452 error_test3_boolean = FALSE;
453  
454 context = g_option_context_new (NULL);
455 g_option_context_add_main_entries (context, entries, NULL);
456  
457 /* Set pre and post parse hooks */
458 main_group = g_option_context_get_main_group (context);
459 g_option_group_set_parse_hooks (main_group,
460 error_test3_pre_parse, error_test3_post_parse);
461  
462 /* Now try parsing */
463 argv = split_string ("program --test", &argc);
464 argv_copy = copy_stringv (argv, argc);
465 retval = g_option_context_parse (context, &argc, &argv, &error);
466  
467 g_assert (retval == FALSE);
468 g_assert (error != NULL);
469 check_identical_stringv (argv_copy, argv);
470 g_clear_error (&error);
471  
472 g_assert (!error_test3_boolean);
473  
474 g_strfreev (argv_copy);
475 g_free (argv);
476 g_option_context_free (context);
477 }
478  
479 static void
480 arg_test1 (void)
481 {
482 GOptionContext *context;
483 gboolean retval;
484 GError *error = NULL;
485 gchar **argv;
486 gchar **argv_copy;
487 int argc;
488 GOptionEntry entries [] =
489 { { "test", 0, 0, G_OPTION_ARG_INT, &arg_test1_int, NULL, NULL },
490 { NULL } };
491  
492 context = g_option_context_new (NULL);
493 g_option_context_add_main_entries (context, entries, NULL);
494  
495 /* Now try parsing */
496 argv = split_string ("program --test 20 --test 30", &argc);
497 argv_copy = copy_stringv (argv, argc);
498  
499 retval = g_option_context_parse (context, &argc, &argv, &error);
500 g_assert_no_error (error);
501 g_assert (retval);
502  
503 /* Last arg specified is the one that should be stored */
504 g_assert (arg_test1_int == 30);
505  
506 /* We free all of the strings in a copy of argv, because now argv is a
507 * subset - some have been removed in-place
508 */
509 g_strfreev (argv_copy);
510 g_free (argv);
511 g_option_context_free (context);
512 }
513  
514 static void
515 arg_test2 (void)
516 {
517 GOptionContext *context;
518 gboolean retval;
519 GError *error = NULL;
520 gchar **argv;
521 gchar **argv_copy;
522 int argc;
523 GOptionEntry entries [] =
524 { { "test", 0, 0, G_OPTION_ARG_STRING, &arg_test2_string, NULL, NULL },
525 { NULL } };
526  
527 context = g_option_context_new (NULL);
528 g_option_context_add_main_entries (context, entries, NULL);
529  
530 /* Now try parsing */
531 argv = split_string ("program --test foo --test bar", &argc);
532 argv_copy = copy_stringv (argv, argc);
533  
534 retval = g_option_context_parse (context, &argc, &argv, &error);
535 g_assert_no_error (error);
536 g_assert (retval);
537  
538 /* Last arg specified is the one that should be stored */
539 g_assert (strcmp (arg_test2_string, "bar") == 0);
540  
541 g_free (arg_test2_string);
542  
543 g_strfreev (argv_copy);
544 g_free (argv);
545 g_option_context_free (context);
546 }
547  
548 static void
549 arg_test3 (void)
550 {
551 GOptionContext *context;
552 gboolean retval;
553 GError *error = NULL;
554 gchar **argv;
555 gchar **argv_copy;
556 int argc;
557 GOptionEntry entries [] =
558 { { "test", 0, 0, G_OPTION_ARG_FILENAME, &arg_test3_filename, NULL, NULL },
559 { NULL } };
560  
561 context = g_option_context_new (NULL);
562 g_option_context_add_main_entries (context, entries, NULL);
563  
564 /* Now try parsing */
565 argv = split_string ("program --test foo.txt", &argc);
566 argv_copy = copy_stringv (argv, argc);
567  
568 retval = g_option_context_parse (context, &argc, &argv, &error);
569 g_assert_no_error (error);
570 g_assert (retval);
571  
572 /* Last arg specified is the one that should be stored */
573 g_assert (strcmp (arg_test3_filename, "foo.txt") == 0);
574  
575 g_free (arg_test3_filename);
576  
577 g_strfreev (argv_copy);
578 g_free (argv);
579 g_option_context_free (context);
580 }
581  
582  
583 static void
584 arg_test4 (void)
585 {
586 GOptionContext *context;
587 gboolean retval;
588 GError *error = NULL;
589 gchar **argv_copy;
590 gchar **argv;
591 int argc;
592 GOptionEntry entries [] =
593 { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test4_double, NULL, NULL },
594 { NULL } };
595  
596 context = g_option_context_new (NULL);
597 g_option_context_add_main_entries (context, entries, NULL);
598  
599 /* Now try parsing */
600 argv = split_string ("program --test 20.0 --test 30.03", &argc);
601 argv_copy = copy_stringv (argv, argc);
602  
603 retval = g_option_context_parse (context, &argc, &argv, &error);
604 g_assert_no_error (error);
605 g_assert (retval);
606  
607 /* Last arg specified is the one that should be stored */
608 g_assert (arg_test4_double == 30.03);
609  
610 g_strfreev (argv_copy);
611 g_free (argv);
612 g_option_context_free (context);
613 }
614  
615 static void
616 arg_test5 (void)
617 {
618 GOptionContext *context;
619 gboolean retval;
620 GError *error = NULL;
621 gchar **argv;
622 gchar **argv_copy;
623 int argc;
624 char *old_locale, *current_locale;
625 const char *locale = "de_DE.UTF-8";
626 GOptionEntry entries [] =
627 { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test5_double, NULL, NULL },
628 { NULL } };
629  
630 context = g_option_context_new (NULL);
631 g_option_context_add_main_entries (context, entries, NULL);
632  
633 /* Now try parsing */
634 argv = split_string ("program --test 20,0 --test 30,03", &argc);
635 argv_copy = copy_stringv (argv, argc);
636  
637 /* set it to some locale that uses commas instead of decimal points */
638  
639 old_locale = g_strdup (setlocale (LC_NUMERIC, locale));
640 current_locale = setlocale (LC_NUMERIC, NULL);
641 if (strcmp (current_locale, locale) != 0)
642 {
643 fprintf (stderr, "Cannot set locale to %s, skipping\n", locale);
644 goto cleanup;
645 }
646  
647 retval = g_option_context_parse (context, &argc, &argv, &error);
648 g_assert_no_error (error);
649 g_assert (retval);
650  
651 /* Last arg specified is the one that should be stored */
652 g_assert (arg_test5_double == 30.03);
653  
654 cleanup:
655 setlocale (LC_NUMERIC, old_locale);
656 g_free (old_locale);
657  
658 g_strfreev (argv_copy);
659 g_free (argv);
660 g_option_context_free (context);
661 }
662  
663 static void
664 arg_test6 (void)
665 {
666 GOptionContext *context;
667 gboolean retval;
668 GError *error = NULL;
669 gchar **argv;
670 gchar **argv_copy;
671 int argc;
672 GOptionEntry entries [] =
673 { { "test", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64, NULL, NULL },
674 { "test2", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64_2, NULL, NULL },
675 { NULL } };
676  
677 context = g_option_context_new (NULL);
678 g_option_context_add_main_entries (context, entries, NULL);
679  
680 /* Now try parsing */
681 argv = split_string ("program --test 4294967297 --test 4294967296 --test2 0xfffffffff", &argc);
682 argv_copy = copy_stringv (argv, argc);
683  
684 retval = g_option_context_parse (context, &argc, &argv, &error);
685 g_assert_no_error (error);
686 g_assert (retval);
687  
688 /* Last arg specified is the one that should be stored */
689 g_assert (arg_test6_int64 == G_GINT64_CONSTANT(4294967296));
690 g_assert (arg_test6_int64_2 == G_GINT64_CONSTANT(0xfffffffff));
691  
692 g_strfreev (argv_copy);
693 g_free (argv);
694 g_option_context_free (context);
695 }
696  
697 static gboolean
698 callback_parse1 (const gchar *option_name, const gchar *value,
699 gpointer data, GError **error)
700 {
701 callback_test1_string = g_strdup (value);
702 return TRUE;
703 }
704  
705 static void
706 callback_test1 (void)
707 {
708 GOptionContext *context;
709 gboolean retval;
710 GError *error = NULL;
711 gchar **argv;
712 gchar **argv_copy;
713 int argc;
714 GOptionEntry entries [] =
715 { { "test", 0, 0, G_OPTION_ARG_CALLBACK, callback_parse1, NULL, NULL },
716 { NULL } };
717  
718 context = g_option_context_new (NULL);
719 g_option_context_add_main_entries (context, entries, NULL);
720  
721 /* Now try parsing */
722 argv = split_string ("program --test foo.txt", &argc);
723 argv_copy = copy_stringv (argv, argc);
724  
725 retval = g_option_context_parse (context, &argc, &argv, &error);
726 g_assert_no_error (error);
727 g_assert (retval);
728  
729 g_assert (strcmp (callback_test1_string, "foo.txt") == 0);
730  
731 g_free (callback_test1_string);
732  
733 g_strfreev (argv_copy);
734 g_free (argv);
735 g_option_context_free (context);
736 }
737  
738 static gboolean
739 callback_parse2 (const gchar *option_name, const gchar *value,
740 gpointer data, GError **error)
741 {
742 callback_test2_int++;
743 return TRUE;
744 }
745  
746 static void
747 callback_test2 (void)
748 {
749 GOptionContext *context;
750 gboolean retval;
751 GError *error = NULL;
752 gchar **argv;
753 gchar **argv_copy;
754 int argc;
755 GOptionEntry entries [] =
756 { { "test", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_parse2, NULL, NULL },
757 { NULL } };
758  
759 context = g_option_context_new (NULL);
760 g_option_context_add_main_entries (context, entries, NULL);
761  
762 /* Now try parsing */
763 argv = split_string ("program --test --test", &argc);
764 argv_copy = copy_stringv (argv, argc);
765  
766 retval = g_option_context_parse (context, &argc, &argv, &error);
767 g_assert_no_error (error);
768 g_assert (retval);
769  
770 g_assert (callback_test2_int == 2);
771  
772 g_strfreev (argv_copy);
773 g_free (argv);
774 g_option_context_free (context);
775 }
776  
777 static gboolean
778 callback_parse_optional (const gchar *option_name, const gchar *value,
779 gpointer data, GError **error)
780 {
781 callback_test_optional_boolean = TRUE;
782 if (value)
783 callback_test_optional_string = g_strdup (value);
784 else
785 callback_test_optional_string = NULL;
786 return TRUE;
787 }
788  
789 static void
790 callback_test_optional_1 (void)
791 {
792 GOptionContext *context;
793 gboolean retval;
794 GError *error = NULL;
795 gchar **argv;
796 gchar **argv_copy;
797 int argc;
798 GOptionEntry entries [] =
799 { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
800 callback_parse_optional, NULL, NULL },
801 { NULL } };
802  
803 context = g_option_context_new (NULL);
804 g_option_context_add_main_entries (context, entries, NULL);
805  
806 /* Now try parsing */
807 argv = split_string ("program --test foo.txt", &argc);
808 argv_copy = copy_stringv (argv, argc);
809  
810 retval = g_option_context_parse (context, &argc, &argv, &error);
811 g_assert_no_error (error);
812 g_assert (retval);
813  
814 g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
815  
816 g_assert (callback_test_optional_boolean);
817  
818 g_free (callback_test_optional_string);
819  
820 g_strfreev (argv_copy);
821 g_free (argv);
822 g_option_context_free (context);
823 }
824  
825 static void
826 callback_test_optional_2 (void)
827 {
828 GOptionContext *context;
829 gboolean retval;
830 GError *error = NULL;
831 gchar **argv;
832 gchar **argv_copy;
833 int argc;
834 GOptionEntry entries [] =
835 { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
836 callback_parse_optional, NULL, NULL },
837 { NULL } };
838  
839 context = g_option_context_new (NULL);
840 g_option_context_add_main_entries (context, entries, NULL);
841  
842 /* Now try parsing */
843 argv = split_string ("program --test", &argc);
844 argv_copy = copy_stringv (argv, argc);
845  
846 retval = g_option_context_parse (context, &argc, &argv, &error);
847 g_assert_no_error (error);
848 g_assert (retval);
849  
850 g_assert (callback_test_optional_string == NULL);
851  
852 g_assert (callback_test_optional_boolean);
853  
854 g_free (callback_test_optional_string);
855  
856 g_strfreev (argv_copy);
857 g_free (argv);
858 g_option_context_free (context);
859 }
860  
861 static void
862 callback_test_optional_3 (void)
863 {
864 GOptionContext *context;
865 gboolean retval;
866 GError *error = NULL;
867 gchar **argv_copy;
868 gchar **argv;
869 int argc;
870 GOptionEntry entries [] =
871 { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
872 callback_parse_optional, NULL, NULL },
873 { NULL } };
874  
875 context = g_option_context_new (NULL);
876 g_option_context_add_main_entries (context, entries, NULL);
877  
878 /* Now try parsing */
879 argv = split_string ("program -t foo.txt", &argc);
880 argv_copy = copy_stringv (argv, argc);
881  
882 retval = g_option_context_parse (context, &argc, &argv, &error);
883 g_assert_no_error (error);
884 g_assert (retval);
885  
886 g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
887  
888 g_assert (callback_test_optional_boolean);
889  
890 g_free (callback_test_optional_string);
891  
892 g_strfreev (argv_copy);
893 g_free (argv);
894 g_option_context_free (context);
895 }
896  
897  
898 static void
899 callback_test_optional_4 (void)
900 {
901 GOptionContext *context;
902 gboolean retval;
903 GError *error = NULL;
904 gchar **argv;
905 gchar **argv_copy;
906 int argc;
907 GOptionEntry entries [] =
908 { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
909 callback_parse_optional, NULL, NULL },
910 { NULL } };
911  
912 context = g_option_context_new (NULL);
913 g_option_context_add_main_entries (context, entries, NULL);
914  
915 /* Now try parsing */
916 argv = split_string ("program -t", &argc);
917 argv_copy = copy_stringv (argv, argc);
918  
919 retval = g_option_context_parse (context, &argc, &argv, &error);
920 g_assert_no_error (error);
921 g_assert (retval);
922  
923 g_assert (callback_test_optional_string == NULL);
924  
925 g_assert (callback_test_optional_boolean);
926  
927 g_free (callback_test_optional_string);
928  
929 g_strfreev (argv_copy);
930 g_free (argv);
931 g_option_context_free (context);
932 }
933  
934 static void
935 callback_test_optional_5 (void)
936 {
937 GOptionContext *context;
938 gboolean dummy;
939 gboolean retval;
940 GError *error = NULL;
941 gchar **argv;
942 gchar **argv_copy;
943 int argc;
944 GOptionEntry entries [] =
945 { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
946 { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
947 callback_parse_optional, NULL, NULL },
948 { NULL } };
949  
950 context = g_option_context_new (NULL);
951 g_option_context_add_main_entries (context, entries, NULL);
952  
953 /* Now try parsing */
954 argv = split_string ("program --test --dummy", &argc);
955 argv_copy = copy_stringv (argv, argc);
956  
957 retval = g_option_context_parse (context, &argc, &argv, &error);
958 g_assert_no_error (error);
959 g_assert (retval);
960  
961 g_assert (callback_test_optional_string == NULL);
962  
963 g_assert (callback_test_optional_boolean);
964  
965 g_free (callback_test_optional_string);
966  
967 g_strfreev (argv_copy);
968 g_free (argv);
969 g_option_context_free (context);
970 }
971  
972 static void
973 callback_test_optional_6 (void)
974 {
975 GOptionContext *context;
976 gboolean dummy;
977 gboolean retval;
978 GError *error = NULL;
979 gchar **argv;
980 gchar **argv_copy;
981 int argc;
982 GOptionEntry entries [] =
983 { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
984 { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
985 callback_parse_optional, NULL, NULL },
986 { NULL } };
987  
988 context = g_option_context_new (NULL);
989 g_option_context_add_main_entries (context, entries, NULL);
990  
991 /* Now try parsing */
992 argv = split_string ("program -t -d", &argc);
993 argv_copy = copy_stringv (argv, argc);
994  
995 retval = g_option_context_parse (context, &argc, &argv, &error);
996 g_assert_no_error (error);
997 g_assert (retval);
998  
999 g_assert (callback_test_optional_string == NULL);
1000  
1001 g_assert (callback_test_optional_boolean);
1002  
1003 g_free (callback_test_optional_string);
1004  
1005 g_strfreev (argv_copy);
1006 g_free (argv);
1007 g_option_context_free (context);
1008 }
1009  
1010 static void
1011 callback_test_optional_7 (void)
1012 {
1013 GOptionContext *context;
1014 gboolean dummy;
1015 gboolean retval;
1016 GError *error = NULL;
1017 gchar **argv;
1018 gchar **argv_copy;
1019 int argc;
1020 GOptionEntry entries [] =
1021 { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
1022 { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
1023 callback_parse_optional, NULL, NULL },
1024 { NULL } };
1025  
1026 context = g_option_context_new (NULL);
1027 g_option_context_add_main_entries (context, entries, NULL);
1028  
1029 /* Now try parsing */
1030 argv = split_string ("program -td", &argc);
1031 argv_copy = copy_stringv (argv, argc);
1032  
1033 retval = g_option_context_parse (context, &argc, &argv, &error);
1034 g_assert_no_error (error);
1035 g_assert (retval);
1036  
1037 g_assert (callback_test_optional_string == NULL);
1038  
1039 g_assert (callback_test_optional_boolean);
1040  
1041 g_free (callback_test_optional_string);
1042  
1043 g_strfreev (argv_copy);
1044 g_free (argv);
1045 g_option_context_free (context);
1046 }
1047  
1048 static void
1049 callback_test_optional_8 (void)
1050 {
1051 GOptionContext *context;
1052 gboolean dummy;
1053 gboolean retval;
1054 GError *error = NULL;
1055 gchar **argv;
1056 gchar **argv_copy;
1057 int argc;
1058 GOptionEntry entries [] =
1059 { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
1060 { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
1061 callback_parse_optional, NULL, NULL },
1062 { NULL } };
1063  
1064 context = g_option_context_new (NULL);
1065 g_option_context_add_main_entries (context, entries, NULL);
1066  
1067 /* Now try parsing */
1068 argv = split_string ("program -dt foo.txt", &argc);
1069 argv_copy = copy_stringv (argv, argc);
1070  
1071 retval = g_option_context_parse (context, &argc, &argv, &error);
1072 g_assert_no_error (error);
1073 g_assert (retval);
1074  
1075 g_assert (callback_test_optional_string);
1076  
1077 g_assert (callback_test_optional_boolean);
1078  
1079 g_free (callback_test_optional_string);
1080  
1081 g_strfreev (argv_copy);
1082 g_free (argv);
1083 g_option_context_free (context);
1084 }
1085  
1086 static GPtrArray *callback_remaining_args;
1087 static gboolean
1088 callback_remaining_test1_callback (const gchar *option_name, const gchar *value,
1089 gpointer data, GError **error)
1090 {
1091 g_ptr_array_add (callback_remaining_args, g_strdup (value));
1092 return TRUE;
1093 }
1094  
1095 static void
1096 callback_remaining_test1 (void)
1097 {
1098 GOptionContext *context;
1099 gboolean retval;
1100 GError *error = NULL;
1101 gchar **argv;
1102 gchar **argv_copy;
1103 int argc;
1104 GOptionEntry entries [] =
1105 { { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_CALLBACK, callback_remaining_test1_callback, NULL, NULL },
1106 { NULL } };
1107  
1108 callback_remaining_args = g_ptr_array_new ();
1109 context = g_option_context_new (NULL);
1110 g_option_context_add_main_entries (context, entries, NULL);
1111  
1112 /* Now try parsing */
1113 argv = split_string ("program foo.txt blah.txt", &argc);
1114 argv_copy = copy_stringv (argv, argc);
1115  
1116 retval = g_option_context_parse (context, &argc, &argv, &error);
1117 g_assert_no_error (error);
1118 g_assert (retval);
1119  
1120 g_assert (callback_remaining_args->len == 2);
1121 g_assert (strcmp (callback_remaining_args->pdata[0], "foo.txt") == 0);
1122 g_assert (strcmp (callback_remaining_args->pdata[1], "blah.txt") == 0);
1123  
1124 g_ptr_array_foreach (callback_remaining_args, (GFunc) g_free, NULL);
1125 g_ptr_array_free (callback_remaining_args, TRUE);
1126  
1127 g_strfreev (argv_copy);
1128 g_free (argv);
1129 g_option_context_free (context);
1130 }
1131  
1132 static gboolean
1133 callback_error (const gchar *option_name, const gchar *value,
1134 gpointer data, GError **error)
1135 {
1136 g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "42");
1137 return FALSE;
1138 }
1139  
1140 static void
1141 callback_returns_false (void)
1142 {
1143 GOptionContext *context;
1144 gboolean retval;
1145 GError *error = NULL;
1146 gchar **argv;
1147 gchar **argv_copy;
1148 int argc;
1149 GOptionEntry entries [] =
1150 { { "error", 0, 0, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1151 { "error-no-arg", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1152 { "error-optional-arg", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1153 { NULL } };
1154  
1155 context = g_option_context_new (NULL);
1156 g_option_context_add_main_entries (context, entries, NULL);
1157  
1158 /* Now try parsing */
1159 argv = split_string ("program --error value", &argc);
1160 argv_copy = copy_stringv (argv, argc);
1161  
1162 retval = g_option_context_parse (context, &argc, &argv, &error);
1163 g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1164 g_assert (retval == FALSE);
1165 check_identical_stringv (argv_copy, argv);
1166  
1167 g_option_context_free (context);
1168 g_clear_error (&error);
1169 g_strfreev (argv_copy);
1170 g_free (argv);
1171  
1172 /* And again, this time with a no-arg variant */
1173 context = g_option_context_new (NULL);
1174 g_option_context_add_main_entries (context, entries, NULL);
1175  
1176 argv = split_string ("program --error-no-arg", &argc);
1177 argv_copy = copy_stringv (argv, argc);
1178  
1179 retval = g_option_context_parse (context, &argc, &argv, &error);
1180 g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1181 g_assert (retval == FALSE);
1182 check_identical_stringv (argv_copy, argv);
1183  
1184 g_option_context_free (context);
1185 g_clear_error (&error);
1186 g_strfreev (argv_copy);
1187 g_free (argv);
1188  
1189 /* And again, this time with a optional arg variant, with argument */
1190 context = g_option_context_new (NULL);
1191 g_option_context_add_main_entries (context, entries, NULL);
1192  
1193 argv = split_string ("program --error-optional-arg value", &argc);
1194 argv_copy = copy_stringv (argv, argc);
1195  
1196 retval = g_option_context_parse (context, &argc, &argv, &error);
1197 g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1198 g_assert (retval == FALSE);
1199 check_identical_stringv (argv_copy, argv);
1200  
1201 g_option_context_free (context);
1202 g_clear_error (&error);
1203 g_strfreev (argv_copy);
1204 g_free (argv);
1205  
1206 /* And again, this time with a optional arg variant, without argument */
1207 context = g_option_context_new (NULL);
1208 g_option_context_add_main_entries (context, entries, NULL);
1209  
1210 argv = split_string ("program --error-optional-arg", &argc);
1211 argv_copy = copy_stringv (argv, argc);
1212  
1213 retval = g_option_context_parse (context, &argc, &argv, &error);
1214 g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1215 g_assert (retval == FALSE);
1216 check_identical_stringv (argv_copy, argv);
1217  
1218 g_option_context_free (context);
1219 g_clear_error (&error);
1220 g_strfreev (argv_copy);
1221 g_free (argv);
1222 }
1223  
1224  
1225 static void
1226 ignore_test1 (void)
1227 {
1228 GOptionContext *context;
1229 gboolean retval;
1230 GError *error = NULL;
1231 gchar **argv, **argv_copy;
1232 int argc;
1233 gchar *arg;
1234 GOptionEntry entries [] =
1235 { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1236 { NULL } };
1237  
1238 context = g_option_context_new (NULL);
1239 g_option_context_set_ignore_unknown_options (context, TRUE);
1240 g_option_context_add_main_entries (context, entries, NULL);
1241  
1242 /* Now try parsing */
1243 argv = split_string ("program --test --hello", &argc);
1244 argv_copy = copy_stringv (argv, argc);
1245  
1246 retval = g_option_context_parse (context, &argc, &argv, &error);
1247 g_assert_no_error (error);
1248 g_assert (retval);
1249  
1250 /* Check array */
1251 arg = join_stringv (argc, argv);
1252 g_assert (strcmp (arg, "program --hello") == 0);
1253  
1254 g_free (arg);
1255 g_strfreev (argv_copy);
1256 g_free (argv);
1257 g_option_context_free (context);
1258 }
1259  
1260 static void
1261 ignore_test2 (void)
1262 {
1263 GOptionContext *context;
1264 gboolean retval;
1265 GError *error = NULL;
1266 gchar **argv;
1267 gchar **argv_copy;
1268 int argc;
1269 gchar *arg;
1270 GOptionEntry entries [] =
1271 { { "test", 't', 0, G_OPTION_ARG_NONE, &ignore_test2_boolean, NULL, NULL },
1272 { NULL } };
1273  
1274 context = g_option_context_new (NULL);
1275 g_option_context_set_ignore_unknown_options (context, TRUE);
1276 g_option_context_add_main_entries (context, entries, NULL);
1277  
1278 /* Now try parsing */
1279 argv = split_string ("program -test", &argc);
1280 argv_copy = copy_stringv (argv, argc);
1281  
1282 retval = g_option_context_parse (context, &argc, &argv, &error);
1283 g_assert_no_error (error);
1284 g_assert (retval);
1285  
1286 /* Check array */
1287 arg = join_stringv (argc, argv);
1288 g_assert (strcmp (arg, "program -es") == 0);
1289  
1290 g_free (arg);
1291 g_strfreev (argv_copy);
1292 g_free (argv);
1293 g_option_context_free (context);
1294 }
1295  
1296 static void
1297 ignore_test3 (void)
1298 {
1299 GOptionContext *context;
1300 gboolean retval;
1301 GError *error = NULL;
1302 gchar **argv, **argv_copy;
1303 int argc;
1304 gchar *arg;
1305 GOptionEntry entries [] =
1306 { { "test", 0, 0, G_OPTION_ARG_STRING, &ignore_test3_string, NULL, NULL },
1307 { NULL } };
1308  
1309 context = g_option_context_new (NULL);
1310 g_option_context_set_ignore_unknown_options (context, TRUE);
1311 g_option_context_add_main_entries (context, entries, NULL);
1312  
1313 /* Now try parsing */
1314 argv = split_string ("program --test foo --hello", &argc);
1315 argv_copy = copy_stringv (argv, argc);
1316  
1317 retval = g_option_context_parse (context, &argc, &argv, &error);
1318 g_assert_no_error (error);
1319 g_assert (retval);
1320  
1321 /* Check array */
1322 arg = join_stringv (argc, argv);
1323 g_assert (strcmp (arg, "program --hello") == 0);
1324  
1325 g_assert (strcmp (ignore_test3_string, "foo") == 0);
1326 g_free (ignore_test3_string);
1327  
1328 g_free (arg);
1329 g_strfreev (argv_copy);
1330 g_free (argv);
1331 g_option_context_free (context);
1332 }
1333  
1334 void
1335 static array_test1 (void)
1336 {
1337 GOptionContext *context;
1338 gboolean retval;
1339 GError *error = NULL;
1340 gchar **argv;
1341 gchar **argv_copy;
1342 int argc;
1343 GOptionEntry entries [] =
1344 { { "test", 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1345 { NULL } };
1346  
1347 context = g_option_context_new (NULL);
1348 g_option_context_add_main_entries (context, entries, NULL);
1349  
1350 /* Now try parsing */
1351 argv = split_string ("program --test foo --test bar", &argc);
1352 argv_copy = copy_stringv (argv, argc);
1353  
1354 retval = g_option_context_parse (context, &argc, &argv, &error);
1355 g_assert_no_error (error);
1356 g_assert (retval);
1357  
1358 /* Check array */
1359 g_assert (strcmp (array_test1_array[0], "foo") == 0);
1360 g_assert (strcmp (array_test1_array[1], "bar") == 0);
1361 g_assert (array_test1_array[2] == NULL);
1362  
1363 g_strfreev (array_test1_array);
1364  
1365 g_strfreev (argv_copy);
1366 g_free (argv);
1367 g_option_context_free (context);
1368 }
1369  
1370 static void
1371 add_test1 (void)
1372 {
1373 GOptionContext *context;
1374  
1375 GOptionEntry entries1 [] =
1376 { { "test1", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
1377 { NULL } };
1378 GOptionEntry entries2 [] =
1379 { { "test2", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
1380 { NULL } };
1381  
1382 context = g_option_context_new (NULL);
1383 g_option_context_add_main_entries (context, entries1, NULL);
1384 g_option_context_add_main_entries (context, entries2, NULL);
1385  
1386 g_option_context_free (context);
1387 }
1388  
1389 static void
1390 empty_test2 (void)
1391 {
1392 GOptionContext *context;
1393  
1394 context = g_option_context_new (NULL);
1395 g_option_context_parse (context, NULL, NULL, NULL);
1396  
1397 g_option_context_free (context);
1398 }
1399  
1400 static void
1401 empty_test3 (void)
1402 {
1403 GOptionContext *context;
1404 gint argc;
1405 gchar **argv;
1406  
1407 argc = 0;
1408 argv = NULL;
1409  
1410 context = g_option_context_new (NULL);
1411 g_option_context_parse (context, &argc, &argv, NULL);
1412  
1413 g_option_context_free (context);
1414 }
1415  
1416 /* check that non-option arguments are left in argv by default */
1417 static void
1418 rest_test1 (void)
1419 {
1420 GOptionContext *context;
1421 gboolean retval;
1422 GError *error = NULL;
1423 gchar **argv;
1424 gchar **argv_copy;
1425 int argc;
1426 GOptionEntry entries [] = {
1427 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1428 { NULL }
1429 };
1430  
1431 context = g_option_context_new (NULL);
1432 g_option_context_add_main_entries (context, entries, NULL);
1433  
1434 /* Now try parsing */
1435 argv = split_string ("program foo --test bar", &argc);
1436 argv_copy = copy_stringv (argv, argc);
1437  
1438 retval = g_option_context_parse (context, &argc, &argv, &error);
1439 g_assert_no_error (error);
1440 g_assert (retval);
1441  
1442 /* Check array */
1443 g_assert (ignore_test1_boolean);
1444 g_assert (strcmp (argv[0], "program") == 0);
1445 g_assert (strcmp (argv[1], "foo") == 0);
1446 g_assert (strcmp (argv[2], "bar") == 0);
1447 g_assert (argv[3] == NULL);
1448  
1449 g_strfreev (argv_copy);
1450 g_free (argv);
1451 g_option_context_free (context);
1452 }
1453  
1454 /* check that -- works */
1455 static void
1456 rest_test2 (void)
1457 {
1458 GOptionContext *context;
1459 gboolean retval;
1460 GError *error = NULL;
1461 gchar **argv;
1462 gchar **argv_copy;
1463 int argc;
1464 GOptionEntry entries [] = {
1465 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1466 { NULL }
1467 };
1468  
1469 context = g_option_context_new (NULL);
1470 g_option_context_add_main_entries (context, entries, NULL);
1471  
1472 /* Now try parsing */
1473 argv = split_string ("program foo --test -- -bar", &argc);
1474 argv_copy = copy_stringv (argv, argc);
1475  
1476 retval = g_option_context_parse (context, &argc, &argv, &error);
1477 g_assert_no_error (error);
1478 g_assert (retval);
1479  
1480 /* Check array */
1481 g_assert (ignore_test1_boolean);
1482 g_assert (strcmp (argv[0], "program") == 0);
1483 g_assert (strcmp (argv[1], "foo") == 0);
1484 g_assert (strcmp (argv[2], "--") == 0);
1485 g_assert (strcmp (argv[3], "-bar") == 0);
1486 g_assert (argv[4] == NULL);
1487  
1488 g_strfreev (argv_copy);
1489 g_free (argv);
1490 g_option_context_free (context);
1491 }
1492  
1493 /* check that -- stripping works */
1494 static void
1495 rest_test2a (void)
1496 {
1497 GOptionContext *context;
1498 gboolean retval;
1499 GError *error = NULL;
1500 gchar **argv;
1501 gchar **argv_copy;
1502 int argc;
1503 GOptionEntry entries [] = {
1504 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1505 { NULL }
1506 };
1507  
1508 context = g_option_context_new (NULL);
1509 g_option_context_add_main_entries (context, entries, NULL);
1510  
1511 /* Now try parsing */
1512 argv = split_string ("program foo --test -- bar", &argc);
1513 argv_copy = copy_stringv (argv, argc);
1514  
1515 retval = g_option_context_parse (context, &argc, &argv, &error);
1516 g_assert_no_error (error);
1517 g_assert (retval);
1518  
1519 /* Check array */
1520 g_assert (ignore_test1_boolean);
1521 g_assert (strcmp (argv[0], "program") == 0);
1522 g_assert (strcmp (argv[1], "foo") == 0);
1523 g_assert (strcmp (argv[2], "bar") == 0);
1524 g_assert (argv[3] == NULL);
1525  
1526 g_strfreev (argv_copy);
1527 g_free (argv);
1528 g_option_context_free (context);
1529 }
1530  
1531 static void
1532 rest_test2b (void)
1533 {
1534 GOptionContext *context;
1535 gboolean retval;
1536 GError *error = NULL;
1537 gchar **argv;
1538 gchar **argv_copy;
1539 int argc;
1540 GOptionEntry entries [] = {
1541 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1542 { NULL }
1543 };
1544  
1545 context = g_option_context_new (NULL);
1546 g_option_context_set_ignore_unknown_options (context, TRUE);
1547 g_option_context_add_main_entries (context, entries, NULL);
1548  
1549 /* Now try parsing */
1550 argv = split_string ("program foo --test -bar --", &argc);
1551 argv_copy = copy_stringv (argv, argc);
1552  
1553 retval = g_option_context_parse (context, &argc, &argv, &error);
1554 g_assert_no_error (error);
1555 g_assert (retval);
1556  
1557 /* Check array */
1558 g_assert (ignore_test1_boolean);
1559 g_assert (strcmp (argv[0], "program") == 0);
1560 g_assert (strcmp (argv[1], "foo") == 0);
1561 g_assert (strcmp (argv[2], "-bar") == 0);
1562 g_assert (argv[3] == NULL);
1563  
1564 g_strfreev (argv_copy);
1565 g_free (argv);
1566 g_option_context_free (context);
1567 }
1568  
1569 static void
1570 rest_test2c (void)
1571 {
1572 GOptionContext *context;
1573 gboolean retval;
1574 GError *error = NULL;
1575 gchar **argv;
1576 gchar **argv_copy;
1577 int argc;
1578 GOptionEntry entries [] = {
1579 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1580 { NULL }
1581 };
1582  
1583 context = g_option_context_new (NULL);
1584 g_option_context_add_main_entries (context, entries, NULL);
1585  
1586 /* Now try parsing */
1587 argv = split_string ("program --test foo -- bar", &argc);
1588 argv_copy = copy_stringv (argv, argc);
1589  
1590 retval = g_option_context_parse (context, &argc, &argv, &error);
1591 g_assert_no_error (error);
1592 g_assert (retval);
1593  
1594 /* Check array */
1595 g_assert (ignore_test1_boolean);
1596 g_assert (strcmp (argv[0], "program") == 0);
1597 g_assert (strcmp (argv[1], "foo") == 0);
1598 g_assert (strcmp (argv[2], "bar") == 0);
1599 g_assert (argv[3] == NULL);
1600  
1601 g_strfreev (argv_copy);
1602 g_free (argv);
1603 g_option_context_free (context);
1604 }
1605  
1606 static void
1607 rest_test2d (void)
1608 {
1609 GOptionContext *context;
1610 gboolean retval;
1611 GError *error = NULL;
1612 gchar **argv;
1613 gchar **argv_copy;
1614 int argc;
1615 GOptionEntry entries [] = {
1616 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1617 { NULL }
1618 };
1619  
1620 context = g_option_context_new (NULL);
1621 g_option_context_add_main_entries (context, entries, NULL);
1622  
1623 /* Now try parsing */
1624 argv = split_string ("program --test -- -bar", &argc);
1625 argv_copy = copy_stringv (argv, argc);
1626  
1627 retval = g_option_context_parse (context, &argc, &argv, &error);
1628 g_assert_no_error (error);
1629 g_assert (retval);
1630  
1631 /* Check array */
1632 g_assert (ignore_test1_boolean);
1633 g_assert (strcmp (argv[0], "program") == 0);
1634 g_assert (strcmp (argv[1], "--") == 0);
1635 g_assert (strcmp (argv[2], "-bar") == 0);
1636 g_assert (argv[3] == NULL);
1637  
1638 g_strfreev (argv_copy);
1639 g_free (argv);
1640 g_option_context_free (context);
1641 }
1642  
1643  
1644 /* check that G_OPTION_REMAINING collects non-option arguments */
1645 static void
1646 rest_test3 (void)
1647 {
1648 GOptionContext *context;
1649 gboolean retval;
1650 GError *error = NULL;
1651 gchar **argv;
1652 gchar **argv_copy;
1653 int argc;
1654 GOptionEntry entries [] = {
1655 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1656 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1657 { NULL }
1658 };
1659  
1660 context = g_option_context_new (NULL);
1661 g_option_context_add_main_entries (context, entries, NULL);
1662  
1663 /* Now try parsing */
1664 argv = split_string ("program foo --test bar", &argc);
1665 argv_copy = copy_stringv (argv, argc);
1666  
1667 retval = g_option_context_parse (context, &argc, &argv, &error);
1668 g_assert_no_error (error);
1669 g_assert (retval);
1670  
1671 /* Check array */
1672 g_assert (ignore_test1_boolean);
1673 g_assert (strcmp (array_test1_array[0], "foo") == 0);
1674 g_assert (strcmp (array_test1_array[1], "bar") == 0);
1675 g_assert (array_test1_array[2] == NULL);
1676  
1677 g_strfreev (array_test1_array);
1678  
1679 g_strfreev (argv_copy);
1680 g_free (argv);
1681 g_option_context_free (context);
1682 }
1683  
1684  
1685 /* check that G_OPTION_REMAINING and -- work together */
1686 static void
1687 rest_test4 (void)
1688 {
1689 GOptionContext *context;
1690 gboolean retval;
1691 GError *error = NULL;
1692 gchar **argv;
1693 gchar **argv_copy;
1694 int argc;
1695 GOptionEntry entries [] = {
1696 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1697 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1698 { NULL }
1699 };
1700  
1701 context = g_option_context_new (NULL);
1702 g_option_context_add_main_entries (context, entries, NULL);
1703  
1704 /* Now try parsing */
1705 argv = split_string ("program foo --test -- -bar", &argc);
1706 argv_copy = copy_stringv (argv, argc);
1707  
1708 retval = g_option_context_parse (context, &argc, &argv, &error);
1709 g_assert_no_error (error);
1710 g_assert (retval);
1711  
1712 /* Check array */
1713 g_assert (ignore_test1_boolean);
1714 g_assert (strcmp (array_test1_array[0], "foo") == 0);
1715 g_assert (strcmp (array_test1_array[1], "-bar") == 0);
1716 g_assert (array_test1_array[2] == NULL);
1717  
1718 g_strfreev (array_test1_array);
1719  
1720 g_strfreev (argv_copy);
1721 g_free (argv);
1722 g_option_context_free (context);
1723 }
1724  
1725 /* test that G_OPTION_REMAINING works with G_OPTION_ARG_FILENAME_ARRAY */
1726 static void
1727 rest_test5 (void)
1728 {
1729 GOptionContext *context;
1730 gboolean retval;
1731 GError *error = NULL;
1732 gchar **argv;
1733 gchar **argv_copy;
1734 int argc;
1735 GOptionEntry entries [] = {
1736 { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1737 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &array_test1_array, NULL, NULL },
1738 { NULL }
1739 };
1740  
1741 context = g_option_context_new (NULL);
1742 g_option_context_add_main_entries (context, entries, NULL);
1743  
1744 /* Now try parsing */
1745 argv = split_string ("program foo --test bar", &argc);
1746 argv_copy = copy_stringv (argv, argc);
1747  
1748 retval = g_option_context_parse (context, &argc, &argv, &error);
1749 g_assert_no_error (error);
1750 g_assert (retval);
1751  
1752 /* Check array */
1753 g_assert (ignore_test1_boolean);
1754 g_assert (strcmp (array_test1_array[0], "foo") == 0);
1755 g_assert (strcmp (array_test1_array[1], "bar") == 0);
1756 g_assert (array_test1_array[2] == NULL);
1757  
1758 g_strfreev (array_test1_array);
1759  
1760 g_strfreev (argv_copy);
1761 g_free (argv);
1762 g_option_context_free (context);
1763 }
1764  
1765 static void
1766 unknown_short_test (void)
1767 {
1768 GOptionContext *context;
1769 gboolean retval;
1770 GError *error = NULL;
1771 gchar **argv;
1772 gchar **argv_copy;
1773 int argc;
1774 GOptionEntry entries [] = { { NULL } };
1775  
1776 g_test_bug ("166609");
1777  
1778 context = g_option_context_new (NULL);
1779 g_option_context_add_main_entries (context, entries, NULL);
1780  
1781 /* Now try parsing */
1782 argv = split_string ("program -0", &argc);
1783 argv_copy = copy_stringv (argv, argc);
1784  
1785 retval = g_option_context_parse (context, &argc, &argv, &error);
1786 g_assert (!retval);
1787 g_assert (error != NULL);
1788 g_clear_error (&error);
1789  
1790 g_strfreev (argv_copy);
1791 g_free (argv);
1792 g_option_context_free (context);
1793 }
1794  
1795 /* test that lone dashes are treated as non-options */
1796 static void
1797 lonely_dash_test (void)
1798 {
1799 GOptionContext *context;
1800 gboolean retval;
1801 GError *error = NULL;
1802 gchar **argv;
1803 gchar **argv_copy;
1804 int argc;
1805  
1806 g_test_bug ("168008");
1807  
1808 context = g_option_context_new (NULL);
1809  
1810 /* Now try parsing */
1811 argv = split_string ("program -", &argc);
1812 argv_copy = copy_stringv (argv, argc);
1813  
1814 retval = g_option_context_parse (context, &argc, &argv, &error);
1815 g_assert_no_error (error);
1816 g_assert (retval);
1817  
1818 g_assert (argv[1] && strcmp (argv[1], "-") == 0);
1819  
1820 g_strfreev (argv_copy);
1821 g_free (argv);
1822 g_option_context_free (context);
1823 }
1824  
1825 static void
1826 missing_arg_test (void)
1827 {
1828 GOptionContext *context;
1829 gboolean retval;
1830 GError *error = NULL;
1831 gchar **argv;
1832 gchar **argv_copy;
1833 int argc;
1834 gchar *arg = NULL;
1835 GOptionEntry entries [] =
1836 { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1837 { NULL } };
1838  
1839 g_test_bug ("305576");
1840  
1841 context = g_option_context_new (NULL);
1842 g_option_context_add_main_entries (context, entries, NULL);
1843  
1844 /* Now try parsing */
1845 argv = split_string ("program --test", &argc);
1846 argv_copy = copy_stringv (argv, argc);
1847  
1848 retval = g_option_context_parse (context, &argc, &argv, &error);
1849 g_assert (retval == FALSE);
1850 g_assert (error != NULL);
1851 /* An error occurred, so argv has not been changed */
1852 check_identical_stringv (argv_copy, argv);
1853 g_clear_error (&error);
1854  
1855 g_strfreev (argv_copy);
1856 g_free (argv);
1857  
1858 /* Try parsing again */
1859 argv = split_string ("program -t", &argc);
1860 argv_copy = copy_stringv (argv, argc);
1861  
1862 retval = g_option_context_parse (context, &argc, &argv, &error);
1863 g_assert (retval == FALSE);
1864 g_assert (error != NULL);
1865 /* An error occurred, so argv has not been changed */
1866 check_identical_stringv (argv_copy, argv);
1867 g_clear_error (&error);
1868  
1869 g_strfreev (argv_copy);
1870 g_free (argv);
1871 g_option_context_free (context);
1872 }
1873  
1874 static gchar *test_arg;
1875  
1876 static gboolean cb (const gchar *option_name,
1877 const gchar *value,
1878 gpointer data,
1879 GError **error)
1880 {
1881 test_arg = g_strdup (value);
1882 return TRUE;
1883 }
1884  
1885 static void
1886 dash_arg_test (void)
1887 {
1888 GOptionContext *context;
1889 gboolean retval;
1890 GError *error = NULL;
1891 gchar **argv;
1892 gchar **argv_copy;
1893 int argc;
1894 gboolean argb = FALSE;
1895 GOptionEntry entries [] =
1896 { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, cb, NULL, NULL },
1897 { "three", '3', 0, G_OPTION_ARG_NONE, &argb, NULL, NULL },
1898 { NULL } };
1899  
1900 g_test_bug ("577638");
1901  
1902 context = g_option_context_new (NULL);
1903 g_option_context_add_main_entries (context, entries, NULL);
1904  
1905 /* Now try parsing */
1906 argv = split_string ("program --test=-3", &argc);
1907 argv_copy = copy_stringv (argv, argc);
1908  
1909 test_arg = NULL;
1910 error = NULL;
1911 retval = g_option_context_parse (context, &argc, &argv, &error);
1912 g_assert (retval);
1913 g_assert_no_error (error);
1914 g_assert_cmpstr (test_arg, ==, "-3");
1915  
1916 g_strfreev (argv_copy);
1917 g_free (argv);
1918 g_free (test_arg);
1919 test_arg = NULL;
1920  
1921 /* Try parsing again */
1922 argv = split_string ("program --test -3", &argc);
1923 argv_copy = copy_stringv (argv, argc);
1924  
1925 error = NULL;
1926 retval = g_option_context_parse (context, &argc, &argv, &error);
1927 g_assert_no_error (error);
1928 g_assert (retval);
1929 g_assert_cmpstr (test_arg, ==, NULL);
1930  
1931 g_option_context_free (context);
1932 g_strfreev (argv_copy);
1933 g_free (argv);
1934 }
1935  
1936 static void
1937 test_basic (void)
1938 {
1939 GOptionContext *context;
1940 gchar *arg = NULL;
1941 GOptionEntry entries [] =
1942 { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1943 { NULL } };
1944  
1945 context = g_option_context_new (NULL);
1946 g_option_context_add_main_entries (context, entries, NULL);
1947  
1948 g_assert (g_option_context_get_help_enabled (context));
1949 g_assert (!g_option_context_get_ignore_unknown_options (context));
1950 g_assert_cmpstr (g_option_context_get_summary (context), ==, NULL);
1951 g_assert_cmpstr (g_option_context_get_description (context), ==, NULL);
1952  
1953 g_option_context_set_help_enabled (context, FALSE);
1954 g_option_context_set_ignore_unknown_options (context, TRUE);
1955 g_option_context_set_summary (context, "summary");
1956 g_option_context_set_description(context, "description");
1957  
1958 g_assert (!g_option_context_get_help_enabled (context));
1959 g_assert (g_option_context_get_ignore_unknown_options (context));
1960 g_assert_cmpstr (g_option_context_get_summary (context), ==, "summary");
1961 g_assert_cmpstr (g_option_context_get_description (context), ==, "description");
1962  
1963 g_option_context_free (context);
1964 }
1965  
1966 typedef struct {
1967 gboolean parameter_seen;
1968 gboolean summary_seen;
1969 gboolean description_seen;
1970 gboolean destroyed;
1971 } TranslateData;
1972  
1973 static const gchar *
1974 translate_func (const gchar *str,
1975 gpointer data)
1976 {
1977 TranslateData *d = data;
1978  
1979 if (strcmp (str, "parameter") == 0)
1980 d->parameter_seen = TRUE;
1981 else if (strcmp (str, "summary") == 0)
1982 d->summary_seen = TRUE;
1983 else if (strcmp (str, "description") == 0)
1984 d->description_seen = TRUE;
1985  
1986 return str;
1987 }
1988  
1989 static void
1990 destroy_notify (gpointer data)
1991 {
1992 TranslateData *d = data;
1993  
1994 d->destroyed = TRUE;
1995 }
1996  
1997 static void
1998 test_translate (void)
1999 {
2000 GOptionContext *context;
2001 gchar *arg = NULL;
2002 GOptionEntry entries [] =
2003 { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
2004 { NULL } };
2005 TranslateData data = { 0, };
2006 gchar *str;
2007  
2008 context = g_option_context_new ("parameter");
2009 g_option_context_add_main_entries (context, entries, NULL);
2010 g_option_context_set_summary (context, "summary");
2011 g_option_context_set_description (context, "description");
2012  
2013 g_option_context_set_translate_func (context, translate_func, &data, destroy_notify);
2014  
2015 str = g_option_context_get_help (context, FALSE, NULL);
2016 g_free (str);
2017 g_option_context_free (context);
2018  
2019 g_assert (data.parameter_seen);
2020 g_assert (data.summary_seen);
2021 g_assert (data.description_seen);
2022 g_assert (data.destroyed);
2023 }
2024  
2025 static void
2026 test_help (void)
2027 {
2028 GOptionContext *context;
2029 GOptionGroup *group;
2030 gchar *str;
2031 gchar *arg = NULL;
2032 gchar **sarr = NULL;
2033 GOptionEntry entries[] = {
2034 { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Test tests", "Argument to use in test" },
2035 { "test2", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, NULL, "Tests also", NULL },
2036 { "frob", 0, 0, G_OPTION_ARG_NONE, NULL, "Main frob", NULL },
2037 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" },
2038 { NULL }
2039 };
2040 GOptionEntry group_entries[] = {
2041 { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Group test", "Group test arg" },
2042 { "frob", 0, G_OPTION_FLAG_NOALIAS, G_OPTION_ARG_NONE, NULL, "Group frob", NULL },
2043 { NULL }
2044 };
2045  
2046 context = g_option_context_new ("blabla");
2047 g_option_context_add_main_entries (context, entries, NULL);
2048 g_option_context_set_summary (context, "Summary");
2049 g_option_context_set_description (context, "Description");
2050  
2051 group = g_option_group_new ("group1", "Group1-description", "Group1-help", NULL, NULL);
2052 g_option_group_add_entries (group, group_entries);
2053  
2054 g_option_context_add_group (context, group);
2055  
2056 str = g_option_context_get_help (context, FALSE, NULL);
2057 g_assert (strstr (str, "blabla") != NULL);
2058 g_assert (strstr (str, "Test tests") != NULL);
2059 g_assert (strstr (str, "Argument to use in test") != NULL);
2060 g_assert (strstr (str, "Tests also") == NULL);
2061 g_assert (strstr (str, "REST") != NULL);
2062 g_assert (strstr (str, "Summary") != NULL);
2063 g_assert (strstr (str, "Description") != NULL);
2064 g_assert (strstr (str, "--help") != NULL);
2065 g_assert (strstr (str, "--help-all") != NULL);
2066 g_assert (strstr (str, "--help-group1") != NULL);
2067 g_assert (strstr (str, "Group1-description") != NULL);
2068 g_assert (strstr (str, "Group1-help") != NULL);
2069 g_assert (strstr (str, "Group test arg") != NULL);
2070 g_assert (strstr (str, "Group frob") != NULL);
2071 g_assert (strstr (str, "Main frob") != NULL);
2072 g_assert (strstr (str, "--frob") != NULL);
2073 g_assert (strstr (str, "--group1-test") != NULL);
2074 g_assert (strstr (str, "--group1-frob") == NULL);
2075 g_free (str);
2076  
2077 g_option_context_free (context);
2078 }
2079  
2080 static void
2081 test_help_no_options (void)
2082 {
2083 GOptionContext *context;
2084 gchar **sarr = NULL;
2085 GOptionEntry entries[] = {
2086 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" },
2087 { NULL }
2088 };
2089 gchar *str;
2090  
2091 context = g_option_context_new ("blabla");
2092 g_option_context_add_main_entries (context, entries, NULL);
2093  
2094 str = g_option_context_get_help (context, FALSE, NULL);
2095 g_assert (strstr (str, "blabla") != NULL);
2096 g_assert (strstr (str, "REST") != NULL);
2097 g_assert (strstr (str, "Help Options") != NULL);
2098 g_assert (strstr (str, "Application Options") == NULL);
2099  
2100 g_free (str);
2101 g_option_context_free (context);
2102 }
2103  
2104 static void
2105 test_help_no_help_options (void)
2106 {
2107 GOptionContext *context;
2108 GOptionGroup *group;
2109 gchar *str;
2110 gchar *arg = NULL;
2111 gchar **sarr = NULL;
2112 GOptionEntry entries[] = {
2113 { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Test tests", "Argument to use in test" },
2114 { "test2", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, NULL, "Tests also", NULL },
2115 { "frob", 0, 0, G_OPTION_ARG_NONE, NULL, "Main frob", NULL },
2116 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" },
2117 { NULL }
2118 };
2119 GOptionEntry group_entries[] = {
2120 { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Group test", "Group test arg" },
2121 { "frob", 0, G_OPTION_FLAG_NOALIAS, G_OPTION_ARG_NONE, NULL, "Group frob", NULL },
2122 { NULL }
2123 };
2124  
2125 g_test_bug ("697652");
2126  
2127 context = g_option_context_new ("blabla");
2128 g_option_context_add_main_entries (context, entries, NULL);
2129 g_option_context_set_summary (context, "Summary");
2130 g_option_context_set_description (context, "Description");
2131 g_option_context_set_help_enabled (context, FALSE);
2132  
2133 group = g_option_group_new ("group1", "Group1-description", "Group1-help", NULL, NULL);
2134 g_option_group_add_entries (group, group_entries);
2135  
2136 g_option_context_add_group (context, group);
2137  
2138 str = g_option_context_get_help (context, FALSE, NULL);
2139 g_assert (strstr (str, "blabla") != NULL);
2140 g_assert (strstr (str, "Test tests") != NULL);
2141 g_assert (strstr (str, "Argument to use in test") != NULL);
2142 g_assert (strstr (str, "Tests also") == NULL);
2143 g_assert (strstr (str, "REST") != NULL);
2144 g_assert (strstr (str, "Summary") != NULL);
2145 g_assert (strstr (str, "Description") != NULL);
2146 g_assert (strstr (str, "Help Options") == NULL);
2147 g_assert (strstr (str, "--help") == NULL);
2148 g_assert (strstr (str, "--help-all") == NULL);
2149 g_assert (strstr (str, "--help-group1") == NULL);
2150 g_assert (strstr (str, "Group1-description") != NULL);
2151 g_assert (strstr (str, "Group1-help") == NULL);
2152 g_assert (strstr (str, "Group test arg") != NULL);
2153 g_assert (strstr (str, "Group frob") != NULL);
2154 g_assert (strstr (str, "Main frob") != NULL);
2155 g_assert (strstr (str, "--frob") != NULL);
2156 g_assert (strstr (str, "--group1-test") != NULL);
2157 g_assert (strstr (str, "--group1-frob") == NULL);
2158 g_free (str);
2159  
2160 g_option_context_free (context);
2161 }
2162  
2163 static void
2164 set_bool (gpointer data)
2165 {
2166 gboolean *b = data;
2167  
2168 *b = TRUE;
2169 }
2170  
2171 static void
2172 test_main_group (void)
2173 {
2174 GOptionContext *context;
2175 GOptionGroup *group;
2176 gboolean b = FALSE;
2177  
2178 context = g_option_context_new (NULL);
2179 g_assert (g_option_context_get_main_group (context) == NULL);
2180 group = g_option_group_new ("name", "description", "hlep", &b, set_bool);
2181 g_option_context_add_group (context, group);
2182 group = g_option_group_new ("name2", "description", "hlep", NULL, NULL);
2183 g_option_context_add_group (context, group);
2184 g_assert (g_option_context_get_main_group (context) == NULL);
2185 group = g_option_group_new ("name", "description", "hlep", NULL, NULL);
2186 g_option_context_set_main_group (context, group);
2187 g_assert (g_option_context_get_main_group (context) == group);
2188  
2189 g_option_context_free (context);
2190  
2191 g_assert (b);
2192 }
2193  
2194 static gboolean error_func_called = FALSE;
2195  
2196 static void
2197 error_func (GOptionContext *context,
2198 GOptionGroup *group,
2199 gpointer data,
2200 GError **error)
2201 {
2202 g_assert_cmpint (GPOINTER_TO_INT(data), ==, 1234);
2203 error_func_called = TRUE;
2204 }
2205  
2206 static void
2207 test_error_hook (void)
2208 {
2209 GOptionContext *context;
2210 gchar *arg = NULL;
2211 GOptionEntry entries [] =
2212 { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
2213 { NULL } };
2214 GOptionGroup *group;
2215 gchar **argv;
2216 gchar **argv_copy;
2217 gint argc;
2218 gboolean retval;
2219 GError *error = NULL;
2220  
2221 context = g_option_context_new (NULL);
2222 group = g_option_group_new ("name", "description", "hlep", GINT_TO_POINTER(1234), NULL);
2223 g_option_group_add_entries (group, entries);
2224 g_option_context_set_main_group (context, group);
2225 g_option_group_set_error_hook (g_option_context_get_main_group (context),
2226 error_func);
2227  
2228 argv = split_string ("program --test", &argc);
2229 argv_copy = copy_stringv (argv, argc);
2230  
2231 retval = g_option_context_parse (context, &argc, &argv, &error);
2232 g_assert (retval == FALSE);
2233 g_assert (error != NULL);
2234 /* An error occurred, so argv has not been changed */
2235 check_identical_stringv (argv_copy, argv);
2236 g_clear_error (&error);
2237  
2238 g_assert (error_func_called);
2239  
2240 g_strfreev (argv_copy);
2241 g_free (argv);
2242 g_option_context_free (context);
2243 }
2244  
2245 static void
2246 test_group_parse (void)
2247 {
2248 GOptionContext *context;
2249 GOptionGroup *group;
2250 gchar *arg1 = NULL;
2251 gchar *arg2 = NULL;
2252 gchar *arg3 = NULL;
2253 gchar *arg4 = NULL;
2254 gchar *arg5 = NULL;
2255 GOptionEntry entries[] = {
2256 { "test", 't', 0, G_OPTION_ARG_STRING, &arg1, NULL, NULL },
2257 { "faz", 'f', 0, G_OPTION_ARG_STRING, &arg2, NULL, NULL },
2258 { NULL }
2259 };
2260 GOptionEntry group_entries[] = {
2261 { "test", 0, 0, G_OPTION_ARG_STRING, &arg3, NULL, NULL },
2262 { "frob", 'f', 0, G_OPTION_ARG_STRING, &arg4, NULL, NULL },
2263 { "faz", 'z', 0, G_OPTION_ARG_STRING, &arg5, NULL, NULL },
2264 { NULL }
2265 };
2266 gchar **argv, **orig_argv;
2267 gint argc;
2268 GError *error = NULL;
2269 gboolean retval;
2270  
2271 context = g_option_context_new (NULL);
2272 g_option_context_add_main_entries (context, entries, NULL);
2273 group = g_option_group_new ("group", "A group", "help for group", NULL, NULL);
2274 g_option_group_add_entries (group, group_entries);
2275 g_option_context_add_group (context, group);
2276  
2277 argv = split_string ("program --test arg1 -f arg2 --group-test arg3 --frob arg4 -z arg5", &argc);
2278 orig_argv = g_memdup (argv, (argc + 1) * sizeof (char *));
2279  
2280 retval = g_option_context_parse (context, &argc, &argv, &error);
2281  
2282 g_assert_no_error (error);
2283 g_assert (retval);
2284 g_assert_cmpstr (arg1, ==, "arg1");
2285 g_assert_cmpstr (arg2, ==, "arg2");
2286 g_assert_cmpstr (arg3, ==, "arg3");
2287 g_assert_cmpstr (arg4, ==, "arg4");
2288 g_assert_cmpstr (arg5, ==, "arg5");
2289  
2290 g_free (arg1);
2291 g_free (arg2);
2292 g_free (arg3);
2293 g_free (arg4);
2294 g_free (arg5);
2295  
2296 g_free (argv);
2297 g_strfreev (orig_argv);
2298 g_option_context_free (context);
2299 }
2300  
2301 static gint
2302 option_context_parse_command_line (GOptionContext *context,
2303 const gchar *command_line)
2304 {
2305 gchar **argv;
2306 guint argv_len, argv_new_len;
2307 gboolean success;
2308  
2309 argv = split_string (command_line, NULL);
2310 argv_len = g_strv_length (argv);
2311  
2312 success = g_option_context_parse_strv (context, &argv, NULL);
2313 argv_new_len = g_strv_length (argv);
2314  
2315 g_strfreev (argv);
2316 return success ? argv_len - argv_new_len : -1;
2317 }
2318  
2319 static void
2320 test_strict_posix (void)
2321 {
2322 GOptionContext *context;
2323 gboolean foo;
2324 gboolean bar;
2325 GOptionEntry entries[] = {
2326 { "foo", 'f', 0, G_OPTION_ARG_NONE, &foo, NULL, NULL },
2327 { "bar", 'b', 0, G_OPTION_ARG_NONE, &bar, NULL, NULL },
2328 { NULL }
2329 };
2330 gint n_parsed;
2331  
2332 context = g_option_context_new (NULL);
2333 g_option_context_add_main_entries (context, entries, NULL);
2334  
2335 foo = bar = FALSE;
2336 g_option_context_set_strict_posix (context, FALSE);
2337 n_parsed = option_context_parse_command_line (context, "program --foo command --bar");
2338 g_assert_cmpint (n_parsed, ==, 2);
2339 g_assert (foo == TRUE);
2340 g_assert (bar == TRUE);
2341  
2342 foo = bar = FALSE;
2343 g_option_context_set_strict_posix (context, TRUE);
2344 n_parsed = option_context_parse_command_line (context, "program --foo command --bar");
2345 g_assert_cmpint (n_parsed, ==, 1);
2346 g_assert (foo == TRUE);
2347 g_assert (bar == FALSE);
2348  
2349 foo = bar = FALSE;
2350 g_option_context_set_strict_posix (context, TRUE);
2351 n_parsed = option_context_parse_command_line (context, "program --foo --bar command");
2352 g_assert_cmpint (n_parsed, ==, 2);
2353 g_assert (foo == TRUE);
2354 g_assert (bar == TRUE);
2355  
2356 foo = bar = FALSE;
2357 g_option_context_set_strict_posix (context, TRUE);
2358 n_parsed = option_context_parse_command_line (context, "program command --foo --bar");
2359 g_assert_cmpint (n_parsed, ==, 0);
2360 g_assert (foo == FALSE);
2361 g_assert (bar == FALSE);
2362  
2363 g_option_context_free (context);
2364 }
2365  
2366 static void
2367 flag_reverse_string (void)
2368 {
2369 GOptionContext *context;
2370 gchar *arg = NULL;
2371 GOptionEntry entries [] =
2372 { { "test", 't', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_STRING, &arg, NULL, NULL },
2373 { NULL } };
2374 gchar **argv;
2375 gint argc;
2376 gboolean retval;
2377 GError *error = NULL;
2378  
2379 if (!g_test_undefined ())
2380 return;
2381  
2382 context = g_option_context_new (NULL);
2383  
2384 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
2385 "*ignoring reverse flag*");
2386 g_option_context_add_main_entries (context, entries, NULL);
2387 g_test_assert_expected_messages ();
2388  
2389 argv = split_string ("program --test bla", &argc);
2390  
2391 retval = g_option_context_parse_strv (context, &argv, &error);
2392 g_assert (retval == TRUE);
2393 g_assert_no_error (error);
2394 g_strfreev (argv);
2395 g_option_context_free (context);
2396 g_free (arg);
2397 }
2398  
2399 static void
2400 flag_optional_int (void)
2401 {
2402 GOptionContext *context;
2403 gint arg = 0;
2404 GOptionEntry entries [] =
2405 { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &arg, NULL, NULL },
2406 { NULL } };
2407 gchar **argv;
2408 gint argc;
2409 gboolean retval;
2410 GError *error = NULL;
2411  
2412 if (!g_test_undefined ())
2413 return;
2414  
2415 context = g_option_context_new (NULL);
2416  
2417 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
2418 "*ignoring no-arg, optional-arg or filename flags*");
2419 g_option_context_add_main_entries (context, entries, NULL);
2420 g_test_assert_expected_messages ();
2421  
2422 argv = split_string ("program --test 5", &argc);
2423  
2424 retval = g_option_context_parse_strv (context, &argv, &error);
2425 g_assert (retval == TRUE);
2426 g_assert_no_error (error);
2427 g_strfreev (argv);
2428 g_option_context_free (context);
2429 }
2430  
2431 static void
2432 short_remaining (void)
2433 {
2434 gboolean ignore = FALSE;
2435 gboolean remaining = FALSE;
2436 gint number = 0;
2437 gchar* text = NULL;
2438 gchar** files = NULL;
2439 GError* error = NULL;
2440 GOptionEntry entries[] =
2441 {
2442 { "ignore", 'i', 0, G_OPTION_ARG_NONE, &ignore, NULL, NULL },
2443 { "remaining", 'r', 0, G_OPTION_ARG_NONE, &remaining, NULL, NULL },
2444 { "number", 'n', 0, G_OPTION_ARG_INT, &number, NULL, NULL },
2445 { "text", 't', 0, G_OPTION_ARG_STRING, &text, NULL, NULL },
2446 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &files, NULL, NULL },
2447 { NULL }
2448 };
2449 GOptionContext* context;
2450 gchar **argv, **argv_copy;
2451 gint argc;
2452  
2453 g_test_bug ("729563");
2454  
2455 argv = split_string ("program -ri -n 4 -t hello file1 file2", &argc);
2456 argv_copy = copy_stringv (argv, argc);
2457  
2458 context = g_option_context_new (NULL);
2459  
2460 g_option_context_add_main_entries (context, entries, NULL);
2461 g_option_context_set_ignore_unknown_options (context, TRUE);
2462  
2463 g_option_context_parse (context, &argc, &argv, &error);
2464 g_assert_no_error (error);
2465  
2466 g_assert (ignore);
2467 g_assert (remaining);
2468 g_assert_cmpint (number, ==, 4);
2469 g_assert_cmpstr (text, ==, "hello");
2470 g_assert_cmpstr (files[0], ==, "file1");
2471 g_assert_cmpstr (files[1], ==, "file2");
2472 g_assert (files[2] == NULL);
2473  
2474 g_free (text);
2475 g_strfreev (files);
2476 g_strfreev (argv_copy);
2477 g_free (argv);
2478 g_option_context_free (context);
2479 }
2480  
2481 int
2482 main (int argc,
2483 char *argv[])
2484 {
2485 int i;
2486 gchar *test_name;
2487  
2488 g_setenv ("LC_ALL", "C", TRUE);
2489 g_test_init (&argc, &argv, NULL);
2490  
2491 g_test_bug_base ("http://bugzilla.gnome.org/");
2492  
2493 g_test_add_func ("/option/help/options", test_help);
2494 g_test_add_func ("/option/help/no-options", test_help_no_options);
2495 g_test_add_func ("/option/help/no-help-options", test_help_no_help_options);
2496  
2497 g_test_add_func ("/option/basic", test_basic);
2498 g_test_add_func ("/option/translate", test_translate);
2499  
2500 g_test_add_func ("/option/group/captions", test_group_captions);
2501 for (i = 0; i < 4; i++)
2502 {
2503 test_name = g_strdup_printf ("/option/group/captions/subprocess/help-%d", i);
2504 g_test_add_data_func (test_name, GINT_TO_POINTER (i),
2505 test_group_captions_help);
2506 g_free (test_name);
2507 test_name = g_strdup_printf ("/option/group/captions/subprocess/help-all-%d", i);
2508 g_test_add_data_func (test_name, GINT_TO_POINTER (i),
2509 test_group_captions_help_all);
2510 g_free (test_name);
2511 test_name = g_strdup_printf ("/option/group/captions/subprocess/help-test-%d", i);
2512 g_test_add_data_func (test_name, GINT_TO_POINTER (i),
2513 test_group_captions_help_test);
2514  
2515 g_free (test_name);
2516 }
2517  
2518 g_test_add_func ("/option/group/main", test_main_group);
2519 g_test_add_func ("/option/group/error-hook", test_error_hook);
2520 g_test_add_func ("/option/group/parse", test_group_parse);
2521 g_test_add_func ("/option/strict-posix", test_strict_posix);
2522  
2523 /* Test that restoration on failure works */
2524 g_test_add_func ("/option/restoration/int", error_test1);
2525 g_test_add_func ("/option/restoration/string", error_test2);
2526 g_test_add_func ("/option/restoration/boolean", error_test3);
2527  
2528 /* Test that special argument parsing works */
2529 g_test_add_func ("/option/arg/repetition/int", arg_test1);
2530 g_test_add_func ("/option/arg/repetition/string", arg_test2);
2531 g_test_add_func ("/option/arg/repetition/filename", arg_test3);
2532 g_test_add_func ("/option/arg/repetition/double", arg_test4);
2533 g_test_add_func ("/option/arg/repetition/locale", arg_test5);
2534 g_test_add_func ("/option/arg/repetition/int64", arg_test6);
2535  
2536 /* Test string arrays */
2537 g_test_add_func ("/option/arg/array/string", array_test1);
2538  
2539 /* Test callback args */
2540 g_test_add_func ("/option/arg/callback/string", callback_test1);
2541 g_test_add_func ("/option/arg/callback/count", callback_test2);
2542  
2543 /* Test optional arg flag for callback */
2544 g_test_add_func ("/option/arg/callback/optional1", callback_test_optional_1);
2545 g_test_add_func ("/option/arg/callback/optional2", callback_test_optional_2);
2546 g_test_add_func ("/option/arg/callback/optional3", callback_test_optional_3);
2547 g_test_add_func ("/option/arg/callback/optional4", callback_test_optional_4);
2548 g_test_add_func ("/option/arg/callback/optional5", callback_test_optional_5);
2549 g_test_add_func ("/option/arg/callback/optional6", callback_test_optional_6);
2550 g_test_add_func ("/option/arg/callback/optional7", callback_test_optional_7);
2551 g_test_add_func ("/option/arg/callback/optional8", callback_test_optional_8);
2552  
2553 /* Test callback with G_OPTION_REMAINING */
2554 g_test_add_func ("/option/arg/remaining/callback", callback_remaining_test1);
2555  
2556 /* Test callbacks which return FALSE */
2557 g_test_add_func ("/option/arg/remaining/callback-false", callback_returns_false);
2558  
2559 /* Test ignoring options */
2560 g_test_add_func ("/option/arg/ignore/long", ignore_test1);
2561 g_test_add_func ("/option/arg/ignore/short", ignore_test2);
2562 g_test_add_func ("/option/arg/ignore/arg", ignore_test3);
2563 g_test_add_func ("/option/context/add", add_test1);
2564  
2565 /* Test parsing empty args */
2566 /* Note there used to be an empty1 here, but it effectively moved
2567 * to option-argv0.c.
2568 */
2569 g_test_add_func ("/option/context/empty2", empty_test2);
2570 g_test_add_func ("/option/context/empty3", empty_test3);
2571  
2572 /* Test handling of rest args */
2573 g_test_add_func ("/option/arg/rest/non-option", rest_test1);
2574 g_test_add_func ("/option/arg/rest/separator1", rest_test2);
2575 g_test_add_func ("/option/arg/rest/separator2", rest_test2a);
2576 g_test_add_func ("/option/arg/rest/separator3", rest_test2b);
2577 g_test_add_func ("/option/arg/rest/separator4", rest_test2c);
2578 g_test_add_func ("/option/arg/rest/separator5", rest_test2d);
2579 g_test_add_func ("/option/arg/remaining/non-option", rest_test3);
2580 g_test_add_func ("/option/arg/remaining/separator", rest_test4);
2581 g_test_add_func ("/option/arg/remaining/array", rest_test5);
2582  
2583 /* Test some invalid flag combinations */
2584 g_test_add_func ("/option/arg/reverse-string", flag_reverse_string);
2585 g_test_add_func ("/option/arg/optional-int", flag_optional_int);
2586  
2587 /* regression tests for individual bugs */
2588 g_test_add_func ("/option/bug/unknown-short", unknown_short_test);
2589 g_test_add_func ("/option/bug/lonely-dash", lonely_dash_test);
2590 g_test_add_func ("/option/bug/missing-arg", missing_arg_test);
2591 g_test_add_func ("/option/bug/dash-arg", dash_arg_test);
2592 g_test_add_func ("/option/bug/short-remaining", short_remaining);
2593  
2594 return g_test_run();
2595 }