Branch data Line data Source code
1 : : /* Unit tests for GOptionContext
2 : : * Copyright (C) 2007 Openismus GmbH
3 : : * Authors: Mathias Hasselmann
4 : : *
5 : : * SPDX-License-Identifier: LicenseRef-old-glib-tests
6 : : *
7 : : * This work is provided "as is"; redistribution and modification
8 : : * in whole or in part, in any medium, physical or electronic is
9 : : * permitted without restriction.
10 : : *
11 : : * This work is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 : : *
15 : : * In no event shall the authors or contributors be liable for any
16 : : * direct, indirect, incidental, special, exemplary, or consequential
17 : : * damages (including, but not limited to, procurement of substitute
18 : : * goods or services; loss of use, data, or profits; or business
19 : : * interruption) however caused and on any theory of liability, whether
20 : : * in contract, strict liability, or tort (including negligence or
21 : : * otherwise) arising in any way out of the use of this software, even
22 : : * if advised of the possibility of such damage.
23 : : */
24 : :
25 : : #include <glib.h>
26 : :
27 : : #include <stdlib.h>
28 : : #include <stdio.h>
29 : : #include <string.h>
30 : : #include <locale.h>
31 : : #include <math.h>
32 : :
33 : : static GOptionEntry global_main_entries[] = {
34 : : { "main-switch", 0, 0,
35 : : G_OPTION_ARG_NONE, NULL,
36 : : "A switch that is in the main group", NULL },
37 : : G_OPTION_ENTRY_NULL
38 : : };
39 : :
40 : : static GOptionEntry global_group_entries[] = {
41 : : { "test-switch", 0, 0,
42 : : G_OPTION_ARG_NONE, NULL,
43 : : "A switch that is in the test group", NULL },
44 : : G_OPTION_ENTRY_NULL
45 : : };
46 : :
47 : : static GOptionContext *
48 : 12 : make_options (int test_number)
49 : : {
50 : : GOptionContext *options;
51 : 12 : GOptionGroup *group = NULL;
52 : 12 : gboolean have_main_entries = (0 != (test_number & 1));
53 : 12 : gboolean have_test_entries = (0 != (test_number & 2));
54 : :
55 : 12 : options = g_option_context_new (NULL);
56 : :
57 [ + + ]: 12 : if (have_main_entries)
58 : 6 : g_option_context_add_main_entries (options, global_main_entries, NULL);
59 [ + + ]: 12 : if (have_test_entries)
60 : : {
61 : 6 : group = g_option_group_new ("test", "Test Options",
62 : : "Show all test options",
63 : : NULL, NULL);
64 : 6 : g_option_context_add_group (options, group);
65 : 6 : g_option_group_add_entries (group, global_group_entries);
66 : : }
67 : :
68 : 12 : return options;
69 : : }
70 : :
71 : : static void
72 : 12 : print_help (GOptionContext *options, gchar **argv)
73 : : {
74 : 12 : gint argc = 3;
75 : 12 : GError *error = NULL;
76 : :
77 : 12 : g_option_context_parse (options, &argc, &argv, &error);
78 : 2 : g_option_context_free (options);
79 : 2 : exit(0);
80 : : }
81 : :
82 : : static void
83 : 4 : test_group_captions_help (gconstpointer test_number)
84 : : {
85 : : GOptionContext *options;
86 : 4 : gchar *argv[] = { __FILE__, "--help", NULL };
87 : :
88 : 4 : options = make_options (GPOINTER_TO_INT (test_number));
89 : 4 : print_help (options, argv);
90 : 0 : }
91 : :
92 : : static void
93 : 4 : test_group_captions_help_all (gconstpointer test_number)
94 : : {
95 : : GOptionContext *options;
96 : 4 : gchar *argv[] = { __FILE__, "--help-all", NULL };
97 : :
98 : 4 : options = make_options (GPOINTER_TO_INT (test_number));
99 : 4 : print_help (options, argv);
100 : 0 : }
101 : :
102 : : static void
103 : 4 : test_group_captions_help_test (gconstpointer test_number)
104 : : {
105 : : GOptionContext *options;
106 : 4 : gchar *argv[] = { __FILE__, "--help-test", NULL };
107 : :
108 : 4 : options = make_options (GPOINTER_TO_INT (test_number));
109 : 4 : print_help (options, argv);
110 : 0 : }
111 : :
112 : : static void
113 : 1 : test_group_captions (void)
114 : : {
115 : 1 : const gchar *test_name_base[] = { "help", "help-all", "help-test" };
116 : : gchar *test_name;
117 : : guint i;
118 : : gsize j;
119 : :
120 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=504142");
121 : :
122 [ + + ]: 5 : for (i = 0; i < 4; ++i)
123 : : {
124 : 4 : gboolean have_main_entries = (0 != (i & 1));
125 : 4 : gboolean have_test_entries = (0 != (i & 2));
126 : :
127 [ + + ]: 16 : for (j = 0; j < G_N_ELEMENTS (test_name_base); ++j)
128 : : {
129 : 12 : GTestSubprocessFlags trap_flags = 0;
130 : 12 : gboolean expect_main_description = FALSE;
131 : 12 : gboolean expect_main_switch = FALSE;
132 : 12 : gboolean expect_test_description = FALSE;
133 : 12 : gboolean expect_test_switch = FALSE;
134 : 12 : gboolean expect_test_group = FALSE;
135 : :
136 [ - + ]: 12 : if (g_test_verbose ())
137 : 0 : trap_flags |= G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR;
138 : :
139 : 12 : test_name = g_strdup_printf ("/option/group/captions/subprocess/%s-%u",
140 : : test_name_base[j], i);
141 : 12 : g_test_trap_subprocess (test_name, 0, trap_flags);
142 : 12 : g_free (test_name);
143 : 12 : g_test_trap_assert_passed ();
144 : 12 : g_test_trap_assert_stderr ("");
145 : :
146 [ + + + - ]: 12 : switch (j)
147 : : {
148 : 4 : case 0:
149 : 4 : g_assert_cmpstr ("help", ==, test_name_base[j]);
150 : 4 : expect_main_switch = have_main_entries;
151 : 4 : expect_test_group = have_test_entries;
152 : 4 : break;
153 : :
154 : 4 : case 1:
155 : 4 : g_assert_cmpstr ("help-all", ==, test_name_base[j]);
156 : 4 : expect_main_switch = have_main_entries;
157 : 4 : expect_test_switch = have_test_entries;
158 : 4 : expect_test_group = have_test_entries;
159 : 4 : break;
160 : :
161 : 4 : case 2:
162 : 4 : g_assert_cmpstr ("help-test", ==, test_name_base[j]);
163 : 4 : expect_test_switch = have_test_entries;
164 : 4 : break;
165 : :
166 : 0 : default:
167 : : g_assert_not_reached ();
168 : : break;
169 : : }
170 : :
171 : 12 : expect_main_description |= expect_main_switch;
172 : 12 : expect_test_description |= expect_test_switch;
173 : :
174 [ + + ]: 12 : if (expect_main_description)
175 : 4 : g_test_trap_assert_stdout ("*Application Options*");
176 : : else
177 : 8 : g_test_trap_assert_stdout_unmatched ("*Application Options*");
178 [ + + ]: 12 : if (expect_main_switch)
179 : 4 : g_test_trap_assert_stdout ("*--main-switch*");
180 : : else
181 : 8 : g_test_trap_assert_stdout_unmatched ("*--main-switch*");
182 : :
183 [ + + ]: 12 : if (expect_test_description)
184 : 4 : g_test_trap_assert_stdout ("*Test Options*");
185 : : else
186 : 8 : g_test_trap_assert_stdout_unmatched ("*Test Options*");
187 [ + + ]: 12 : if (expect_test_switch)
188 : 4 : g_test_trap_assert_stdout ("*--test-switch*");
189 : : else
190 : 8 : g_test_trap_assert_stdout_unmatched ("*--test-switch*");
191 : :
192 [ + + ]: 12 : if (expect_test_group)
193 : 4 : g_test_trap_assert_stdout ("*--help-test*");
194 : : else
195 : 8 : g_test_trap_assert_stdout_unmatched ("*--help-test*");
196 : : }
197 : : }
198 : 1 : }
199 : :
200 : : int error_test1_int;
201 : : char *error_test2_string;
202 : : gboolean error_test3_boolean;
203 : :
204 : : int arg_test1_int;
205 : : gchar *arg_test2_string;
206 : : gchar *arg_test3_filename;
207 : : gdouble arg_test4_double;
208 : : gdouble arg_test5_double;
209 : : gint64 arg_test6_int64;
210 : : gint64 arg_test6_int64_2;
211 : :
212 : : gchar *callback_test1_string;
213 : : int callback_test2_int;
214 : :
215 : : gchar *callback_test_optional_string;
216 : : gboolean callback_test_optional_boolean;
217 : :
218 : : gchar **array_test1_array;
219 : :
220 : : gboolean ignore_test1_boolean;
221 : : gboolean ignore_test2_boolean;
222 : : gchar *ignore_test3_string;
223 : :
224 : : static gchar **
225 : 55 : split_string (const char *str, int *argc)
226 : : {
227 : : gchar **argv;
228 : : int len;
229 : :
230 : 55 : argv = g_strsplit (str, " ", 0);
231 : :
232 [ + + ]: 254 : for (len = 0; argv[len] != NULL; len++);
233 : :
234 [ + + ]: 55 : if (argc)
235 : 51 : *argc = len;
236 : :
237 : 55 : return argv;
238 : : }
239 : :
240 : : static gchar *
241 : 3 : join_stringv (int argc, char **argv)
242 : : {
243 : : int i;
244 : : GString *str;
245 : :
246 : 3 : str = g_string_new (NULL);
247 : :
248 [ + + ]: 9 : for (i = 0; i < argc; i++)
249 : : {
250 [ - + ]: 6 : g_string_append (str, argv[i]);
251 : :
252 [ + + ]: 6 : if (i < argc - 1)
253 : : g_string_append_c (str, ' ');
254 : : }
255 : :
256 : 3 : return g_string_free (str, FALSE);
257 : : }
258 : :
259 : : /* Performs a shallow copy */
260 : : static char **
261 : 47 : copy_stringv (char **argv, int argc)
262 : : {
263 : 47 : return g_memdup2 (argv, sizeof (char *) * (argc + 1));
264 : : }
265 : :
266 : : static void
267 : 10 : check_identical_stringv (gchar **before, gchar **after)
268 : : {
269 : : guint i;
270 : :
271 : : /* Not only is it the same string... */
272 [ + + ]: 34 : for (i = 0; before[i] != NULL; i++)
273 : 24 : g_assert_cmpstr (before[i], ==, after[i]);
274 : :
275 : : /* ... it is actually the same pointer */
276 [ + + ]: 34 : for (i = 0; before[i] != NULL; i++)
277 : 24 : g_assert (before[i] == after[i]);
278 : :
279 : 10 : g_assert (after[i] == NULL);
280 : 10 : }
281 : :
282 : :
283 : : static gboolean
284 : 1 : error_test1_pre_parse (GOptionContext *context,
285 : : GOptionGroup *group,
286 : : gpointer data,
287 : : GError **error)
288 : : {
289 : 1 : g_assert (error_test1_int == 0x12345678);
290 : :
291 : 1 : return TRUE;
292 : : }
293 : :
294 : : static gboolean
295 : 1 : error_test1_post_parse (GOptionContext *context,
296 : : GOptionGroup *group,
297 : : gpointer data,
298 : : GError **error)
299 : : {
300 : 1 : g_assert (error_test1_int == 20);
301 : :
302 : : /* Set an error in the post hook */
303 : 1 : g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
304 : :
305 : 1 : return FALSE;
306 : : }
307 : :
308 : : static void
309 : 1 : error_test1 (void)
310 : : {
311 : : GOptionContext *context;
312 : : gboolean retval;
313 : 1 : GError *error = NULL;
314 : : gchar **argv;
315 : : gchar **argv_copy;
316 : : int argc;
317 : : GOptionGroup *main_group;
318 : 1 : GOptionEntry entries [] =
319 : : { { "test", 0, 0, G_OPTION_ARG_INT, &error_test1_int, NULL, NULL },
320 : : G_OPTION_ENTRY_NULL };
321 : :
322 : 1 : error_test1_int = 0x12345678;
323 : :
324 : 1 : context = g_option_context_new (NULL);
325 : 1 : g_option_context_add_main_entries (context, entries, NULL);
326 : :
327 : : /* Set pre and post parse hooks */
328 : 1 : main_group = g_option_context_get_main_group (context);
329 : 1 : g_option_group_set_parse_hooks (main_group,
330 : : error_test1_pre_parse, error_test1_post_parse);
331 : :
332 : : /* Now try parsing */
333 : 1 : argv = split_string ("program --test 20", &argc);
334 : 1 : argv_copy = copy_stringv (argv, argc);
335 : :
336 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
337 : 1 : g_assert (retval == FALSE);
338 : 1 : g_assert (error != NULL);
339 : : /* An error occurred, so argv has not been changed */
340 : 1 : check_identical_stringv (argv_copy, argv);
341 : 1 : g_clear_error (&error);
342 : :
343 : : /* On failure, values should be reset */
344 : 1 : g_assert (error_test1_int == 0x12345678);
345 : :
346 : 1 : g_strfreev (argv_copy);
347 : 1 : g_free (argv);
348 : 1 : g_option_context_free (context);
349 : 1 : }
350 : :
351 : : static gboolean
352 : 1 : error_test2_pre_parse (GOptionContext *context,
353 : : GOptionGroup *group,
354 : : gpointer data,
355 : : GError **error)
356 : : {
357 : 1 : g_assert (strcmp (error_test2_string, "foo") == 0);
358 : :
359 : 1 : return TRUE;
360 : : }
361 : :
362 : : static gboolean
363 : 1 : error_test2_post_parse (GOptionContext *context,
364 : : GOptionGroup *group,
365 : : gpointer data,
366 : : GError **error)
367 : : {
368 : 1 : g_assert (strcmp (error_test2_string, "bar") == 0);
369 : :
370 : : /* Set an error in the post hook */
371 : 1 : g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
372 : :
373 : 1 : return FALSE;
374 : : }
375 : :
376 : : static void
377 : 1 : error_test2 (void)
378 : : {
379 : : GOptionContext *context;
380 : : gboolean retval;
381 : 1 : GError *error = NULL;
382 : : gchar **argv;
383 : : gchar **argv_copy;
384 : : int argc;
385 : : GOptionGroup *main_group;
386 : 1 : GOptionEntry entries [] =
387 : : { { "test", 0, 0, G_OPTION_ARG_STRING, &error_test2_string, NULL, NULL },
388 : : G_OPTION_ENTRY_NULL };
389 : :
390 : 1 : error_test2_string = "foo";
391 : :
392 : 1 : context = g_option_context_new (NULL);
393 : 1 : g_option_context_add_main_entries (context, entries, NULL);
394 : :
395 : : /* Set pre and post parse hooks */
396 : 1 : main_group = g_option_context_get_main_group (context);
397 : 1 : g_option_group_set_parse_hooks (main_group,
398 : : error_test2_pre_parse, error_test2_post_parse);
399 : :
400 : : /* Now try parsing */
401 : 1 : argv = split_string ("program --test bar", &argc);
402 : 1 : argv_copy = copy_stringv (argv, argc);
403 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
404 : :
405 : 1 : g_assert (retval == FALSE);
406 : 1 : g_assert (error != NULL);
407 : 1 : check_identical_stringv (argv_copy, argv);
408 : 1 : g_clear_error (&error);
409 : :
410 : 1 : g_assert (strcmp (error_test2_string, "foo") == 0);
411 : :
412 : 1 : g_strfreev (argv_copy);
413 : 1 : g_free (argv);
414 : 1 : g_option_context_free (context);
415 : 1 : }
416 : :
417 : : static gboolean
418 : 1 : error_test3_pre_parse (GOptionContext *context,
419 : : GOptionGroup *group,
420 : : gpointer data,
421 : : GError **error)
422 : : {
423 : 1 : g_assert (!error_test3_boolean);
424 : :
425 : 1 : return TRUE;
426 : : }
427 : :
428 : : static gboolean
429 : 1 : error_test3_post_parse (GOptionContext *context,
430 : : GOptionGroup *group,
431 : : gpointer data,
432 : : GError **error)
433 : : {
434 : 1 : g_assert (error_test3_boolean);
435 : :
436 : : /* Set an error in the post hook */
437 : 1 : g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, " ");
438 : :
439 : 1 : return FALSE;
440 : : }
441 : :
442 : : static void
443 : 1 : error_test3 (void)
444 : : {
445 : : GOptionContext *context;
446 : : gboolean retval;
447 : 1 : GError *error = NULL;
448 : : gchar **argv;
449 : : gchar **argv_copy;
450 : : int argc;
451 : : GOptionGroup *main_group;
452 : 1 : GOptionEntry entries [] =
453 : : { { "test", 0, 0, G_OPTION_ARG_NONE, &error_test3_boolean, NULL, NULL },
454 : : G_OPTION_ENTRY_NULL };
455 : :
456 : 1 : error_test3_boolean = FALSE;
457 : :
458 : 1 : context = g_option_context_new (NULL);
459 : 1 : g_option_context_add_main_entries (context, entries, NULL);
460 : :
461 : : /* Set pre and post parse hooks */
462 : 1 : main_group = g_option_context_get_main_group (context);
463 : 1 : g_option_group_set_parse_hooks (main_group,
464 : : error_test3_pre_parse, error_test3_post_parse);
465 : :
466 : : /* Now try parsing */
467 : 1 : argv = split_string ("program --test", &argc);
468 : 1 : argv_copy = copy_stringv (argv, argc);
469 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
470 : :
471 : 1 : g_assert (retval == FALSE);
472 : 1 : g_assert (error != NULL);
473 : 1 : check_identical_stringv (argv_copy, argv);
474 : 1 : g_clear_error (&error);
475 : :
476 : 1 : g_assert (!error_test3_boolean);
477 : :
478 : 1 : g_strfreev (argv_copy);
479 : 1 : g_free (argv);
480 : 1 : g_option_context_free (context);
481 : 1 : }
482 : :
483 : : static void
484 : 1 : arg_test1 (void)
485 : : {
486 : : GOptionContext *context;
487 : : gboolean retval;
488 : 1 : GError *error = NULL;
489 : : gchar **argv;
490 : : gchar **argv_copy;
491 : : int argc;
492 : 1 : GOptionEntry entries [] =
493 : : { { "test", 0, 0, G_OPTION_ARG_INT, &arg_test1_int, NULL, NULL },
494 : : G_OPTION_ENTRY_NULL };
495 : :
496 : 1 : context = g_option_context_new (NULL);
497 : 1 : g_option_context_add_main_entries (context, entries, NULL);
498 : :
499 : : /* Now try parsing */
500 : 1 : argv = split_string ("program --test 20 --test 30", &argc);
501 : 1 : argv_copy = copy_stringv (argv, argc);
502 : :
503 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
504 : 1 : g_assert_no_error (error);
505 : 1 : g_assert (retval);
506 : :
507 : : /* Last arg specified is the one that should be stored */
508 : 1 : g_assert (arg_test1_int == 30);
509 : :
510 : : /* We free all of the strings in a copy of argv, because now argv is a
511 : : * subset - some have been removed in-place
512 : : */
513 : 1 : g_strfreev (argv_copy);
514 : 1 : g_free (argv);
515 : 1 : g_option_context_free (context);
516 : 1 : }
517 : :
518 : : static void
519 : 1 : arg_test2 (void)
520 : : {
521 : : GOptionContext *context;
522 : : gboolean retval;
523 : 1 : GError *error = NULL;
524 : : gchar **argv;
525 : : gchar **argv_copy;
526 : : int argc;
527 : 1 : GOptionEntry entries [] =
528 : : { { "test", 0, 0, G_OPTION_ARG_STRING, &arg_test2_string, NULL, NULL },
529 : : G_OPTION_ENTRY_NULL };
530 : :
531 : 1 : context = g_option_context_new (NULL);
532 : 1 : g_option_context_add_main_entries (context, entries, NULL);
533 : :
534 : : /* Now try parsing */
535 : 1 : argv = split_string ("program --test foo --test bar", &argc);
536 : 1 : argv_copy = copy_stringv (argv, argc);
537 : :
538 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
539 : 1 : g_assert_no_error (error);
540 : 1 : g_assert (retval);
541 : :
542 : : /* Last arg specified is the one that should be stored */
543 : 1 : g_assert (strcmp (arg_test2_string, "bar") == 0);
544 : :
545 : 1 : g_free (arg_test2_string);
546 : :
547 : 1 : g_strfreev (argv_copy);
548 : 1 : g_free (argv);
549 : 1 : g_option_context_free (context);
550 : 1 : }
551 : :
552 : : static void
553 : 1 : arg_test3 (void)
554 : : {
555 : : GOptionContext *context;
556 : : gboolean retval;
557 : 1 : GError *error = NULL;
558 : : gchar **argv;
559 : : gchar **argv_copy;
560 : : int argc;
561 : 1 : GOptionEntry entries [] =
562 : : { { "test", 0, 0, G_OPTION_ARG_FILENAME, &arg_test3_filename, NULL, NULL },
563 : : G_OPTION_ENTRY_NULL };
564 : :
565 : 1 : context = g_option_context_new (NULL);
566 : 1 : g_option_context_add_main_entries (context, entries, NULL);
567 : :
568 : : /* Now try parsing */
569 : 1 : argv = split_string ("program --test foo.txt", &argc);
570 : 1 : argv_copy = copy_stringv (argv, argc);
571 : :
572 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
573 : 1 : g_assert_no_error (error);
574 : 1 : g_assert (retval);
575 : :
576 : : /* Last arg specified is the one that should be stored */
577 : 1 : g_assert (strcmp (arg_test3_filename, "foo.txt") == 0);
578 : :
579 : 1 : g_free (arg_test3_filename);
580 : :
581 : 1 : g_strfreev (argv_copy);
582 : 1 : g_free (argv);
583 : 1 : g_option_context_free (context);
584 : 1 : }
585 : :
586 : : static void
587 : 1 : arg_test4 (void)
588 : : {
589 : : GOptionContext *context;
590 : : gboolean retval;
591 : 1 : GError *error = NULL;
592 : : gchar **argv_copy;
593 : : gchar **argv;
594 : : int argc;
595 : 1 : GOptionEntry entries [] =
596 : : { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test4_double, NULL, NULL },
597 : : G_OPTION_ENTRY_NULL };
598 : :
599 : 1 : context = g_option_context_new (NULL);
600 : 1 : g_option_context_add_main_entries (context, entries, NULL);
601 : :
602 : : /* Now try parsing */
603 : 1 : argv = split_string ("program --test 20.0 --test 30.03", &argc);
604 : 1 : argv_copy = copy_stringv (argv, argc);
605 : :
606 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
607 : 1 : g_assert_no_error (error);
608 : 1 : g_assert (retval);
609 : :
610 : : /* Last arg specified is the one that should be stored */
611 : 1 : g_assert (arg_test4_double == 30.03);
612 : :
613 : 1 : g_strfreev (argv_copy);
614 : 1 : g_free (argv);
615 : 1 : g_option_context_free (context);
616 : 1 : }
617 : :
618 : : static void
619 : 1 : arg_test5 (void)
620 : : {
621 : : GOptionContext *context;
622 : : gboolean retval;
623 : 1 : GError *error = NULL;
624 : : gchar **argv;
625 : : gchar **argv_copy;
626 : : int argc;
627 : : char *old_locale, *current_locale;
628 : 1 : const char *locale = "de_DE.UTF-8";
629 : 1 : GOptionEntry entries [] =
630 : : { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &arg_test5_double, NULL, NULL },
631 : : G_OPTION_ENTRY_NULL };
632 : :
633 : 1 : context = g_option_context_new (NULL);
634 : 1 : g_option_context_add_main_entries (context, entries, NULL);
635 : :
636 : : /* Now try parsing */
637 : 1 : argv = split_string ("program --test 20,0 --test 30,03", &argc);
638 : 1 : argv_copy = copy_stringv (argv, argc);
639 : :
640 : : /* set it to some locale that uses commas instead of decimal points */
641 : :
642 : 1 : old_locale = g_strdup (setlocale (LC_NUMERIC, locale));
643 : 1 : current_locale = setlocale (LC_NUMERIC, NULL);
644 [ - + ]: 1 : if (strcmp (current_locale, locale) != 0)
645 : : {
646 : 0 : fprintf (stderr, "Cannot set locale to %s, skipping\n", locale);
647 : 0 : goto cleanup;
648 : : }
649 : :
650 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
651 : 1 : g_assert_no_error (error);
652 : 1 : g_assert (retval);
653 : :
654 : : /* Last arg specified is the one that should be stored */
655 : 1 : g_assert (arg_test5_double == 30.03);
656 : :
657 : 1 : cleanup:
658 : 1 : setlocale (LC_NUMERIC, old_locale);
659 : 1 : g_free (old_locale);
660 : :
661 : 1 : g_strfreev (argv_copy);
662 : 1 : g_free (argv);
663 : 1 : g_option_context_free (context);
664 : 1 : }
665 : :
666 : : static void
667 : 1 : arg_test6 (void)
668 : : {
669 : : GOptionContext *context;
670 : : gboolean retval;
671 : 1 : GError *error = NULL;
672 : : gchar **argv;
673 : : gchar **argv_copy;
674 : : int argc;
675 : 1 : GOptionEntry entries [] =
676 : : { { "test", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64, NULL, NULL },
677 : : { "test2", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64_2, NULL, NULL },
678 : : G_OPTION_ENTRY_NULL };
679 : :
680 : 1 : context = g_option_context_new (NULL);
681 : 1 : g_option_context_add_main_entries (context, entries, NULL);
682 : :
683 : : /* Now try parsing */
684 : 1 : argv = split_string ("program --test 4294967297 --test 4294967296 --test2 0xfffffffff", &argc);
685 : 1 : argv_copy = copy_stringv (argv, argc);
686 : :
687 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
688 : 1 : g_assert_no_error (error);
689 : 1 : g_assert (retval);
690 : :
691 : : /* Last arg specified is the one that should be stored */
692 : 1 : g_assert (arg_test6_int64 == G_GINT64_CONSTANT(4294967296));
693 : 1 : g_assert (arg_test6_int64_2 == G_GINT64_CONSTANT(0xfffffffff));
694 : :
695 : 1 : g_strfreev (argv_copy);
696 : 1 : g_free (argv);
697 : 1 : g_option_context_free (context);
698 : 1 : }
699 : :
700 : : static gboolean
701 : 1 : callback_parse1 (const gchar *option_name, const gchar *value,
702 : : gpointer data, GError **error)
703 : : {
704 : 1 : callback_test1_string = g_strdup (value);
705 : 1 : return TRUE;
706 : : }
707 : :
708 : : static void
709 : 1 : callback_test1 (void)
710 : : {
711 : : GOptionContext *context;
712 : : gboolean retval;
713 : 1 : GError *error = NULL;
714 : : gchar **argv;
715 : : gchar **argv_copy;
716 : : int argc;
717 : 1 : GOptionEntry entries [] =
718 : : { { "test", 0, 0, G_OPTION_ARG_CALLBACK, callback_parse1, NULL, NULL },
719 : : G_OPTION_ENTRY_NULL };
720 : :
721 : 1 : context = g_option_context_new (NULL);
722 : 1 : g_option_context_add_main_entries (context, entries, NULL);
723 : :
724 : : /* Now try parsing */
725 : 1 : argv = split_string ("program --test foo.txt", &argc);
726 : 1 : argv_copy = copy_stringv (argv, argc);
727 : :
728 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
729 : 1 : g_assert_no_error (error);
730 : 1 : g_assert (retval);
731 : :
732 : 1 : g_assert (strcmp (callback_test1_string, "foo.txt") == 0);
733 : :
734 : 1 : g_free (callback_test1_string);
735 : :
736 : 1 : g_strfreev (argv_copy);
737 : 1 : g_free (argv);
738 : 1 : g_option_context_free (context);
739 : 1 : }
740 : :
741 : : static gboolean
742 : 2 : callback_parse2 (const gchar *option_name, const gchar *value,
743 : : gpointer data, GError **error)
744 : : {
745 : 2 : callback_test2_int++;
746 : 2 : return TRUE;
747 : : }
748 : :
749 : : static void
750 : 1 : callback_test2 (void)
751 : : {
752 : : GOptionContext *context;
753 : : gboolean retval;
754 : 1 : GError *error = NULL;
755 : : gchar **argv;
756 : : gchar **argv_copy;
757 : : int argc;
758 : 1 : GOptionEntry entries [] =
759 : : { { "test", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_parse2, NULL, NULL },
760 : : G_OPTION_ENTRY_NULL };
761 : :
762 : 1 : context = g_option_context_new (NULL);
763 : 1 : g_option_context_add_main_entries (context, entries, NULL);
764 : :
765 : : /* Now try parsing */
766 : 1 : argv = split_string ("program --test --test", &argc);
767 : 1 : argv_copy = copy_stringv (argv, argc);
768 : :
769 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
770 : 1 : g_assert_no_error (error);
771 : 1 : g_assert (retval);
772 : :
773 : 1 : g_assert (callback_test2_int == 2);
774 : :
775 : 1 : g_strfreev (argv_copy);
776 : 1 : g_free (argv);
777 : 1 : g_option_context_free (context);
778 : 1 : }
779 : :
780 : : static gboolean
781 : 8 : callback_parse_optional (const gchar *option_name, const gchar *value,
782 : : gpointer data, GError **error)
783 : : {
784 : 8 : callback_test_optional_boolean = TRUE;
785 [ + + ]: 8 : if (value)
786 : 3 : callback_test_optional_string = g_strdup (value);
787 : : else
788 : 5 : callback_test_optional_string = NULL;
789 : 8 : return TRUE;
790 : : }
791 : :
792 : : static void
793 : 1 : callback_test_optional_1 (void)
794 : : {
795 : : GOptionContext *context;
796 : : gboolean retval;
797 : 1 : GError *error = NULL;
798 : : gchar **argv;
799 : : gchar **argv_copy;
800 : : int argc;
801 : 1 : GOptionEntry entries [] =
802 : : { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
803 : : callback_parse_optional, NULL, NULL },
804 : : G_OPTION_ENTRY_NULL };
805 : :
806 : 1 : context = g_option_context_new (NULL);
807 : 1 : g_option_context_add_main_entries (context, entries, NULL);
808 : :
809 : : /* Now try parsing */
810 : 1 : argv = split_string ("program --test foo.txt", &argc);
811 : 1 : argv_copy = copy_stringv (argv, argc);
812 : :
813 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
814 : 1 : g_assert_no_error (error);
815 : 1 : g_assert (retval);
816 : :
817 : 1 : g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
818 : :
819 : 1 : g_assert (callback_test_optional_boolean);
820 : :
821 : 1 : g_free (callback_test_optional_string);
822 : :
823 : 1 : g_strfreev (argv_copy);
824 : 1 : g_free (argv);
825 : 1 : g_option_context_free (context);
826 : 1 : }
827 : :
828 : : static void
829 : 1 : callback_test_optional_2 (void)
830 : : {
831 : : GOptionContext *context;
832 : : gboolean retval;
833 : 1 : GError *error = NULL;
834 : : gchar **argv;
835 : : gchar **argv_copy;
836 : : int argc;
837 : 1 : GOptionEntry entries [] =
838 : : { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
839 : : callback_parse_optional, NULL, NULL },
840 : : G_OPTION_ENTRY_NULL };
841 : :
842 : 1 : context = g_option_context_new (NULL);
843 : 1 : g_option_context_add_main_entries (context, entries, NULL);
844 : :
845 : : /* Now try parsing */
846 : 1 : argv = split_string ("program --test", &argc);
847 : 1 : argv_copy = copy_stringv (argv, argc);
848 : :
849 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
850 : 1 : g_assert_no_error (error);
851 : 1 : g_assert (retval);
852 : :
853 : 1 : g_assert (callback_test_optional_string == NULL);
854 : :
855 : 1 : g_assert (callback_test_optional_boolean);
856 : :
857 : 1 : g_free (callback_test_optional_string);
858 : :
859 : 1 : g_strfreev (argv_copy);
860 : 1 : g_free (argv);
861 : 1 : g_option_context_free (context);
862 : 1 : }
863 : :
864 : : static void
865 : 1 : callback_test_optional_3 (void)
866 : : {
867 : : GOptionContext *context;
868 : : gboolean retval;
869 : 1 : GError *error = NULL;
870 : : gchar **argv_copy;
871 : : gchar **argv;
872 : : int argc;
873 : 1 : GOptionEntry entries [] =
874 : : { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
875 : : callback_parse_optional, NULL, NULL },
876 : : G_OPTION_ENTRY_NULL };
877 : :
878 : 1 : context = g_option_context_new (NULL);
879 : 1 : g_option_context_add_main_entries (context, entries, NULL);
880 : :
881 : : /* Now try parsing */
882 : 1 : argv = split_string ("program -t foo.txt", &argc);
883 : 1 : argv_copy = copy_stringv (argv, argc);
884 : :
885 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
886 : 1 : g_assert_no_error (error);
887 : 1 : g_assert (retval);
888 : :
889 : 1 : g_assert (strcmp (callback_test_optional_string, "foo.txt") == 0);
890 : :
891 : 1 : g_assert (callback_test_optional_boolean);
892 : :
893 : 1 : g_free (callback_test_optional_string);
894 : :
895 : 1 : g_strfreev (argv_copy);
896 : 1 : g_free (argv);
897 : 1 : g_option_context_free (context);
898 : 1 : }
899 : :
900 : :
901 : : static void
902 : 1 : callback_test_optional_4 (void)
903 : : {
904 : : GOptionContext *context;
905 : : gboolean retval;
906 : 1 : GError *error = NULL;
907 : : gchar **argv;
908 : : gchar **argv_copy;
909 : : int argc;
910 : 1 : GOptionEntry entries [] =
911 : : { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
912 : : callback_parse_optional, NULL, NULL },
913 : : G_OPTION_ENTRY_NULL };
914 : :
915 : 1 : context = g_option_context_new (NULL);
916 : 1 : g_option_context_add_main_entries (context, entries, NULL);
917 : :
918 : : /* Now try parsing */
919 : 1 : argv = split_string ("program -t", &argc);
920 : 1 : argv_copy = copy_stringv (argv, argc);
921 : :
922 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
923 : 1 : g_assert_no_error (error);
924 : 1 : g_assert (retval);
925 : :
926 : 1 : g_assert (callback_test_optional_string == NULL);
927 : :
928 : 1 : g_assert (callback_test_optional_boolean);
929 : :
930 : 1 : g_free (callback_test_optional_string);
931 : :
932 : 1 : g_strfreev (argv_copy);
933 : 1 : g_free (argv);
934 : 1 : g_option_context_free (context);
935 : 1 : }
936 : :
937 : : static void
938 : 1 : callback_test_optional_5 (void)
939 : : {
940 : : GOptionContext *context;
941 : : gboolean dummy;
942 : : gboolean retval;
943 : 1 : GError *error = NULL;
944 : : gchar **argv;
945 : : gchar **argv_copy;
946 : : int argc;
947 : 1 : GOptionEntry entries [] =
948 : : { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
949 : : { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
950 : : callback_parse_optional, NULL, NULL },
951 : : G_OPTION_ENTRY_NULL };
952 : :
953 : 1 : context = g_option_context_new (NULL);
954 : 1 : g_option_context_add_main_entries (context, entries, NULL);
955 : :
956 : : /* Now try parsing */
957 : 1 : argv = split_string ("program --test --dummy", &argc);
958 : 1 : argv_copy = copy_stringv (argv, argc);
959 : :
960 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
961 : 1 : g_assert_no_error (error);
962 : 1 : g_assert (retval);
963 : :
964 : 1 : g_assert (callback_test_optional_string == NULL);
965 : :
966 : 1 : g_assert (callback_test_optional_boolean);
967 : :
968 : 1 : g_free (callback_test_optional_string);
969 : :
970 : 1 : g_strfreev (argv_copy);
971 : 1 : g_free (argv);
972 : 1 : g_option_context_free (context);
973 : 1 : }
974 : :
975 : : static void
976 : 1 : callback_test_optional_6 (void)
977 : : {
978 : : GOptionContext *context;
979 : : gboolean dummy;
980 : : gboolean retval;
981 : 1 : GError *error = NULL;
982 : : gchar **argv;
983 : : gchar **argv_copy;
984 : : int argc;
985 : 1 : GOptionEntry entries [] =
986 : : { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
987 : : { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
988 : : callback_parse_optional, NULL, NULL },
989 : : G_OPTION_ENTRY_NULL };
990 : :
991 : 1 : context = g_option_context_new (NULL);
992 : 1 : g_option_context_add_main_entries (context, entries, NULL);
993 : :
994 : : /* Now try parsing */
995 : 1 : argv = split_string ("program -t -d", &argc);
996 : 1 : argv_copy = copy_stringv (argv, argc);
997 : :
998 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
999 : 1 : g_assert_no_error (error);
1000 : 1 : g_assert (retval);
1001 : :
1002 : 1 : g_assert (callback_test_optional_string == NULL);
1003 : :
1004 : 1 : g_assert (callback_test_optional_boolean);
1005 : :
1006 : 1 : g_free (callback_test_optional_string);
1007 : :
1008 : 1 : g_strfreev (argv_copy);
1009 : 1 : g_free (argv);
1010 : 1 : g_option_context_free (context);
1011 : 1 : }
1012 : :
1013 : : static void
1014 : 1 : callback_test_optional_7 (void)
1015 : : {
1016 : : GOptionContext *context;
1017 : : gboolean dummy;
1018 : : gboolean retval;
1019 : 1 : GError *error = NULL;
1020 : : gchar **argv;
1021 : : gchar **argv_copy;
1022 : : int argc;
1023 : 1 : GOptionEntry entries [] =
1024 : : { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
1025 : : { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
1026 : : callback_parse_optional, NULL, NULL },
1027 : : G_OPTION_ENTRY_NULL };
1028 : :
1029 : 1 : context = g_option_context_new (NULL);
1030 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1031 : :
1032 : : /* Now try parsing */
1033 : 1 : argv = split_string ("program -td", &argc);
1034 : 1 : argv_copy = copy_stringv (argv, argc);
1035 : :
1036 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1037 : 1 : g_assert_no_error (error);
1038 : 1 : g_assert (retval);
1039 : :
1040 : 1 : g_assert (callback_test_optional_string == NULL);
1041 : :
1042 : 1 : g_assert (callback_test_optional_boolean);
1043 : :
1044 : 1 : g_free (callback_test_optional_string);
1045 : :
1046 : 1 : g_strfreev (argv_copy);
1047 : 1 : g_free (argv);
1048 : 1 : g_option_context_free (context);
1049 : 1 : }
1050 : :
1051 : : static void
1052 : 1 : callback_test_optional_8 (void)
1053 : : {
1054 : : GOptionContext *context;
1055 : : gboolean dummy;
1056 : : gboolean retval;
1057 : 1 : GError *error = NULL;
1058 : : gchar **argv;
1059 : : gchar **argv_copy;
1060 : : int argc;
1061 : 1 : GOptionEntry entries [] =
1062 : : { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL, NULL },
1063 : : { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
1064 : : callback_parse_optional, NULL, NULL },
1065 : : G_OPTION_ENTRY_NULL };
1066 : :
1067 : 1 : context = g_option_context_new (NULL);
1068 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1069 : :
1070 : : /* Now try parsing */
1071 : 1 : argv = split_string ("program -dt foo.txt", &argc);
1072 : 1 : argv_copy = copy_stringv (argv, argc);
1073 : :
1074 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1075 : 1 : g_assert_no_error (error);
1076 : 1 : g_assert (retval);
1077 : :
1078 : 1 : g_assert (callback_test_optional_string);
1079 : :
1080 : 1 : g_assert (callback_test_optional_boolean);
1081 : :
1082 : 1 : g_free (callback_test_optional_string);
1083 : :
1084 : 1 : g_strfreev (argv_copy);
1085 : 1 : g_free (argv);
1086 : 1 : g_option_context_free (context);
1087 : 1 : }
1088 : :
1089 : : static GPtrArray *callback_remaining_args;
1090 : : static gboolean
1091 : 2 : callback_remaining_test1_callback (const gchar *option_name, const gchar *value,
1092 : : gpointer data, GError **error)
1093 : : {
1094 : 2 : g_ptr_array_add (callback_remaining_args, g_strdup (value));
1095 : 2 : return TRUE;
1096 : : }
1097 : :
1098 : : static void
1099 : 1 : callback_remaining_test1 (void)
1100 : : {
1101 : : GOptionContext *context;
1102 : : gboolean retval;
1103 : 1 : GError *error = NULL;
1104 : : gchar **argv;
1105 : : gchar **argv_copy;
1106 : : int argc;
1107 : 1 : GOptionEntry entries [] =
1108 : : { { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_CALLBACK, callback_remaining_test1_callback, NULL, NULL },
1109 : : G_OPTION_ENTRY_NULL };
1110 : :
1111 : 1 : callback_remaining_args = g_ptr_array_new ();
1112 : 1 : context = g_option_context_new (NULL);
1113 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1114 : :
1115 : : /* Now try parsing */
1116 : 1 : argv = split_string ("program foo.txt blah.txt", &argc);
1117 : 1 : argv_copy = copy_stringv (argv, argc);
1118 : :
1119 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1120 : 1 : g_assert_no_error (error);
1121 : 1 : g_assert (retval);
1122 : :
1123 : 1 : g_assert (callback_remaining_args->len == 2);
1124 : 1 : g_assert (strcmp (callback_remaining_args->pdata[0], "foo.txt") == 0);
1125 : 1 : g_assert (strcmp (callback_remaining_args->pdata[1], "blah.txt") == 0);
1126 : :
1127 : 1 : g_ptr_array_foreach (callback_remaining_args, (GFunc) g_free, NULL);
1128 : 1 : g_ptr_array_free (callback_remaining_args, TRUE);
1129 : :
1130 : 1 : g_strfreev (argv_copy);
1131 : 1 : g_free (argv);
1132 : 1 : g_option_context_free (context);
1133 : 1 : }
1134 : :
1135 : : static gboolean
1136 : 4 : callback_error (const gchar *option_name, const gchar *value,
1137 : : gpointer data, GError **error)
1138 : : {
1139 : 4 : g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "42");
1140 : 4 : return FALSE;
1141 : : }
1142 : :
1143 : : static void
1144 : 1 : callback_returns_false (void)
1145 : : {
1146 : : GOptionContext *context;
1147 : : gboolean retval;
1148 : 1 : GError *error = NULL;
1149 : : gchar **argv;
1150 : : gchar **argv_copy;
1151 : : int argc;
1152 : 1 : GOptionEntry entries [] =
1153 : : { { "error", 0, 0, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1154 : : { "error-no-arg", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1155 : : { "error-optional-arg", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL },
1156 : : G_OPTION_ENTRY_NULL };
1157 : :
1158 : 1 : context = g_option_context_new (NULL);
1159 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1160 : :
1161 : : /* Now try parsing */
1162 : 1 : argv = split_string ("program --error value", &argc);
1163 : 1 : argv_copy = copy_stringv (argv, argc);
1164 : :
1165 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1166 : 1 : g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1167 : 1 : g_assert (retval == FALSE);
1168 : 1 : check_identical_stringv (argv_copy, argv);
1169 : :
1170 : 1 : g_option_context_free (context);
1171 : 1 : g_clear_error (&error);
1172 : 1 : g_strfreev (argv_copy);
1173 : 1 : g_free (argv);
1174 : :
1175 : : /* And again, this time with a no-arg variant */
1176 : 1 : context = g_option_context_new (NULL);
1177 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1178 : :
1179 : 1 : argv = split_string ("program --error-no-arg", &argc);
1180 : 1 : argv_copy = copy_stringv (argv, argc);
1181 : :
1182 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1183 : 1 : g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1184 : 1 : g_assert (retval == FALSE);
1185 : 1 : check_identical_stringv (argv_copy, argv);
1186 : :
1187 : 1 : g_option_context_free (context);
1188 : 1 : g_clear_error (&error);
1189 : 1 : g_strfreev (argv_copy);
1190 : 1 : g_free (argv);
1191 : :
1192 : : /* And again, this time with an optional arg variant, with argument */
1193 : 1 : context = g_option_context_new (NULL);
1194 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1195 : :
1196 : 1 : argv = split_string ("program --error-optional-arg value", &argc);
1197 : 1 : argv_copy = copy_stringv (argv, argc);
1198 : :
1199 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1200 : 1 : g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1201 : 1 : g_assert (retval == FALSE);
1202 : 1 : check_identical_stringv (argv_copy, argv);
1203 : :
1204 : 1 : g_option_context_free (context);
1205 : 1 : g_clear_error (&error);
1206 : 1 : g_strfreev (argv_copy);
1207 : 1 : g_free (argv);
1208 : :
1209 : : /* And again, this time with an optional arg variant, without argument */
1210 : 1 : context = g_option_context_new (NULL);
1211 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1212 : :
1213 : 1 : argv = split_string ("program --error-optional-arg", &argc);
1214 : 1 : argv_copy = copy_stringv (argv, argc);
1215 : :
1216 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1217 : 1 : g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE);
1218 : 1 : g_assert (retval == FALSE);
1219 : 1 : check_identical_stringv (argv_copy, argv);
1220 : :
1221 : 1 : g_option_context_free (context);
1222 : 1 : g_clear_error (&error);
1223 : 1 : g_strfreev (argv_copy);
1224 : 1 : g_free (argv);
1225 : 1 : }
1226 : :
1227 : :
1228 : : static void
1229 : 1 : ignore_test1 (void)
1230 : : {
1231 : : GOptionContext *context;
1232 : : gboolean retval;
1233 : 1 : GError *error = NULL;
1234 : : gchar **argv, **argv_copy;
1235 : : int argc;
1236 : : gchar *arg;
1237 : 1 : GOptionEntry entries [] =
1238 : : { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1239 : : G_OPTION_ENTRY_NULL };
1240 : :
1241 : 1 : context = g_option_context_new (NULL);
1242 : 1 : g_option_context_set_ignore_unknown_options (context, TRUE);
1243 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1244 : :
1245 : : /* Now try parsing */
1246 : 1 : argv = split_string ("program --test --hello", &argc);
1247 : 1 : argv_copy = copy_stringv (argv, argc);
1248 : :
1249 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1250 : 1 : g_assert_no_error (error);
1251 : 1 : g_assert (retval);
1252 : :
1253 : : /* Check array */
1254 : 1 : arg = join_stringv (argc, argv);
1255 : 1 : g_assert (strcmp (arg, "program --hello") == 0);
1256 : :
1257 : 1 : g_free (arg);
1258 : 1 : g_strfreev (argv_copy);
1259 : 1 : g_free (argv);
1260 : 1 : g_option_context_free (context);
1261 : 1 : }
1262 : :
1263 : : static void
1264 : 1 : ignore_test2 (void)
1265 : : {
1266 : : GOptionContext *context;
1267 : : gboolean retval;
1268 : 1 : GError *error = NULL;
1269 : : gchar **argv;
1270 : : gchar **argv_copy;
1271 : : int argc;
1272 : : gchar *arg;
1273 : 1 : GOptionEntry entries [] =
1274 : : { { "test", 't', 0, G_OPTION_ARG_NONE, &ignore_test2_boolean, NULL, NULL },
1275 : : G_OPTION_ENTRY_NULL };
1276 : :
1277 : 1 : context = g_option_context_new (NULL);
1278 : 1 : g_option_context_set_ignore_unknown_options (context, TRUE);
1279 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1280 : :
1281 : : /* Now try parsing */
1282 : 1 : argv = split_string ("program -test", &argc);
1283 : 1 : argv_copy = copy_stringv (argv, argc);
1284 : :
1285 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1286 : 1 : g_assert_no_error (error);
1287 : 1 : g_assert (retval);
1288 : :
1289 : : /* Check array */
1290 : 1 : arg = join_stringv (argc, argv);
1291 : 1 : g_assert (strcmp (arg, "program -es") == 0);
1292 : :
1293 : 1 : g_free (arg);
1294 : 1 : g_strfreev (argv_copy);
1295 : 1 : g_free (argv);
1296 : 1 : g_option_context_free (context);
1297 : 1 : }
1298 : :
1299 : : static void
1300 : 1 : ignore_test3 (void)
1301 : : {
1302 : : GOptionContext *context;
1303 : : gboolean retval;
1304 : 1 : GError *error = NULL;
1305 : : gchar **argv, **argv_copy;
1306 : : int argc;
1307 : : gchar *arg;
1308 : 1 : GOptionEntry entries [] =
1309 : : { { "test", 0, 0, G_OPTION_ARG_STRING, &ignore_test3_string, NULL, NULL },
1310 : : G_OPTION_ENTRY_NULL };
1311 : :
1312 : 1 : context = g_option_context_new (NULL);
1313 : 1 : g_option_context_set_ignore_unknown_options (context, TRUE);
1314 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1315 : :
1316 : : /* Now try parsing */
1317 : 1 : argv = split_string ("program --test foo --hello", &argc);
1318 : 1 : argv_copy = copy_stringv (argv, argc);
1319 : :
1320 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1321 : 1 : g_assert_no_error (error);
1322 : 1 : g_assert (retval);
1323 : :
1324 : : /* Check array */
1325 : 1 : arg = join_stringv (argc, argv);
1326 : 1 : g_assert (strcmp (arg, "program --hello") == 0);
1327 : :
1328 : 1 : g_assert (strcmp (ignore_test3_string, "foo") == 0);
1329 : 1 : g_free (ignore_test3_string);
1330 : :
1331 : 1 : g_free (arg);
1332 : 1 : g_strfreev (argv_copy);
1333 : 1 : g_free (argv);
1334 : 1 : g_option_context_free (context);
1335 : 1 : }
1336 : :
1337 : : static void
1338 : 1 : array_test1 (void)
1339 : : {
1340 : : GOptionContext *context;
1341 : : gboolean retval;
1342 : 1 : GError *error = NULL;
1343 : : gchar **argv;
1344 : : gchar **argv_copy;
1345 : : int argc;
1346 : 1 : GOptionEntry entries [] =
1347 : : { { "test", 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1348 : : G_OPTION_ENTRY_NULL };
1349 : :
1350 : 1 : context = g_option_context_new (NULL);
1351 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1352 : :
1353 : : /* Now try parsing */
1354 : 1 : argv = split_string ("program --test foo --test bar", &argc);
1355 : 1 : argv_copy = copy_stringv (argv, argc);
1356 : :
1357 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1358 : 1 : g_assert_no_error (error);
1359 : 1 : g_assert (retval);
1360 : :
1361 : : /* Check array */
1362 : 1 : g_assert (strcmp (array_test1_array[0], "foo") == 0);
1363 : 1 : g_assert (strcmp (array_test1_array[1], "bar") == 0);
1364 : 1 : g_assert (array_test1_array[2] == NULL);
1365 : :
1366 : 1 : g_strfreev (array_test1_array);
1367 : :
1368 : 1 : g_strfreev (argv_copy);
1369 : 1 : g_free (argv);
1370 : 1 : g_option_context_free (context);
1371 : 1 : }
1372 : :
1373 : : static void
1374 : 1 : add_test1 (void)
1375 : : {
1376 : : GOptionContext *context;
1377 : :
1378 : 1 : GOptionEntry entries1 [] =
1379 : : { { "test1", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
1380 : : G_OPTION_ENTRY_NULL };
1381 : 1 : GOptionEntry entries2 [] =
1382 : : { { "test2", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL, NULL, NULL },
1383 : : G_OPTION_ENTRY_NULL };
1384 : :
1385 : 1 : context = g_option_context_new (NULL);
1386 : 1 : g_option_context_add_main_entries (context, entries1, NULL);
1387 : 1 : g_option_context_add_main_entries (context, entries2, NULL);
1388 : :
1389 : 1 : g_option_context_free (context);
1390 : 1 : }
1391 : :
1392 : : static void
1393 : 1 : empty_test2 (void)
1394 : : {
1395 : : GOptionContext *context;
1396 : :
1397 : 1 : context = g_option_context_new (NULL);
1398 : 1 : g_option_context_parse (context, NULL, NULL, NULL);
1399 : :
1400 : 1 : g_option_context_free (context);
1401 : 1 : }
1402 : :
1403 : : static void
1404 : 1 : empty_test3 (void)
1405 : : {
1406 : : GOptionContext *context;
1407 : : gint argc;
1408 : : gchar **argv;
1409 : :
1410 : 1 : argc = 0;
1411 : 1 : argv = NULL;
1412 : :
1413 : 1 : context = g_option_context_new (NULL);
1414 : 1 : g_option_context_parse (context, &argc, &argv, NULL);
1415 : :
1416 : 1 : g_option_context_free (context);
1417 : 1 : }
1418 : :
1419 : : /* check that non-option arguments are left in argv by default */
1420 : : static void
1421 : 1 : rest_test1 (void)
1422 : : {
1423 : : GOptionContext *context;
1424 : : gboolean retval;
1425 : 1 : GError *error = NULL;
1426 : : gchar **argv;
1427 : : gchar **argv_copy;
1428 : : int argc;
1429 : 1 : GOptionEntry entries [] = {
1430 : : { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1431 : : G_OPTION_ENTRY_NULL
1432 : : };
1433 : :
1434 : 1 : context = g_option_context_new (NULL);
1435 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1436 : :
1437 : : /* Now try parsing */
1438 : 1 : argv = split_string ("program foo --test bar", &argc);
1439 : 1 : argv_copy = copy_stringv (argv, argc);
1440 : :
1441 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1442 : 1 : g_assert_no_error (error);
1443 : 1 : g_assert (retval);
1444 : :
1445 : : /* Check array */
1446 : 1 : g_assert (ignore_test1_boolean);
1447 : 1 : g_assert (strcmp (argv[0], "program") == 0);
1448 : 1 : g_assert (strcmp (argv[1], "foo") == 0);
1449 : 1 : g_assert (strcmp (argv[2], "bar") == 0);
1450 : 1 : g_assert (argv[3] == NULL);
1451 : :
1452 : 1 : g_strfreev (argv_copy);
1453 : 1 : g_free (argv);
1454 : 1 : g_option_context_free (context);
1455 : 1 : }
1456 : :
1457 : : /* check that -- works */
1458 : : static void
1459 : 1 : rest_test2 (void)
1460 : : {
1461 : : GOptionContext *context;
1462 : : gboolean retval;
1463 : 1 : GError *error = NULL;
1464 : : gchar **argv;
1465 : : gchar **argv_copy;
1466 : : int argc;
1467 : 1 : GOptionEntry entries [] = {
1468 : : { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1469 : : G_OPTION_ENTRY_NULL
1470 : : };
1471 : :
1472 : 1 : context = g_option_context_new (NULL);
1473 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1474 : :
1475 : : /* Now try parsing */
1476 : 1 : argv = split_string ("program foo --test -- -bar", &argc);
1477 : 1 : argv_copy = copy_stringv (argv, argc);
1478 : :
1479 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1480 : 1 : g_assert_no_error (error);
1481 : 1 : g_assert (retval);
1482 : :
1483 : : /* Check array */
1484 : 1 : g_assert (ignore_test1_boolean);
1485 : 1 : g_assert (strcmp (argv[0], "program") == 0);
1486 : 1 : g_assert (strcmp (argv[1], "foo") == 0);
1487 : 1 : g_assert (strcmp (argv[2], "--") == 0);
1488 : 1 : g_assert (strcmp (argv[3], "-bar") == 0);
1489 : 1 : g_assert (argv[4] == NULL);
1490 : :
1491 : 1 : g_strfreev (argv_copy);
1492 : 1 : g_free (argv);
1493 : 1 : g_option_context_free (context);
1494 : 1 : }
1495 : :
1496 : : /* check that -- stripping works */
1497 : : static void
1498 : 1 : rest_test2a (void)
1499 : : {
1500 : : GOptionContext *context;
1501 : : gboolean retval;
1502 : 1 : GError *error = NULL;
1503 : : gchar **argv;
1504 : : gchar **argv_copy;
1505 : : int argc;
1506 : 1 : GOptionEntry entries [] = {
1507 : : { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1508 : : G_OPTION_ENTRY_NULL
1509 : : };
1510 : :
1511 : 1 : context = g_option_context_new (NULL);
1512 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1513 : :
1514 : : /* Now try parsing */
1515 : 1 : argv = split_string ("program foo --test -- bar", &argc);
1516 : 1 : argv_copy = copy_stringv (argv, argc);
1517 : :
1518 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1519 : 1 : g_assert_no_error (error);
1520 : 1 : g_assert (retval);
1521 : :
1522 : : /* Check array */
1523 : 1 : g_assert (ignore_test1_boolean);
1524 : 1 : g_assert (strcmp (argv[0], "program") == 0);
1525 : 1 : g_assert (strcmp (argv[1], "foo") == 0);
1526 : 1 : g_assert (strcmp (argv[2], "bar") == 0);
1527 : 1 : g_assert (argv[3] == NULL);
1528 : :
1529 : 1 : g_strfreev (argv_copy);
1530 : 1 : g_free (argv);
1531 : 1 : g_option_context_free (context);
1532 : 1 : }
1533 : :
1534 : : static void
1535 : 1 : rest_test2b (void)
1536 : : {
1537 : : GOptionContext *context;
1538 : : gboolean retval;
1539 : 1 : GError *error = NULL;
1540 : : gchar **argv;
1541 : : gchar **argv_copy;
1542 : : int argc;
1543 : 1 : GOptionEntry entries [] = {
1544 : : { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1545 : : G_OPTION_ENTRY_NULL
1546 : : };
1547 : :
1548 : 1 : context = g_option_context_new (NULL);
1549 : 1 : g_option_context_set_ignore_unknown_options (context, TRUE);
1550 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1551 : :
1552 : : /* Now try parsing */
1553 : 1 : argv = split_string ("program foo --test -bar --", &argc);
1554 : 1 : argv_copy = copy_stringv (argv, argc);
1555 : :
1556 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1557 : 1 : g_assert_no_error (error);
1558 : 1 : g_assert (retval);
1559 : :
1560 : : /* Check array */
1561 : 1 : g_assert (ignore_test1_boolean);
1562 : 1 : g_assert (strcmp (argv[0], "program") == 0);
1563 : 1 : g_assert (strcmp (argv[1], "foo") == 0);
1564 : 1 : g_assert (strcmp (argv[2], "-bar") == 0);
1565 : 1 : g_assert (argv[3] == NULL);
1566 : :
1567 : 1 : g_strfreev (argv_copy);
1568 : 1 : g_free (argv);
1569 : 1 : g_option_context_free (context);
1570 : 1 : }
1571 : :
1572 : : static void
1573 : 1 : rest_test2c (void)
1574 : : {
1575 : : GOptionContext *context;
1576 : : gboolean retval;
1577 : 1 : GError *error = NULL;
1578 : : gchar **argv;
1579 : : gchar **argv_copy;
1580 : : int argc;
1581 : 1 : GOptionEntry entries [] = {
1582 : : { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1583 : : G_OPTION_ENTRY_NULL
1584 : : };
1585 : :
1586 : 1 : context = g_option_context_new (NULL);
1587 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1588 : :
1589 : : /* Now try parsing */
1590 : 1 : argv = split_string ("program --test foo -- bar", &argc);
1591 : 1 : argv_copy = copy_stringv (argv, argc);
1592 : :
1593 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1594 : 1 : g_assert_no_error (error);
1595 : 1 : g_assert (retval);
1596 : :
1597 : : /* Check array */
1598 : 1 : g_assert (ignore_test1_boolean);
1599 : 1 : g_assert (strcmp (argv[0], "program") == 0);
1600 : 1 : g_assert (strcmp (argv[1], "foo") == 0);
1601 : 1 : g_assert (strcmp (argv[2], "bar") == 0);
1602 : 1 : g_assert (argv[3] == NULL);
1603 : :
1604 : 1 : g_strfreev (argv_copy);
1605 : 1 : g_free (argv);
1606 : 1 : g_option_context_free (context);
1607 : 1 : }
1608 : :
1609 : : static void
1610 : 1 : rest_test2d (void)
1611 : : {
1612 : : GOptionContext *context;
1613 : : gboolean retval;
1614 : 1 : GError *error = NULL;
1615 : : gchar **argv;
1616 : : gchar **argv_copy;
1617 : : int argc;
1618 : 1 : GOptionEntry entries [] = {
1619 : : { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1620 : : G_OPTION_ENTRY_NULL
1621 : : };
1622 : :
1623 : 1 : context = g_option_context_new (NULL);
1624 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1625 : :
1626 : : /* Now try parsing */
1627 : 1 : argv = split_string ("program --test -- -bar", &argc);
1628 : 1 : argv_copy = copy_stringv (argv, argc);
1629 : :
1630 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1631 : 1 : g_assert_no_error (error);
1632 : 1 : g_assert (retval);
1633 : :
1634 : : /* Check array */
1635 : 1 : g_assert (ignore_test1_boolean);
1636 : 1 : g_assert (strcmp (argv[0], "program") == 0);
1637 : 1 : g_assert (strcmp (argv[1], "--") == 0);
1638 : 1 : g_assert (strcmp (argv[2], "-bar") == 0);
1639 : 1 : g_assert (argv[3] == NULL);
1640 : :
1641 : 1 : g_strfreev (argv_copy);
1642 : 1 : g_free (argv);
1643 : 1 : g_option_context_free (context);
1644 : 1 : }
1645 : :
1646 : :
1647 : : /* check that G_OPTION_REMAINING collects non-option arguments */
1648 : : static void
1649 : 1 : rest_test3 (void)
1650 : : {
1651 : : GOptionContext *context;
1652 : : gboolean retval;
1653 : 1 : GError *error = NULL;
1654 : : gchar **argv;
1655 : : gchar **argv_copy;
1656 : : int argc;
1657 : 1 : GOptionEntry entries [] = {
1658 : : { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1659 : : { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1660 : : G_OPTION_ENTRY_NULL
1661 : : };
1662 : :
1663 : 1 : context = g_option_context_new (NULL);
1664 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1665 : :
1666 : : /* Now try parsing */
1667 : 1 : argv = split_string ("program foo --test bar", &argc);
1668 : 1 : argv_copy = copy_stringv (argv, argc);
1669 : :
1670 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1671 : 1 : g_assert_no_error (error);
1672 : 1 : g_assert (retval);
1673 : :
1674 : : /* Check array */
1675 : 1 : g_assert (ignore_test1_boolean);
1676 : 1 : g_assert (strcmp (array_test1_array[0], "foo") == 0);
1677 : 1 : g_assert (strcmp (array_test1_array[1], "bar") == 0);
1678 : 1 : g_assert (array_test1_array[2] == NULL);
1679 : :
1680 : 1 : g_strfreev (array_test1_array);
1681 : :
1682 : 1 : g_strfreev (argv_copy);
1683 : 1 : g_free (argv);
1684 : 1 : g_option_context_free (context);
1685 : 1 : }
1686 : :
1687 : :
1688 : : /* check that G_OPTION_REMAINING and -- work together */
1689 : : static void
1690 : 1 : rest_test4 (void)
1691 : : {
1692 : : GOptionContext *context;
1693 : : gboolean retval;
1694 : 1 : GError *error = NULL;
1695 : : gchar **argv;
1696 : : gchar **argv_copy;
1697 : : int argc;
1698 : 1 : GOptionEntry entries [] = {
1699 : : { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1700 : : { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL },
1701 : : G_OPTION_ENTRY_NULL
1702 : : };
1703 : :
1704 : 1 : context = g_option_context_new (NULL);
1705 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1706 : :
1707 : : /* Now try parsing */
1708 : 1 : argv = split_string ("program foo --test -- -bar", &argc);
1709 : 1 : argv_copy = copy_stringv (argv, argc);
1710 : :
1711 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1712 : 1 : g_assert_no_error (error);
1713 : 1 : g_assert (retval);
1714 : :
1715 : : /* Check array */
1716 : 1 : g_assert (ignore_test1_boolean);
1717 : 1 : g_assert (strcmp (array_test1_array[0], "foo") == 0);
1718 : 1 : g_assert (strcmp (array_test1_array[1], "-bar") == 0);
1719 : 1 : g_assert (array_test1_array[2] == NULL);
1720 : :
1721 : 1 : g_strfreev (array_test1_array);
1722 : :
1723 : 1 : g_strfreev (argv_copy);
1724 : 1 : g_free (argv);
1725 : 1 : g_option_context_free (context);
1726 : 1 : }
1727 : :
1728 : : /* test that G_OPTION_REMAINING works with G_OPTION_ARG_FILENAME_ARRAY */
1729 : : static void
1730 : 1 : rest_test5 (void)
1731 : : {
1732 : : GOptionContext *context;
1733 : : gboolean retval;
1734 : 1 : GError *error = NULL;
1735 : : gchar **argv;
1736 : : gchar **argv_copy;
1737 : : int argc;
1738 : 1 : GOptionEntry entries [] = {
1739 : : { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL },
1740 : : { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &array_test1_array, NULL, NULL },
1741 : : G_OPTION_ENTRY_NULL
1742 : : };
1743 : :
1744 : 1 : context = g_option_context_new (NULL);
1745 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1746 : :
1747 : : /* Now try parsing */
1748 : 1 : argv = split_string ("program foo --test bar", &argc);
1749 : 1 : argv_copy = copy_stringv (argv, argc);
1750 : :
1751 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1752 : 1 : g_assert_no_error (error);
1753 : 1 : g_assert (retval);
1754 : :
1755 : : /* Check array */
1756 : 1 : g_assert (ignore_test1_boolean);
1757 : 1 : g_assert (strcmp (array_test1_array[0], "foo") == 0);
1758 : 1 : g_assert (strcmp (array_test1_array[1], "bar") == 0);
1759 : 1 : g_assert (array_test1_array[2] == NULL);
1760 : :
1761 : 1 : g_strfreev (array_test1_array);
1762 : :
1763 : 1 : g_strfreev (argv_copy);
1764 : 1 : g_free (argv);
1765 : 1 : g_option_context_free (context);
1766 : 1 : }
1767 : :
1768 : : static void
1769 : 1 : unknown_short_test (void)
1770 : : {
1771 : : GOptionContext *context;
1772 : : gboolean retval;
1773 : 1 : GError *error = NULL;
1774 : : gchar **argv;
1775 : : gchar **argv_copy;
1776 : : int argc;
1777 : 1 : GOptionEntry entries [] = { G_OPTION_ENTRY_NULL };
1778 : :
1779 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=166609");
1780 : :
1781 : 1 : context = g_option_context_new (NULL);
1782 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1783 : :
1784 : : /* Now try parsing */
1785 : 1 : argv = split_string ("program -0", &argc);
1786 : 1 : argv_copy = copy_stringv (argv, argc);
1787 : :
1788 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1789 : 1 : g_assert (!retval);
1790 : 1 : g_assert (error != NULL);
1791 : 1 : g_clear_error (&error);
1792 : :
1793 : 1 : g_strfreev (argv_copy);
1794 : 1 : g_free (argv);
1795 : 1 : g_option_context_free (context);
1796 : 1 : }
1797 : :
1798 : : /* test that lone dashes are treated as non-options */
1799 : : static void
1800 : 1 : lonely_dash_test (void)
1801 : : {
1802 : : GOptionContext *context;
1803 : : gboolean retval;
1804 : 1 : GError *error = NULL;
1805 : : gchar **argv;
1806 : : gchar **argv_copy;
1807 : : int argc;
1808 : :
1809 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=168008");
1810 : :
1811 : 1 : context = g_option_context_new (NULL);
1812 : :
1813 : : /* Now try parsing */
1814 : 1 : argv = split_string ("program -", &argc);
1815 : 1 : argv_copy = copy_stringv (argv, argc);
1816 : :
1817 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1818 : 1 : g_assert_no_error (error);
1819 : 1 : g_assert (retval);
1820 : :
1821 : 1 : g_assert (argv[1] && strcmp (argv[1], "-") == 0);
1822 : :
1823 : 1 : g_strfreev (argv_copy);
1824 : 1 : g_free (argv);
1825 : 1 : g_option_context_free (context);
1826 : 1 : }
1827 : :
1828 : : /* test that three dashes are treated as non-options */
1829 : : static void
1830 : 1 : triple_dash_test (void)
1831 : : {
1832 : : GOptionContext *context;
1833 : : GOptionGroup *group;
1834 : : gboolean retval;
1835 : 1 : GError *error = NULL;
1836 : : gchar **argv;
1837 : : gchar **argv_copy;
1838 : : int argc;
1839 : : gint arg1, arg2;
1840 : 1 : GOptionEntry entries [] =
1841 : : { { "foo", 0, 0, G_OPTION_ARG_INT, &arg1, NULL, NULL},
1842 : : G_OPTION_ENTRY_NULL
1843 : : };
1844 : 1 : GOptionEntry group_entries [] =
1845 : : { { "test", 0, 0, G_OPTION_ARG_INT, &arg2, NULL, NULL},
1846 : : G_OPTION_ENTRY_NULL
1847 : : };
1848 : :
1849 : 1 : context = g_option_context_new (NULL);
1850 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1851 : :
1852 : 1 : group = g_option_group_new ("group", "Group description", "Group help", NULL, NULL);
1853 : 1 : g_option_group_add_entries (group, group_entries);
1854 : :
1855 : 1 : g_option_context_add_group (context, group);
1856 : :
1857 : : /* Now try parsing */
1858 : 1 : argv = split_string ("program ---test 42", &argc);
1859 : 1 : argv_copy = copy_stringv (argv, argc);
1860 : :
1861 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1862 : 1 : g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_UNKNOWN_OPTION);
1863 : 1 : g_assert (retval == FALSE);
1864 : :
1865 : 1 : g_option_context_free (context);
1866 : 1 : g_clear_error (&error);
1867 : 1 : g_strfreev (argv_copy);
1868 : 1 : g_free (argv);
1869 : 1 : }
1870 : :
1871 : : static void
1872 : 1 : missing_arg_test (void)
1873 : : {
1874 : : GOptionContext *context;
1875 : : gboolean retval;
1876 : 1 : GError *error = NULL;
1877 : : gchar **argv;
1878 : : gchar **argv_copy;
1879 : : int argc;
1880 : 1 : gchar *arg = NULL;
1881 : 1 : GOptionEntry entries [] =
1882 : : { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1883 : : G_OPTION_ENTRY_NULL };
1884 : :
1885 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=305576");
1886 : :
1887 : 1 : context = g_option_context_new (NULL);
1888 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1889 : :
1890 : : /* Now try parsing */
1891 : 1 : argv = split_string ("program --test", &argc);
1892 : 1 : argv_copy = copy_stringv (argv, argc);
1893 : :
1894 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1895 : 1 : g_assert (retval == FALSE);
1896 : 1 : g_assert (error != NULL);
1897 : : /* An error occurred, so argv has not been changed */
1898 : 1 : check_identical_stringv (argv_copy, argv);
1899 : 1 : g_clear_error (&error);
1900 : :
1901 : 1 : g_strfreev (argv_copy);
1902 : 1 : g_free (argv);
1903 : :
1904 : : /* Try parsing again */
1905 : 1 : argv = split_string ("program -t", &argc);
1906 : 1 : argv_copy = copy_stringv (argv, argc);
1907 : :
1908 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1909 : 1 : g_assert (retval == FALSE);
1910 : 1 : g_assert (error != NULL);
1911 : : /* An error occurred, so argv has not been changed */
1912 : 1 : check_identical_stringv (argv_copy, argv);
1913 : 1 : g_clear_error (&error);
1914 : :
1915 : 1 : g_strfreev (argv_copy);
1916 : 1 : g_free (argv);
1917 : 1 : g_option_context_free (context);
1918 : :
1919 : : /* Checking g_option_context_parse_strv on NULL args */
1920 : 1 : context = g_option_context_new (NULL);
1921 : 1 : g_assert_true (g_option_context_parse_strv (context, NULL, NULL));
1922 : 1 : g_option_context_free (context);
1923 : 1 : }
1924 : :
1925 : : static gchar *test_arg;
1926 : :
1927 : 2 : static gboolean cb (const gchar *option_name,
1928 : : const gchar *value,
1929 : : gpointer data,
1930 : : GError **error)
1931 : : {
1932 : 2 : test_arg = g_strdup (value);
1933 : 2 : return TRUE;
1934 : : }
1935 : :
1936 : : static void
1937 : 1 : dash_arg_test (void)
1938 : : {
1939 : : GOptionContext *context;
1940 : : gboolean retval;
1941 : 1 : GError *error = NULL;
1942 : : gchar **argv;
1943 : : gchar **argv_copy;
1944 : : int argc;
1945 : 1 : gboolean argb = FALSE;
1946 : 1 : GOptionEntry entries [] =
1947 : : { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, cb, NULL, NULL },
1948 : : { "three", '3', 0, G_OPTION_ARG_NONE, &argb, NULL, NULL },
1949 : : G_OPTION_ENTRY_NULL };
1950 : :
1951 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=577638");
1952 : :
1953 : 1 : context = g_option_context_new (NULL);
1954 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1955 : :
1956 : : /* Now try parsing */
1957 : 1 : argv = split_string ("program --test=-3", &argc);
1958 : 1 : argv_copy = copy_stringv (argv, argc);
1959 : :
1960 : 1 : test_arg = NULL;
1961 : 1 : error = NULL;
1962 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1963 : 1 : g_assert (retval);
1964 : 1 : g_assert_no_error (error);
1965 : 1 : g_assert_cmpstr (test_arg, ==, "-3");
1966 : :
1967 : 1 : g_strfreev (argv_copy);
1968 : 1 : g_free (argv);
1969 : 1 : g_free (test_arg);
1970 : 1 : test_arg = NULL;
1971 : :
1972 : : /* Try parsing again */
1973 : 1 : argv = split_string ("program --test -3", &argc);
1974 : 1 : argv_copy = copy_stringv (argv, argc);
1975 : :
1976 : 1 : error = NULL;
1977 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
1978 : 1 : g_assert_no_error (error);
1979 : 1 : g_assert (retval);
1980 : 1 : g_assert_cmpstr (test_arg, ==, NULL);
1981 : :
1982 : 1 : g_option_context_free (context);
1983 : 1 : g_strfreev (argv_copy);
1984 : 1 : g_free (argv);
1985 : 1 : }
1986 : :
1987 : : static void
1988 : 1 : test_basic (void)
1989 : : {
1990 : : GOptionContext *context;
1991 : 1 : gchar *arg = NULL;
1992 : 1 : GOptionEntry entries [] =
1993 : : { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
1994 : : G_OPTION_ENTRY_NULL };
1995 : :
1996 : 1 : context = g_option_context_new (NULL);
1997 : 1 : g_option_context_add_main_entries (context, entries, NULL);
1998 : :
1999 : 1 : g_assert (g_option_context_get_help_enabled (context));
2000 : 1 : g_assert (!g_option_context_get_ignore_unknown_options (context));
2001 : 1 : g_assert_cmpstr (g_option_context_get_summary (context), ==, NULL);
2002 : 1 : g_assert_cmpstr (g_option_context_get_description (context), ==, NULL);
2003 : :
2004 : 1 : g_option_context_set_help_enabled (context, FALSE);
2005 : 1 : g_option_context_set_ignore_unknown_options (context, TRUE);
2006 : 1 : g_option_context_set_summary (context, "summary");
2007 : 1 : g_option_context_set_description(context, "description");
2008 : :
2009 : 1 : g_assert (!g_option_context_get_help_enabled (context));
2010 : 1 : g_assert (g_option_context_get_ignore_unknown_options (context));
2011 : 1 : g_assert_cmpstr (g_option_context_get_summary (context), ==, "summary");
2012 : 1 : g_assert_cmpstr (g_option_context_get_description (context), ==, "description");
2013 : :
2014 : 1 : g_option_context_free (context);
2015 : 1 : }
2016 : :
2017 : : typedef struct {
2018 : : gboolean parameter_seen;
2019 : : gboolean summary_seen;
2020 : : gboolean description_seen;
2021 : : gboolean destroyed;
2022 : : } TranslateData;
2023 : :
2024 : : static const gchar *
2025 : 3 : translate_func (const gchar *str,
2026 : : gpointer data)
2027 : : {
2028 : 3 : TranslateData *d = data;
2029 : :
2030 [ + + ]: 3 : if (strcmp (str, "parameter") == 0)
2031 : 1 : d->parameter_seen = TRUE;
2032 [ + + ]: 2 : else if (strcmp (str, "summary") == 0)
2033 : 1 : d->summary_seen = TRUE;
2034 [ + - ]: 1 : else if (strcmp (str, "description") == 0)
2035 : 1 : d->description_seen = TRUE;
2036 : :
2037 : 3 : return str;
2038 : : }
2039 : :
2040 : : static void
2041 : 1 : destroy_notify (gpointer data)
2042 : : {
2043 : 1 : TranslateData *d = data;
2044 : :
2045 : 1 : d->destroyed = TRUE;
2046 : 1 : }
2047 : :
2048 : : static void
2049 : 1 : test_translate (void)
2050 : : {
2051 : : GOptionContext *context;
2052 : 1 : gchar *arg = NULL;
2053 : 1 : GOptionEntry entries [] =
2054 : : { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
2055 : : G_OPTION_ENTRY_NULL };
2056 : 1 : TranslateData data = { 0, };
2057 : : gchar *str;
2058 : :
2059 : 1 : context = g_option_context_new ("parameter");
2060 : 1 : g_option_context_add_main_entries (context, entries, NULL);
2061 : 1 : g_option_context_set_summary (context, "summary");
2062 : 1 : g_option_context_set_description (context, "description");
2063 : :
2064 : 1 : g_option_context_set_translate_func (context, translate_func, &data, destroy_notify);
2065 : :
2066 : 1 : str = g_option_context_get_help (context, FALSE, NULL);
2067 : 1 : g_free (str);
2068 : 1 : g_option_context_free (context);
2069 : :
2070 : 1 : g_assert (data.parameter_seen);
2071 : 1 : g_assert (data.summary_seen);
2072 : 1 : g_assert (data.description_seen);
2073 : 1 : g_assert (data.destroyed);
2074 : 1 : }
2075 : :
2076 : : static void
2077 : 1 : test_help (void)
2078 : : {
2079 : : GOptionContext *context;
2080 : : GOptionGroup *group;
2081 : : gchar *str;
2082 : 1 : gchar *arg = NULL;
2083 : 1 : gchar **sarr = NULL;
2084 : 1 : GOptionEntry entries[] = {
2085 : : { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Test tests", "Argument to use in test" },
2086 : : { "test2", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, NULL, "Tests also", NULL },
2087 : : { "frob", 0, 0, G_OPTION_ARG_NONE, NULL, "Main frob", NULL },
2088 : : { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" },
2089 : : G_OPTION_ENTRY_NULL
2090 : : };
2091 : 1 : GOptionEntry group_entries[] = {
2092 : : { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Group test", "Group test arg" },
2093 : : { "frob", 0, G_OPTION_FLAG_NOALIAS, G_OPTION_ARG_NONE, NULL, "Group frob", NULL },
2094 : : G_OPTION_ENTRY_NULL
2095 : : };
2096 : :
2097 : 1 : context = g_option_context_new ("blabla");
2098 : 1 : g_option_context_add_main_entries (context, entries, NULL);
2099 : 1 : g_option_context_set_summary (context, "Summary");
2100 : 1 : g_option_context_set_description (context, "Description");
2101 : :
2102 : 1 : group = g_option_group_new ("group1", "Group1-description", "Group1-help", NULL, NULL);
2103 : 1 : g_option_group_add_entries (group, group_entries);
2104 : :
2105 : 1 : g_option_context_add_group (context, group);
2106 : :
2107 : 1 : str = g_option_context_get_help (context, FALSE, NULL);
2108 : 1 : g_assert (strstr (str, "blabla") != NULL);
2109 : 1 : g_assert (strstr (str, "Test tests") != NULL);
2110 : 1 : g_assert (strstr (str, "Argument to use in test") != NULL);
2111 : 1 : g_assert (strstr (str, "Tests also") == NULL);
2112 : 1 : g_assert (strstr (str, "REST") != NULL);
2113 : 1 : g_assert (strstr (str, "Summary") != NULL);
2114 : 1 : g_assert (strstr (str, "Description") != NULL);
2115 : 1 : g_assert (strstr (str, "--help") != NULL);
2116 : 1 : g_assert (strstr (str, "--help-all") != NULL);
2117 : 1 : g_assert (strstr (str, "--help-group1") != NULL);
2118 : 1 : g_assert (strstr (str, "Group1-description") != NULL);
2119 : 1 : g_assert (strstr (str, "Group1-help") != NULL);
2120 : 1 : g_assert (strstr (str, "Group test arg") != NULL);
2121 : 1 : g_assert (strstr (str, "Group frob") != NULL);
2122 : 1 : g_assert (strstr (str, "Main frob") != NULL);
2123 : 1 : g_assert (strstr (str, "--frob") != NULL);
2124 : 1 : g_assert (strstr (str, "--group1-test") != NULL);
2125 : 1 : g_assert (strstr (str, "--group1-frob") == NULL);
2126 : 1 : g_free (str);
2127 : :
2128 : 1 : g_option_context_free (context);
2129 : 1 : }
2130 : :
2131 : : static void
2132 : 1 : test_help_no_options (void)
2133 : : {
2134 : : GOptionContext *context;
2135 : 1 : gchar **sarr = NULL;
2136 : 1 : GOptionEntry entries[] = {
2137 : : { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" },
2138 : : G_OPTION_ENTRY_NULL
2139 : : };
2140 : : gchar *str;
2141 : :
2142 : 1 : context = g_option_context_new ("blabla");
2143 : 1 : g_option_context_add_main_entries (context, entries, NULL);
2144 : :
2145 : 1 : str = g_option_context_get_help (context, FALSE, NULL);
2146 : 1 : g_assert (strstr (str, "blabla") != NULL);
2147 : 1 : g_assert (strstr (str, "REST") != NULL);
2148 : 1 : g_assert (strstr (str, "Help Options") != NULL);
2149 : 1 : g_assert (strstr (str, "Application Options") == NULL);
2150 : :
2151 : 1 : g_free (str);
2152 : 1 : g_option_context_free (context);
2153 : 1 : }
2154 : :
2155 : : static void
2156 : 1 : test_help_no_help_options (void)
2157 : : {
2158 : : GOptionContext *context;
2159 : : GOptionGroup *group;
2160 : : gchar *str;
2161 : 1 : gchar *arg = NULL;
2162 : 1 : gchar **sarr = NULL;
2163 : 1 : GOptionEntry entries[] = {
2164 : : { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Test tests", "Argument to use in test" },
2165 : : { "test2", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, NULL, "Tests also", NULL },
2166 : : { "frob", 0, 0, G_OPTION_ARG_NONE, NULL, "Main frob", NULL },
2167 : : { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &sarr, "Rest goes here", "REST" },
2168 : : G_OPTION_ENTRY_NULL
2169 : : };
2170 : 1 : GOptionEntry group_entries[] = {
2171 : : { "test", 't', 0, G_OPTION_ARG_STRING, &arg, "Group test", "Group test arg" },
2172 : : { "frob", 0, G_OPTION_FLAG_NOALIAS, G_OPTION_ARG_NONE, NULL, "Group frob", NULL },
2173 : : G_OPTION_ENTRY_NULL
2174 : : };
2175 : :
2176 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=697652");
2177 : :
2178 : 1 : context = g_option_context_new ("blabla");
2179 : 1 : g_option_context_add_main_entries (context, entries, NULL);
2180 : 1 : g_option_context_set_summary (context, "Summary");
2181 : 1 : g_option_context_set_description (context, "Description");
2182 : 1 : g_option_context_set_help_enabled (context, FALSE);
2183 : :
2184 : 1 : group = g_option_group_new ("group1", "Group1-description", "Group1-help", NULL, NULL);
2185 : 1 : g_option_group_add_entries (group, group_entries);
2186 : :
2187 : 1 : g_option_context_add_group (context, group);
2188 : :
2189 : 1 : str = g_option_context_get_help (context, FALSE, NULL);
2190 : 1 : g_assert (strstr (str, "blabla") != NULL);
2191 : 1 : g_assert (strstr (str, "Test tests") != NULL);
2192 : 1 : g_assert (strstr (str, "Argument to use in test") != NULL);
2193 : 1 : g_assert (strstr (str, "Tests also") == NULL);
2194 : 1 : g_assert (strstr (str, "REST") != NULL);
2195 : 1 : g_assert (strstr (str, "Summary") != NULL);
2196 : 1 : g_assert (strstr (str, "Description") != NULL);
2197 : 1 : g_assert (strstr (str, "Help Options") == NULL);
2198 : 1 : g_assert (strstr (str, "--help") == NULL);
2199 : 1 : g_assert (strstr (str, "--help-all") == NULL);
2200 : 1 : g_assert (strstr (str, "--help-group1") == NULL);
2201 : 1 : g_assert (strstr (str, "Group1-description") != NULL);
2202 : 1 : g_assert (strstr (str, "Group1-help") == NULL);
2203 : 1 : g_assert (strstr (str, "Group test arg") != NULL);
2204 : 1 : g_assert (strstr (str, "Group frob") != NULL);
2205 : 1 : g_assert (strstr (str, "Main frob") != NULL);
2206 : 1 : g_assert (strstr (str, "--frob") != NULL);
2207 : 1 : g_assert (strstr (str, "--group1-test") != NULL);
2208 : 1 : g_assert (strstr (str, "--group1-frob") == NULL);
2209 : 1 : g_free (str);
2210 : :
2211 : 1 : g_option_context_free (context);
2212 : 1 : }
2213 : :
2214 : : static void
2215 : 1 : set_bool (gpointer data)
2216 : : {
2217 : 1 : gboolean *b = data;
2218 : :
2219 : 1 : *b = TRUE;
2220 : 1 : }
2221 : :
2222 : : static void
2223 : 1 : test_main_group (void)
2224 : : {
2225 : : GOptionContext *context;
2226 : : GOptionGroup *group;
2227 : 1 : gboolean b = FALSE;
2228 : :
2229 : 1 : context = g_option_context_new (NULL);
2230 : 1 : g_assert (g_option_context_get_main_group (context) == NULL);
2231 : 1 : group = g_option_group_new ("name", "description", "hlep", &b, set_bool);
2232 : 1 : g_option_context_add_group (context, group);
2233 : 1 : group = g_option_group_new ("name2", "description", "hlep", NULL, NULL);
2234 : 1 : g_option_context_add_group (context, group);
2235 : 1 : g_assert (g_option_context_get_main_group (context) == NULL);
2236 : 1 : group = g_option_group_new ("name", "description", "hlep", NULL, NULL);
2237 : 1 : g_option_context_set_main_group (context, group);
2238 : 1 : g_assert (g_option_context_get_main_group (context) == group);
2239 : :
2240 : 1 : g_option_context_free (context);
2241 : :
2242 : 1 : g_assert (b);
2243 : 1 : }
2244 : :
2245 : : static gboolean error_func_called = FALSE;
2246 : :
2247 : : static void
2248 : 1 : error_func (GOptionContext *context,
2249 : : GOptionGroup *group,
2250 : : gpointer data,
2251 : : GError **error)
2252 : : {
2253 : 1 : g_assert_cmpint (GPOINTER_TO_INT(data), ==, 1234);
2254 : 1 : error_func_called = TRUE;
2255 : 1 : }
2256 : :
2257 : : static void
2258 : 1 : test_error_hook (void)
2259 : : {
2260 : : GOptionContext *context;
2261 : 1 : gchar *arg = NULL;
2262 : 1 : GOptionEntry entries [] =
2263 : : { { "test", 't', 0, G_OPTION_ARG_STRING, &arg, NULL, NULL },
2264 : : G_OPTION_ENTRY_NULL };
2265 : : GOptionGroup *group;
2266 : : gchar **argv;
2267 : : gchar **argv_copy;
2268 : : gint argc;
2269 : : gboolean retval;
2270 : 1 : GError *error = NULL;
2271 : :
2272 : 1 : context = g_option_context_new (NULL);
2273 : 1 : group = g_option_group_new ("name", "description", "hlep", GINT_TO_POINTER(1234), NULL);
2274 : 1 : g_option_group_add_entries (group, entries);
2275 : 1 : g_option_context_set_main_group (context, group);
2276 : 1 : g_option_group_set_error_hook (g_option_context_get_main_group (context),
2277 : : error_func);
2278 : :
2279 : 1 : argv = split_string ("program --test", &argc);
2280 : 1 : argv_copy = copy_stringv (argv, argc);
2281 : :
2282 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
2283 : 1 : g_assert (retval == FALSE);
2284 : 1 : g_assert (error != NULL);
2285 : : /* An error occurred, so argv has not been changed */
2286 : 1 : check_identical_stringv (argv_copy, argv);
2287 : 1 : g_clear_error (&error);
2288 : :
2289 : 1 : g_assert (error_func_called);
2290 : :
2291 : 1 : g_strfreev (argv_copy);
2292 : 1 : g_free (argv);
2293 : 1 : g_option_context_free (context);
2294 : 1 : }
2295 : :
2296 : : static void
2297 : 1 : test_group_parse (void)
2298 : : {
2299 : : GOptionContext *context;
2300 : : GOptionGroup *group;
2301 : 1 : gchar *arg1 = NULL;
2302 : 1 : gchar *arg2 = NULL;
2303 : 1 : gchar *arg3 = NULL;
2304 : 1 : gchar *arg4 = NULL;
2305 : 1 : gchar *arg5 = NULL;
2306 : 1 : GOptionEntry entries[] = {
2307 : : { "test", 't', 0, G_OPTION_ARG_STRING, &arg1, NULL, NULL },
2308 : : { "faz", 'f', 0, G_OPTION_ARG_STRING, &arg2, NULL, NULL },
2309 : : G_OPTION_ENTRY_NULL
2310 : : };
2311 : 1 : GOptionEntry group_entries[] = {
2312 : : { "test", 0, 0, G_OPTION_ARG_STRING, &arg3, NULL, NULL },
2313 : : { "frob", 'f', 0, G_OPTION_ARG_STRING, &arg4, NULL, NULL },
2314 : : { "faz", 'z', 0, G_OPTION_ARG_STRING, &arg5, NULL, NULL },
2315 : : G_OPTION_ENTRY_NULL
2316 : : };
2317 : : gchar **argv, **orig_argv;
2318 : : gint argc;
2319 : 1 : GError *error = NULL;
2320 : : gboolean retval;
2321 : :
2322 : 1 : context = g_option_context_new (NULL);
2323 : 1 : g_option_context_add_main_entries (context, entries, NULL);
2324 : 1 : group = g_option_group_new ("group", "A group", "help for group", NULL, NULL);
2325 : 1 : g_option_group_add_entries (group, group_entries);
2326 : 1 : g_option_context_add_group (context, group);
2327 : :
2328 : 1 : argv = split_string ("program --test arg1 -f arg2 --group-test arg3 --frob arg4 -z arg5", &argc);
2329 : 1 : orig_argv = g_memdup2 (argv, (argc + 1) * sizeof (char *));
2330 : :
2331 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
2332 : :
2333 : 1 : g_assert_no_error (error);
2334 : 1 : g_assert (retval);
2335 : 1 : g_assert_cmpstr (arg1, ==, "arg1");
2336 : 1 : g_assert_cmpstr (arg2, ==, "arg2");
2337 : 1 : g_assert_cmpstr (arg3, ==, "arg3");
2338 : 1 : g_assert_cmpstr (arg4, ==, "arg4");
2339 : 1 : g_assert_cmpstr (arg5, ==, "arg5");
2340 : :
2341 : 1 : g_free (arg1);
2342 : 1 : g_free (arg2);
2343 : 1 : g_free (arg3);
2344 : 1 : g_free (arg4);
2345 : 1 : g_free (arg5);
2346 : :
2347 : 1 : g_free (argv);
2348 : 1 : g_strfreev (orig_argv);
2349 : 1 : g_option_context_free (context);
2350 : 1 : }
2351 : :
2352 : : static gint
2353 : 4 : option_context_parse_command_line (GOptionContext *context,
2354 : : const gchar *command_line)
2355 : : {
2356 : : gchar **argv;
2357 : : guint argv_len, argv_new_len;
2358 : : gboolean success;
2359 : :
2360 : 4 : argv = split_string (command_line, NULL);
2361 : 4 : argv_len = g_strv_length (argv);
2362 : :
2363 : 4 : success = g_option_context_parse_strv (context, &argv, NULL);
2364 : 4 : argv_new_len = g_strv_length (argv);
2365 : :
2366 : 4 : g_strfreev (argv);
2367 [ + - ]: 4 : return success ? (gint) (argv_len - argv_new_len) : -1;
2368 : : }
2369 : :
2370 : : static void
2371 : 1 : test_strict_posix (void)
2372 : : {
2373 : : GOptionContext *context;
2374 : : gboolean foo;
2375 : : gboolean bar;
2376 : 1 : GOptionEntry entries[] = {
2377 : : { "foo", 'f', 0, G_OPTION_ARG_NONE, &foo, NULL, NULL },
2378 : : { "bar", 'b', 0, G_OPTION_ARG_NONE, &bar, NULL, NULL },
2379 : : G_OPTION_ENTRY_NULL
2380 : : };
2381 : : gint n_parsed;
2382 : :
2383 : 1 : context = g_option_context_new (NULL);
2384 : 1 : g_option_context_add_main_entries (context, entries, NULL);
2385 : :
2386 : 1 : foo = bar = FALSE;
2387 : 1 : g_option_context_set_strict_posix (context, FALSE);
2388 : 1 : n_parsed = option_context_parse_command_line (context, "program --foo command --bar");
2389 : 1 : g_assert_cmpint (n_parsed, ==, 2);
2390 : 1 : g_assert (foo == TRUE);
2391 : 1 : g_assert (bar == TRUE);
2392 : :
2393 : 1 : foo = bar = FALSE;
2394 : 1 : g_option_context_set_strict_posix (context, TRUE);
2395 : 1 : n_parsed = option_context_parse_command_line (context, "program --foo command --bar");
2396 : 1 : g_assert_cmpint (n_parsed, ==, 1);
2397 : 1 : g_assert (foo == TRUE);
2398 : 1 : g_assert (bar == FALSE);
2399 : :
2400 : 1 : foo = bar = FALSE;
2401 : 1 : g_option_context_set_strict_posix (context, TRUE);
2402 : 1 : n_parsed = option_context_parse_command_line (context, "program --foo --bar command");
2403 : 1 : g_assert_cmpint (n_parsed, ==, 2);
2404 : 1 : g_assert (foo == TRUE);
2405 : 1 : g_assert (bar == TRUE);
2406 : :
2407 : 1 : foo = bar = FALSE;
2408 : 1 : g_option_context_set_strict_posix (context, TRUE);
2409 : 1 : n_parsed = option_context_parse_command_line (context, "program command --foo --bar");
2410 : 1 : g_assert_cmpint (n_parsed, ==, 0);
2411 : 1 : g_assert (foo == FALSE);
2412 : 1 : g_assert (bar == FALSE);
2413 : :
2414 : 1 : g_option_context_free (context);
2415 : 1 : }
2416 : :
2417 : : static void
2418 : 1 : flag_reverse_string (void)
2419 : : {
2420 : : GOptionContext *context;
2421 : 1 : gchar *arg = NULL;
2422 : 1 : GOptionEntry entries [] =
2423 : : { { "test", 't', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_STRING, &arg, NULL, NULL },
2424 : : G_OPTION_ENTRY_NULL };
2425 : : gchar **argv;
2426 : : gint argc;
2427 : : gboolean retval;
2428 : 1 : GError *error = NULL;
2429 : :
2430 [ - + ]: 1 : if (!g_test_undefined ())
2431 : 0 : return;
2432 : :
2433 : 1 : context = g_option_context_new (NULL);
2434 : :
2435 : 1 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
2436 : : "*ignoring reverse flag*");
2437 : 1 : g_option_context_add_main_entries (context, entries, NULL);
2438 : 1 : g_test_assert_expected_messages ();
2439 : :
2440 : 1 : argv = split_string ("program --test bla", &argc);
2441 : :
2442 : 1 : retval = g_option_context_parse_strv (context, &argv, &error);
2443 : 1 : g_assert (retval == TRUE);
2444 : 1 : g_assert_no_error (error);
2445 : 1 : g_strfreev (argv);
2446 : 1 : g_option_context_free (context);
2447 : 1 : g_free (arg);
2448 : : }
2449 : :
2450 : : static void
2451 : 1 : flag_optional_int (void)
2452 : : {
2453 : : GOptionContext *context;
2454 : 1 : gint arg = 0;
2455 : 1 : GOptionEntry entries [] =
2456 : : { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_INT, &arg, NULL, NULL },
2457 : : G_OPTION_ENTRY_NULL };
2458 : : gchar **argv;
2459 : : gint argc;
2460 : : gboolean retval;
2461 : 1 : GError *error = NULL;
2462 : :
2463 [ - + ]: 1 : if (!g_test_undefined ())
2464 : 0 : return;
2465 : :
2466 : 1 : context = g_option_context_new (NULL);
2467 : :
2468 : 1 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
2469 : : "*ignoring no-arg, optional-arg or filename flags*");
2470 : 1 : g_option_context_add_main_entries (context, entries, NULL);
2471 : 1 : g_test_assert_expected_messages ();
2472 : :
2473 : 1 : argv = split_string ("program --test 5", &argc);
2474 : :
2475 : 1 : retval = g_option_context_parse_strv (context, &argv, &error);
2476 : 1 : g_assert (retval == TRUE);
2477 : 1 : g_assert_no_error (error);
2478 : 1 : g_strfreev (argv);
2479 : 1 : g_option_context_free (context);
2480 : : }
2481 : :
2482 : : static void
2483 : 1 : short_remaining (void)
2484 : : {
2485 : 1 : gboolean ignore = FALSE;
2486 : 1 : gboolean remaining = FALSE;
2487 : 1 : gint number = 0;
2488 : 1 : gchar* text = NULL;
2489 : 1 : gchar** files = NULL;
2490 : 1 : GError* error = NULL;
2491 : 1 : GOptionEntry entries[] =
2492 : : {
2493 : : { "ignore", 'i', 0, G_OPTION_ARG_NONE, &ignore, NULL, NULL },
2494 : : { "remaining", 'r', 0, G_OPTION_ARG_NONE, &remaining, NULL, NULL },
2495 : : { "number", 'n', 0, G_OPTION_ARG_INT, &number, NULL, NULL },
2496 : : { "text", 't', 0, G_OPTION_ARG_STRING, &text, NULL, NULL },
2497 : : { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &files, NULL, NULL },
2498 : : G_OPTION_ENTRY_NULL
2499 : : };
2500 : : GOptionContext* context;
2501 : : gchar **argv, **argv_copy;
2502 : : gint argc;
2503 : :
2504 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=729563");
2505 : :
2506 : 1 : argv = split_string ("program -ri -n 4 -t hello file1 file2", &argc);
2507 : 1 : argv_copy = copy_stringv (argv, argc);
2508 : :
2509 : 1 : context = g_option_context_new (NULL);
2510 : :
2511 : 1 : g_option_context_add_main_entries (context, entries, NULL);
2512 : 1 : g_option_context_set_ignore_unknown_options (context, TRUE);
2513 : :
2514 : 1 : g_option_context_parse (context, &argc, &argv, &error);
2515 : 1 : g_assert_no_error (error);
2516 : :
2517 : 1 : g_assert (ignore);
2518 : 1 : g_assert (remaining);
2519 : 1 : g_assert_cmpint (number, ==, 4);
2520 : 1 : g_assert_cmpstr (text, ==, "hello");
2521 : 1 : g_assert_cmpstr (files[0], ==, "file1");
2522 : 1 : g_assert_cmpstr (files[1], ==, "file2");
2523 : 1 : g_assert (files[2] == NULL);
2524 : :
2525 : 1 : g_free (text);
2526 : 1 : g_strfreev (files);
2527 : 1 : g_strfreev (argv_copy);
2528 : 1 : g_free (argv);
2529 : 1 : g_option_context_free (context);
2530 : 1 : }
2531 : :
2532 : : static void
2533 : 1 : double_free (void)
2534 : : {
2535 : 1 : gchar* text = NULL;
2536 : 1 : GOptionEntry entries[] =
2537 : : {
2538 : : { "known", 0, 0, G_OPTION_ARG_STRING, &text, NULL, NULL },
2539 : : G_OPTION_ENTRY_NULL
2540 : : };
2541 : : GOptionContext* context;
2542 : : gchar **argv;
2543 : : gint argc;
2544 : 1 : GError *error = NULL;
2545 : :
2546 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=646926");
2547 : :
2548 : 1 : argv = split_string ("program --known=foo --known=bar --unknown=baz", &argc);
2549 : :
2550 : 1 : context = g_option_context_new (NULL);
2551 : :
2552 : 1 : g_option_context_add_main_entries (context, entries, NULL);
2553 : 1 : g_option_context_set_ignore_unknown_options (context, FALSE);
2554 : 1 : g_option_context_parse (context, &argc, &argv, &error);
2555 : :
2556 : 1 : g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_UNKNOWN_OPTION);
2557 : 1 : g_assert_null (text);
2558 : :
2559 : 1 : g_option_context_free (context);
2560 : 1 : g_clear_error (&error);
2561 : 1 : g_strfreev (argv);
2562 : :
2563 : 1 : }
2564 : :
2565 : : static void
2566 : 1 : double_zero (void)
2567 : : {
2568 : : GOptionContext *context;
2569 : : gboolean retval;
2570 : 1 : GError *error = NULL;
2571 : : gchar **argv_copy;
2572 : : gchar **argv;
2573 : : int argc;
2574 : 1 : double test_val = NAN;
2575 : 1 : GOptionEntry entries [] =
2576 : : { { "test", 0, 0, G_OPTION_ARG_DOUBLE, &test_val, NULL, NULL },
2577 : : G_OPTION_ENTRY_NULL };
2578 : :
2579 : 1 : context = g_option_context_new (NULL);
2580 : 1 : g_option_context_add_main_entries (context, entries, NULL);
2581 : :
2582 : : /* Now try parsing */
2583 : 1 : argv = split_string ("program --test 0", &argc);
2584 : 1 : argv_copy = copy_stringv (argv, argc);
2585 : :
2586 : 1 : retval = g_option_context_parse (context, &argc, &argv, &error);
2587 : 1 : g_assert_no_error (error);
2588 : 1 : g_assert (retval);
2589 : :
2590 : : /* Last arg specified is the one that should be stored */
2591 : 1 : g_assert (test_val == 0);
2592 : :
2593 : 1 : g_strfreev (argv_copy);
2594 : 1 : g_free (argv);
2595 : 1 : g_option_context_free (context);
2596 : 1 : }
2597 : :
2598 : : int
2599 : 13 : main (int argc,
2600 : : char *argv[])
2601 : : {
2602 : : int i;
2603 : : gchar *test_name;
2604 : :
2605 : 13 : g_setenv ("LC_ALL", "C", TRUE);
2606 : 13 : g_test_init (&argc, &argv, NULL);
2607 : :
2608 : 13 : g_test_add_func ("/option/help/options", test_help);
2609 : 13 : g_test_add_func ("/option/help/no-options", test_help_no_options);
2610 : 13 : g_test_add_func ("/option/help/no-help-options", test_help_no_help_options);
2611 : :
2612 : 13 : g_test_add_func ("/option/basic", test_basic);
2613 : 13 : g_test_add_func ("/option/translate", test_translate);
2614 : :
2615 : 13 : g_test_add_func ("/option/group/captions", test_group_captions);
2616 [ + + ]: 65 : for (i = 0; i < 4; i++)
2617 : : {
2618 : 52 : test_name = g_strdup_printf ("/option/group/captions/subprocess/help-%d", i);
2619 : 52 : g_test_add_data_func (test_name, GINT_TO_POINTER (i),
2620 : : test_group_captions_help);
2621 : 52 : g_free (test_name);
2622 : 52 : test_name = g_strdup_printf ("/option/group/captions/subprocess/help-all-%d", i);
2623 : 52 : g_test_add_data_func (test_name, GINT_TO_POINTER (i),
2624 : : test_group_captions_help_all);
2625 : 52 : g_free (test_name);
2626 : 52 : test_name = g_strdup_printf ("/option/group/captions/subprocess/help-test-%d", i);
2627 : 52 : g_test_add_data_func (test_name, GINT_TO_POINTER (i),
2628 : : test_group_captions_help_test);
2629 : :
2630 : 52 : g_free (test_name);
2631 : : }
2632 : :
2633 : 13 : g_test_add_func ("/option/group/main", test_main_group);
2634 : 13 : g_test_add_func ("/option/group/error-hook", test_error_hook);
2635 : 13 : g_test_add_func ("/option/group/parse", test_group_parse);
2636 : 13 : g_test_add_func ("/option/strict-posix", test_strict_posix);
2637 : :
2638 : : /* Test that restoration on failure works */
2639 : 13 : g_test_add_func ("/option/restoration/int", error_test1);
2640 : 13 : g_test_add_func ("/option/restoration/string", error_test2);
2641 : 13 : g_test_add_func ("/option/restoration/boolean", error_test3);
2642 : :
2643 : : /* Test that special argument parsing works */
2644 : 13 : g_test_add_func ("/option/arg/repetition/int", arg_test1);
2645 : 13 : g_test_add_func ("/option/arg/repetition/string", arg_test2);
2646 : 13 : g_test_add_func ("/option/arg/repetition/filename", arg_test3);
2647 : 13 : g_test_add_func ("/option/arg/repetition/double", arg_test4);
2648 : 13 : g_test_add_func ("/option/arg/repetition/locale", arg_test5);
2649 : 13 : g_test_add_func ("/option/arg/repetition/int64", arg_test6);
2650 : :
2651 : : /* Test string arrays */
2652 : 13 : g_test_add_func ("/option/arg/array/string", array_test1);
2653 : :
2654 : : /* Test callback args */
2655 : 13 : g_test_add_func ("/option/arg/callback/string", callback_test1);
2656 : 13 : g_test_add_func ("/option/arg/callback/count", callback_test2);
2657 : :
2658 : : /* Test optional arg flag for callback */
2659 : 13 : g_test_add_func ("/option/arg/callback/optional1", callback_test_optional_1);
2660 : 13 : g_test_add_func ("/option/arg/callback/optional2", callback_test_optional_2);
2661 : 13 : g_test_add_func ("/option/arg/callback/optional3", callback_test_optional_3);
2662 : 13 : g_test_add_func ("/option/arg/callback/optional4", callback_test_optional_4);
2663 : 13 : g_test_add_func ("/option/arg/callback/optional5", callback_test_optional_5);
2664 : 13 : g_test_add_func ("/option/arg/callback/optional6", callback_test_optional_6);
2665 : 13 : g_test_add_func ("/option/arg/callback/optional7", callback_test_optional_7);
2666 : 13 : g_test_add_func ("/option/arg/callback/optional8", callback_test_optional_8);
2667 : :
2668 : : /* Test callback with G_OPTION_REMAINING */
2669 : 13 : g_test_add_func ("/option/arg/remaining/callback", callback_remaining_test1);
2670 : :
2671 : : /* Test callbacks which return FALSE */
2672 : 13 : g_test_add_func ("/option/arg/remaining/callback-false", callback_returns_false);
2673 : :
2674 : : /* Test ignoring options */
2675 : 13 : g_test_add_func ("/option/arg/ignore/long", ignore_test1);
2676 : 13 : g_test_add_func ("/option/arg/ignore/short", ignore_test2);
2677 : 13 : g_test_add_func ("/option/arg/ignore/arg", ignore_test3);
2678 : 13 : g_test_add_func ("/option/context/add", add_test1);
2679 : :
2680 : : /* Test parsing empty args */
2681 : : /* Note there used to be an empty1 here, but it effectively moved
2682 : : * to option-argv0.c.
2683 : : */
2684 : 13 : g_test_add_func ("/option/context/empty2", empty_test2);
2685 : 13 : g_test_add_func ("/option/context/empty3", empty_test3);
2686 : :
2687 : : /* Test handling of rest args */
2688 : 13 : g_test_add_func ("/option/arg/rest/non-option", rest_test1);
2689 : 13 : g_test_add_func ("/option/arg/rest/separator1", rest_test2);
2690 : 13 : g_test_add_func ("/option/arg/rest/separator2", rest_test2a);
2691 : 13 : g_test_add_func ("/option/arg/rest/separator3", rest_test2b);
2692 : 13 : g_test_add_func ("/option/arg/rest/separator4", rest_test2c);
2693 : 13 : g_test_add_func ("/option/arg/rest/separator5", rest_test2d);
2694 : 13 : g_test_add_func ("/option/arg/remaining/non-option", rest_test3);
2695 : 13 : g_test_add_func ("/option/arg/remaining/separator", rest_test4);
2696 : 13 : g_test_add_func ("/option/arg/remaining/array", rest_test5);
2697 : :
2698 : : /* Test some invalid flag combinations */
2699 : 13 : g_test_add_func ("/option/arg/reverse-string", flag_reverse_string);
2700 : 13 : g_test_add_func ("/option/arg/optional-int", flag_optional_int);
2701 : :
2702 : : /* regression tests for individual bugs */
2703 : 13 : g_test_add_func ("/option/bug/unknown-short", unknown_short_test);
2704 : 13 : g_test_add_func ("/option/bug/lonely-dash", lonely_dash_test);
2705 : 13 : g_test_add_func ("/option/bug/triple-dash", triple_dash_test);
2706 : 13 : g_test_add_func ("/option/bug/missing-arg", missing_arg_test);
2707 : 13 : g_test_add_func ("/option/bug/dash-arg", dash_arg_test);
2708 : 13 : g_test_add_func ("/option/bug/short-remaining", short_remaining);
2709 : 13 : g_test_add_func ("/option/bug/double-free", double_free);
2710 : 13 : g_test_add_func ("/option/bug/double-zero", double_zero);
2711 : :
2712 : 13 : return g_test_run();
2713 : : }
|