Mark some functions 'static' in glib/tests
[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               exit(0);
99             }
100           else
101             {
102               gboolean expect_main_description = FALSE;
103               gboolean expect_main_switch      = FALSE;
104
105               gboolean expect_test_description = FALSE;
106               gboolean expect_test_switch      = FALSE;
107               gboolean expect_test_group       = FALSE;
108
109               g_test_trap_assert_passed ();
110               g_test_trap_assert_stderr ("");
111
112               switch (j)
113                 {
114                   case 0:
115                     g_assert_cmpstr ("--help", ==, args[1]);
116                     expect_main_switch = have_main_entries;
117                     expect_test_group  = have_test_entries;
118                     break;
119
120                   case 1:
121                     g_assert_cmpstr ("--help-all", ==, args[1]);
122                     expect_main_switch = have_main_entries;
123                     expect_test_switch = have_test_entries;
124                     expect_test_group  = have_test_entries;
125                     break;
126
127                   case 2:
128                     g_assert_cmpstr ("--help-test", ==, args[1]);
129                     expect_test_switch = have_test_entries;
130                     break;
131
132                   default:
133                     g_assert_not_reached ();
134                     break;
135                 }
136
137               expect_main_description |= expect_main_switch;
138               expect_test_description |= expect_test_switch;
139
140               if (expect_main_description)
141                 g_test_trap_assert_stdout           ("*Application Options*");
142               else
143                 g_test_trap_assert_stdout_unmatched ("*Application Options*");
144               if (expect_main_switch)
145                 g_test_trap_assert_stdout           ("*--main-switch*");
146               else
147                 g_test_trap_assert_stdout_unmatched ("*--main-switch*");
148
149               if (expect_test_description)
150                 g_test_trap_assert_stdout           ("*Test Options*");
151               else
152                 g_test_trap_assert_stdout_unmatched ("*Test Options*");
153               if (expect_test_switch)
154                 g_test_trap_assert_stdout           ("*--test-switch*");
155               else
156                 g_test_trap_assert_stdout_unmatched ("*--test-switch*");
157
158               if (expect_test_group)
159                 g_test_trap_assert_stdout           ("*--help-test*");
160               else
161                 g_test_trap_assert_stdout_unmatched ("*--help-test*");
162             }
163         }
164     }
165 }
166
167 int error_test1_int;
168 char *error_test2_string;
169 gboolean error_test3_boolean;
170
171 int arg_test1_int;
172 gchar *arg_test2_string;
173 gchar *arg_test3_filename;
174 gdouble arg_test4_double;
175 gdouble arg_test5_double;
176 gint64 arg_test6_int64;
177 gint64 arg_test6_int64_2;
178
179 gchar *callback_test1_string;
180 int callback_test2_int;
181
182 gchar *callback_test_optional_string;
183 gboolean callback_test_optional_boolean;
184
185 gchar **array_test1_array;
186
187 gboolean ignore_test1_boolean;
188 gboolean ignore_test2_boolean;
189 gchar *ignore_test3_string;
190
191 static gchar **
192 split_string (const char *str, int *argc)
193 {
194   gchar **argv;
195   int len;
196   
197   argv = g_strsplit (str, " ", 0);
198
199   for (len = 0; argv[len] != NULL; len++);
200
201   if (argc)
202     *argc = len;
203     
204   return argv;
205 }
206
207 static gchar *
208 join_stringv (int argc, char **argv)
209 {
210   int i;
211   GString *str;
212
213   str = g_string_new (NULL);
214
215   for (i = 0; i < argc; i++)
216     {
217       g_string_append (str, argv[i]);
218
219       if (i < argc - 1)
220         g_string_append_c (str, ' ');
221     }
222
223   return g_string_free (str, FALSE);
224 }
225
226 /* Performs a shallow copy */
227 static char **
228 copy_stringv (char **argv, int argc)
229 {
230   return g_memdup (argv, sizeof (char *) * (argc + 1));
231 }
232
233
234 static gboolean
235 error_test1_pre_parse (GOptionContext *context,
236                        GOptionGroup   *group,
237                        gpointer        data,
238                        GError        **error)
239 {
240   g_assert (error_test1_int == 0x12345678);
241
242   return TRUE;
243 }
244
245 static gboolean
246 error_test1_post_parse (GOptionContext *context,
247                         GOptionGroup   *group,
248                         gpointer          data,
249                         GError        **error)
250 {
251   g_assert (error_test1_int == 20);
252
253   /* Set an error in the post hook */
254   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
255
256   return FALSE;
257 }
258
259 static void
260 error_test1 (void)
261 {
262   GOptionContext *context;
263   gboolean retval;
264   GError *error = NULL;
265   gchar **argv;
266   int argc;
267   GOptionGroup *main_group;
268   GOptionEntry entries [] =
269     { { "test", 0, 0, G_OPTION_ARG_INT, &error_test1_int, NULL, NULL },
270       { NULL } };
271   
272   error_test1_int = 0x12345678;
273
274   context = g_option_context_new (NULL);
275   g_option_context_add_main_entries (context, entries, NULL);
276
277   /* Set pre and post parse hooks */
278   main_group = g_option_context_get_main_group (context);
279   g_option_group_set_parse_hooks (main_group,
280                                   error_test1_pre_parse, error_test1_post_parse);
281   
282   /* Now try parsing */
283   argv = split_string ("program --test 20", &argc);
284
285   retval = g_option_context_parse (context, &argc, &argv, &error);
286   g_assert (retval == FALSE);
287
288   /* On failure, values should be reset */
289   g_assert (error_test1_int == 0x12345678);
290   
291   g_strfreev (argv);
292   g_option_context_free (context);
293 }
294
295 static gboolean
296 error_test2_pre_parse (GOptionContext *context,
297                        GOptionGroup   *group,
298                        gpointer   data,
299                        GError        **error)
300 {
301   g_assert (strcmp (error_test2_string, "foo") == 0);
302
303   return TRUE;
304 }
305
306 static gboolean
307 error_test2_post_parse (GOptionContext *context,
308                         GOptionGroup   *group,
309                         gpointer          data,
310                         GError        **error)
311 {
312   g_assert (strcmp (error_test2_string, "bar") == 0);
313
314   /* Set an error in the post hook */
315   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
316
317   return FALSE;
318 }
319
320 static void
321 error_test2 (void)
322 {
323   GOptionContext *context;
324   gboolean retval;
325   GError *error = NULL;
326   gchar **argv;
327   int argc;
328   GOptionGroup *main_group;
329   GOptionEntry entries [] =
330     { { "test", 0, 0, G_OPTION_ARG_STRING, &error_test2_string, NULL, NULL },
331       { NULL } };
332
333   error_test2_string = "foo";
334
335   context = g_option_context_new (NULL);
336   g_option_context_add_main_entries (context, entries, NULL);
337
338   /* Set pre and post parse hooks */
339   main_group = g_option_context_get_main_group (context);
340   g_option_group_set_parse_hooks (main_group,
341                                   error_test2_pre_parse, error_test2_post_parse);
342   
343   /* Now try parsing */
344   argv = split_string ("program --test bar", &argc);
345   retval = g_option_context_parse (context, &argc, &argv, &error);
346
347   g_error_free (error);
348   g_assert (retval == FALSE);
349
350   g_assert (strcmp (error_test2_string, "foo") == 0);
351   
352   g_strfreev (argv);
353   g_option_context_free (context);
354 }
355
356 static gboolean
357 error_test3_pre_parse (GOptionContext *context,
358                        GOptionGroup   *group,
359                        gpointer   data,
360                        GError        **error)
361 {
362   g_assert (!error_test3_boolean);
363
364   return TRUE;
365 }
366
367 static gboolean
368 error_test3_post_parse (GOptionContext *context,
369                         GOptionGroup   *group,
370                         gpointer          data,
371                         GError        **error)
372 {
373   g_assert (error_test3_boolean);
374
375   /* Set an error in the post hook */
376   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
377
378   return FALSE;
379 }
380
381 static void
382 error_test3 (void)
383 {
384   GOptionContext *context;
385   gboolean retval;
386   GError *error = NULL;
387   gchar **argv;
388   int argc;
389   GOptionGroup *main_group;
390   GOptionEntry entries [] =
391     { { "test", 0, 0, G_OPTION_ARG_NONE, &error_test3_boolean, NULL, NULL },
392       { NULL } };
393
394   error_test3_boolean = FALSE;
395
396   context = g_option_context_new (NULL);
397   g_option_context_add_main_entries (context, entries, NULL);
398
399   /* Set pre and post parse hooks */
400   main_group = g_option_context_get_main_group (context);
401   g_option_group_set_parse_hooks (main_group,
402                                   error_test3_pre_parse, error_test3_post_parse);
403   
404   /* Now try parsing */
405   argv = split_string ("program --test", &argc);
406   retval = g_option_context_parse (context, &argc, &argv, &error);
407
408   g_error_free (error);
409   g_assert (retval == FALSE);
410
411   g_assert (!error_test3_boolean);
412   
413   g_strfreev (argv);
414   g_option_context_free (context);
415 }
416
417 static void
418 arg_test1 (void)
419 {
420   GOptionContext *context;
421   gboolean retval;
422   GError *error = NULL;
423   gchar **argv;
424   int argc;
425   GOptionEntry entries [] =
426     { { "test", 0, 0, G_OPTION_ARG_INT, &arg_test1_int, NULL, NULL },
427       { NULL } };
428
429   context = g_option_context_new (NULL);
430   g_option_context_add_main_entries (context, entries, NULL);
431
432   /* Now try parsing */
433   argv = split_string ("program --test 20 --test 30", &argc);
434
435   retval = g_option_context_parse (context, &argc, &argv, &error);
436   g_assert_no_error (error);
437   g_assert (retval);
438
439   /* Last arg specified is the one that should be stored */
440   g_assert (arg_test1_int == 30);
441
442   g_strfreev (argv);
443   g_option_context_free (context);
444 }
445
446 static void
447 arg_test2 (void)
448 {
449   GOptionContext *context;
450   gboolean retval;
451   GError *error = NULL;
452   gchar **argv;
453   int argc;
454   GOptionEntry entries [] =
455     { { "test", 0, 0, G_OPTION_ARG_STRING, &arg_test2_string, NULL, NULL },
456       { NULL } };
457   
458   context = g_option_context_new (NULL);
459   g_option_context_add_main_entries (context, entries, NULL);
460
461   /* Now try parsing */
462   argv = split_string ("program --test foo --test bar", &argc);
463   
464   retval = g_option_context_parse (context, &argc, &argv, &error);
465   g_assert_no_error (error);
466   g_assert (retval);
467
468   /* Last arg specified is the one that should be stored */
469   g_assert (strcmp (arg_test2_string, "bar") == 0);
470
471   g_free (arg_test2_string);
472   
473   g_strfreev (argv);
474   g_option_context_free (context);
475 }
476
477 static void
478 arg_test3 (void)
479 {
480   GOptionContext *context;
481   gboolean retval;
482   GError *error = NULL;
483   gchar **argv;
484   int argc;
485   GOptionEntry entries [] =
486     { { "test", 0, 0, G_OPTION_ARG_FILENAME, &arg_test3_filename, NULL, NULL },
487       { NULL } };
488   
489   context = g_option_context_new (NULL);
490   g_option_context_add_main_entries (context, entries, NULL);
491
492   /* Now try parsing */
493   argv = split_string ("program --test foo.txt", &argc);
494   
495   retval = g_option_context_parse (context, &argc, &argv, &error);
496   g_assert_no_error (error);
497   g_assert (retval);
498
499   /* Last arg specified is the one that should be stored */
500   g_assert (strcmp (arg_test3_filename, "foo.txt") == 0);
501
502   g_free (arg_test3_filename);
503   
504   g_strfreev (argv);
505   g_option_context_free (context);
506 }
507
508
509 static void
510 arg_test4 (void)
511 {
512   GOptionContext *context;
513   gboolean retval;
514   GError *error = NULL;
515   gchar **argv;
516   int argc;
517   GOptionEntry entries [] =
518     { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test4_double, NULL, NULL },
519       { NULL } };
520
521   context = g_option_context_new (NULL);
522   g_option_context_add_main_entries (context, entries, NULL);
523
524   /* Now try parsing */
525   argv = split_string ("program --test 20.0 --test 30.03", &argc);
526
527   retval = g_option_context_parse (context, &argc, &argv, &error);
528   g_assert_no_error (error);
529   g_assert (retval);
530
531   /* Last arg specified is the one that should be stored */
532   g_assert (arg_test4_double == 30.03);
533
534   g_strfreev (argv);
535   g_option_context_free (context);
536 }
537
538 static void
539 arg_test5 (void)
540 {
541   GOptionContext *context;
542   gboolean retval;
543   GError *error = NULL;
544   gchar **argv;
545   int argc;
546   char *old_locale, *current_locale;
547   const char *locale = "de_DE";
548   GOptionEntry entries [] =
549     { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test5_double, NULL, NULL },
550       { NULL } };
551
552   context = g_option_context_new (NULL);
553   g_option_context_add_main_entries (context, entries, NULL);
554
555   /* Now try parsing */
556   argv = split_string ("program --test 20,0 --test 30,03", &argc);
557
558   /* set it to some locale that uses commas instead of decimal points */
559   
560   old_locale = g_strdup (setlocale (LC_NUMERIC, locale));
561   current_locale = setlocale (LC_NUMERIC, NULL);
562   if (strcmp (current_locale, locale) != 0)
563     {
564       fprintf (stderr, "Cannot set locale to %s, skipping\n", locale);
565       goto cleanup; 
566     }
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 (arg_test5_double == 30.03);
574
575  cleanup:
576   setlocale (LC_NUMERIC, old_locale);
577   g_free (old_locale);
578
579   g_strfreev (argv);
580   g_option_context_free (context);
581 }
582
583 static void
584 arg_test6 (void)
585 {
586   GOptionContext *context;
587   gboolean retval;
588   GError *error = NULL;
589   gchar **argv;
590   int argc;
591   GOptionEntry entries [] =
592     { { "test", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64, NULL, NULL },
593       { "test2", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64_2, 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 4294967297 --test 4294967296 --test2 0xfffffffff", &argc);
601
602   retval = g_option_context_parse (context, &argc, &argv, &error);
603   g_assert_no_error (error);
604   g_assert (retval);
605
606   /* Last arg specified is the one that should be stored */
607   g_assert (arg_test6_int64 == G_GINT64_CONSTANT(4294967296));
608   g_assert (arg_test6_int64_2 == G_GINT64_CONSTANT(0xfffffffff));
609
610   g_strfreev (argv);
611   g_option_context_free (context);
612 }
613
614 static gboolean
615 callback_parse1 (const gchar *option_name, const gchar *value,
616                  gpointer data, GError **error)
617 {
618         callback_test1_string = g_strdup (value);
619         return TRUE;
620 }
621
622 static void
623 callback_test1 (void)
624 {
625   GOptionContext *context;
626   gboolean retval;
627   GError *error = NULL;
628   gchar **argv;
629   int argc;
630   GOptionEntry entries [] =
631     { { "test", 0, 0, G_OPTION_ARG_CALLBACK, callback_parse1, NULL, NULL },
632       { NULL } };
633   
634   context = g_option_context_new (NULL);
635   g_option_context_add_main_entries (context, entries, NULL);
636
637   /* Now try parsing */
638   argv = split_string ("program --test foo.txt", &argc);
639   
640   retval = g_option_context_parse (context, &argc, &argv, &error);
641   g_assert_no_error (error);
642   g_assert (retval);
643
644   g_assert (strcmp (callback_test1_string, "foo.txt") == 0);
645
646   g_free (callback_test1_string);
647   
648   g_strfreev (argv);
649   g_option_context_free (context);
650 }
651
652 static gboolean
653 callback_parse2 (const gchar *option_name, const gchar *value,
654                  gpointer data, GError **error)
655 {
656         callback_test2_int++;
657         return TRUE;
658 }
659
660 static void
661 callback_test2 (void)
662 {
663   GOptionContext *context;
664   gboolean retval;
665   GError *error = NULL;
666   gchar **argv;
667   int argc;
668   GOptionEntry entries [] =
669     { { "test", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_parse2, NULL, NULL },
670       { NULL } };
671   
672   context = g_option_context_new (NULL);
673   g_option_context_add_main_entries (context, entries, NULL);
674
675   /* Now try parsing */
676   argv = split_string ("program --test --test", &argc);
677   
678   retval = g_option_context_parse (context, &argc, &argv, &error);
679   g_assert_no_error (error);
680   g_assert (retval);
681
682   g_assert (callback_test2_int == 2);
683   
684   g_strfreev (argv);
685   g_option_context_free (context);
686 }
687
688 static gboolean
689 callback_parse_optional (const gchar *option_name, const gchar *value,
690                  gpointer data, GError **error)
691 {
692         callback_test_optional_boolean = TRUE;
693         if (value)
694                 callback_test_optional_string = g_strdup (value);
695         else
696                 callback_test_optional_string = NULL;
697         return TRUE;
698 }
699
700 static void
701 callback_test_optional_1 (void)
702 {
703   GOptionContext *context;
704   gboolean retval;
705   GError *error = NULL;
706   gchar **argv;
707   int argc;
708   GOptionEntry entries [] =
709     { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
710         callback_parse_optional, NULL, NULL },
711       { NULL } };
712   
713   context = g_option_context_new (NULL);
714   g_option_context_add_main_entries (context, entries, NULL);
715
716   /* Now try parsing */
717   argv = split_string ("program --test foo.txt", &argc);
718   
719   retval = g_option_context_parse (context, &argc, &argv, &error);
720   g_assert_no_error (error);
721   g_assert (retval);
722
723   g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
724   
725   g_assert (callback_test_optional_boolean);
726
727   g_free (callback_test_optional_string);
728   
729   g_strfreev (argv);
730   g_option_context_free (context);
731 }
732
733 static void
734 callback_test_optional_2 (void)
735 {
736   GOptionContext *context;
737   gboolean retval;
738   GError *error = NULL;
739   gchar **argv;
740   int argc;
741   GOptionEntry entries [] =
742     { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
743         callback_parse_optional, NULL, NULL },
744       { NULL } };
745   
746   context = g_option_context_new (NULL);
747   g_option_context_add_main_entries (context, entries, NULL);
748
749   /* Now try parsing */
750   argv = split_string ("program --test", &argc);
751   
752   retval = g_option_context_parse (context, &argc, &argv, &error);
753   g_assert_no_error (error);
754   g_assert (retval);
755
756   g_assert (callback_test_optional_string == NULL);
757   
758   g_assert (callback_test_optional_boolean);
759
760   g_free (callback_test_optional_string);
761   
762   g_strfreev (argv);
763   g_option_context_free (context);
764 }
765
766 static void
767 callback_test_optional_3 (void)
768 {
769   GOptionContext *context;
770   gboolean retval;
771   GError *error = NULL;
772   gchar **argv;
773   int argc;
774   GOptionEntry entries [] =
775     { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
776         callback_parse_optional, NULL, NULL },
777       { NULL } };
778   
779   context = g_option_context_new (NULL);
780   g_option_context_add_main_entries (context, entries, NULL);
781
782   /* Now try parsing */
783   argv = split_string ("program -t foo.txt", &argc);
784   
785   retval = g_option_context_parse (context, &argc, &argv, &error);
786   g_assert_no_error (error);
787   g_assert (retval);
788
789   g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
790   
791   g_assert (callback_test_optional_boolean);
792
793   g_free (callback_test_optional_string);
794   
795   g_strfreev (argv);
796   g_option_context_free (context);
797 }
798
799
800 static void
801 callback_test_optional_4 (void)
802 {
803   GOptionContext *context;
804   gboolean retval;
805   GError *error = NULL;
806   gchar **argv;
807   int argc;
808   GOptionEntry entries [] =
809     { { "test", 't', 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 -t", &argc);
818   
819   retval = g_option_context_parse (context, &argc, &argv, &error);
820   g_assert_no_error (error);
821   g_assert (retval);
822
823   g_assert (callback_test_optional_string == NULL);
824   
825   g_assert (callback_test_optional_boolean);
826
827   g_free (callback_test_optional_string);
828   
829   g_strfreev (argv);
830   g_option_context_free (context);
831 }
832
833 static void
834 callback_test_optional_5 (void)
835 {
836   GOptionContext *context;
837   gboolean dummy;
838   gboolean retval;
839   GError *error = NULL;
840   gchar **argv;
841   int argc;
842   GOptionEntry entries [] =
843     { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
844       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
845         callback_parse_optional, NULL, NULL },
846       { NULL } };
847   
848   context = g_option_context_new (NULL);
849   g_option_context_add_main_entries (context, entries, NULL);
850
851   /* Now try parsing */
852   argv = split_string ("program --test --dummy", &argc);
853   
854   retval = g_option_context_parse (context, &argc, &argv, &error);
855   g_assert_no_error (error);
856   g_assert (retval);
857
858   g_assert (callback_test_optional_string == NULL);
859   
860   g_assert (callback_test_optional_boolean);
861
862   g_free (callback_test_optional_string);
863   
864   g_strfreev (argv);
865   g_option_context_free (context);
866 }
867
868 static void
869 callback_test_optional_6 (void)
870 {
871   GOptionContext *context;
872   gboolean dummy;
873   gboolean retval;
874   GError *error = NULL;
875   gchar **argv;
876   int argc;
877   GOptionEntry entries [] =
878     { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
879       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
880         callback_parse_optional, NULL, NULL },
881       { NULL } };
882   
883   context = g_option_context_new (NULL);
884   g_option_context_add_main_entries (context, entries, NULL);
885
886   /* Now try parsing */
887   argv = split_string ("program -t -d", &argc);
888   
889   retval = g_option_context_parse (context, &argc, &argv, &error);
890   g_assert_no_error (error);
891   g_assert (retval);
892
893   g_assert (callback_test_optional_string == NULL);
894   
895   g_assert (callback_test_optional_boolean);
896
897   g_free (callback_test_optional_string);
898   
899   g_strfreev (argv);
900   g_option_context_free (context);
901 }
902
903 static void
904 callback_test_optional_7 (void)
905 {
906   GOptionContext *context;
907   gboolean dummy;
908   gboolean retval;
909   GError *error = NULL;
910   gchar **argv;
911   int argc;
912   GOptionEntry entries [] =
913     { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
914       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
915         callback_parse_optional, NULL, NULL },
916       { NULL } };
917   
918   context = g_option_context_new (NULL);
919   g_option_context_add_main_entries (context, entries, NULL);
920
921   /* Now try parsing */
922   argv = split_string ("program -td", &argc);
923   
924   retval = g_option_context_parse (context, &argc, &argv, &error);
925   g_assert_no_error (error);
926   g_assert (retval);
927
928   g_assert (callback_test_optional_string == NULL);
929   
930   g_assert (callback_test_optional_boolean);
931
932   g_free (callback_test_optional_string);
933   
934   g_strfreev (argv);
935   g_option_context_free (context);
936 }
937
938 static void
939 callback_test_optional_8 (void)
940 {
941   GOptionContext *context;
942   gboolean dummy;
943   gboolean retval;
944   GError *error = NULL;
945   gchar **argv;
946   int argc;
947   GOptionEntry entries [] =
948     { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
949       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
950         callback_parse_optional, NULL, NULL },
951       { NULL } };
952   
953   context = g_option_context_new (NULL);
954   g_option_context_add_main_entries (context, entries, NULL);
955
956   /* Now try parsing */
957   argv = split_string ("program -dt foo.txt", &argc);
958   
959   retval = g_option_context_parse (context, &argc, &argv, &error);
960   g_assert_no_error (error);
961   g_assert (retval);
962
963   g_assert (callback_test_optional_string);
964   
965   g_assert (callback_test_optional_boolean);
966
967   g_free (callback_test_optional_string);
968   
969   g_strfreev (argv);
970   g_option_context_free (context);
971 }
972
973 static void
974 callback_test_optional_9 (void)
975 {
976   GOptionContext *context;
977   gboolean retval;
978   GError *error = NULL;
979   gchar **argv;
980   int argc;
981   gchar *string = NULL;
982   GOptionEntry entries [] =
983     { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING,
984                 &string, NULL, NULL },
985       { NULL } };
986
987   context = g_option_context_new (NULL);
988   g_option_context_add_main_entries (context, entries, NULL);
989
990   /* Now try parsing */
991   argv = split_string ("program -t", &argc);
992
993   retval = g_option_context_parse (context, &argc, &argv, &error);
994   g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
995   g_assert (!retval);
996   g_assert (string == NULL);
997
998   g_error_free (error);
999   g_strfreev (argv);
1000   g_option_context_free (context);
1001 }
1002
1003 static void
1004 callback_test_optional_10 (void)
1005 {
1006   GOptionContext *context;
1007   gboolean retval;
1008   GError *error = NULL;
1009   gchar **argv;
1010   int argc;
1011   gchar *string = NULL;
1012   GOptionEntry entries [] =
1013     { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING,
1014                 &string, NULL, NULL },
1015       { NULL } };
1016
1017   context = g_option_context_new (NULL);
1018   g_option_context_add_main_entries (context, entries, NULL);
1019
1020   /* Now try parsing */
1021   argv = split_string ("program --test", &argc);
1022
1023   retval = g_option_context_parse (context, &argc, &argv, &error);
1024   g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1025   g_assert (!retval);
1026   g_assert (string == NULL);
1027
1028   g_error_free (error);
1029   g_strfreev (argv);
1030   g_option_context_free (context);
1031 }
1032
1033 static GPtrArray *callback_remaining_args;
1034 static gboolean
1035 callback_remaining_test1_callback (const gchar *option_name, const gchar *value,
1036                          gpointer data, GError **error)
1037 {
1038         g_ptr_array_add (callback_remaining_args, g_strdup (value));
1039         return TRUE;
1040 }
1041
1042 static void
1043 callback_remaining_test1 (void)
1044 {
1045   GOptionContext *context;
1046   gboolean retval;
1047   GError *error = NULL;
1048   gchar **argv;
1049   int argc;
1050   GOptionEntry entries [] =
1051     { { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_CALLBACK, callback_remaining_test1_callback, NULL, NULL },
1052       { NULL } };
1053   
1054   callback_remaining_args = g_ptr_array_new ();
1055   context = g_option_context_new (NULL);
1056   g_option_context_add_main_entries (context, entries, NULL);
1057
1058   /* Now try parsing */
1059   argv = split_string ("program foo.txt blah.txt", &argc);
1060   
1061   retval = g_option_context_parse (context, &argc, &argv, &error);
1062   g_assert_no_error (error);
1063   g_assert (retval);
1064
1065   g_assert (callback_remaining_args->len == 2);
1066   g_assert (strcmp (callback_remaining_args->pdata[0], "foo.txt") == 0);
1067   g_assert (strcmp (callback_remaining_args->pdata[1], "blah.txt") == 0);
1068
1069   g_ptr_array_foreach (callback_remaining_args, (GFunc) g_free, NULL);
1070   g_ptr_array_free (callback_remaining_args, TRUE);
1071   
1072   g_strfreev (argv);
1073   g_option_context_free (context);
1074 }
1075
1076 static gboolean
1077 callback_error (const gchar *option_name, const gchar *value,
1078                 gpointer data, GError **error)
1079 {
1080   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "42");
1081   return FALSE;
1082 }
1083
1084 static void
1085 callback_returns_false (void)
1086 {
1087   GOptionContext *context;
1088   gboolean retval;
1089   GError *error = NULL;
1090   gchar **argv;
1091   int argc;
1092   GOptionEntry entries [] =
1093     { { "error", 0, 0, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1094       { "error-no-arg", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1095       { "error-optional-arg", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1096       { NULL } };
1097
1098   context = g_option_context_new (NULL);
1099   g_option_context_add_main_entries (context, entries, NULL);
1100
1101   /* Now try parsing */
1102   argv = split_string ("program --error value", &argc);
1103   
1104   retval = g_option_context_parse (context, &argc, &argv, &error);
1105   g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1106   g_assert (retval == FALSE);
1107
1108   g_option_context_free (context);
1109   g_clear_error (&error);
1110
1111   /* And again, this time with a no-arg variant */
1112   context = g_option_context_new (NULL);
1113   g_option_context_add_main_entries (context, entries, NULL);
1114
1115   argv = split_string ("program --error-no-arg", &argc);
1116   
1117   retval = g_option_context_parse (context, &argc, &argv, &error);
1118   g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1119   g_assert (retval == FALSE);
1120
1121   g_option_context_free (context);
1122   g_clear_error (&error);
1123
1124   /* And again, this time with a optional arg variant, with argument */
1125   context = g_option_context_new (NULL);
1126   g_option_context_add_main_entries (context, entries, NULL);
1127
1128   argv = split_string ("program --error-optional-arg value", &argc);
1129   
1130   retval = g_option_context_parse (context, &argc, &argv, &error);
1131   g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1132   g_assert (retval == FALSE);
1133
1134   g_option_context_free (context);
1135   g_clear_error (&error);
1136
1137   /* And again, this time with a optional arg variant, without argument */
1138   context = g_option_context_new (NULL);
1139   g_option_context_add_main_entries (context, entries, NULL);
1140
1141   argv = split_string ("program --error-optional-arg", &argc);
1142   
1143   retval = g_option_context_parse (context, &argc, &argv, &error);
1144   g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1145   g_assert (retval == FALSE);
1146
1147   g_option_context_free (context);
1148   g_clear_error (&error);
1149 }
1150
1151
1152 static void
1153 ignore_test1 (void)
1154 {
1155   GOptionContext *context;
1156   gboolean retval;
1157   GError *error = NULL;
1158   gchar **argv, **argv_copy;
1159   int argc;
1160   gchar *arg;
1161   GOptionEntry entries [] =
1162     { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1163       { NULL } };
1164
1165   context = g_option_context_new (NULL);
1166   g_option_context_set_ignore_unknown_options (context, TRUE);
1167   g_option_context_add_main_entries (context, entries, NULL);
1168
1169   /* Now try parsing */
1170   argv = split_string ("program --test --hello", &argc);
1171   argv_copy = copy_stringv (argv, argc);
1172   
1173   retval = g_option_context_parse (context, &argc, &argv, &error);
1174   g_assert_no_error (error);
1175   g_assert (retval);
1176
1177   /* Check array */
1178   arg = join_stringv (argc, argv);
1179   g_assert (strcmp (arg, "program --hello") == 0);
1180
1181   g_free (arg);
1182   g_strfreev (argv_copy);
1183   g_free (argv);
1184   g_option_context_free (context);
1185 }
1186
1187 static void
1188 ignore_test2 (void)
1189 {
1190   GOptionContext *context;
1191   gboolean retval;
1192   GError *error = NULL;
1193   gchar **argv;
1194   int argc;
1195   gchar *arg;
1196   GOptionEntry entries [] =
1197     { { "test", 't', 0, G_OPTION_ARG_NONE, &ignore_test2_boolean, NULL, NULL },
1198       { NULL } };
1199
1200   context = g_option_context_new (NULL);
1201   g_option_context_set_ignore_unknown_options (context, TRUE);
1202   g_option_context_add_main_entries (context, entries, NULL);
1203
1204   /* Now try parsing */
1205   argv = split_string ("program -test", &argc);
1206   
1207   retval = g_option_context_parse (context, &argc, &argv, &error);
1208   g_assert_no_error (error);
1209   g_assert (retval);
1210
1211   /* Check array */
1212   arg = join_stringv (argc, argv);
1213   g_assert (strcmp (arg, "program -es") == 0);
1214
1215   g_free (arg);
1216   g_strfreev (argv);
1217   g_option_context_free (context);
1218 }
1219
1220 static void
1221 ignore_test3 (void)
1222 {
1223   GOptionContext *context;
1224   gboolean retval;
1225   GError *error = NULL;
1226   gchar **argv, **argv_copy;
1227   int argc;
1228   gchar *arg;
1229   GOptionEntry entries [] =
1230     { { "test", 0, 0, G_OPTION_ARG_STRING, &ignore_test3_string, NULL, NULL },
1231       { NULL } };
1232
1233   context = g_option_context_new (NULL);
1234   g_option_context_set_ignore_unknown_options (context, TRUE);
1235   g_option_context_add_main_entries (context, entries, NULL);
1236
1237   /* Now try parsing */
1238   argv = split_string ("program --test foo --hello", &argc);
1239   argv_copy = copy_stringv (argv, argc);
1240   
1241   retval = g_option_context_parse (context, &argc, &argv, &error);
1242   g_assert_no_error (error);
1243   g_assert (retval);
1244
1245   /* Check array */
1246   arg = join_stringv (argc, argv);
1247   g_assert (strcmp (arg, "program --hello") == 0);
1248
1249   g_assert (strcmp (ignore_test3_string, "foo") == 0);
1250   g_free (ignore_test3_string);
1251
1252   g_free (arg);
1253   g_strfreev (argv_copy);
1254   g_free (argv);
1255   g_option_context_free (context);
1256 }
1257
1258 void
1259 static array_test1 (void)
1260 {
1261   GOptionContext *context;
1262   gboolean retval;
1263   GError *error = NULL;
1264   gchar **argv;
1265   int argc;
1266   GOptionEntry entries [] =
1267     { { "test", 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1268       { NULL } };
1269         
1270   context = g_option_context_new (NULL);
1271   g_option_context_add_main_entries (context, entries, NULL);
1272
1273   /* Now try parsing */
1274   argv = split_string ("program --test foo --test bar", &argc);
1275   
1276   retval = g_option_context_parse (context, &argc, &argv, &error);
1277   g_assert_no_error (error);
1278   g_assert (retval);
1279
1280   /* Check array */
1281   g_assert (strcmp (array_test1_array[0], "foo") == 0);
1282   g_assert (strcmp (array_test1_array[1], "bar") == 0);
1283   g_assert (array_test1_array[2] == NULL);
1284
1285   g_strfreev (array_test1_array);
1286   
1287   g_strfreev (argv);
1288   g_option_context_free (context);
1289 }
1290
1291 static void
1292 add_test1 (void)
1293 {
1294   GOptionContext *context;
1295
1296   GOptionEntry entries1 [] =
1297     { { "test1", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
1298       { NULL } };
1299   GOptionEntry entries2 [] =
1300     { { "test2", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
1301       { NULL } };
1302
1303   context = g_option_context_new (NULL);
1304   g_option_context_add_main_entries (context, entries1, NULL);
1305   g_option_context_add_main_entries (context, entries2, NULL);
1306
1307   g_option_context_free (context);
1308 }
1309
1310 static void
1311 empty_test2 (void)
1312 {
1313   GOptionContext *context;
1314
1315   context = g_option_context_new (NULL);
1316   g_option_context_parse (context, NULL, NULL, NULL);
1317   
1318   g_option_context_free (context);
1319 }
1320
1321 static void
1322 empty_test3 (void)
1323 {
1324   GOptionContext *context;
1325   gint argc;
1326   gchar **argv;
1327
1328   argc = 0;
1329   argv = NULL;
1330
1331   context = g_option_context_new (NULL);
1332   g_option_context_parse (context, &argc, &argv, NULL);
1333   
1334   g_option_context_free (context);
1335 }
1336
1337 /* check that non-option arguments are left in argv by default */
1338 static void
1339 rest_test1 (void)
1340 {
1341   GOptionContext *context;
1342   gboolean retval;
1343   GError *error = NULL;
1344   gchar **argv;
1345   int argc;
1346   GOptionEntry entries [] = { 
1347       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1348       { NULL } 
1349   };
1350         
1351   context = g_option_context_new (NULL);
1352   g_option_context_add_main_entries (context, entries, NULL);
1353
1354   /* Now try parsing */
1355   argv = split_string ("program foo --test bar", &argc);
1356   
1357   retval = g_option_context_parse (context, &argc, &argv, &error);
1358   g_assert_no_error (error);
1359   g_assert (retval);
1360
1361   /* Check array */
1362   g_assert (ignore_test1_boolean);
1363   g_assert (strcmp (argv[0], "program") == 0);
1364   g_assert (strcmp (argv[1], "foo") == 0);
1365   g_assert (strcmp (argv[2], "bar") == 0);
1366   g_assert (argv[3] == NULL);
1367
1368   g_strfreev (argv);
1369   g_option_context_free (context);
1370 }
1371
1372 /* check that -- works */
1373 static void
1374 rest_test2 (void)
1375 {
1376   GOptionContext *context;
1377   gboolean retval;
1378   GError *error = NULL;
1379   gchar **argv;
1380   int argc;
1381   GOptionEntry entries [] = { 
1382       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1383       { NULL } 
1384   };
1385         
1386   context = g_option_context_new (NULL);
1387   g_option_context_add_main_entries (context, entries, NULL);
1388
1389   /* Now try parsing */
1390   argv = split_string ("program foo --test -- -bar", &argc);
1391   
1392   retval = g_option_context_parse (context, &argc, &argv, &error);
1393   g_assert_no_error (error);
1394   g_assert (retval);
1395
1396   /* Check array */
1397   g_assert (ignore_test1_boolean);
1398   g_assert (strcmp (argv[0], "program") == 0);
1399   g_assert (strcmp (argv[1], "foo") == 0);
1400   g_assert (strcmp (argv[2], "--") == 0);
1401   g_assert (strcmp (argv[3], "-bar") == 0);
1402   g_assert (argv[4] == NULL);
1403
1404   g_strfreev (argv);
1405   g_option_context_free (context);
1406 }
1407
1408 /* check that -- stripping works */
1409 static void
1410 rest_test2a (void)
1411 {
1412   GOptionContext *context;
1413   gboolean retval;
1414   GError *error = NULL;
1415   gchar **argv;
1416   int argc;
1417   GOptionEntry entries [] = { 
1418       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1419       { NULL } 
1420   };
1421         
1422   context = g_option_context_new (NULL);
1423   g_option_context_add_main_entries (context, entries, NULL);
1424
1425   /* Now try parsing */
1426   argv = split_string ("program foo --test -- bar", &argc);
1427   
1428   retval = g_option_context_parse (context, &argc, &argv, &error);
1429   g_assert_no_error (error);
1430   g_assert (retval);
1431
1432   /* Check array */
1433   g_assert (ignore_test1_boolean);
1434   g_assert (strcmp (argv[0], "program") == 0);
1435   g_assert (strcmp (argv[1], "foo") == 0);
1436   g_assert (strcmp (argv[2], "bar") == 0);
1437   g_assert (argv[3] == NULL);
1438
1439   g_strfreev (argv);
1440   g_option_context_free (context);
1441 }
1442
1443 static void
1444 rest_test2b (void)
1445 {
1446   GOptionContext *context;
1447   gboolean retval;
1448   GError *error = NULL;
1449   gchar **argv;
1450   int argc;
1451   GOptionEntry entries [] = { 
1452       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1453       { NULL } 
1454   };
1455         
1456   context = g_option_context_new (NULL);
1457   g_option_context_set_ignore_unknown_options (context, TRUE);
1458   g_option_context_add_main_entries (context, entries, NULL);
1459
1460   /* Now try parsing */
1461   argv = split_string ("program foo --test -bar --", &argc);
1462   
1463   retval = g_option_context_parse (context, &argc, &argv, &error);
1464   g_assert_no_error (error);
1465   g_assert (retval);
1466
1467   /* Check array */
1468   g_assert (ignore_test1_boolean);
1469   g_assert (strcmp (argv[0], "program") == 0);
1470   g_assert (strcmp (argv[1], "foo") == 0);
1471   g_assert (strcmp (argv[2], "-bar") == 0);
1472   g_assert (argv[3] == NULL);
1473
1474   g_strfreev (argv);
1475   g_option_context_free (context);
1476 }
1477
1478 static void
1479 rest_test2c (void)
1480 {
1481   GOptionContext *context;
1482   gboolean retval;
1483   GError *error = NULL;
1484   gchar **argv;
1485   int argc;
1486   GOptionEntry entries [] = { 
1487       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1488       { NULL } 
1489   };
1490         
1491   context = g_option_context_new (NULL);
1492   g_option_context_add_main_entries (context, entries, NULL);
1493
1494   /* Now try parsing */
1495   argv = split_string ("program --test foo -- bar", &argc);
1496   
1497   retval = g_option_context_parse (context, &argc, &argv, &error);
1498   g_assert_no_error (error);
1499   g_assert (retval);
1500
1501   /* Check array */
1502   g_assert (ignore_test1_boolean);
1503   g_assert (strcmp (argv[0], "program") == 0);
1504   g_assert (strcmp (argv[1], "foo") == 0);
1505   g_assert (strcmp (argv[2], "bar") == 0);
1506   g_assert (argv[3] == NULL);
1507
1508   g_strfreev (argv);
1509   g_option_context_free (context);
1510 }
1511
1512 static void
1513 rest_test2d (void)
1514 {
1515   GOptionContext *context;
1516   gboolean retval;
1517   GError *error = NULL;
1518   gchar **argv;
1519   int argc;
1520   GOptionEntry entries [] = { 
1521       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1522       { NULL } 
1523   };
1524         
1525   context = g_option_context_new (NULL);
1526   g_option_context_add_main_entries (context, entries, NULL);
1527
1528   /* Now try parsing */
1529   argv = split_string ("program --test -- -bar", &argc);
1530   
1531   retval = g_option_context_parse (context, &argc, &argv, &error);
1532   g_assert_no_error (error);
1533   g_assert (retval);
1534
1535   /* Check array */
1536   g_assert (ignore_test1_boolean);
1537   g_assert (strcmp (argv[0], "program") == 0);
1538   g_assert (strcmp (argv[1], "--") == 0);
1539   g_assert (strcmp (argv[2], "-bar") == 0);
1540   g_assert (argv[3] == NULL);
1541
1542   g_strfreev (argv);
1543   g_option_context_free (context);
1544 }
1545
1546
1547 /* check that G_OPTION_REMAINING collects non-option arguments */
1548 static void
1549 rest_test3 (void)
1550 {
1551   GOptionContext *context;
1552   gboolean retval;
1553   GError *error = NULL;
1554   gchar **argv;
1555   int argc;
1556   GOptionEntry entries [] = { 
1557       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1558       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1559       { NULL } 
1560   };
1561         
1562   context = g_option_context_new (NULL);
1563   g_option_context_add_main_entries (context, entries, NULL);
1564
1565   /* Now try parsing */
1566   argv = split_string ("program foo --test bar", &argc);
1567   
1568   retval = g_option_context_parse (context, &argc, &argv, &error);
1569   g_assert_no_error (error);
1570   g_assert (retval);
1571
1572   /* Check array */
1573   g_assert (ignore_test1_boolean);
1574   g_assert (strcmp (array_test1_array[0], "foo") == 0);
1575   g_assert (strcmp (array_test1_array[1], "bar") == 0);
1576   g_assert (array_test1_array[2] == NULL);
1577
1578   g_strfreev (array_test1_array);
1579   
1580   g_strfreev (argv);
1581   g_option_context_free (context);
1582 }
1583
1584
1585 /* check that G_OPTION_REMAINING and -- work together */
1586 static void
1587 rest_test4 (void)
1588 {
1589   GOptionContext *context;
1590   gboolean retval;
1591   GError *error = NULL;
1592   gchar **argv;
1593   int argc;
1594   GOptionEntry entries [] = { 
1595       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1596       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1597       { NULL } 
1598   };
1599         
1600   context = g_option_context_new (NULL);
1601   g_option_context_add_main_entries (context, entries, NULL);
1602
1603   /* Now try parsing */
1604   argv = split_string ("program foo --test -- -bar", &argc);
1605   
1606   retval = g_option_context_parse (context, &argc, &argv, &error);
1607   g_assert_no_error (error);
1608   g_assert (retval);
1609
1610   /* Check array */
1611   g_assert (ignore_test1_boolean);
1612   g_assert (strcmp (array_test1_array[0], "foo") == 0);
1613   g_assert (strcmp (array_test1_array[1], "-bar") == 0);
1614   g_assert (array_test1_array[2] == NULL);
1615
1616   g_strfreev (array_test1_array);
1617   
1618   g_strfreev (argv);
1619   g_option_context_free (context);
1620 }
1621
1622 /* test that G_OPTION_REMAINING works with G_OPTION_ARG_FILENAME_ARRAY */
1623 static void
1624 rest_test5 (void)
1625 {
1626   GOptionContext *context;
1627   gboolean retval;
1628   GError *error = NULL;
1629   gchar **argv;
1630   int argc;
1631   GOptionEntry entries [] = { 
1632       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1633       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &array_test1_array, NULL, NULL },
1634       { NULL } 
1635   };
1636         
1637   context = g_option_context_new (NULL);
1638   g_option_context_add_main_entries (context, entries, NULL);
1639
1640   /* Now try parsing */
1641   argv = split_string ("program foo --test bar", &argc);
1642   
1643   retval = g_option_context_parse (context, &argc, &argv, &error);
1644   g_assert_no_error (error);
1645   g_assert (retval);
1646
1647   /* Check array */
1648   g_assert (ignore_test1_boolean);
1649   g_assert (strcmp (array_test1_array[0], "foo") == 0);
1650   g_assert (strcmp (array_test1_array[1], "bar") == 0);
1651   g_assert (array_test1_array[2] == NULL);
1652
1653   g_strfreev (array_test1_array);
1654   
1655   g_strfreev (argv);
1656   g_option_context_free (context);
1657 }
1658
1659 static void
1660 unknown_short_test (void)
1661 {
1662   GOptionContext *context;
1663   gboolean retval;
1664   GError *error = NULL;
1665   gchar **argv;
1666   int argc;
1667   GOptionEntry entries [] = { { NULL } };
1668
1669   g_test_bug ("166609");
1670
1671   context = g_option_context_new (NULL);
1672   g_option_context_add_main_entries (context, entries, NULL);
1673
1674   /* Now try parsing */
1675   argv = split_string ("program -0", &argc);
1676
1677   retval = g_option_context_parse (context, &argc, &argv, &error);
1678   g_assert (!retval);
1679
1680   g_strfreev (argv);
1681   g_option_context_free (context);
1682 }
1683
1684 /* test that lone dashes are treated as non-options */
1685 static void
1686 lonely_dash_test (void)
1687 {
1688   GOptionContext *context;
1689   gboolean retval;
1690   GError *error = NULL;
1691   gchar **argv;
1692   int argc;
1693
1694   g_test_bug ("168008");
1695
1696   context = g_option_context_new (NULL);
1697
1698   /* Now try parsing */
1699   argv = split_string ("program -", &argc);
1700
1701   retval = g_option_context_parse (context, &argc, &argv, &error);
1702   g_assert_no_error (error);
1703   g_assert (retval);
1704
1705   g_assert (argv[1] && strcmp (argv[1], "-") == 0);
1706
1707   g_strfreev (argv);
1708   g_option_context_free (context);
1709 }
1710
1711 static void
1712 missing_arg_test (void)
1713 {
1714   GOptionContext *context;
1715   gboolean retval;
1716   GError *error = NULL;
1717   gchar **argv;
1718   int argc;
1719   gchar *arg = NULL;
1720   GOptionEntry entries [] =
1721     { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1722       { NULL } };
1723
1724   g_test_bug ("305576");
1725
1726   context = g_option_context_new (NULL);
1727   g_option_context_add_main_entries (context, entries, NULL);
1728
1729   /* Now try parsing */
1730   argv = split_string ("program --test", &argc);
1731
1732   retval = g_option_context_parse (context, &argc, &argv, &error);
1733   g_assert (retval == FALSE);
1734   g_clear_error (&error);
1735
1736   g_strfreev (argv);
1737
1738   /* Try parsing again */
1739   argv = split_string ("program -t", &argc);
1740
1741   retval = g_option_context_parse (context, &argc, &argv, &error);
1742   g_assert (retval == FALSE);
1743
1744   g_strfreev (argv);
1745   g_option_context_free (context);
1746 }
1747
1748 static gchar *test_arg;
1749
1750 static gboolean cb (const gchar  *option_name,
1751                     const gchar  *value,
1752                     gpointer      data,
1753                     GError      **error)
1754 {
1755   test_arg = g_strdup (value);
1756   return TRUE;
1757 }
1758
1759 static void
1760 dash_arg_test (void)
1761 {
1762   GOptionContext *context;
1763   gboolean retval;
1764   GError *error = NULL;
1765   gchar **argv;
1766   int argc;
1767   gboolean argb = FALSE;
1768   GOptionEntry entries [] =
1769     { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, cb, NULL, NULL },
1770       { "three", '3', 0, G_OPTION_ARG_NONE, &argb, NULL, NULL },
1771       { NULL } };
1772
1773   g_test_bug ("577638");
1774
1775   context = g_option_context_new (NULL);
1776   g_option_context_add_main_entries (context, entries, NULL);
1777
1778   /* Now try parsing */
1779   argv = split_string ("program --test=-3", &argc);
1780
1781   test_arg = NULL;
1782   error = NULL;
1783   retval = g_option_context_parse (context, &argc, &argv, &error);
1784   g_assert (retval);
1785   g_assert_no_error (error);
1786   g_assert_cmpstr (test_arg, ==, "-3");
1787
1788   g_strfreev (argv);
1789   g_free (test_arg);
1790   test_arg = NULL;
1791
1792   /* Try parsing again */
1793   argv = split_string ("program --test -3", &argc);
1794
1795   error = NULL;
1796   retval = g_option_context_parse (context, &argc, &argv, &error);
1797   g_assert_no_error (error);
1798   g_assert (retval);
1799   g_assert_cmpstr (test_arg, ==, NULL);
1800
1801   g_option_context_free (context);
1802 }
1803
1804 static void
1805 test_basic (void)
1806 {
1807   GOptionContext *context;
1808   gchar *arg = NULL;
1809   GOptionEntry entries [] =
1810     { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1811       { NULL } };
1812
1813   context = g_option_context_new (NULL);
1814   g_option_context_add_main_entries (context, entries, NULL);
1815
1816   g_assert (g_option_context_get_help_enabled (context));
1817   g_assert (!g_option_context_get_ignore_unknown_options (context));
1818   g_assert_cmpstr (g_option_context_get_summary (context), ==, NULL);
1819   g_assert_cmpstr (g_option_context_get_description (context), ==, NULL);
1820
1821   g_option_context_set_help_enabled (context, FALSE);
1822   g_option_context_set_ignore_unknown_options (context, TRUE);
1823   g_option_context_set_summary (context, "summary");
1824   g_option_context_set_description(context, "description");
1825
1826   g_assert (!g_option_context_get_help_enabled (context));
1827   g_assert (g_option_context_get_ignore_unknown_options (context));
1828   g_assert_cmpstr (g_option_context_get_summary (context), ==, "summary");
1829   g_assert_cmpstr (g_option_context_get_description (context), ==, "description");
1830
1831   g_option_context_free (context);
1832 }
1833
1834 static void
1835 test_main_group (void)
1836 {
1837   GOptionContext *context;
1838   GOptionGroup *group;
1839
1840   context = g_option_context_new (NULL);
1841   g_assert (g_option_context_get_main_group (context) == NULL);
1842   group = g_option_group_new ("name", "description", "hlep", NULL, NULL);
1843   g_option_context_add_group (context, group);
1844   g_assert (g_option_context_get_main_group (context) == NULL);
1845   group = g_option_group_new ("name", "description", "hlep", NULL, NULL);
1846   g_option_context_set_main_group (context, group);
1847   g_assert (g_option_context_get_main_group (context) == group);
1848
1849   g_option_context_free (context);
1850 }
1851
1852 static gboolean error_func_called = FALSE;
1853
1854 static void
1855 error_func (GOptionContext  *context,
1856             GOptionGroup    *group,
1857             gpointer         data,
1858             GError         **error)
1859 {
1860   g_assert_cmpint (GPOINTER_TO_INT(data), ==, 1234);
1861   error_func_called = TRUE;
1862 }
1863
1864 static void
1865 test_error_hook (void)
1866 {
1867   GOptionContext *context;
1868   gchar *arg = NULL;
1869   GOptionEntry entries [] =
1870     { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1871       { NULL } };
1872   GOptionGroup *group;
1873   gchar **argv;
1874   gint argc;
1875   gboolean retval;
1876   GError *error = NULL;
1877
1878   context = g_option_context_new (NULL);
1879   group = g_option_group_new ("name", "description", "hlep", GINT_TO_POINTER(1234), NULL);
1880   g_option_group_add_entries (group, entries);
1881   g_option_context_set_main_group (context, group);
1882   g_option_group_set_error_hook (g_option_context_get_main_group (context),
1883                                  error_func);
1884
1885   argv = split_string ("program --test", &argc);
1886
1887   retval = g_option_context_parse (context, &argc, &argv, &error);
1888   g_assert (retval == FALSE);
1889   g_clear_error (&error);
1890
1891   g_assert (error_func_called);
1892
1893   g_strfreev (argv);
1894   g_option_context_free (context);
1895 }
1896
1897 static void
1898 flag_reverse_string (void)
1899 {
1900   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1901     {
1902       GOptionContext *context;
1903       gchar *arg = NULL;
1904       GOptionEntry entries [] =
1905         { { "test", 't', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1906           { NULL } };
1907       gchar **argv;
1908       gint argc;
1909       gboolean retval;
1910       GError *error = NULL;
1911
1912       context = g_option_context_new (NULL);
1913       g_option_context_add_main_entries (context, entries, NULL);
1914
1915       argv = split_string ("program --test bla", &argc);
1916
1917       retval = g_option_context_parse (context, &argc, &argv, &error);
1918       g_assert (retval == FALSE);
1919       g_clear_error (&error);
1920       g_strfreev (argv);
1921       g_option_context_free (context);
1922       exit (0);
1923     }
1924   g_test_trap_assert_failed ();
1925   g_test_trap_assert_stderr ("*ignoring reverse flag*");
1926 }
1927
1928 static void
1929 flag_optional_int (void)
1930 {
1931   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
1932     {
1933       GOptionContext *context;
1934       gint arg = 0;
1935       GOptionEntry entries [] =
1936         { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &arg, NULL, NULL },
1937           { NULL } };
1938       gchar **argv;
1939       gint argc;
1940       gboolean retval;
1941       GError *error = NULL;
1942
1943       context = g_option_context_new (NULL);
1944       g_option_context_add_main_entries (context, entries, NULL);
1945
1946       argv = split_string ("program --test 5", &argc);
1947
1948       retval = g_option_context_parse (context, &argc, &argv, &error);
1949       g_assert (retval == FALSE);
1950       g_clear_error (&error);
1951       g_strfreev (argv);
1952       g_option_context_free (context);
1953       exit (0);
1954     }
1955   g_test_trap_assert_failed ();
1956   g_test_trap_assert_stderr ("*ignoring no-arg, optional-arg or filename flags*");
1957 }
1958 int
1959 main (int   argc,
1960       char *argv[])
1961 {
1962   g_test_init (&argc, &argv, NULL);
1963
1964   g_test_bug_base ("http://bugzilla.gnome.org/");
1965
1966   g_test_add_func ("/option/basic", test_basic);
1967   g_test_add_func ("/option/group/captions", group_captions);
1968   g_test_add_func ("/option/group/main", test_main_group);
1969   g_test_add_func ("/option/group/error-hook", test_error_hook);
1970
1971   /* Test that restoration on failure works */
1972   g_test_add_func ("/option/restoration/int", error_test1);
1973   g_test_add_func ("/option/restoration/string", error_test2);
1974   g_test_add_func ("/option/restoration/boolean", error_test3);
1975
1976   /* Test that special argument parsing works */
1977   g_test_add_func ("/option/arg/repetition/int", arg_test1);
1978   g_test_add_func ("/option/arg/repetition/string", arg_test2);
1979   g_test_add_func ("/option/arg/repetition/filename", arg_test3);
1980   g_test_add_func ("/option/arg/repetition/double", arg_test4);
1981   g_test_add_func ("/option/arg/repetition/locale", arg_test5);
1982   g_test_add_func ("/option/arg/repetition/int64", arg_test6);
1983
1984   /* Test string arrays */
1985   g_test_add_func ("/option/arg/array/string", array_test1);
1986
1987   /* Test callback args */
1988   g_test_add_func ("/option/arg/callback/string", callback_test1);
1989   g_test_add_func ("/option/arg/callback/count", callback_test2);
1990
1991   /* Test optional arg flag for callback */
1992   g_test_add_func ("/option/arg/callback/optional1", callback_test_optional_1);
1993   g_test_add_func ("/option/arg/callback/optional2", callback_test_optional_2);
1994   g_test_add_func ("/option/arg/callback/optional3", callback_test_optional_3);
1995   g_test_add_func ("/option/arg/callback/optional4", callback_test_optional_4);
1996   g_test_add_func ("/option/arg/callback/optional5", callback_test_optional_5);
1997   g_test_add_func ("/option/arg/callback/optional6", callback_test_optional_6);
1998   g_test_add_func ("/option/arg/callback/optional7", callback_test_optional_7);
1999   g_test_add_func ("/option/arg/callback/optional8", callback_test_optional_8);
2000
2001   /* Test callback with G_OPTION_REMAINING */
2002   g_test_add_func ("/option/arg/remaining/callback", callback_remaining_test1);
2003
2004   /* Test callbacks which return FALSE */
2005   g_test_add_func ("/option/arg/remaining/callback-false", callback_returns_false);
2006
2007   /* Test ignoring options */
2008   g_test_add_func ("/option/arg/ignore/long", ignore_test1);
2009   g_test_add_func ("/option/arg/ignore/short", ignore_test2);
2010   g_test_add_func ("/option/arg/ignore/arg", ignore_test3);
2011   g_test_add_func ("/option/context/add", add_test1);
2012
2013   /* Test parsing empty args */
2014   /* Note there used to be an empty1 here, but it effectively moved
2015    * to option-argv0.c.
2016    */
2017   g_test_add_func ("/option/context/empty2", empty_test2);
2018   g_test_add_func ("/option/context/empty3", empty_test3);
2019
2020   /* Test handling of rest args */
2021   g_test_add_func ("/option/arg/rest/non-option", rest_test1);
2022   g_test_add_func ("/option/arg/rest/separator1", rest_test2);
2023   g_test_add_func ("/option/arg/rest/separator2", rest_test2a);
2024   g_test_add_func ("/option/arg/rest/separator3", rest_test2b);
2025   g_test_add_func ("/option/arg/rest/separator4", rest_test2c);
2026   g_test_add_func ("/option/arg/rest/separator5", rest_test2d);
2027   g_test_add_func ("/option/arg/remaining/non-option", rest_test3);
2028   g_test_add_func ("/option/arg/remaining/separator", rest_test4);
2029   g_test_add_func ("/option/arg/remaining/array", rest_test5);
2030
2031   /* Test some invalid flag combinations */
2032   g_test_add_func ("/option/arg/reverse-string", flag_reverse_string);
2033   g_test_add_func ("/option/arg/optional-int", flag_optional_int);
2034
2035   /* regression tests for individual bugs */
2036   g_test_add_func ("/option/bug/unknown-short", unknown_short_test);
2037   g_test_add_func ("/option/bug/lonely-dash", lonely_dash_test);
2038   g_test_add_func ("/option/bug/missing-arg", missing_arg_test);
2039   g_test_add_func ("/option/bug/dash-arg", dash_arg_test);
2040
2041   return g_test_run();
2042 }