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