initialize automake variables EXTRA_DIST and TEST_PROGS for unconditional
[platform/upstream/glib.git] / tests / option-test.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <locale.h>
4 #include <glib.h>
5
6 int error_test1_int;
7 char *error_test2_string;
8 gboolean error_test3_boolean;
9
10 int arg_test1_int;
11 gchar *arg_test2_string;
12 gchar *arg_test3_filename;
13 gdouble arg_test4_double;
14 gdouble arg_test5_double;
15 gint64 arg_test6_int64;
16 gint64 arg_test6_int64_2;
17
18 gchar *callback_test1_string;
19 int callback_test2_int;
20
21 gchar *callback_test_optional_string;
22 gboolean callback_test_optional_boolean;
23
24 gchar **array_test1_array;
25
26 gboolean ignore_test1_boolean;
27 gboolean ignore_test2_boolean;
28 gchar *ignore_test3_string;
29
30 gchar **
31 split_string (const char *str, int *argc)
32 {
33   gchar **argv;
34   int len;
35   
36   argv = g_strsplit (str, " ", 0);
37
38   for (len = 0; argv[len] != NULL; len++);
39
40   if (argc)
41     *argc = len;
42     
43   return argv;
44 }
45
46 gchar *
47 join_stringv (int argc, char **argv)
48 {
49   int i;
50   GString *str;
51
52   str = g_string_new (NULL);
53
54   for (i = 0; i < argc; i++)
55     {
56       g_string_append (str, argv[i]);
57
58       if (i < argc - 1)
59         g_string_append_c (str, ' ');
60     }
61
62   return g_string_free (str, FALSE);
63 }
64
65 /* Performs a shallow copy */
66 char **
67 copy_stringv (char **argv, int argc)
68 {
69   return g_memdup (argv, sizeof (char *) * (argc + 1));
70 }
71
72
73 static gboolean
74 error_test1_pre_parse (GOptionContext *context,
75                        GOptionGroup   *group,
76                        gpointer        data,
77                        GError        **error)
78 {
79   g_assert (error_test1_int == 0x12345678);
80
81   return TRUE;
82 }
83
84 static gboolean
85 error_test1_post_parse (GOptionContext *context,
86                         GOptionGroup   *group,
87                         gpointer          data,
88                         GError        **error)
89 {
90   g_assert (error_test1_int == 20);
91
92   /* Set an error in the post hook */
93   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "");
94
95   return FALSE;
96 }
97
98 void
99 error_test1 (void)
100 {
101   GOptionContext *context;
102   gboolean retval;
103   GError *error = NULL;
104   gchar **argv;
105   int argc;
106   GOptionGroup *main_group;
107   GOptionEntry entries [] =
108     { { "test", 0, 0, G_OPTION_ARG_INT, &error_test1_int, NULL, NULL },
109       { NULL } };
110   
111   context = g_option_context_new (NULL);
112   g_option_context_add_main_entries (context, entries, NULL);
113
114   /* Set pre and post parse hooks */
115   main_group = g_option_context_get_main_group (context);
116   g_option_group_set_parse_hooks (main_group,
117                                   error_test1_pre_parse, error_test1_post_parse);
118   
119   /* Now try parsing */
120   argv = split_string ("program --test 20", &argc);
121
122   retval = g_option_context_parse (context, &argc, &argv, &error);
123   g_assert (retval == FALSE);
124
125   /* On failure, values should be reset */
126   g_assert (error_test1_int == 0x12345678);
127   
128   g_strfreev (argv);
129   g_option_context_free (context);
130   
131 }
132
133 static gboolean
134 error_test2_pre_parse (GOptionContext *context,
135                        GOptionGroup   *group,
136                        gpointer   data,
137                        GError        **error)
138 {
139   g_assert (strcmp (error_test2_string, "foo") == 0);
140
141   return TRUE;
142 }
143
144 static gboolean
145 error_test2_post_parse (GOptionContext *context,
146                         GOptionGroup   *group,
147                         gpointer          data,
148                         GError        **error)
149 {
150   g_assert (strcmp (error_test2_string, "bar") == 0);
151
152   /* Set an error in the post hook */
153   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "");
154
155   return FALSE;
156 }
157
158 void
159 error_test2 (void)
160 {
161   GOptionContext *context;
162   gboolean retval;
163   GError *error = NULL;
164   gchar **argv;
165   int argc;
166   GOptionGroup *main_group;
167   GOptionEntry entries [] =
168     { { "test", 0, 0, G_OPTION_ARG_STRING, &error_test2_string, NULL, NULL },
169       { NULL } };
170
171   context = g_option_context_new (NULL);
172   g_option_context_add_main_entries (context, entries, NULL);
173
174   /* Set pre and post parse hooks */
175   main_group = g_option_context_get_main_group (context);
176   g_option_group_set_parse_hooks (main_group,
177                                   error_test2_pre_parse, error_test2_post_parse);
178   
179   /* Now try parsing */
180   argv = split_string ("program --test bar", &argc);
181   retval = g_option_context_parse (context, &argc, &argv, &error);
182
183   g_error_free (error);
184   g_assert (retval == FALSE);
185
186   g_assert (strcmp (error_test2_string, "foo") == 0);
187   
188   g_strfreev (argv);
189   g_option_context_free (context);
190 }
191
192 static gboolean
193 error_test3_pre_parse (GOptionContext *context,
194                        GOptionGroup   *group,
195                        gpointer   data,
196                        GError        **error)
197 {
198   g_assert (!error_test3_boolean);
199
200   return TRUE;
201 }
202
203 static gboolean
204 error_test3_post_parse (GOptionContext *context,
205                         GOptionGroup   *group,
206                         gpointer          data,
207                         GError        **error)
208 {
209   g_assert (error_test3_boolean);
210
211   /* Set an error in the post hook */
212   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "");
213
214   return FALSE;
215 }
216
217 void
218 error_test3 (void)
219 {
220   GOptionContext *context;
221   gboolean retval;
222   GError *error = NULL;
223   gchar **argv;
224   int argc;
225   GOptionGroup *main_group;
226   GOptionEntry entries [] =
227     { { "test", 0, 0, G_OPTION_ARG_NONE, &error_test3_boolean, NULL, NULL },
228       { NULL } };
229
230   context = g_option_context_new (NULL);
231   g_option_context_add_main_entries (context, entries, NULL);
232
233   /* Set pre and post parse hooks */
234   main_group = g_option_context_get_main_group (context);
235   g_option_group_set_parse_hooks (main_group,
236                                   error_test3_pre_parse, error_test3_post_parse);
237   
238   /* Now try parsing */
239   argv = split_string ("program --test", &argc);
240   retval = g_option_context_parse (context, &argc, &argv, &error);
241
242   g_error_free (error);
243   g_assert (retval == FALSE);
244
245   g_assert (!error_test3_boolean);
246   
247   g_strfreev (argv);
248   g_option_context_free (context);
249 }
250
251 void
252 arg_test1 (void)
253 {
254   GOptionContext *context;
255   gboolean retval;
256   GError *error = NULL;
257   gchar **argv;
258   int argc;
259   GOptionEntry entries [] =
260     { { "test", 0, 0, G_OPTION_ARG_INT, &arg_test1_int, NULL, NULL },
261       { NULL } };
262
263   context = g_option_context_new (NULL);
264   g_option_context_add_main_entries (context, entries, NULL);
265
266   /* Now try parsing */
267   argv = split_string ("program --test 20 --test 30", &argc);
268
269   retval = g_option_context_parse (context, &argc, &argv, &error);
270   g_assert (retval);
271
272   /* Last arg specified is the one that should be stored */
273   g_assert (arg_test1_int == 30);
274
275   g_strfreev (argv);
276   g_option_context_free (context);
277 }
278
279 void
280 arg_test2 (void)
281 {
282   GOptionContext *context;
283   gboolean retval;
284   GError *error = NULL;
285   gchar **argv;
286   int argc;
287   GOptionEntry entries [] =
288     { { "test", 0, 0, G_OPTION_ARG_STRING, &arg_test2_string, NULL, NULL },
289       { NULL } };
290   
291   context = g_option_context_new (NULL);
292   g_option_context_add_main_entries (context, entries, NULL);
293
294   /* Now try parsing */
295   argv = split_string ("program --test foo --test bar", &argc);
296   
297   retval = g_option_context_parse (context, &argc, &argv, &error);
298   g_assert (retval);
299
300   /* Last arg specified is the one that should be stored */
301   g_assert (strcmp (arg_test2_string, "bar") == 0);
302
303   g_free (arg_test2_string);
304   
305   g_strfreev (argv);
306   g_option_context_free (context);
307 }
308
309 void
310 arg_test3 (void)
311 {
312   GOptionContext *context;
313   gboolean retval;
314   GError *error = NULL;
315   gchar **argv;
316   int argc;
317   GOptionEntry entries [] =
318     { { "test", 0, 0, G_OPTION_ARG_FILENAME, &arg_test3_filename, NULL, NULL },
319       { NULL } };
320   
321   context = g_option_context_new (NULL);
322   g_option_context_add_main_entries (context, entries, NULL);
323
324   /* Now try parsing */
325   argv = split_string ("program --test foo.txt", &argc);
326   
327   retval = g_option_context_parse (context, &argc, &argv, &error);
328   g_assert (retval);
329
330   /* Last arg specified is the one that should be stored */
331   g_assert (strcmp (arg_test3_filename, "foo.txt") == 0);
332
333   g_free (arg_test3_filename);
334   
335   g_strfreev (argv);
336   g_option_context_free (context);
337 }
338
339
340 void
341 arg_test4 (void)
342 {
343   GOptionContext *context;
344   gboolean retval;
345   GError *error = NULL;
346   gchar **argv;
347   int argc;
348   GOptionEntry entries [] =
349     { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test4_double, NULL, NULL },
350       { NULL } };
351
352   context = g_option_context_new (NULL);
353   g_option_context_add_main_entries (context, entries, NULL);
354
355   /* Now try parsing */
356   argv = split_string ("program --test 20.0 --test 30.03", &argc);
357
358   retval = g_option_context_parse (context, &argc, &argv, &error);
359   g_assert (retval);
360
361   /* Last arg specified is the one that should be stored */
362   g_assert (arg_test4_double == 30.03);
363
364   g_strfreev (argv);
365   g_option_context_free (context);
366 }
367
368 void
369 arg_test5 (void)
370 {
371   GOptionContext *context;
372   gboolean retval;
373   GError *error = NULL;
374   gchar **argv;
375   int argc;
376   char *old_locale, *current_locale;
377   const char *locale = "de_DE";
378   GOptionEntry entries [] =
379     { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test5_double, NULL, NULL },
380       { NULL } };
381
382   context = g_option_context_new (NULL);
383   g_option_context_add_main_entries (context, entries, NULL);
384
385   /* Now try parsing */
386   argv = split_string ("program --test 20,0 --test 30,03", &argc);
387
388   /* set it to some locale that uses commas instead of decimal points */
389   
390   old_locale = g_strdup (setlocale (LC_NUMERIC, locale));
391   current_locale = setlocale (LC_NUMERIC, NULL);
392   if (strcmp (current_locale, locale) != 0)
393     {
394       fprintf (stderr, "Cannot set locale to %s, skipping\n", locale);
395       goto cleanup; 
396     }
397
398   retval = g_option_context_parse (context, &argc, &argv, &error);
399   g_assert (retval);
400
401   /* Last arg specified is the one that should be stored */
402   g_assert (arg_test5_double == 30.03);
403
404  cleanup:
405   setlocale (LC_NUMERIC, old_locale);
406   g_free (old_locale);
407
408   g_strfreev (argv);
409   g_option_context_free (context);
410 }
411
412 void
413 arg_test6 (void)
414 {
415   GOptionContext *context;
416   gboolean retval;
417   GError *error = NULL;
418   gchar **argv;
419   int argc;
420   GOptionEntry entries [] =
421     { { "test", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64, NULL, NULL },
422       { "test2", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64_2, NULL, NULL },
423       { NULL } };
424
425   context = g_option_context_new (NULL);
426   g_option_context_add_main_entries (context, entries, NULL);
427
428   /* Now try parsing */
429   argv = split_string ("program --test 4294967297 --test 4294967296 --test2 0xfffffffff", &argc);
430
431   retval = g_option_context_parse (context, &argc, &argv, &error);
432   g_assert (retval);
433
434   /* Last arg specified is the one that should be stored */
435   g_assert (arg_test6_int64 == G_GINT64_CONSTANT(4294967296));
436   g_assert (arg_test6_int64_2 == G_GINT64_CONSTANT(0xfffffffff));
437
438   g_strfreev (argv);
439   g_option_context_free (context);
440 }
441
442 static gboolean
443 callback_parse1 (const gchar *option_name, const gchar *value,
444                  gpointer data, GError **error)
445 {
446         callback_test1_string = g_strdup (value);
447         return TRUE;
448 }
449
450 void
451 callback_test1 (void)
452 {
453   GOptionContext *context;
454   gboolean retval;
455   GError *error = NULL;
456   gchar **argv;
457   int argc;
458   GOptionEntry entries [] =
459     { { "test", 0, 0, G_OPTION_ARG_CALLBACK, callback_parse1, NULL, NULL },
460       { NULL } };
461   
462   context = g_option_context_new (NULL);
463   g_option_context_add_main_entries (context, entries, NULL);
464
465   /* Now try parsing */
466   argv = split_string ("program --test foo.txt", &argc);
467   
468   retval = g_option_context_parse (context, &argc, &argv, &error);
469   g_assert (retval);
470
471   g_assert (strcmp (callback_test1_string, "foo.txt") == 0);
472
473   g_free (callback_test1_string);
474   
475   g_strfreev (argv);
476   g_option_context_free (context);
477 }
478
479 static gboolean
480 callback_parse2 (const gchar *option_name, const gchar *value,
481                  gpointer data, GError **error)
482 {
483         callback_test2_int++;
484         return TRUE;
485 }
486
487 void
488 callback_test2 (void)
489 {
490   GOptionContext *context;
491   gboolean retval;
492   GError *error = NULL;
493   gchar **argv;
494   int argc;
495   GOptionEntry entries [] =
496     { { "test", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_parse2, NULL, NULL },
497       { NULL } };
498   
499   context = g_option_context_new (NULL);
500   g_option_context_add_main_entries (context, entries, NULL);
501
502   /* Now try parsing */
503   argv = split_string ("program --test --test", &argc);
504   
505   retval = g_option_context_parse (context, &argc, &argv, &error);
506   g_assert (retval);
507
508   g_assert (callback_test2_int == 2);
509   
510   g_strfreev (argv);
511   g_option_context_free (context);
512 }
513
514 static gboolean
515 callback_parse_optional (const gchar *option_name, const gchar *value,
516                  gpointer data, GError **error)
517 {
518         callback_test_optional_boolean = TRUE;
519         if (value)
520                 callback_test_optional_string = g_strdup (value);
521         else
522                 callback_test_optional_string = NULL;
523         return TRUE;
524 }
525
526 void
527 callback_test_optional_1 (void)
528 {
529   GOptionContext *context;
530   gboolean retval;
531   GError *error = NULL;
532   gchar **argv;
533   int argc;
534   GOptionEntry entries [] =
535     { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
536         callback_parse_optional, NULL, NULL },
537       { NULL } };
538   
539   context = g_option_context_new (NULL);
540   g_option_context_add_main_entries (context, entries, NULL);
541
542   /* Now try parsing */
543   argv = split_string ("program --test foo.txt", &argc);
544   
545   retval = g_option_context_parse (context, &argc, &argv, &error);
546   g_assert (retval);
547
548   g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
549   
550   g_assert (callback_test_optional_boolean);
551
552   g_free (callback_test_optional_string);
553   
554   g_strfreev (argv);
555   g_option_context_free (context);
556 }
557
558 void
559 callback_test_optional_2 (void)
560 {
561   GOptionContext *context;
562   gboolean retval;
563   GError *error = NULL;
564   gchar **argv;
565   int argc;
566   GOptionEntry entries [] =
567     { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
568         callback_parse_optional, NULL, NULL },
569       { NULL } };
570   
571   context = g_option_context_new (NULL);
572   g_option_context_add_main_entries (context, entries, NULL);
573
574   /* Now try parsing */
575   argv = split_string ("program --test", &argc);
576   
577   retval = g_option_context_parse (context, &argc, &argv, &error);
578   g_assert (retval);
579
580   g_assert (callback_test_optional_string == NULL);
581   
582   g_assert (callback_test_optional_boolean);
583
584   g_free (callback_test_optional_string);
585   
586   g_strfreev (argv);
587   g_option_context_free (context);
588 }
589
590 void
591 callback_test_optional_3 (void)
592 {
593   GOptionContext *context;
594   gboolean retval;
595   GError *error = NULL;
596   gchar **argv;
597   int argc;
598   GOptionEntry entries [] =
599     { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
600         callback_parse_optional, NULL, NULL },
601       { NULL } };
602   
603   context = g_option_context_new (NULL);
604   g_option_context_add_main_entries (context, entries, NULL);
605
606   /* Now try parsing */
607   argv = split_string ("program -t foo.txt", &argc);
608   
609   retval = g_option_context_parse (context, &argc, &argv, &error);
610   g_assert (retval);
611
612   g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
613   
614   g_assert (callback_test_optional_boolean);
615
616   g_free (callback_test_optional_string);
617   
618   g_strfreev (argv);
619   g_option_context_free (context);
620 }
621
622
623 void
624 callback_test_optional_4 (void)
625 {
626   GOptionContext *context;
627   gboolean retval;
628   GError *error = NULL;
629   gchar **argv;
630   int argc;
631   GOptionEntry entries [] =
632     { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
633         callback_parse_optional, NULL, NULL },
634       { NULL } };
635   
636   context = g_option_context_new (NULL);
637   g_option_context_add_main_entries (context, entries, NULL);
638
639   /* Now try parsing */
640   argv = split_string ("program -t", &argc);
641   
642   retval = g_option_context_parse (context, &argc, &argv, &error);
643   g_assert (retval);
644
645   g_assert (callback_test_optional_string == NULL);
646   
647   g_assert (callback_test_optional_boolean);
648
649   g_free (callback_test_optional_string);
650   
651   g_strfreev (argv);
652   g_option_context_free (context);
653 }
654
655 void
656 callback_test_optional_5 (void)
657 {
658   GOptionContext *context;
659   gboolean dummy;
660   gboolean retval;
661   GError *error = NULL;
662   gchar **argv;
663   int argc;
664   GOptionEntry entries [] =
665     { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
666       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
667         callback_parse_optional, NULL, NULL },
668       { NULL } };
669   
670   context = g_option_context_new (NULL);
671   g_option_context_add_main_entries (context, entries, NULL);
672
673   /* Now try parsing */
674   argv = split_string ("program --test --dummy", &argc);
675   
676   retval = g_option_context_parse (context, &argc, &argv, &error);
677   g_assert (retval);
678
679   g_assert (callback_test_optional_string == NULL);
680   
681   g_assert (callback_test_optional_boolean);
682
683   g_free (callback_test_optional_string);
684   
685   g_strfreev (argv);
686   g_option_context_free (context);
687 }
688
689 void
690 callback_test_optional_6 (void)
691 {
692   GOptionContext *context;
693   gboolean dummy;
694   gboolean retval;
695   GError *error = NULL;
696   gchar **argv;
697   int argc;
698   GOptionEntry entries [] =
699     { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
700       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
701         callback_parse_optional, NULL, NULL },
702       { NULL } };
703   
704   context = g_option_context_new (NULL);
705   g_option_context_add_main_entries (context, entries, NULL);
706
707   /* Now try parsing */
708   argv = split_string ("program -t -d", &argc);
709   
710   retval = g_option_context_parse (context, &argc, &argv, &error);
711   g_assert (retval);
712
713   g_assert (callback_test_optional_string == NULL);
714   
715   g_assert (callback_test_optional_boolean);
716
717   g_free (callback_test_optional_string);
718   
719   g_strfreev (argv);
720   g_option_context_free (context);
721 }
722
723 void
724 callback_test_optional_7 (void)
725 {
726   GOptionContext *context;
727   gboolean dummy;
728   gboolean retval;
729   GError *error = NULL;
730   gchar **argv;
731   int argc;
732   GOptionEntry entries [] =
733     { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
734       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
735         callback_parse_optional, NULL, NULL },
736       { NULL } };
737   
738   context = g_option_context_new (NULL);
739   g_option_context_add_main_entries (context, entries, NULL);
740
741   /* Now try parsing */
742   argv = split_string ("program -td", &argc);
743   
744   retval = g_option_context_parse (context, &argc, &argv, &error);
745   g_assert (retval);
746
747   g_assert (callback_test_optional_string == NULL);
748   
749   g_assert (callback_test_optional_boolean);
750
751   g_free (callback_test_optional_string);
752   
753   g_strfreev (argv);
754   g_option_context_free (context);
755 }
756
757 void
758 callback_test_optional_8 (void)
759 {
760   GOptionContext *context;
761   gboolean dummy;
762   gboolean retval;
763   GError *error = NULL;
764   gchar **argv;
765   int argc;
766   GOptionEntry entries [] =
767     { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
768       { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, 
769         callback_parse_optional, NULL, NULL },
770       { NULL } };
771   
772   context = g_option_context_new (NULL);
773   g_option_context_add_main_entries (context, entries, NULL);
774
775   /* Now try parsing */
776   argv = split_string ("program -dt foo.txt", &argc);
777   
778   retval = g_option_context_parse (context, &argc, &argv, &error);
779   g_assert (retval);
780
781   g_assert (callback_test_optional_string);
782   
783   g_assert (callback_test_optional_boolean);
784
785   g_free (callback_test_optional_string);
786   
787   g_strfreev (argv);
788   g_option_context_free (context);
789 }
790
791 static GPtrArray *callback_remaining_args;
792 static gboolean
793 callback_remaining_test1_callback (const gchar *option_name, const gchar *value,
794                          gpointer data, GError **error)
795 {
796         g_ptr_array_add (callback_remaining_args, g_strdup (value));
797         return TRUE;
798 }
799
800 void
801 callback_remaining_test1 (void)
802 {
803   GOptionContext *context;
804   gboolean retval;
805   GError *error = NULL;
806   gchar **argv;
807   int argc;
808   GOptionEntry entries [] =
809     { { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_CALLBACK, callback_remaining_test1_callback, NULL, NULL },
810       { NULL } };
811   
812   callback_remaining_args = g_ptr_array_new ();
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 foo.txt blah.txt", &argc);
818   
819   retval = g_option_context_parse (context, &argc, &argv, &error);
820   g_assert (retval);
821
822   g_assert (callback_remaining_args->len == 2);
823   g_assert (strcmp (callback_remaining_args->pdata[0], "foo.txt") == 0);
824   g_assert (strcmp (callback_remaining_args->pdata[1], "blah.txt") == 0);
825
826   g_ptr_array_foreach (callback_remaining_args, (GFunc) g_free, NULL);
827   g_ptr_array_free (callback_remaining_args, TRUE);
828   
829   g_strfreev (argv);
830   g_option_context_free (context);
831 }
832
833 void
834 ignore_test1 (void)
835 {
836   GOptionContext *context;
837   gboolean retval;
838   GError *error = NULL;
839   gchar **argv, **argv_copy;
840   int argc;
841   gchar *arg;
842   GOptionEntry entries [] =
843     { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
844       { NULL } };
845
846   context = g_option_context_new (NULL);
847   g_option_context_set_ignore_unknown_options (context, TRUE);
848   g_option_context_add_main_entries (context, entries, NULL);
849
850   /* Now try parsing */
851   argv = split_string ("program --test --hello", &argc);
852   argv_copy = copy_stringv (argv, argc);
853   
854   retval = g_option_context_parse (context, &argc, &argv, &error);
855   g_assert (retval);
856
857   /* Check array */
858   arg = join_stringv (argc, argv);
859   g_assert (strcmp (arg, "program --hello") == 0);
860
861   g_free (arg);
862   g_strfreev (argv_copy);
863   g_free (argv);
864   g_option_context_free (context);
865 }
866
867 void
868 ignore_test2 (void)
869 {
870   GOptionContext *context;
871   gboolean retval;
872   GError *error = NULL;
873   gchar **argv;
874   int argc;
875   gchar *arg;
876   GOptionEntry entries [] =
877     { { "test", 't', 0, G_OPTION_ARG_NONE, &ignore_test2_boolean, NULL, NULL },
878       { NULL } };
879
880   context = g_option_context_new (NULL);
881   g_option_context_set_ignore_unknown_options (context, TRUE);
882   g_option_context_add_main_entries (context, entries, NULL);
883
884   /* Now try parsing */
885   argv = split_string ("program -test", &argc);
886   
887   retval = g_option_context_parse (context, &argc, &argv, &error);
888   g_assert (retval);
889
890   /* Check array */
891   arg = join_stringv (argc, argv);
892   g_assert (strcmp (arg, "program -es") == 0);
893
894   g_free (arg);
895   g_strfreev (argv);
896   g_option_context_free (context);
897 }
898
899 void
900 ignore_test3 (void)
901 {
902   GOptionContext *context;
903   gboolean retval;
904   GError *error = NULL;
905   gchar **argv, **argv_copy;
906   int argc;
907   gchar *arg;
908   GOptionEntry entries [] =
909     { { "test", 0, 0, G_OPTION_ARG_STRING, &ignore_test3_string, NULL, NULL },
910       { NULL } };
911
912   context = g_option_context_new (NULL);
913   g_option_context_set_ignore_unknown_options (context, TRUE);
914   g_option_context_add_main_entries (context, entries, NULL);
915
916   /* Now try parsing */
917   argv = split_string ("program --test foo --hello", &argc);
918   argv_copy = copy_stringv (argv, argc);
919   
920   retval = g_option_context_parse (context, &argc, &argv, &error);
921   g_assert (retval);
922
923   /* Check array */
924   arg = join_stringv (argc, argv);
925   g_assert (strcmp (arg, "program --hello") == 0);
926
927   g_assert (strcmp (ignore_test3_string, "foo") == 0);
928   g_free (ignore_test3_string);
929
930   g_free (arg);
931   g_strfreev (argv_copy);
932   g_free (argv);
933   g_option_context_free (context);
934 }
935
936 void
937 array_test1 (void)
938 {
939   GOptionContext *context;
940   gboolean retval;
941   GError *error = NULL;
942   gchar **argv;
943   int argc;
944   GOptionEntry entries [] =
945     { { "test", 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
946       { NULL } };
947         
948   context = g_option_context_new (NULL);
949   g_option_context_add_main_entries (context, entries, NULL);
950
951   /* Now try parsing */
952   argv = split_string ("program --test foo --test bar", &argc);
953   
954   retval = g_option_context_parse (context, &argc, &argv, &error);
955   g_assert (retval);
956
957   /* Check array */
958   g_assert (strcmp (array_test1_array[0], "foo") == 0);
959   g_assert (strcmp (array_test1_array[1], "bar") == 0);
960   g_assert (array_test1_array[2] == NULL);
961
962   g_strfreev (array_test1_array);
963   
964   g_strfreev (argv);
965   g_option_context_free (context);
966 }
967
968 void
969 add_test1 (void)
970 {
971   GOptionContext *context;
972
973   GOptionEntry entries1 [] =
974     { { "test1", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
975       { NULL } };
976   GOptionEntry entries2 [] =
977     { { "test2", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
978       { NULL } };
979
980   context = g_option_context_new (NULL);
981   g_option_context_add_main_entries (context, entries1, NULL);
982   g_option_context_add_main_entries (context, entries2, NULL);
983
984   g_option_context_free (context);
985 }
986
987 void
988 empty_test1 (void)
989 {
990   GOptionContext *context;
991   GOptionEntry entries [] =
992     { { NULL } };
993   char *prgname;
994
995   g_set_prgname (NULL);
996   context = g_option_context_new (NULL);
997
998   g_option_context_add_main_entries (context, entries, NULL);
999   
1000   g_option_context_parse (context, NULL, NULL, NULL);
1001
1002   prgname = g_get_prgname ();
1003   g_assert (prgname && strcmp (prgname, "<unknown>") == 0);
1004   
1005   g_option_context_free (context);
1006 }
1007
1008 void
1009 empty_test2 (void)
1010 {
1011   GOptionContext *context;
1012
1013   context = g_option_context_new (NULL);
1014   g_option_context_parse (context, NULL, NULL, NULL);
1015   
1016   g_option_context_free (context);
1017 }
1018
1019 void
1020 empty_test3 (void)
1021 {
1022   GOptionContext *context;
1023   gint argc;
1024   gchar **argv;
1025
1026   argc = 0;
1027   argv = NULL;
1028
1029   context = g_option_context_new (NULL);
1030   g_option_context_parse (context, &argc, &argv, NULL);
1031   
1032   g_option_context_free (context);
1033 }
1034
1035 /* check that non-option arguments are left in argv by default */
1036 void
1037 rest_test1 (void)
1038 {
1039   GOptionContext *context;
1040   gboolean retval;
1041   GError *error = NULL;
1042   gchar **argv;
1043   int argc;
1044   GOptionEntry entries [] = { 
1045       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1046       { NULL } 
1047   };
1048         
1049   context = g_option_context_new (NULL);
1050   g_option_context_add_main_entries (context, entries, NULL);
1051
1052   /* Now try parsing */
1053   argv = split_string ("program foo --test bar", &argc);
1054   
1055   retval = g_option_context_parse (context, &argc, &argv, &error);
1056   g_assert (retval);
1057
1058   /* Check array */
1059   g_assert (ignore_test1_boolean);
1060   g_assert (strcmp (argv[0], "program") == 0);
1061   g_assert (strcmp (argv[1], "foo") == 0);
1062   g_assert (strcmp (argv[2], "bar") == 0);
1063   g_assert (argv[3] == NULL);
1064
1065   g_strfreev (argv);
1066   g_option_context_free (context);
1067 }
1068
1069 /* check that -- works */
1070 void
1071 rest_test2 (void)
1072 {
1073   GOptionContext *context;
1074   gboolean retval;
1075   GError *error = NULL;
1076   gchar **argv;
1077   int argc;
1078   GOptionEntry entries [] = { 
1079       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1080       { NULL } 
1081   };
1082         
1083   context = g_option_context_new (NULL);
1084   g_option_context_add_main_entries (context, entries, NULL);
1085
1086   /* Now try parsing */
1087   argv = split_string ("program foo --test -- -bar", &argc);
1088   
1089   retval = g_option_context_parse (context, &argc, &argv, &error);
1090   g_assert (retval);
1091
1092   /* Check array */
1093   g_assert (ignore_test1_boolean);
1094   g_assert (strcmp (argv[0], "program") == 0);
1095   g_assert (strcmp (argv[1], "foo") == 0);
1096   g_assert (strcmp (argv[2], "--") == 0);
1097   g_assert (strcmp (argv[3], "-bar") == 0);
1098   g_assert (argv[4] == NULL);
1099
1100   g_strfreev (argv);
1101   g_option_context_free (context);
1102 }
1103
1104 /* check that -- stripping works */
1105 void
1106 rest_test2a (void)
1107 {
1108   GOptionContext *context;
1109   gboolean retval;
1110   GError *error = NULL;
1111   gchar **argv;
1112   int argc;
1113   GOptionEntry entries [] = { 
1114       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1115       { NULL } 
1116   };
1117         
1118   context = g_option_context_new (NULL);
1119   g_option_context_add_main_entries (context, entries, NULL);
1120
1121   /* Now try parsing */
1122   argv = split_string ("program foo --test -- bar", &argc);
1123   
1124   retval = g_option_context_parse (context, &argc, &argv, &error);
1125   g_assert (retval);
1126
1127   /* Check array */
1128   g_assert (ignore_test1_boolean);
1129   g_assert (strcmp (argv[0], "program") == 0);
1130   g_assert (strcmp (argv[1], "foo") == 0);
1131   g_assert (strcmp (argv[2], "bar") == 0);
1132   g_assert (argv[3] == NULL);
1133
1134   g_strfreev (argv);
1135   g_option_context_free (context);
1136 }
1137
1138 void
1139 rest_test2b (void)
1140 {
1141   GOptionContext *context;
1142   gboolean retval;
1143   GError *error = NULL;
1144   gchar **argv;
1145   int argc;
1146   GOptionEntry entries [] = { 
1147       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1148       { NULL } 
1149   };
1150         
1151   context = g_option_context_new (NULL);
1152   g_option_context_set_ignore_unknown_options (context, TRUE);
1153   g_option_context_add_main_entries (context, entries, NULL);
1154
1155   /* Now try parsing */
1156   argv = split_string ("program foo --test -bar --", &argc);
1157   
1158   retval = g_option_context_parse (context, &argc, &argv, &error);
1159   g_assert (retval);
1160
1161   /* Check array */
1162   g_assert (ignore_test1_boolean);
1163   g_assert (strcmp (argv[0], "program") == 0);
1164   g_assert (strcmp (argv[1], "foo") == 0);
1165   g_assert (strcmp (argv[2], "-bar") == 0);
1166   g_assert (argv[3] == NULL);
1167
1168   g_strfreev (argv);
1169   g_option_context_free (context);
1170 }
1171
1172 void
1173 rest_test2c (void)
1174 {
1175   GOptionContext *context;
1176   gboolean retval;
1177   GError *error = NULL;
1178   gchar **argv;
1179   int argc;
1180   GOptionEntry entries [] = { 
1181       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1182       { NULL } 
1183   };
1184         
1185   context = g_option_context_new (NULL);
1186   g_option_context_add_main_entries (context, entries, NULL);
1187
1188   /* Now try parsing */
1189   argv = split_string ("program --test foo -- bar", &argc);
1190   
1191   retval = g_option_context_parse (context, &argc, &argv, &error);
1192   g_assert (retval);
1193
1194   /* Check array */
1195   g_assert (ignore_test1_boolean);
1196   g_assert (strcmp (argv[0], "program") == 0);
1197   g_assert (strcmp (argv[1], "foo") == 0);
1198   g_assert (strcmp (argv[2], "bar") == 0);
1199   g_assert (argv[3] == NULL);
1200
1201   g_strfreev (argv);
1202   g_option_context_free (context);
1203 }
1204
1205 void
1206 rest_test2d (void)
1207 {
1208   GOptionContext *context;
1209   gboolean retval;
1210   GError *error = NULL;
1211   gchar **argv;
1212   int argc;
1213   GOptionEntry entries [] = { 
1214       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1215       { NULL } 
1216   };
1217         
1218   context = g_option_context_new (NULL);
1219   g_option_context_add_main_entries (context, entries, NULL);
1220
1221   /* Now try parsing */
1222   argv = split_string ("program --test -- -bar", &argc);
1223   
1224   retval = g_option_context_parse (context, &argc, &argv, &error);
1225   g_assert (retval);
1226
1227   /* Check array */
1228   g_assert (ignore_test1_boolean);
1229   g_assert (strcmp (argv[0], "program") == 0);
1230   g_assert (strcmp (argv[1], "--") == 0);
1231   g_assert (strcmp (argv[2], "-bar") == 0);
1232   g_assert (argv[3] == NULL);
1233
1234   g_strfreev (argv);
1235   g_option_context_free (context);
1236 }
1237
1238
1239 /* check that G_OPTION_REMAINING collects non-option arguments */
1240 void
1241 rest_test3 (void)
1242 {
1243   GOptionContext *context;
1244   gboolean retval;
1245   GError *error = NULL;
1246   gchar **argv;
1247   int argc;
1248   GOptionEntry entries [] = { 
1249       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1250       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1251       { NULL } 
1252   };
1253         
1254   context = g_option_context_new (NULL);
1255   g_option_context_add_main_entries (context, entries, NULL);
1256
1257   /* Now try parsing */
1258   argv = split_string ("program foo --test bar", &argc);
1259   
1260   retval = g_option_context_parse (context, &argc, &argv, &error);
1261   g_assert (retval);
1262
1263   /* Check array */
1264   g_assert (ignore_test1_boolean);
1265   g_assert (strcmp (array_test1_array[0], "foo") == 0);
1266   g_assert (strcmp (array_test1_array[1], "bar") == 0);
1267   g_assert (array_test1_array[2] == NULL);
1268
1269   g_strfreev (array_test1_array);
1270   
1271   g_strfreev (argv);
1272   g_option_context_free (context);
1273 }
1274
1275
1276 /* check that G_OPTION_REMAINING and -- work together */
1277 void
1278 rest_test4 (void)
1279 {
1280   GOptionContext *context;
1281   gboolean retval;
1282   GError *error = NULL;
1283   gchar **argv;
1284   int argc;
1285   GOptionEntry entries [] = { 
1286       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1287       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1288       { NULL } 
1289   };
1290         
1291   context = g_option_context_new (NULL);
1292   g_option_context_add_main_entries (context, entries, NULL);
1293
1294   /* Now try parsing */
1295   argv = split_string ("program foo --test -- -bar", &argc);
1296   
1297   retval = g_option_context_parse (context, &argc, &argv, &error);
1298   g_assert (retval);
1299
1300   /* Check array */
1301   g_assert (ignore_test1_boolean);
1302   g_assert (strcmp (array_test1_array[0], "foo") == 0);
1303   g_assert (strcmp (array_test1_array[1], "-bar") == 0);
1304   g_assert (array_test1_array[2] == NULL);
1305
1306   g_strfreev (array_test1_array);
1307   
1308   g_strfreev (argv);
1309   g_option_context_free (context);
1310 }
1311
1312 /* test that G_OPTION_REMAINING works with G_OPTION_ARG_FILENAME_ARRAY */
1313 void
1314 rest_test5 (void)
1315 {
1316   GOptionContext *context;
1317   gboolean retval;
1318   GError *error = NULL;
1319   gchar **argv;
1320   int argc;
1321   GOptionEntry entries [] = { 
1322       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1323       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &array_test1_array, NULL, NULL },
1324       { NULL } 
1325   };
1326         
1327   context = g_option_context_new (NULL);
1328   g_option_context_add_main_entries (context, entries, NULL);
1329
1330   /* Now try parsing */
1331   argv = split_string ("program foo --test bar", &argc);
1332   
1333   retval = g_option_context_parse (context, &argc, &argv, &error);
1334   g_assert (retval);
1335
1336   /* Check array */
1337   g_assert (ignore_test1_boolean);
1338   g_assert (strcmp (array_test1_array[0], "foo") == 0);
1339   g_assert (strcmp (array_test1_array[1], "bar") == 0);
1340   g_assert (array_test1_array[2] == NULL);
1341
1342   g_strfreev (array_test1_array);
1343   
1344   g_strfreev (argv);
1345   g_option_context_free (context);
1346 }
1347
1348 void
1349 unknown_short_test (void)
1350 {
1351   GOptionContext *context;
1352   gboolean retval;
1353   GError *error = NULL;
1354   gchar **argv;
1355   int argc;
1356   GOptionEntry entries [] = { { NULL } };
1357
1358   context = g_option_context_new (NULL);
1359   g_option_context_add_main_entries (context, entries, NULL);
1360
1361   /* Now try parsing */
1362   argv = split_string ("program -0", &argc);
1363
1364   retval = g_option_context_parse (context, &argc, &argv, &error);
1365   g_assert (!retval);
1366
1367   g_strfreev (argv);
1368   g_option_context_free (context);
1369 }
1370
1371 /* test that lone dashes are treated as non-options */
1372 void lonely_dash_test (void)
1373 {
1374   GOptionContext *context;
1375   gboolean retval;
1376   GError *error = NULL;
1377   gchar **argv;
1378   int argc;
1379
1380   context = g_option_context_new (NULL);
1381
1382   /* Now try parsing */
1383   argv = split_string ("program -", &argc);
1384
1385   retval = g_option_context_parse (context, &argc, &argv, &error);
1386
1387   g_assert (retval);
1388
1389   g_assert (argv[1] && strcmp (argv[1], "-") == 0);
1390
1391   g_strfreev (argv);
1392   g_option_context_free (context);
1393 }
1394
1395 void
1396 missing_arg_test (void)
1397 {
1398   GOptionContext *context;
1399   gboolean retval;
1400   GError *error = NULL;
1401   gchar **argv;
1402   int argc;
1403   gchar *arg = NULL;
1404   GOptionEntry entries [] =
1405     { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1406       { NULL } };
1407
1408   context = g_option_context_new (NULL);
1409   g_option_context_add_main_entries (context, entries, NULL);
1410
1411   /* Now try parsing */
1412   argv = split_string ("program --test", &argc);
1413
1414   retval = g_option_context_parse (context, &argc, &argv, &error);
1415   g_assert (retval == FALSE);
1416   g_clear_error (&error);
1417
1418   g_strfreev (argv);
1419
1420   /* Try parsing again */
1421   argv = split_string ("program --t", &argc);
1422
1423   retval = g_option_context_parse (context, &argc, &argv, &error);
1424   g_assert (retval == FALSE);
1425
1426   g_strfreev (argv);
1427   g_option_context_free (context);
1428 }
1429
1430 int
1431 main (int argc, char **argv)
1432 {
1433   /* Test that restoration on failure works */
1434   error_test1_int = 0x12345678;
1435   error_test1 ();
1436   error_test2_string = "foo";
1437   error_test2 ();
1438   error_test3_boolean = FALSE;
1439   error_test3 ();
1440   
1441   /* Test that special argument parsing works */
1442   arg_test1 ();
1443   arg_test2 ();
1444   arg_test3 ();
1445   arg_test4 ();
1446   arg_test5 ();
1447   arg_test6 ();
1448
1449   /* Test string arrays */
1450   array_test1 ();
1451
1452   /* Test callback args */
1453   callback_test1 ();
1454   callback_test2 ();
1455
1456   /* Test optional arg flag for callback */
1457   callback_test_optional_1 ();
1458   callback_test_optional_2 ();
1459   callback_test_optional_3 ();
1460   callback_test_optional_4 ();
1461   callback_test_optional_5 ();
1462   callback_test_optional_6 ();
1463   callback_test_optional_7 ();
1464   callback_test_optional_8 ();
1465
1466   /* Test callback with G_OPTION_REMAINING */
1467   callback_remaining_test1 ();
1468   
1469   /* Test ignoring options */
1470   ignore_test1 ();
1471   ignore_test2 ();
1472   ignore_test3 ();
1473
1474   add_test1 ();
1475
1476   /* Test parsing empty args */
1477   empty_test1 ();
1478   empty_test2 ();
1479   empty_test3 ();
1480
1481   /* Test handling of rest args */
1482   rest_test1 ();
1483   rest_test2 ();
1484   rest_test2a ();
1485   rest_test2b ();
1486   rest_test2c ();
1487   rest_test2d ();
1488   rest_test3 ();
1489   rest_test4 ();
1490   rest_test5 ();
1491
1492   /* test for bug 166609 */
1493   unknown_short_test ();
1494
1495   /* test for bug 168008 */
1496   lonely_dash_test ();
1497
1498   /* test for bug 305576 */
1499   missing_arg_test ();
1500
1501   return 0;
1502 }