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