various tests: do not provoke SIGTRAP with -m no-undefined
[platform/upstream/glib.git] / glib / tests / option-context.c
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 void
31 group_captions (void)
32 {
33   gchar *help_variants[] = { "--help", "--help-all", "--help-test" };
34
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 }
40   };
41
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 }
47   };
48
49   gint i, j;
50
51   g_test_bug ("504142");
52
53   for (i = 0; i < 4; ++i)
54     {
55       gboolean have_main_entries = (0 != (i & 1));
56       gboolean have_test_entries = (0 != (i & 2));
57
58       GOptionContext *options;
59       GOptionGroup   *group = NULL;
60
61       options = g_option_context_new (NULL);
62
63       if (have_main_entries)
64         g_option_context_add_main_entries (options, main_entries, NULL);
65       if (have_test_entries)
66         {
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);
72         }
73
74       for (j = 0; j < G_N_ELEMENTS (help_variants); ++j)
75         {
76           GTestTrapFlags trap_flags = 0;
77           gchar *args[3];
78
79           args[0] = __FILE__;
80           args[1] = help_variants[j];
81           args[2] = NULL;
82
83           if (!g_test_verbose ())
84             trap_flags |= G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR;
85
86           g_test_message ("test setup: args='%s', main-entries=%d, test-entries=%d",
87                           args[1], have_main_entries, have_test_entries);
88
89           if (g_test_trap_fork (0, trap_flags))
90             {
91               gchar **argv = args;
92               gint    argc = 2;
93               GError *error = NULL;
94
95               g_setenv ("LANG", "C", TRUE);
96
97               g_option_context_parse (options, &argc, &argv, &error);
98               g_option_context_free (options);
99               exit(0);
100             }
101           else
102             {
103               gboolean expect_main_description = FALSE;
104               gboolean expect_main_switch      = FALSE;
105
106               gboolean expect_test_description = FALSE;
107               gboolean expect_test_switch      = FALSE;
108               gboolean expect_test_group       = FALSE;
109
110               g_test_trap_assert_passed ();
111               g_test_trap_assert_stderr ("");
112
113               switch (j)
114                 {
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;
120
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;
127
128                   case 2:
129                     g_assert_cmpstr ("--help-test", ==, args[1]);
130                     expect_test_switch = have_test_entries;
131                     break;
132
133                   default:
134                     g_assert_not_reached ();
135                     break;
136                 }
137
138               expect_main_description |= expect_main_switch;
139               expect_test_description |= expect_test_switch;
140
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*");
149
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*");
158
159               if (expect_test_group)
160                 g_test_trap_assert_stdout           ("*--help-test*");
161               else
162                 g_test_trap_assert_stdout_unmatched ("*--help-test*");
163             }
164         }
165
166       g_option_context_free (options);
167     }
168 }
169
170 int error_test1_int;
171 char *error_test2_string;
172 gboolean error_test3_boolean;
173
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;
181
182 gchar *callback_test1_string;
183 int callback_test2_int;
184
185 gchar *callback_test_optional_string;
186 gboolean callback_test_optional_boolean;
187
188 gchar **array_test1_array;
189
190 gboolean ignore_test1_boolean;
191 gboolean ignore_test2_boolean;
192 gchar *ignore_test3_string;
193
194 static gchar **
195 split_string (const char *str, int *argc)
196 {
197   gchar **argv;
198   int len;
199   
200   argv = g_strsplit (str, " ", 0);
201
202   for (len = 0; argv[len] != NULL; len++);
203
204   if (argc)
205     *argc = len;
206     
207   return argv;
208 }
209
210 static gchar *
211 join_stringv (int argc, char **argv)
212 {
213   int i;
214   GString *str;
215
216   str = g_string_new (NULL);
217
218   for (i = 0; i < argc; i++)
219     {
220       g_string_append (str, argv[i]);
221
222       if (i < argc - 1)
223         g_string_append_c (str, ' ');
224     }
225
226   return g_string_free (str, FALSE);
227 }
228
229 /* Performs a shallow copy */
230 static char **
231 copy_stringv (char **argv, int argc)
232 {
233   return g_memdup (argv, sizeof (char *) * (argc + 1));
234 }
235
236 static void
237 check_identical_stringv (gchar **before, gchar **after)
238 {
239   guint i;
240
241   /* Not only is it the same string... */
242   for (i = 0; before[i] != NULL; i++)
243     g_assert_cmpstr (before[i], ==, after[i]);
244
245   /* ... it is actually the same pointer */
246   for (i = 0; before[i] != NULL; i++)
247     g_assert (before[i] == after[i]);
248
249   g_assert (after[i] == NULL);
250 }
251
252
253 static gboolean
254 error_test1_pre_parse (GOptionContext *context,
255                        GOptionGroup   *group,
256                        gpointer        data,
257                        GError        **error)
258 {
259   g_assert (error_test1_int == 0x12345678);
260
261   return TRUE;
262 }
263
264 static gboolean
265 error_test1_post_parse (GOptionContext *context,
266                         GOptionGroup   *group,
267                         gpointer          data,
268                         GError        **error)
269 {
270   g_assert (error_test1_int == 20);
271
272   /* Set an error in the post hook */
273   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
274
275   return FALSE;
276 }
277
278 static void
279 error_test1 (void)
280 {
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 } };
291   
292   error_test1_int = 0x12345678;
293
294   context = g_option_context_new (NULL);
295   g_option_context_add_main_entries (context, entries, NULL);
296
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);
301   
302   /* Now try parsing */
303   argv = split_string ("program --test 20", &argc);
304   argv_copy = copy_stringv (argv, argc);
305
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);
312
313   /* On failure, values should be reset */
314   g_assert (error_test1_int == 0x12345678);
315
316   g_strfreev (argv_copy);
317   g_free (argv);
318   g_option_context_free (context);
319 }
320
321 static gboolean
322 error_test2_pre_parse (GOptionContext *context,
323                        GOptionGroup   *group,
324                        gpointer   data,
325                        GError        **error)
326 {
327   g_assert (strcmp (error_test2_string, "foo") == 0);
328
329   return TRUE;
330 }
331
332 static gboolean
333 error_test2_post_parse (GOptionContext *context,
334                         GOptionGroup   *group,
335                         gpointer          data,
336                         GError        **error)
337 {
338   g_assert (strcmp (error_test2_string, "bar") == 0);
339
340   /* Set an error in the post hook */
341   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
342
343   return FALSE;
344 }
345
346 static void
347 error_test2 (void)
348 {
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 } };
359
360   error_test2_string = "foo";
361
362   context = g_option_context_new (NULL);
363   g_option_context_add_main_entries (context, entries, NULL);
364
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);
369   
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);
374
375   g_assert (retval == FALSE);
376   g_assert (error != NULL);
377   check_identical_stringv (argv_copy, argv);
378   g_clear_error (&error);
379
380   g_assert (strcmp (error_test2_string, "foo") == 0);
381
382   g_strfreev (argv_copy);
383   g_free (argv);
384   g_option_context_free (context);
385 }
386
387 static gboolean
388 error_test3_pre_parse (GOptionContext *context,
389                        GOptionGroup   *group,
390                        gpointer   data,
391                        GError        **error)
392 {
393   g_assert (!error_test3_boolean);
394
395   return TRUE;
396 }
397
398 static gboolean
399 error_test3_post_parse (GOptionContext *context,
400                         GOptionGroup   *group,
401                         gpointer          data,
402                         GError        **error)
403 {
404   g_assert (error_test3_boolean);
405
406   /* Set an error in the post hook */
407   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
408
409   return FALSE;
410 }
411
412 static void
413 error_test3 (void)
414 {
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 } };
425
426   error_test3_boolean = FALSE;
427
428   context = g_option_context_new (NULL);
429   g_option_context_add_main_entries (context, entries, NULL);
430
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);
435   
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);
440
441   g_assert (retval == FALSE);
442   g_assert (error != NULL);
443   check_identical_stringv (argv_copy, argv);
444   g_clear_error (&error);
445
446   g_assert (!error_test3_boolean);
447
448   g_strfreev (argv_copy);
449   g_free (argv);
450   g_option_context_free (context);
451 }
452
453 static void
454 arg_test1 (void)
455 {
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 } };
465
466   context = g_option_context_new (NULL);
467   g_option_context_add_main_entries (context, entries, NULL);
468
469   /* Now try parsing */
470   argv = split_string ("program --test 20 --test 30", &argc);
471   argv_copy = copy_stringv (argv, argc);
472
473   retval = g_option_context_parse (context, &argc, &argv, &error);
474   g_assert_no_error (error);
475   g_assert (retval);
476
477   /* Last arg specified is the one that should be stored */
478   g_assert (arg_test1_int == 30);
479
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
482    */
483   g_strfreev (argv_copy);
484   g_free (argv);
485   g_option_context_free (context);
486 }
487
488 static void
489 arg_test2 (void)
490 {
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 } };
500   
501   context = g_option_context_new (NULL);
502   g_option_context_add_main_entries (context, entries, NULL);
503
504   /* Now try parsing */
505   argv = split_string ("program --test foo --test bar", &argc);
506   argv_copy = copy_stringv (argv, argc);
507
508   retval = g_option_context_parse (context, &argc, &argv, &error);
509   g_assert_no_error (error);
510   g_assert (retval);
511
512   /* Last arg specified is the one that should be stored */
513   g_assert (strcmp (arg_test2_string, "bar") == 0);
514
515   g_free (arg_test2_string);
516
517   g_strfreev (argv_copy);
518   g_free (argv);
519   g_option_context_free (context);
520 }
521
522 static void
523 arg_test3 (void)
524 {
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 } };
534   
535   context = g_option_context_new (NULL);
536   g_option_context_add_main_entries (context, entries, NULL);
537
538   /* Now try parsing */
539   argv = split_string ("program --test foo.txt", &argc);
540   argv_copy = copy_stringv (argv, argc);
541
542   retval = g_option_context_parse (context, &argc, &argv, &error);
543   g_assert_no_error (error);
544   g_assert (retval);
545
546   /* Last arg specified is the one that should be stored */
547   g_assert (strcmp (arg_test3_filename, "foo.txt") == 0);
548
549   g_free (arg_test3_filename);
550
551   g_strfreev (argv_copy);
552   g_free (argv);
553   g_option_context_free (context);
554 }
555
556
557 static void
558 arg_test4 (void)
559 {
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 } };
569
570   context = g_option_context_new (NULL);
571   g_option_context_add_main_entries (context, entries, NULL);
572
573   /* Now try parsing */
574   argv = split_string ("program --test 20.0 --test 30.03", &argc);
575   argv_copy = copy_stringv (argv, argc);
576
577   retval = g_option_context_parse (context, &argc, &argv, &error);
578   g_assert_no_error (error);
579   g_assert (retval);
580
581   /* Last arg specified is the one that should be stored */
582   g_assert (arg_test4_double == 30.03);
583
584   g_strfreev (argv_copy);
585   g_free (argv);
586   g_option_context_free (context);
587 }
588
589 static void
590 arg_test5 (void)
591 {
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 } };
603
604   context = g_option_context_new (NULL);
605   g_option_context_add_main_entries (context, entries, NULL);
606
607   /* Now try parsing */
608   argv = split_string ("program --test 20,0 --test 30,03", &argc);
609   argv_copy = copy_stringv (argv, argc);
610
611   /* set it to some locale that uses commas instead of decimal points */
612   
613   old_locale = g_strdup (setlocale (LC_NUMERIC, locale));
614   current_locale = setlocale (LC_NUMERIC, NULL);
615   if (strcmp (current_locale, locale) != 0)
616     {
617       fprintf (stderr, "Cannot set locale to %s, skipping\n", locale);
618       goto cleanup; 
619     }
620
621   retval = g_option_context_parse (context, &argc, &argv, &error);
622   g_assert_no_error (error);
623   g_assert (retval);
624
625   /* Last arg specified is the one that should be stored */
626   g_assert (arg_test5_double == 30.03);
627
628  cleanup:
629   setlocale (LC_NUMERIC, old_locale);
630   g_free (old_locale);
631
632   g_strfreev (argv_copy);
633   g_free (argv);
634   g_option_context_free (context);
635 }
636
637 static void
638 arg_test6 (void)
639 {
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 } };
650
651   context = g_option_context_new (NULL);
652   g_option_context_add_main_entries (context, entries, NULL);
653
654   /* Now try parsing */
655   argv = split_string ("program --test 4294967297 --test 4294967296 --test2 0xfffffffff", &argc);
656   argv_copy = copy_stringv (argv, argc);
657
658   retval = g_option_context_parse (context, &argc, &argv, &error);
659   g_assert_no_error (error);
660   g_assert (retval);
661
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));
665
666   g_strfreev (argv_copy);
667   g_free (argv);
668   g_option_context_free (context);
669 }
670
671 static gboolean
672 callback_parse1 (const gchar *option_name, const gchar *value,
673                  gpointer data, GError **error)
674 {
675         callback_test1_string = g_strdup (value);
676         return TRUE;
677 }
678
679 static void
680 callback_test1 (void)
681 {
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 } };
691   
692   context = g_option_context_new (NULL);
693   g_option_context_add_main_entries (context, entries, NULL);
694
695   /* Now try parsing */
696   argv = split_string ("program --test foo.txt", &argc);
697   argv_copy = copy_stringv (argv, argc);
698
699   retval = g_option_context_parse (context, &argc, &argv, &error);
700   g_assert_no_error (error);
701   g_assert (retval);
702
703   g_assert (strcmp (callback_test1_string, "foo.txt") == 0);
704
705   g_free (callback_test1_string);
706
707   g_strfreev (argv_copy);
708   g_free (argv);
709   g_option_context_free (context);
710 }
711
712 static gboolean
713 callback_parse2 (const gchar *option_name, const gchar *value,
714                  gpointer data, GError **error)
715 {
716         callback_test2_int++;
717         return TRUE;
718 }
719
720 static void
721 callback_test2 (void)
722 {
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 } };
732   
733   context = g_option_context_new (NULL);
734   g_option_context_add_main_entries (context, entries, NULL);
735
736   /* Now try parsing */
737   argv = split_string ("program --test --test", &argc);
738   argv_copy = copy_stringv (argv, argc);
739
740   retval = g_option_context_parse (context, &argc, &argv, &error);
741   g_assert_no_error (error);
742   g_assert (retval);
743
744   g_assert (callback_test2_int == 2);
745
746   g_strfreev (argv_copy);
747   g_free (argv);
748   g_option_context_free (context);
749 }
750
751 static gboolean
752 callback_parse_optional (const gchar *option_name, const gchar *value,
753                  gpointer data, GError **error)
754 {
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;
761 }
762
763 static void
764 callback_test_optional_1 (void)
765 {
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 } };
776   
777   context = g_option_context_new (NULL);
778   g_option_context_add_main_entries (context, entries, NULL);
779
780   /* Now try parsing */
781   argv = split_string ("program --test foo.txt", &argc);
782   argv_copy = copy_stringv (argv, argc);
783
784   retval = g_option_context_parse (context, &argc, &argv, &error);
785   g_assert_no_error (error);
786   g_assert (retval);
787
788   g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
789   
790   g_assert (callback_test_optional_boolean);
791
792   g_free (callback_test_optional_string);
793
794   g_strfreev (argv_copy);
795   g_free (argv);
796   g_option_context_free (context);
797 }
798
799 static void
800 callback_test_optional_2 (void)
801 {
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 } };
812   
813   context = g_option_context_new (NULL);
814   g_option_context_add_main_entries (context, entries, NULL);
815
816   /* Now try parsing */
817   argv = split_string ("program --test", &argc);
818   argv_copy = copy_stringv (argv, argc);
819
820   retval = g_option_context_parse (context, &argc, &argv, &error);
821   g_assert_no_error (error);
822   g_assert (retval);
823
824   g_assert (callback_test_optional_string == NULL);
825   
826   g_assert (callback_test_optional_boolean);
827
828   g_free (callback_test_optional_string);
829
830   g_strfreev (argv_copy);
831   g_free (argv);
832   g_option_context_free (context);
833 }
834
835 static void
836 callback_test_optional_3 (void)
837 {
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 } };
848   
849   context = g_option_context_new (NULL);
850   g_option_context_add_main_entries (context, entries, NULL);
851
852   /* Now try parsing */
853   argv = split_string ("program -t foo.txt", &argc);
854   argv_copy = copy_stringv (argv, argc);
855
856   retval = g_option_context_parse (context, &argc, &argv, &error);
857   g_assert_no_error (error);
858   g_assert (retval);
859
860   g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
861   
862   g_assert (callback_test_optional_boolean);
863
864   g_free (callback_test_optional_string);
865
866   g_strfreev (argv_copy);
867   g_free (argv);
868   g_option_context_free (context);
869 }
870
871
872 static void
873 callback_test_optional_4 (void)
874 {
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 } };
885   
886   context = g_option_context_new (NULL);
887   g_option_context_add_main_entries (context, entries, NULL);
888
889   /* Now try parsing */
890   argv = split_string ("program -t", &argc);
891   argv_copy = copy_stringv (argv, argc);
892
893   retval = g_option_context_parse (context, &argc, &argv, &error);
894   g_assert_no_error (error);
895   g_assert (retval);
896
897   g_assert (callback_test_optional_string == NULL);
898   
899   g_assert (callback_test_optional_boolean);
900
901   g_free (callback_test_optional_string);
902
903   g_strfreev (argv_copy);
904   g_free (argv);
905   g_option_context_free (context);
906 }
907
908 static void
909 callback_test_optional_5 (void)
910 {
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 } };
923   
924   context = g_option_context_new (NULL);
925   g_option_context_add_main_entries (context, entries, NULL);
926
927   /* Now try parsing */
928   argv = split_string ("program --test --dummy", &argc);
929   argv_copy = copy_stringv (argv, argc);
930
931   retval = g_option_context_parse (context, &argc, &argv, &error);
932   g_assert_no_error (error);
933   g_assert (retval);
934
935   g_assert (callback_test_optional_string == NULL);
936   
937   g_assert (callback_test_optional_boolean);
938
939   g_free (callback_test_optional_string);
940
941   g_strfreev (argv_copy);
942   g_free (argv);
943   g_option_context_free (context);
944 }
945
946 static void
947 callback_test_optional_6 (void)
948 {
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 } };
961   
962   context = g_option_context_new (NULL);
963   g_option_context_add_main_entries (context, entries, NULL);
964
965   /* Now try parsing */
966   argv = split_string ("program -t -d", &argc);
967   argv_copy = copy_stringv (argv, argc);
968
969   retval = g_option_context_parse (context, &argc, &argv, &error);
970   g_assert_no_error (error);
971   g_assert (retval);
972
973   g_assert (callback_test_optional_string == NULL);
974   
975   g_assert (callback_test_optional_boolean);
976
977   g_free (callback_test_optional_string);
978
979   g_strfreev (argv_copy);
980   g_free (argv);
981   g_option_context_free (context);
982 }
983
984 static void
985 callback_test_optional_7 (void)
986 {
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 } };
999   
1000   context = g_option_context_new (NULL);
1001   g_option_context_add_main_entries (context, entries, NULL);
1002
1003   /* Now try parsing */
1004   argv = split_string ("program -td", &argc);
1005   argv_copy = copy_stringv (argv, argc);
1006
1007   retval = g_option_context_parse (context, &argc, &argv, &error);
1008   g_assert_no_error (error);
1009   g_assert (retval);
1010
1011   g_assert (callback_test_optional_string == NULL);
1012   
1013   g_assert (callback_test_optional_boolean);
1014
1015   g_free (callback_test_optional_string);
1016
1017   g_strfreev (argv_copy);
1018   g_free (argv);
1019   g_option_context_free (context);
1020 }
1021
1022 static void
1023 callback_test_optional_8 (void)
1024 {
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 } };
1037   
1038   context = g_option_context_new (NULL);
1039   g_option_context_add_main_entries (context, entries, NULL);
1040
1041   /* Now try parsing */
1042   argv = split_string ("program -dt foo.txt", &argc);
1043   argv_copy = copy_stringv (argv, argc);
1044
1045   retval = g_option_context_parse (context, &argc, &argv, &error);
1046   g_assert_no_error (error);
1047   g_assert (retval);
1048
1049   g_assert (callback_test_optional_string);
1050   
1051   g_assert (callback_test_optional_boolean);
1052
1053   g_free (callback_test_optional_string);
1054
1055   g_strfreev (argv_copy);
1056   g_free (argv);
1057   g_option_context_free (context);
1058 }
1059
1060 static void
1061 callback_test_optional_9 (void)
1062 {
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 } };
1074
1075   context = g_option_context_new (NULL);
1076   g_option_context_add_main_entries (context, entries, NULL);
1077
1078   /* Now try parsing */
1079   argv = split_string ("program -t", &argc);
1080   argv_copy = copy_stringv (argv, argc);
1081
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);
1087
1088   g_error_free (error);
1089   g_strfreev (argv_copy);
1090   g_free (argv);
1091   g_option_context_free (context);
1092 }
1093
1094 static void
1095 callback_test_optional_10 (void)
1096 {
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 } };
1108
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 --test", &argc);
1114   argv_copy = copy_stringv (argv, argc);
1115
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);
1121
1122   g_error_free (error);
1123   g_strfreev (argv_copy);
1124   g_free (argv);
1125   g_option_context_free (context);
1126 }
1127
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)
1132 {
1133         g_ptr_array_add (callback_remaining_args, g_strdup (value));
1134         return TRUE;
1135 }
1136
1137 static void
1138 callback_remaining_test1 (void)
1139 {
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 } };
1149   
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);
1153
1154   /* Now try parsing */
1155   argv = split_string ("program foo.txt blah.txt", &argc);
1156   argv_copy = copy_stringv (argv, argc);
1157
1158   retval = g_option_context_parse (context, &argc, &argv, &error);
1159   g_assert_no_error (error);
1160   g_assert (retval);
1161
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);
1165
1166   g_ptr_array_foreach (callback_remaining_args, (GFunc) g_free, NULL);
1167   g_ptr_array_free (callback_remaining_args, TRUE);
1168
1169   g_strfreev (argv_copy);
1170   g_free (argv);
1171   g_option_context_free (context);
1172 }
1173
1174 static gboolean
1175 callback_error (const gchar *option_name, const gchar *value,
1176                 gpointer data, GError **error)
1177 {
1178   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "42");
1179   return FALSE;
1180 }
1181
1182 static void
1183 callback_returns_false (void)
1184 {
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 } };
1196
1197   context = g_option_context_new (NULL);
1198   g_option_context_add_main_entries (context, entries, NULL);
1199
1200   /* Now try parsing */
1201   argv = split_string ("program --error value", &argc);
1202   argv_copy = copy_stringv (argv, argc);
1203
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);
1208
1209   g_option_context_free (context);
1210   g_clear_error (&error);
1211   g_strfreev (argv_copy);
1212   g_free (argv);
1213
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);
1217
1218   argv = split_string ("program --error-no-arg", &argc);
1219   argv_copy = copy_stringv (argv, argc);
1220
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);
1225
1226   g_option_context_free (context);
1227   g_clear_error (&error);
1228   g_strfreev (argv_copy);
1229   g_free (argv);
1230
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);
1234
1235   argv = split_string ("program --error-optional-arg value", &argc);
1236   argv_copy = copy_stringv (argv, argc);
1237
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);
1242
1243   g_option_context_free (context);
1244   g_clear_error (&error);
1245   g_strfreev (argv_copy);
1246   g_free (argv);
1247
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);
1251
1252   argv = split_string ("program --error-optional-arg", &argc);
1253   argv_copy = copy_stringv (argv, argc);
1254
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);
1259
1260   g_option_context_free (context);
1261   g_clear_error (&error);
1262   g_strfreev (argv_copy);
1263   g_free (argv);
1264 }
1265
1266
1267 static void
1268 ignore_test1 (void)
1269 {
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 } };
1279
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);
1283
1284   /* Now try parsing */
1285   argv = split_string ("program --test --hello", &argc);
1286   argv_copy = copy_stringv (argv, argc);
1287   
1288   retval = g_option_context_parse (context, &argc, &argv, &error);
1289   g_assert_no_error (error);
1290   g_assert (retval);
1291
1292   /* Check array */
1293   arg = join_stringv (argc, argv);
1294   g_assert (strcmp (arg, "program --hello") == 0);
1295
1296   g_free (arg);
1297   g_strfreev (argv_copy);
1298   g_free (argv);
1299   g_option_context_free (context);
1300 }
1301
1302 static void
1303 ignore_test2 (void)
1304 {
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 } };
1315
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);
1319
1320   /* Now try parsing */
1321   argv = split_string ("program -test", &argc);
1322   argv_copy = copy_stringv (argv, argc);
1323
1324   retval = g_option_context_parse (context, &argc, &argv, &error);
1325   g_assert_no_error (error);
1326   g_assert (retval);
1327
1328   /* Check array */
1329   arg = join_stringv (argc, argv);
1330   g_assert (strcmp (arg, "program -es") == 0);
1331
1332   g_free (arg);
1333   g_strfreev (argv_copy);
1334   g_free (argv);
1335   g_option_context_free (context);
1336 }
1337
1338 static void
1339 ignore_test3 (void)
1340 {
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 } };
1350
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);
1354
1355   /* Now try parsing */
1356   argv = split_string ("program --test foo --hello", &argc);
1357   argv_copy = copy_stringv (argv, argc);
1358   
1359   retval = g_option_context_parse (context, &argc, &argv, &error);
1360   g_assert_no_error (error);
1361   g_assert (retval);
1362
1363   /* Check array */
1364   arg = join_stringv (argc, argv);
1365   g_assert (strcmp (arg, "program --hello") == 0);
1366
1367   g_assert (strcmp (ignore_test3_string, "foo") == 0);
1368   g_free (ignore_test3_string);
1369
1370   g_free (arg);
1371   g_strfreev (argv_copy);
1372   g_free (argv);
1373   g_option_context_free (context);
1374 }
1375
1376 void
1377 static array_test1 (void)
1378 {
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 } };
1388         
1389   context = g_option_context_new (NULL);
1390   g_option_context_add_main_entries (context, entries, NULL);
1391
1392   /* Now try parsing */
1393   argv = split_string ("program --test foo --test bar", &argc);
1394   argv_copy = copy_stringv (argv, argc);
1395
1396   retval = g_option_context_parse (context, &argc, &argv, &error);
1397   g_assert_no_error (error);
1398   g_assert (retval);
1399
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);
1404
1405   g_strfreev (array_test1_array);
1406   
1407   g_strfreev (argv_copy);
1408   g_free (argv);
1409   g_option_context_free (context);
1410 }
1411
1412 static void
1413 add_test1 (void)
1414 {
1415   GOptionContext *context;
1416
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 } };
1423
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);
1427
1428   g_option_context_free (context);
1429 }
1430
1431 static void
1432 empty_test2 (void)
1433 {
1434   GOptionContext *context;
1435
1436   context = g_option_context_new (NULL);
1437   g_option_context_parse (context, NULL, NULL, NULL);
1438   
1439   g_option_context_free (context);
1440 }
1441
1442 static void
1443 empty_test3 (void)
1444 {
1445   GOptionContext *context;
1446   gint argc;
1447   gchar **argv;
1448
1449   argc = 0;
1450   argv = NULL;
1451
1452   context = g_option_context_new (NULL);
1453   g_option_context_parse (context, &argc, &argv, NULL);
1454   
1455   g_option_context_free (context);
1456 }
1457
1458 /* check that non-option arguments are left in argv by default */
1459 static void
1460 rest_test1 (void)
1461 {
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 } 
1471   };
1472         
1473   context = g_option_context_new (NULL);
1474   g_option_context_add_main_entries (context, entries, NULL);
1475
1476   /* Now try parsing */
1477   argv = split_string ("program foo --test bar", &argc);
1478   argv_copy = copy_stringv (argv, argc);
1479
1480   retval = g_option_context_parse (context, &argc, &argv, &error);
1481   g_assert_no_error (error);
1482   g_assert (retval);
1483
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);
1490
1491   g_strfreev (argv_copy);
1492   g_free (argv);
1493   g_option_context_free (context);
1494 }
1495
1496 /* check that -- works */
1497 static void
1498 rest_test2 (void)
1499 {
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 } 
1509   };
1510         
1511   context = g_option_context_new (NULL);
1512   g_option_context_add_main_entries (context, entries, NULL);
1513
1514   /* Now try parsing */
1515   argv = split_string ("program foo --test -- -bar", &argc);
1516   argv_copy = copy_stringv (argv, argc);
1517
1518   retval = g_option_context_parse (context, &argc, &argv, &error);
1519   g_assert_no_error (error);
1520   g_assert (retval);
1521
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);
1529
1530   g_strfreev (argv_copy);
1531   g_free (argv);
1532   g_option_context_free (context);
1533 }
1534
1535 /* check that -- stripping works */
1536 static void
1537 rest_test2a (void)
1538 {
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 } 
1548   };
1549         
1550   context = g_option_context_new (NULL);
1551   g_option_context_add_main_entries (context, entries, NULL);
1552
1553   /* Now try parsing */
1554   argv = split_string ("program foo --test -- bar", &argc);
1555   argv_copy = copy_stringv (argv, argc);
1556
1557   retval = g_option_context_parse (context, &argc, &argv, &error);
1558   g_assert_no_error (error);
1559   g_assert (retval);
1560
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);
1567
1568   g_strfreev (argv_copy);
1569   g_free (argv);
1570   g_option_context_free (context);
1571 }
1572
1573 static void
1574 rest_test2b (void)
1575 {
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 } 
1585   };
1586         
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);
1590
1591   /* Now try parsing */
1592   argv = split_string ("program foo --test -bar --", &argc);
1593   argv_copy = copy_stringv (argv, argc);
1594
1595   retval = g_option_context_parse (context, &argc, &argv, &error);
1596   g_assert_no_error (error);
1597   g_assert (retval);
1598
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);
1605
1606   g_strfreev (argv_copy);
1607   g_free (argv);
1608   g_option_context_free (context);
1609 }
1610
1611 static void
1612 rest_test2c (void)
1613 {
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 } 
1623   };
1624         
1625   context = g_option_context_new (NULL);
1626   g_option_context_add_main_entries (context, entries, NULL);
1627
1628   /* Now try parsing */
1629   argv = split_string ("program --test foo -- bar", &argc);
1630   argv_copy = copy_stringv (argv, argc);
1631
1632   retval = g_option_context_parse (context, &argc, &argv, &error);
1633   g_assert_no_error (error);
1634   g_assert (retval);
1635
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);
1642
1643   g_strfreev (argv_copy);
1644   g_free (argv);
1645   g_option_context_free (context);
1646 }
1647
1648 static void
1649 rest_test2d (void)
1650 {
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 } 
1660   };
1661         
1662   context = g_option_context_new (NULL);
1663   g_option_context_add_main_entries (context, entries, NULL);
1664
1665   /* Now try parsing */
1666   argv = split_string ("program --test -- -bar", &argc);
1667   argv_copy = copy_stringv (argv, argc);
1668
1669   retval = g_option_context_parse (context, &argc, &argv, &error);
1670   g_assert_no_error (error);
1671   g_assert (retval);
1672
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);
1679
1680   g_strfreev (argv_copy);
1681   g_free (argv);
1682   g_option_context_free (context);
1683 }
1684
1685
1686 /* check that G_OPTION_REMAINING collects non-option arguments */
1687 static void
1688 rest_test3 (void)
1689 {
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 } 
1700   };
1701         
1702   context = g_option_context_new (NULL);
1703   g_option_context_add_main_entries (context, entries, NULL);
1704
1705   /* Now try parsing */
1706   argv = split_string ("program foo --test bar", &argc);
1707   argv_copy = copy_stringv (argv, argc);
1708
1709   retval = g_option_context_parse (context, &argc, &argv, &error);
1710   g_assert_no_error (error);
1711   g_assert (retval);
1712
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);
1718
1719   g_strfreev (array_test1_array);
1720
1721   g_strfreev (argv_copy);
1722   g_free (argv);
1723   g_option_context_free (context);
1724 }
1725
1726
1727 /* check that G_OPTION_REMAINING and -- work together */
1728 static void
1729 rest_test4 (void)
1730 {
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 } 
1741   };
1742         
1743   context = g_option_context_new (NULL);
1744   g_option_context_add_main_entries (context, entries, NULL);
1745
1746   /* Now try parsing */
1747   argv = split_string ("program foo --test -- -bar", &argc);
1748   argv_copy = copy_stringv (argv, argc);
1749
1750   retval = g_option_context_parse (context, &argc, &argv, &error);
1751   g_assert_no_error (error);
1752   g_assert (retval);
1753
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);
1759
1760   g_strfreev (array_test1_array);
1761
1762   g_strfreev (argv_copy);
1763   g_free (argv);
1764   g_option_context_free (context);
1765 }
1766
1767 /* test that G_OPTION_REMAINING works with G_OPTION_ARG_FILENAME_ARRAY */
1768 static void
1769 rest_test5 (void)
1770 {
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 } 
1781   };
1782         
1783   context = g_option_context_new (NULL);
1784   g_option_context_add_main_entries (context, entries, NULL);
1785
1786   /* Now try parsing */
1787   argv = split_string ("program foo --test bar", &argc);
1788   argv_copy = copy_stringv (argv, argc);
1789
1790   retval = g_option_context_parse (context, &argc, &argv, &error);
1791   g_assert_no_error (error);
1792   g_assert (retval);
1793
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);
1799
1800   g_strfreev (array_test1_array);
1801
1802   g_strfreev (argv_copy);
1803   g_free (argv);
1804   g_option_context_free (context);
1805 }
1806
1807 static void
1808 unknown_short_test (void)
1809 {
1810   GOptionContext *context;
1811   gboolean retval;
1812   GError *error = NULL;
1813   gchar **argv;
1814   gchar **argv_copy;
1815   int argc;
1816   GOptionEntry entries [] = { { NULL } };
1817
1818   g_test_bug ("166609");
1819
1820   context = g_option_context_new (NULL);
1821   g_option_context_add_main_entries (context, entries, NULL);
1822
1823   /* Now try parsing */
1824   argv = split_string ("program -0", &argc);
1825   argv_copy = copy_stringv (argv, argc);
1826
1827   retval = g_option_context_parse (context, &argc, &argv, &error);
1828   g_assert (!retval);
1829   g_assert (error != NULL);
1830   g_clear_error (&error);
1831
1832   g_strfreev (argv_copy);
1833   g_free (argv);
1834   g_option_context_free (context);
1835 }
1836
1837 /* test that lone dashes are treated as non-options */
1838 static void
1839 lonely_dash_test (void)
1840 {
1841   GOptionContext *context;
1842   gboolean retval;
1843   GError *error = NULL;
1844   gchar **argv;
1845   gchar **argv_copy;
1846   int argc;
1847
1848   g_test_bug ("168008");
1849
1850   context = g_option_context_new (NULL);
1851
1852   /* Now try parsing */
1853   argv = split_string ("program -", &argc);
1854   argv_copy = copy_stringv (argv, argc);
1855
1856   retval = g_option_context_parse (context, &argc, &argv, &error);
1857   g_assert_no_error (error);
1858   g_assert (retval);
1859
1860   g_assert (argv[1] && strcmp (argv[1], "-") == 0);
1861
1862   g_strfreev (argv_copy);
1863   g_free (argv);
1864   g_option_context_free (context);
1865 }
1866
1867 static void
1868 missing_arg_test (void)
1869 {
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 } };
1880
1881   g_test_bug ("305576");
1882
1883   context = g_option_context_new (NULL);
1884   g_option_context_add_main_entries (context, entries, NULL);
1885
1886   /* Now try parsing */
1887   argv = split_string ("program --test", &argc);
1888   argv_copy = copy_stringv (argv, argc);
1889
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);
1896
1897   g_strfreev (argv_copy);
1898   g_free (argv);
1899
1900   /* Try parsing again */
1901   argv = split_string ("program -t", &argc);
1902   argv_copy = copy_stringv (argv, argc);
1903
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);
1910
1911   g_strfreev (argv_copy);
1912   g_free (argv);
1913   g_option_context_free (context);
1914 }
1915
1916 static gchar *test_arg;
1917
1918 static gboolean cb (const gchar  *option_name,
1919                     const gchar  *value,
1920                     gpointer      data,
1921                     GError      **error)
1922 {
1923   test_arg = g_strdup (value);
1924   return TRUE;
1925 }
1926
1927 static void
1928 dash_arg_test (void)
1929 {
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 } };
1941
1942   g_test_bug ("577638");
1943
1944   context = g_option_context_new (NULL);
1945   g_option_context_add_main_entries (context, entries, NULL);
1946
1947   /* Now try parsing */
1948   argv = split_string ("program --test=-3", &argc);
1949   argv_copy = copy_stringv (argv, argc);
1950
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");
1957
1958   g_strfreev (argv_copy);
1959   g_free (argv);
1960   g_free (test_arg);
1961   test_arg = NULL;
1962
1963   /* Try parsing again */
1964   argv = split_string ("program --test -3", &argc);
1965   argv_copy = copy_stringv (argv, argc);
1966
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);
1972
1973   g_option_context_free (context);
1974   g_strfreev (argv_copy);
1975   g_free (argv);
1976 }
1977
1978 static void
1979 test_basic (void)
1980 {
1981   GOptionContext *context;
1982   gchar *arg = NULL;
1983   GOptionEntry entries [] =
1984     { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1985       { NULL } };
1986
1987   context = g_option_context_new (NULL);
1988   g_option_context_add_main_entries (context, entries, NULL);
1989
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);
1994
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");
1999
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");
2004
2005   g_option_context_free (context);
2006 }
2007
2008 static void
2009 test_main_group (void)
2010 {
2011   GOptionContext *context;
2012   GOptionGroup *group;
2013
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);
2022
2023   g_option_context_free (context);
2024 }
2025
2026 static gboolean error_func_called = FALSE;
2027
2028 static void
2029 error_func (GOptionContext  *context,
2030             GOptionGroup    *group,
2031             gpointer         data,
2032             GError         **error)
2033 {
2034   g_assert_cmpint (GPOINTER_TO_INT(data), ==, 1234);
2035   error_func_called = TRUE;
2036 }
2037
2038 static void
2039 test_error_hook (void)
2040 {
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;
2052
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);
2059
2060   argv = split_string ("program --test", &argc);
2061   argv_copy = copy_stringv (argv, argc);
2062
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);
2069
2070   g_assert (error_func_called);
2071
2072   g_strfreev (argv_copy);
2073   g_free (argv);
2074   g_option_context_free (context);
2075 }
2076
2077 static void
2078 flag_reverse_string (void)
2079 {
2080   if (!g_test_undefined ())
2081     return;
2082
2083   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
2084     {
2085       GOptionContext *context;
2086       gchar *arg = NULL;
2087       GOptionEntry entries [] =
2088         { { "test", 't', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_STRING, &arg, NULL, NULL },
2089           { NULL } };
2090       gchar **argv;
2091       gint argc;
2092       gboolean retval;
2093       GError *error = NULL;
2094
2095       context = g_option_context_new (NULL);
2096       g_option_context_add_main_entries (context, entries, NULL);
2097
2098       argv = split_string ("program --test bla", &argc);
2099
2100       retval = g_option_context_parse (context, &argc, &argv, &error);
2101       g_assert (retval == FALSE);
2102       g_clear_error (&error);
2103       g_strfreev (argv);
2104       g_option_context_free (context);
2105       exit (0);
2106     }
2107   g_test_trap_assert_failed ();
2108   g_test_trap_assert_stderr ("*ignoring reverse flag*");
2109 }
2110
2111 static void
2112 flag_optional_int (void)
2113 {
2114   if (!g_test_undefined ())
2115     return;
2116
2117   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
2118     {
2119       GOptionContext *context;
2120       gint arg = 0;
2121       GOptionEntry entries [] =
2122         { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &arg, NULL, NULL },
2123           { NULL } };
2124       gchar **argv;
2125       gint argc;
2126       gboolean retval;
2127       GError *error = NULL;
2128
2129       context = g_option_context_new (NULL);
2130       g_option_context_add_main_entries (context, entries, NULL);
2131
2132       argv = split_string ("program --test 5", &argc);
2133
2134       retval = g_option_context_parse (context, &argc, &argv, &error);
2135       g_assert (retval == FALSE);
2136       g_clear_error (&error);
2137       g_strfreev (argv);
2138       g_option_context_free (context);
2139       exit (0);
2140     }
2141   g_test_trap_assert_failed ();
2142   g_test_trap_assert_stderr ("*ignoring no-arg, optional-arg or filename flags*");
2143 }
2144 int
2145 main (int   argc,
2146       char *argv[])
2147 {
2148   g_test_init (&argc, &argv, NULL);
2149
2150   g_test_bug_base ("http://bugzilla.gnome.org/");
2151
2152   g_test_add_func ("/option/basic", test_basic);
2153   g_test_add_func ("/option/group/captions", group_captions);
2154   g_test_add_func ("/option/group/main", test_main_group);
2155   g_test_add_func ("/option/group/error-hook", test_error_hook);
2156
2157   /* Test that restoration on failure works */
2158   g_test_add_func ("/option/restoration/int", error_test1);
2159   g_test_add_func ("/option/restoration/string", error_test2);
2160   g_test_add_func ("/option/restoration/boolean", error_test3);
2161
2162   /* Test that special argument parsing works */
2163   g_test_add_func ("/option/arg/repetition/int", arg_test1);
2164   g_test_add_func ("/option/arg/repetition/string", arg_test2);
2165   g_test_add_func ("/option/arg/repetition/filename", arg_test3);
2166   g_test_add_func ("/option/arg/repetition/double", arg_test4);
2167   g_test_add_func ("/option/arg/repetition/locale", arg_test5);
2168   g_test_add_func ("/option/arg/repetition/int64", arg_test6);
2169
2170   /* Test string arrays */
2171   g_test_add_func ("/option/arg/array/string", array_test1);
2172
2173   /* Test callback args */
2174   g_test_add_func ("/option/arg/callback/string", callback_test1);
2175   g_test_add_func ("/option/arg/callback/count", callback_test2);
2176
2177   /* Test optional arg flag for callback */
2178   g_test_add_func ("/option/arg/callback/optional1", callback_test_optional_1);
2179   g_test_add_func ("/option/arg/callback/optional2", callback_test_optional_2);
2180   g_test_add_func ("/option/arg/callback/optional3", callback_test_optional_3);
2181   g_test_add_func ("/option/arg/callback/optional4", callback_test_optional_4);
2182   g_test_add_func ("/option/arg/callback/optional5", callback_test_optional_5);
2183   g_test_add_func ("/option/arg/callback/optional6", callback_test_optional_6);
2184   g_test_add_func ("/option/arg/callback/optional7", callback_test_optional_7);
2185   g_test_add_func ("/option/arg/callback/optional8", callback_test_optional_8);
2186
2187   /* Test callback with G_OPTION_REMAINING */
2188   g_test_add_func ("/option/arg/remaining/callback", callback_remaining_test1);
2189
2190   /* Test callbacks which return FALSE */
2191   g_test_add_func ("/option/arg/remaining/callback-false", callback_returns_false);
2192
2193   /* Test ignoring options */
2194   g_test_add_func ("/option/arg/ignore/long", ignore_test1);
2195   g_test_add_func ("/option/arg/ignore/short", ignore_test2);
2196   g_test_add_func ("/option/arg/ignore/arg", ignore_test3);
2197   g_test_add_func ("/option/context/add", add_test1);
2198
2199   /* Test parsing empty args */
2200   /* Note there used to be an empty1 here, but it effectively moved
2201    * to option-argv0.c.
2202    */
2203   g_test_add_func ("/option/context/empty2", empty_test2);
2204   g_test_add_func ("/option/context/empty3", empty_test3);
2205
2206   /* Test handling of rest args */
2207   g_test_add_func ("/option/arg/rest/non-option", rest_test1);
2208   g_test_add_func ("/option/arg/rest/separator1", rest_test2);
2209   g_test_add_func ("/option/arg/rest/separator2", rest_test2a);
2210   g_test_add_func ("/option/arg/rest/separator3", rest_test2b);
2211   g_test_add_func ("/option/arg/rest/separator4", rest_test2c);
2212   g_test_add_func ("/option/arg/rest/separator5", rest_test2d);
2213   g_test_add_func ("/option/arg/remaining/non-option", rest_test3);
2214   g_test_add_func ("/option/arg/remaining/separator", rest_test4);
2215   g_test_add_func ("/option/arg/remaining/array", rest_test5);
2216
2217   /* Test some invalid flag combinations */
2218   g_test_add_func ("/option/arg/reverse-string", flag_reverse_string);
2219   g_test_add_func ("/option/arg/optional-int", flag_optional_int);
2220
2221   /* regression tests for individual bugs */
2222   g_test_add_func ("/option/bug/unknown-short", unknown_short_test);
2223   g_test_add_func ("/option/bug/lonely-dash", lonely_dash_test);
2224   g_test_add_func ("/option/bug/missing-arg", missing_arg_test);
2225   g_test_add_func ("/option/bug/dash-arg", dash_arg_test);
2226
2227   return g_test_run();
2228 }