Add GRegex for regular expression matching. (#50075)
[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 == 4294967296LL);
436   g_assert (arg_test6_int64_2 == 0xfffffffffLL);
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 void
792 ignore_test1 (void)
793 {
794   GOptionContext *context;
795   gboolean retval;
796   GError *error = NULL;
797   gchar **argv, **argv_copy;
798   int argc;
799   gchar *arg;
800   GOptionEntry entries [] =
801     { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
802       { NULL } };
803
804   context = g_option_context_new (NULL);
805   g_option_context_set_ignore_unknown_options (context, TRUE);
806   g_option_context_add_main_entries (context, entries, NULL);
807
808   /* Now try parsing */
809   argv = split_string ("program --test --hello", &argc);
810   argv_copy = copy_stringv (argv, argc);
811   
812   retval = g_option_context_parse (context, &argc, &argv, &error);
813   g_assert (retval);
814
815   /* Check array */
816   arg = join_stringv (argc, argv);
817   g_assert (strcmp (arg, "program --hello") == 0);
818
819   g_free (arg);
820   g_strfreev (argv_copy);
821   g_free (argv);
822   g_option_context_free (context);
823 }
824
825 void
826 ignore_test2 (void)
827 {
828   GOptionContext *context;
829   gboolean retval;
830   GError *error = NULL;
831   gchar **argv;
832   int argc;
833   gchar *arg;
834   GOptionEntry entries [] =
835     { { "test", 't', 0, G_OPTION_ARG_NONE, &ignore_test2_boolean, NULL, NULL },
836       { NULL } };
837
838   context = g_option_context_new (NULL);
839   g_option_context_set_ignore_unknown_options (context, TRUE);
840   g_option_context_add_main_entries (context, entries, NULL);
841
842   /* Now try parsing */
843   argv = split_string ("program -test", &argc);
844   
845   retval = g_option_context_parse (context, &argc, &argv, &error);
846   g_assert (retval);
847
848   /* Check array */
849   arg = join_stringv (argc, argv);
850   g_assert (strcmp (arg, "program -es") == 0);
851
852   g_free (arg);
853   g_strfreev (argv);
854   g_option_context_free (context);
855 }
856
857 void
858 ignore_test3 (void)
859 {
860   GOptionContext *context;
861   gboolean retval;
862   GError *error = NULL;
863   gchar **argv, **argv_copy;
864   int argc;
865   gchar *arg;
866   GOptionEntry entries [] =
867     { { "test", 0, 0, G_OPTION_ARG_STRING, &ignore_test3_string, NULL, NULL },
868       { NULL } };
869
870   context = g_option_context_new (NULL);
871   g_option_context_set_ignore_unknown_options (context, TRUE);
872   g_option_context_add_main_entries (context, entries, NULL);
873
874   /* Now try parsing */
875   argv = split_string ("program --test foo --hello", &argc);
876   argv_copy = copy_stringv (argv, argc);
877   
878   retval = g_option_context_parse (context, &argc, &argv, &error);
879   g_assert (retval);
880
881   /* Check array */
882   arg = join_stringv (argc, argv);
883   g_assert (strcmp (arg, "program --hello") == 0);
884
885   g_assert (strcmp (ignore_test3_string, "foo") == 0);
886   g_free (ignore_test3_string);
887
888   g_free (arg);
889   g_strfreev (argv_copy);
890   g_free (argv);
891   g_option_context_free (context);
892 }
893
894 void
895 array_test1 (void)
896 {
897   GOptionContext *context;
898   gboolean retval;
899   GError *error = NULL;
900   gchar **argv;
901   int argc;
902   GOptionEntry entries [] =
903     { { "test", 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
904       { NULL } };
905         
906   context = g_option_context_new (NULL);
907   g_option_context_add_main_entries (context, entries, NULL);
908
909   /* Now try parsing */
910   argv = split_string ("program --test foo --test bar", &argc);
911   
912   retval = g_option_context_parse (context, &argc, &argv, &error);
913   g_assert (retval);
914
915   /* Check array */
916   g_assert (strcmp (array_test1_array[0], "foo") == 0);
917   g_assert (strcmp (array_test1_array[1], "bar") == 0);
918   g_assert (array_test1_array[2] == NULL);
919
920   g_strfreev (array_test1_array);
921   
922   g_strfreev (argv);
923   g_option_context_free (context);
924 }
925
926 void
927 add_test1 (void)
928 {
929   GOptionContext *context;
930
931   GOptionEntry entries1 [] =
932     { { "test1", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
933       { NULL } };
934   GOptionEntry entries2 [] =
935     { { "test2", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
936       { NULL } };
937
938   context = g_option_context_new (NULL);
939   g_option_context_add_main_entries (context, entries1, NULL);
940   g_option_context_add_main_entries (context, entries2, NULL);
941
942   g_option_context_free (context);
943 }
944
945 void
946 empty_test1 (void)
947 {
948   GOptionContext *context;
949   GOptionEntry entries [] =
950     { { NULL } };
951   char *prgname;
952
953   g_set_prgname (NULL);
954   context = g_option_context_new (NULL);
955
956   g_option_context_add_main_entries (context, entries, NULL);
957   
958   g_option_context_parse (context, NULL, NULL, NULL);
959
960   prgname = g_get_prgname ();
961   g_assert (prgname && strcmp (prgname, "<unknown>") == 0);
962   
963   g_option_context_free (context);
964 }
965
966 void
967 empty_test2 (void)
968 {
969   GOptionContext *context;
970
971   context = g_option_context_new (NULL);
972   g_option_context_parse (context, NULL, NULL, NULL);
973   
974   g_option_context_free (context);
975 }
976
977 void
978 empty_test3 (void)
979 {
980   GOptionContext *context;
981   gint argc;
982   gchar **argv;
983
984   argc = 0;
985   argv = NULL;
986
987   context = g_option_context_new (NULL);
988   g_option_context_parse (context, &argc, &argv, NULL);
989   
990   g_option_context_free (context);
991 }
992
993 /* check that non-option arguments are left in argv by default */
994 void
995 rest_test1 (void)
996 {
997   GOptionContext *context;
998   gboolean retval;
999   GError *error = NULL;
1000   gchar **argv;
1001   int argc;
1002   GOptionEntry entries [] = { 
1003       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1004       { NULL } 
1005   };
1006         
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 --test bar", &argc);
1012   
1013   retval = g_option_context_parse (context, &argc, &argv, &error);
1014   g_assert (retval);
1015
1016   /* Check array */
1017   g_assert (ignore_test1_boolean);
1018   g_assert (strcmp (argv[0], "program") == 0);
1019   g_assert (strcmp (argv[1], "foo") == 0);
1020   g_assert (strcmp (argv[2], "bar") == 0);
1021   g_assert (argv[3] == NULL);
1022
1023   g_strfreev (argv);
1024   g_option_context_free (context);
1025 }
1026
1027 /* check that -- works */
1028 void
1029 rest_test2 (void)
1030 {
1031   GOptionContext *context;
1032   gboolean retval;
1033   GError *error = NULL;
1034   gchar **argv;
1035   int argc;
1036   GOptionEntry entries [] = { 
1037       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1038       { NULL } 
1039   };
1040         
1041   context = g_option_context_new (NULL);
1042   g_option_context_add_main_entries (context, entries, NULL);
1043
1044   /* Now try parsing */
1045   argv = split_string ("program foo --test -- -bar", &argc);
1046   
1047   retval = g_option_context_parse (context, &argc, &argv, &error);
1048   g_assert (retval);
1049
1050   /* Check array */
1051   g_assert (ignore_test1_boolean);
1052   g_assert (strcmp (argv[0], "program") == 0);
1053   g_assert (strcmp (argv[1], "foo") == 0);
1054   g_assert (strcmp (argv[2], "--") == 0);
1055   g_assert (strcmp (argv[3], "-bar") == 0);
1056   g_assert (argv[4] == NULL);
1057
1058   g_strfreev (argv);
1059   g_option_context_free (context);
1060 }
1061
1062 /* check that -- stripping works */
1063 void
1064 rest_test2a (void)
1065 {
1066   GOptionContext *context;
1067   gboolean retval;
1068   GError *error = NULL;
1069   gchar **argv;
1070   int argc;
1071   GOptionEntry entries [] = { 
1072       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1073       { NULL } 
1074   };
1075         
1076   context = g_option_context_new (NULL);
1077   g_option_context_add_main_entries (context, entries, NULL);
1078
1079   /* Now try parsing */
1080   argv = split_string ("program foo --test -- bar", &argc);
1081   
1082   retval = g_option_context_parse (context, &argc, &argv, &error);
1083   g_assert (retval);
1084
1085   /* Check array */
1086   g_assert (ignore_test1_boolean);
1087   g_assert (strcmp (argv[0], "program") == 0);
1088   g_assert (strcmp (argv[1], "foo") == 0);
1089   g_assert (strcmp (argv[2], "bar") == 0);
1090   g_assert (argv[3] == NULL);
1091
1092   g_strfreev (argv);
1093   g_option_context_free (context);
1094 }
1095
1096 void
1097 rest_test2b (void)
1098 {
1099   GOptionContext *context;
1100   gboolean retval;
1101   GError *error = NULL;
1102   gchar **argv;
1103   int argc;
1104   GOptionEntry entries [] = { 
1105       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1106       { NULL } 
1107   };
1108         
1109   context = g_option_context_new (NULL);
1110   g_option_context_set_ignore_unknown_options (context, TRUE);
1111   g_option_context_add_main_entries (context, entries, NULL);
1112
1113   /* Now try parsing */
1114   argv = split_string ("program foo --test -bar --", &argc);
1115   
1116   retval = g_option_context_parse (context, &argc, &argv, &error);
1117   g_assert (retval);
1118
1119   /* Check array */
1120   g_assert (ignore_test1_boolean);
1121   g_assert (strcmp (argv[0], "program") == 0);
1122   g_assert (strcmp (argv[1], "foo") == 0);
1123   g_assert (strcmp (argv[2], "-bar") == 0);
1124   g_assert (argv[3] == NULL);
1125
1126   g_strfreev (argv);
1127   g_option_context_free (context);
1128 }
1129
1130 void
1131 rest_test2c (void)
1132 {
1133   GOptionContext *context;
1134   gboolean retval;
1135   GError *error = NULL;
1136   gchar **argv;
1137   int argc;
1138   GOptionEntry entries [] = { 
1139       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1140       { NULL } 
1141   };
1142         
1143   context = g_option_context_new (NULL);
1144   g_option_context_add_main_entries (context, entries, NULL);
1145
1146   /* Now try parsing */
1147   argv = split_string ("program --test foo -- bar", &argc);
1148   
1149   retval = g_option_context_parse (context, &argc, &argv, &error);
1150   g_assert (retval);
1151
1152   /* Check array */
1153   g_assert (ignore_test1_boolean);
1154   g_assert (strcmp (argv[0], "program") == 0);
1155   g_assert (strcmp (argv[1], "foo") == 0);
1156   g_assert (strcmp (argv[2], "bar") == 0);
1157   g_assert (argv[3] == NULL);
1158
1159   g_strfreev (argv);
1160   g_option_context_free (context);
1161 }
1162
1163 void
1164 rest_test2d (void)
1165 {
1166   GOptionContext *context;
1167   gboolean retval;
1168   GError *error = NULL;
1169   gchar **argv;
1170   int argc;
1171   GOptionEntry entries [] = { 
1172       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1173       { NULL } 
1174   };
1175         
1176   context = g_option_context_new (NULL);
1177   g_option_context_add_main_entries (context, entries, NULL);
1178
1179   /* Now try parsing */
1180   argv = split_string ("program --test -- -bar", &argc);
1181   
1182   retval = g_option_context_parse (context, &argc, &argv, &error);
1183   g_assert (retval);
1184
1185   /* Check array */
1186   g_assert (ignore_test1_boolean);
1187   g_assert (strcmp (argv[0], "program") == 0);
1188   g_assert (strcmp (argv[1], "--") == 0);
1189   g_assert (strcmp (argv[2], "-bar") == 0);
1190   g_assert (argv[3] == NULL);
1191
1192   g_strfreev (argv);
1193   g_option_context_free (context);
1194 }
1195
1196
1197 /* check that G_OPTION_REMAINING collects non-option arguments */
1198 void
1199 rest_test3 (void)
1200 {
1201   GOptionContext *context;
1202   gboolean retval;
1203   GError *error = NULL;
1204   gchar **argv;
1205   int argc;
1206   GOptionEntry entries [] = { 
1207       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1208       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1209       { NULL } 
1210   };
1211         
1212   context = g_option_context_new (NULL);
1213   g_option_context_add_main_entries (context, entries, NULL);
1214
1215   /* Now try parsing */
1216   argv = split_string ("program foo --test bar", &argc);
1217   
1218   retval = g_option_context_parse (context, &argc, &argv, &error);
1219   g_assert (retval);
1220
1221   /* Check array */
1222   g_assert (ignore_test1_boolean);
1223   g_assert (strcmp (array_test1_array[0], "foo") == 0);
1224   g_assert (strcmp (array_test1_array[1], "bar") == 0);
1225   g_assert (array_test1_array[2] == NULL);
1226
1227   g_strfreev (array_test1_array);
1228   
1229   g_strfreev (argv);
1230   g_option_context_free (context);
1231 }
1232
1233
1234 /* check that G_OPTION_REMAINING and -- work together */
1235 void
1236 rest_test4 (void)
1237 {
1238   GOptionContext *context;
1239   gboolean retval;
1240   GError *error = NULL;
1241   gchar **argv;
1242   int argc;
1243   GOptionEntry entries [] = { 
1244       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1245       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1246       { NULL } 
1247   };
1248         
1249   context = g_option_context_new (NULL);
1250   g_option_context_add_main_entries (context, entries, NULL);
1251
1252   /* Now try parsing */
1253   argv = split_string ("program foo --test -- -bar", &argc);
1254   
1255   retval = g_option_context_parse (context, &argc, &argv, &error);
1256   g_assert (retval);
1257
1258   /* Check array */
1259   g_assert (ignore_test1_boolean);
1260   g_assert (strcmp (array_test1_array[0], "foo") == 0);
1261   g_assert (strcmp (array_test1_array[1], "-bar") == 0);
1262   g_assert (array_test1_array[2] == NULL);
1263
1264   g_strfreev (array_test1_array);
1265   
1266   g_strfreev (argv);
1267   g_option_context_free (context);
1268 }
1269
1270 /* test that G_OPTION_REMAINING works with G_OPTION_ARG_FILENAME_ARRAY */
1271 void
1272 rest_test5 (void)
1273 {
1274   GOptionContext *context;
1275   gboolean retval;
1276   GError *error = NULL;
1277   gchar **argv;
1278   int argc;
1279   GOptionEntry entries [] = { 
1280       { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1281       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &array_test1_array, NULL, NULL },
1282       { NULL } 
1283   };
1284         
1285   context = g_option_context_new (NULL);
1286   g_option_context_add_main_entries (context, entries, NULL);
1287
1288   /* Now try parsing */
1289   argv = split_string ("program foo --test bar", &argc);
1290   
1291   retval = g_option_context_parse (context, &argc, &argv, &error);
1292   g_assert (retval);
1293
1294   /* Check array */
1295   g_assert (ignore_test1_boolean);
1296   g_assert (strcmp (array_test1_array[0], "foo") == 0);
1297   g_assert (strcmp (array_test1_array[1], "bar") == 0);
1298   g_assert (array_test1_array[2] == NULL);
1299
1300   g_strfreev (array_test1_array);
1301   
1302   g_strfreev (argv);
1303   g_option_context_free (context);
1304 }
1305
1306 void
1307 unknown_short_test (void)
1308 {
1309   GOptionContext *context;
1310   gboolean retval;
1311   GError *error = NULL;
1312   gchar **argv;
1313   int argc;
1314   GOptionEntry entries [] = { { NULL } };
1315
1316   context = g_option_context_new (NULL);
1317   g_option_context_add_main_entries (context, entries, NULL);
1318
1319   /* Now try parsing */
1320   argv = split_string ("program -0", &argc);
1321
1322   retval = g_option_context_parse (context, &argc, &argv, &error);
1323   g_assert (!retval);
1324
1325   g_strfreev (argv);
1326   g_option_context_free (context);
1327 }
1328
1329 /* test that lone dashes are treated as non-options */
1330 void lonely_dash_test (void)
1331 {
1332   GOptionContext *context;
1333   gboolean retval;
1334   GError *error = NULL;
1335   gchar **argv;
1336   int argc;
1337
1338   context = g_option_context_new (NULL);
1339
1340   /* Now try parsing */
1341   argv = split_string ("program -", &argc);
1342
1343   retval = g_option_context_parse (context, &argc, &argv, &error);
1344
1345   g_assert (retval);
1346
1347   g_assert (argv[1] && strcmp (argv[1], "-") == 0);
1348
1349   g_strfreev (argv);
1350   g_option_context_free (context);
1351 }
1352
1353 void
1354 missing_arg_test (void)
1355 {
1356   GOptionContext *context;
1357   gboolean retval;
1358   GError *error = NULL;
1359   gchar **argv;
1360   int argc;
1361   gchar *arg = NULL;
1362   GOptionEntry entries [] =
1363     { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1364       { NULL } };
1365
1366   context = g_option_context_new (NULL);
1367   g_option_context_add_main_entries (context, entries, NULL);
1368
1369   /* Now try parsing */
1370   argv = split_string ("program --test", &argc);
1371
1372   retval = g_option_context_parse (context, &argc, &argv, &error);
1373   g_assert (retval == FALSE);
1374   g_clear_error (&error);
1375
1376   g_strfreev (argv);
1377
1378   /* Try parsing again */
1379   argv = split_string ("program --t", &argc);
1380
1381   retval = g_option_context_parse (context, &argc, &argv, &error);
1382   g_assert (retval == FALSE);
1383
1384   g_strfreev (argv);
1385   g_option_context_free (context);
1386 }
1387
1388 int
1389 main (int argc, char **argv)
1390 {
1391   /* Test that restoration on failure works */
1392   error_test1_int = 0x12345678;
1393   error_test1 ();
1394   error_test2_string = "foo";
1395   error_test2 ();
1396   error_test3_boolean = FALSE;
1397   error_test3 ();
1398   
1399   /* Test that special argument parsing works */
1400   arg_test1 ();
1401   arg_test2 ();
1402   arg_test3 ();
1403   arg_test4 ();
1404   arg_test5 ();
1405   arg_test6 ();
1406
1407   /* Test string arrays */
1408   array_test1 ();
1409
1410   /* Test callback args */
1411   callback_test1 ();
1412   callback_test2 ();
1413
1414   /* Test optional arg flag for callback */
1415   callback_test_optional_1 ();
1416   callback_test_optional_2 ();
1417   callback_test_optional_3 ();
1418   callback_test_optional_4 ();
1419   callback_test_optional_5 ();
1420   callback_test_optional_6 ();
1421   callback_test_optional_7 ();
1422   callback_test_optional_8 ();
1423   
1424   /* Test ignoring options */
1425   ignore_test1 ();
1426   ignore_test2 ();
1427   ignore_test3 ();
1428
1429   add_test1 ();
1430
1431   /* Test parsing empty args */
1432   empty_test1 ();
1433   empty_test2 ();
1434   empty_test3 ();
1435
1436   /* Test handling of rest args */
1437   rest_test1 ();
1438   rest_test2 ();
1439   rest_test2a ();
1440   rest_test2b ();
1441   rest_test2c ();
1442   rest_test2d ();
1443   rest_test3 ();
1444   rest_test4 ();
1445   rest_test5 ();
1446
1447   /* test for bug 166609 */
1448   unknown_short_test ();
1449
1450   /* test for bug 168008 */
1451   lonely_dash_test ();
1452
1453   /* test for bug 305576 */
1454   missing_arg_test ();
1455
1456   return 0;
1457 }