Add check for if argc is 0.
[platform/upstream/glib.git] / tests / option-test.c
1 #include <glib.h>
2 #include "goption.h"
3 #include <string.h>
4
5 int error_test1_int;
6 char *error_test2_string;
7 gboolean error_test3_boolean;
8
9 int arg_test1_int;
10 gchar *arg_test2_string;
11 gchar *arg_test3_filename;
12
13 gchar **array_test1_array;
14
15 gboolean ignore_test1_boolean;
16 gboolean ignore_test2_boolean;
17 gchar *ignore_test3_string;
18
19 gchar **
20 split_string (const char *str, int *argc)
21 {
22   gchar **argv;
23   int len;
24   
25   argv = g_strsplit (str, " ", 0);
26
27   for (len = 0; argv[len] != NULL; len++);
28
29   if (argc)
30     *argc = len;
31     
32   return argv;
33 }
34
35 gchar *
36 join_stringv (int argc, char **argv)
37 {
38   int i;
39   GString *str;
40
41   str = g_string_new (NULL);
42
43   for (i = 0; i < argc; i++)
44     {
45       g_string_append (str, argv[i]);
46
47       if (i < argc - 1)
48         g_string_append_c (str, ' ');
49     }
50
51   return g_string_free (str, FALSE);
52 }
53
54 /* Performs a shallow copy */
55 char **
56 copy_stringv (char **argv, int argc)
57 {
58   return g_memdup (argv, sizeof (char *) * (argc + 1));
59 }
60
61
62 static gboolean
63 error_test1_pre_parse (GOptionContext *context,
64                        GOptionGroup   *group,
65                        gpointer        data,
66                        GError        **error)
67 {
68   g_assert (error_test1_int == 0x12345678);
69
70   return TRUE;
71 }
72
73 static gboolean
74 error_test1_post_parse (GOptionContext *context,
75                         GOptionGroup   *group,
76                         gpointer          data,
77                         GError        **error)
78 {
79   g_assert (error_test1_int == 20);
80
81   /* Set an error in the post hook */
82   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "");
83
84   return FALSE;
85 }
86
87 void
88 error_test1 (void)
89 {
90   GOptionContext *context;
91   gboolean retval;
92   GError *error = NULL;
93   gchar **argv;
94   int argc;
95   GOptionGroup *main_group;
96   GOptionEntry entries [] =
97     { { "test", 0, 0, G_OPTION_ARG_INT, &error_test1_int, NULL, NULL },
98       { NULL } };
99   
100   context = g_option_context_new (NULL);
101   g_option_context_add_main_entries (context, entries, NULL);
102
103   /* Set pre and post parse hooks */
104   main_group = g_option_context_get_main_group (context);
105   g_option_group_set_parse_hooks (main_group,
106                                   error_test1_pre_parse, error_test1_post_parse);
107   
108   /* Now try parsing */
109   argv = split_string ("program --test 20", &argc);
110
111   retval = g_option_context_parse (context, &argc, &argv, &error);
112   g_assert (retval == FALSE);
113
114   /* On failure, values should be reset */
115   g_assert (error_test1_int == 0x12345678);
116   
117   g_strfreev (argv);
118   g_option_context_free (context);
119   
120 }
121
122 static gboolean
123 error_test2_pre_parse (GOptionContext *context,
124                        GOptionGroup   *group,
125                        gpointer   data,
126                        GError        **error)
127 {
128   g_assert (strcmp (error_test2_string, "foo") == 0);
129
130   return TRUE;
131 }
132
133 static gboolean
134 error_test2_post_parse (GOptionContext *context,
135                         GOptionGroup   *group,
136                         gpointer          data,
137                         GError        **error)
138 {
139   g_assert (strcmp (error_test2_string, "bar") == 0);
140
141   /* Set an error in the post hook */
142   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "");
143
144   return FALSE;
145 }
146
147 void
148 error_test2 (void)
149 {
150   GOptionContext *context;
151   gboolean retval;
152   GError *error = NULL;
153   gchar **argv;
154   int argc;
155   GOptionGroup *main_group;
156   GOptionEntry entries [] =
157     { { "test", 0, 0, G_OPTION_ARG_STRING, &error_test2_string, NULL, NULL },
158       { NULL } };
159
160   context = g_option_context_new (NULL);
161   g_option_context_add_main_entries (context, entries, NULL);
162
163   /* Set pre and post parse hooks */
164   main_group = g_option_context_get_main_group (context);
165   g_option_group_set_parse_hooks (main_group,
166                                   error_test2_pre_parse, error_test2_post_parse);
167   
168   /* Now try parsing */
169   argv = split_string ("program --test bar", &argc);
170   retval = g_option_context_parse (context, &argc, &argv, &error);
171
172   g_error_free (error);
173   g_assert (retval == FALSE);
174
175   g_assert (strcmp (error_test2_string, "foo") == 0);
176   
177   g_strfreev (argv);
178   g_option_context_free (context);
179 }
180
181 static gboolean
182 error_test3_pre_parse (GOptionContext *context,
183                        GOptionGroup   *group,
184                        gpointer   data,
185                        GError        **error)
186 {
187   g_assert (!error_test3_boolean);
188
189   return TRUE;
190 }
191
192 static gboolean
193 error_test3_post_parse (GOptionContext *context,
194                         GOptionGroup   *group,
195                         gpointer          data,
196                         GError        **error)
197 {
198   g_assert (error_test3_boolean);
199
200   /* Set an error in the post hook */
201   g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "");
202
203   return FALSE;
204 }
205
206 void
207 error_test3 (void)
208 {
209   GOptionContext *context;
210   gboolean retval;
211   GError *error = NULL;
212   gchar **argv;
213   int argc;
214   GOptionGroup *main_group;
215   GOptionEntry entries [] =
216     { { "test", 0, 0, G_OPTION_ARG_NONE, &error_test3_boolean, NULL, NULL },
217       { NULL } };
218
219   context = g_option_context_new (NULL);
220   g_option_context_add_main_entries (context, entries, NULL);
221
222   /* Set pre and post parse hooks */
223   main_group = g_option_context_get_main_group (context);
224   g_option_group_set_parse_hooks (main_group,
225                                   error_test3_pre_parse, error_test3_post_parse);
226   
227   /* Now try parsing */
228   argv = split_string ("program --test", &argc);
229   retval = g_option_context_parse (context, &argc, &argv, &error);
230
231   g_error_free (error);
232   g_assert (retval == FALSE);
233
234   g_assert (!error_test3_boolean);
235   
236   g_strfreev (argv);
237   g_option_context_free (context);
238 }
239
240 void
241 arg_test1 (void)
242 {
243   GOptionContext *context;
244   gboolean retval;
245   GError *error = NULL;
246   gchar **argv;
247   int argc;
248   GOptionEntry entries [] =
249     { { "test", 0, 0, G_OPTION_ARG_INT, &arg_test1_int, NULL, NULL },
250       { NULL } };
251
252   context = g_option_context_new (NULL);
253   g_option_context_add_main_entries (context, entries, NULL);
254
255   /* Now try parsing */
256   argv = split_string ("program --test 20 --test 30", &argc);
257
258   retval = g_option_context_parse (context, &argc, &argv, &error);
259   g_assert (retval);
260
261   /* Last arg specified is the one that should be stored */
262   g_assert (arg_test1_int == 30);
263
264   g_strfreev (argv);
265   g_option_context_free (context);
266 }
267
268 void
269 arg_test2 (void)
270 {
271   GOptionContext *context;
272   gboolean retval;
273   GError *error = NULL;
274   gchar **argv;
275   int argc;
276   GOptionEntry entries [] =
277     { { "test", 0, 0, G_OPTION_ARG_STRING, &arg_test2_string, NULL, NULL },
278       { NULL } };
279   
280   context = g_option_context_new (NULL);
281   g_option_context_add_main_entries (context, entries, NULL);
282
283   /* Now try parsing */
284   argv = split_string ("program --test foo --test bar", &argc);
285   
286   retval = g_option_context_parse (context, &argc, &argv, &error);
287   g_assert (retval);
288
289   /* Last arg specified is the one that should be stored */
290   g_assert (strcmp (arg_test2_string, "bar") == 0);
291
292   g_free (arg_test2_string);
293   
294   g_strfreev (argv);
295   g_option_context_free (context);
296 }
297
298 void
299 arg_test3 (void)
300 {
301   GOptionContext *context;
302   gboolean retval;
303   GError *error = NULL;
304   gchar **argv;
305   int argc;
306   GOptionEntry entries [] =
307     { { "test", 0, 0, G_OPTION_ARG_FILENAME, &arg_test3_filename, NULL, NULL },
308       { NULL } };
309   
310   context = g_option_context_new (NULL);
311   g_option_context_add_main_entries (context, entries, NULL);
312
313   /* Now try parsing */
314   argv = split_string ("program --test foo.txt", &argc);
315   
316   retval = g_option_context_parse (context, &argc, &argv, &error);
317   g_assert (retval);
318
319   /* Last arg specified is the one that should be stored */
320   g_assert (strcmp (arg_test3_filename, "foo.txt") == 0);
321
322   g_free (arg_test3_filename);
323   
324   g_strfreev (argv);
325   g_option_context_free (context);
326 }
327
328 void
329 ignore_test1 (void)
330 {
331   GOptionContext *context;
332   gboolean retval;
333   GError *error = NULL;
334   gchar **argv, **argv_copy;
335   int argc;
336   gchar *arg;
337   GOptionEntry entries [] =
338     { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
339       { NULL } };
340
341   context = g_option_context_new (NULL);
342   g_option_context_set_ignore_unknown_options (context, TRUE);
343   g_option_context_add_main_entries (context, entries, NULL);
344
345   /* Now try parsing */
346   argv = split_string ("program --test --hello", &argc);
347   argv_copy = copy_stringv (argv, argc);
348   
349   retval = g_option_context_parse (context, &argc, &argv, &error);
350   g_assert (retval);
351
352   /* Check array */
353   arg = join_stringv (argc, argv);
354   g_assert (strcmp (arg, "program --hello") == 0);
355
356   g_free (arg);
357   g_strfreev (argv_copy);
358   g_free (argv);
359   g_option_context_free (context);
360 }
361
362 void
363 ignore_test2 (void)
364 {
365   GOptionContext *context;
366   gboolean retval;
367   GError *error = NULL;
368   gchar **argv;
369   int argc;
370   gchar *arg;
371   GOptionEntry entries [] =
372     { { "test", 't', 0, G_OPTION_ARG_NONE, &ignore_test2_boolean, NULL, NULL },
373       { NULL } };
374
375   context = g_option_context_new (NULL);
376   g_option_context_set_ignore_unknown_options (context, TRUE);
377   g_option_context_add_main_entries (context, entries, NULL);
378
379   /* Now try parsing */
380   argv = split_string ("program -test", &argc);
381   
382   retval = g_option_context_parse (context, &argc, &argv, &error);
383   g_assert (retval);
384
385   /* Check array */
386   arg = join_stringv (argc, argv);
387   g_assert (strcmp (arg, "program -es") == 0);
388
389   g_free (arg);
390   g_strfreev (argv);
391   g_option_context_free (context);
392 }
393
394 void
395 ignore_test3 (void)
396 {
397   GOptionContext *context;
398   gboolean retval;
399   GError *error = NULL;
400   gchar **argv, **argv_copy;
401   int argc;
402   gchar *arg;
403   GOptionEntry entries [] =
404     { { "test", 0, 0, G_OPTION_ARG_STRING, &ignore_test3_string, NULL, NULL },
405       { NULL } };
406
407   context = g_option_context_new (NULL);
408   g_option_context_set_ignore_unknown_options (context, TRUE);
409   g_option_context_add_main_entries (context, entries, NULL);
410
411   /* Now try parsing */
412   argv = split_string ("program --test foo --hello", &argc);
413   argv_copy = copy_stringv (argv, argc);
414   
415   retval = g_option_context_parse (context, &argc, &argv, &error);
416   g_assert (retval);
417
418   /* Check array */
419   arg = join_stringv (argc, argv);
420   g_assert (strcmp (arg, "program --hello") == 0);
421
422   g_assert (strcmp (ignore_test3_string, "foo") == 0);
423   g_free (ignore_test3_string);
424
425   g_free (arg);
426   g_strfreev (argv_copy);
427   g_free (argv);
428   g_option_context_free (context);
429 }
430
431 void
432 array_test1 (void)
433 {
434   GOptionContext *context;
435   gboolean retval;
436   GError *error = NULL;
437   gchar **argv;
438   int argc;
439   GOptionEntry entries [] =
440     { { "test", 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
441       { NULL } };
442         
443   context = g_option_context_new (NULL);
444   g_option_context_add_main_entries (context, entries, NULL);
445
446   /* Now try parsing */
447   argv = split_string ("program --test foo --test bar", &argc);
448   
449   retval = g_option_context_parse (context, &argc, &argv, &error);
450   g_assert (retval);
451
452   /* Check array */
453   g_assert (strcmp (array_test1_array[0], "foo") == 0);
454   g_assert (strcmp (array_test1_array[1], "bar") == 0);
455   g_assert (array_test1_array[2] == NULL);
456
457   g_strfreev (array_test1_array);
458   
459   g_strfreev (argv);
460   g_option_context_free (context);
461 }
462
463 void
464 add_test1 (void)
465 {
466   GOptionContext *context;
467
468   GOptionEntry entries1 [] =
469     { { "test1", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
470       { NULL } };
471   GOptionEntry entries2 [] =
472     { { "test2", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
473       { NULL } };
474
475   context = g_option_context_new (NULL);
476   g_option_context_add_main_entries (context, entries1, NULL);
477   g_option_context_add_main_entries (context, entries2, NULL);
478
479   g_option_context_free (context);
480 }
481
482 void
483 empty_test1 (void)
484 {
485   GOptionContext *context;
486   GOptionEntry entries [] =
487     { { NULL } };
488
489   context = g_option_context_new (NULL);
490
491   g_option_context_add_main_entries (context, entries, NULL);
492   
493   g_option_context_parse (context, NULL, NULL, NULL);
494
495   g_assert (strcmp (g_get_prgname (), "<unknown>") == 0);
496   
497   g_option_context_free (context);
498 }
499
500 void
501 empty_test2 (void)
502 {
503   GOptionContext *context;
504
505   context = g_option_context_new (NULL);
506   g_option_context_parse (context, NULL, NULL, NULL);
507   
508   g_option_context_free (context);
509 }
510
511 void
512 empty_test3 (void)
513 {
514   GOptionContext *context;
515   gint argc;
516   gchar **argv;
517
518   argc = 0;
519   argv = NULL;
520
521   context = g_option_context_new (NULL);
522   g_option_context_parse (context, &argc, &argv, NULL);
523   
524   g_option_context_free (context);
525 }
526
527 int
528 main (int argc, char **argv)
529 {
530   /* Test that restoration on failure works */
531   error_test1_int = 0x12345678;
532   error_test1 ();
533   error_test2_string = "foo";
534   error_test2 ();
535   error_test3_boolean = FALSE;
536   error_test3 ();
537   
538   /* Test that special argument parsing works */
539   arg_test1 ();
540   arg_test2 ();
541   arg_test3 ();
542
543   /* Test string arrays */
544   array_test1 ();
545
546   /* Test ignoring options */
547   ignore_test1 ();
548   ignore_test2 ();
549   ignore_test3 ();
550
551   add_test1 ();
552
553   /* Test parsing empty args */
554   empty_test1 ();
555   empty_test2 ();
556   empty_test3 ();
557
558   return 0;
559 }