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