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