Fix handling of ambiguous command line options.
The approach used so far failed to recognize ambiguous abbreviations located in different groups. It also didn't work when MU_PARSEOPT_NO_SORT was requested. This commit fixes it by keeping an additional array of indices to long options. The array is sorted so that its elements produce a lexicographically ascending list of long options. * include/mailutils/opt.h (mu_parseopt): New members po_longcnt, po_longidx keep a sorted array of indices to po_optv with long options. * libmailutils/opt/opt.c (find_long_option): Iterate over po_longidx. (parseopt_init): Initialize and sort po_longidx. (mu_parseopt_free): Free po_longidx. * libmailutils/tests/parseopt.c: Add three more potentially ambiguous options * libmailutils/tests/parseopt26.at: New testcase. * libmailutils/tests/parseopt27.at: New testcase. * libmailutils/tests/Makefile.am: Add new testcases. * libmailutils/tests/testsuite.at: Likewise.
Showing
40 changed files
with
277 additions
and
63 deletions
... | @@ -171,6 +171,9 @@ struct mu_parseopt | ... | @@ -171,6 +171,9 @@ struct mu_parseopt |
171 | int po_arg_count; | 171 | int po_arg_count; |
172 | 172 | ||
173 | unsigned po_permuted:1; /* Whether the arguments were permuted */ | 173 | unsigned po_permuted:1; /* Whether the arguments were permuted */ |
174 | |||
175 | size_t po_longcnt; /* Number of long options */ | ||
176 | size_t *po_longidx; /* Indices of long options in po_optv */ | ||
174 | }; | 177 | }; |
175 | 178 | ||
176 | 179 | ... | ... |
... | @@ -285,61 +285,60 @@ find_long_option (struct mu_parseopt *po, char const *optstr, | ... | @@ -285,61 +285,60 @@ find_long_option (struct mu_parseopt *po, char const *optstr, |
285 | 285 | ||
286 | optlen = strcspn (optstr, "="); | 286 | optlen = strcspn (optstr, "="); |
287 | 287 | ||
288 | for (i = 0; i < po->po_optc; i++) | 288 | for (i = 0; i < po->po_longcnt; i++) |
289 | { | 289 | { |
290 | if (MU_OPTION_IS_VALID_LONG_OPTION (po->po_optv[i])) | 290 | size_t j = po->po_longidx[i]; |
291 | size_t len = strlen (po->po_optv[j]->opt_long); | ||
292 | struct mu_option *opt = option_unalias (po, j); | ||
293 | neg = neg_nomatch; | ||
294 | if ((optlen <= len | ||
295 | && memcmp (po->po_optv[j]->opt_long, optstr, optlen) == 0) | ||
296 | || (neg = negmatch (po, j, optstr, optlen))) | ||
291 | { | 297 | { |
292 | size_t len = strlen (po->po_optv[i]->opt_long); | 298 | switch (found) |
293 | struct mu_option *opt = option_unalias (po, i); | ||
294 | neg = neg_nomatch; | ||
295 | if ((optlen <= len | ||
296 | && memcmp (po->po_optv[i]->opt_long, optstr, optlen) == 0) | ||
297 | || (neg = negmatch (po, i, optstr, optlen))) | ||
298 | { | 299 | { |
299 | switch (found) | 300 | case 0: |
300 | { | 301 | used_opt = po->po_optv[j]; |
301 | case 0: | 302 | ret_opt = opt; |
302 | used_opt = po->po_optv[i]; | 303 | found++; |
303 | ret_opt = opt; | 304 | if (optlen == len || neg == neg_match_exact) |
304 | found++; | 305 | i = po->po_longcnt - 1; /* exact match: break the loop */ |
305 | if (optlen == len || neg == neg_match_exact) | 306 | break; |
306 | i = po->po_optc - 1; /* exact match: break the loop */ | ||
307 | break; | ||
308 | 307 | ||
309 | case 1: | 308 | case 1: |
310 | if (opt == ret_opt) | 309 | if (opt == ret_opt) |
311 | continue; | 310 | continue; |
312 | if (po->po_flags & MU_PARSEOPT_IGNORE_ERRORS) | 311 | if (po->po_flags & MU_PARSEOPT_IGNORE_ERRORS) |
313 | return NULL; | 312 | return NULL; |
314 | mu_parseopt_error (po, | 313 | mu_parseopt_error (po, |
315 | _("option '%s%*.*s' is ambiguous; possibilities:"), | 314 | _("option '%s%*.*s' is ambiguous; possibilities:"), |
316 | po->po_long_opt_start, | 315 | po->po_long_opt_start, |
317 | optlen, optlen, optstr); | 316 | optlen, optlen, optstr); |
318 | fprintf (stderr, "%s%s%s\n", | 317 | fprintf (stderr, "%s%s%s\n", |
319 | po->po_long_opt_start, | 318 | po->po_long_opt_start, |
320 | neg ? po->po_negation : "", | 319 | neg ? po->po_negation : "", |
321 | used_opt->opt_long); | 320 | used_opt->opt_long); |
322 | if (neg == neg_nomatch && negmatch (po, i, optstr, optlen)) | 321 | if (neg == neg_nomatch && negmatch (po, j, optstr, optlen)) |
323 | fprintf (stderr, "%s%s%s\n", | 322 | fprintf (stderr, "%s%s%s\n", |
324 | po->po_long_opt_start, | 323 | po->po_long_opt_start, |
325 | po->po_negation, | 324 | po->po_negation, |
326 | po->po_optv[i]->opt_long); | 325 | po->po_optv[j]->opt_long); |
327 | found++; | 326 | found++; |
328 | 327 | ||
329 | case 2: | 328 | case 2: |
330 | fprintf (stderr, "%s%s%s\n", | 329 | fprintf (stderr, "%s%s%s\n", |
331 | po->po_long_opt_start, | 330 | po->po_long_opt_start, |
332 | neg ? po->po_negation : "", | 331 | neg ? po->po_negation : "", |
333 | po->po_optv[i]->opt_long); | 332 | po->po_optv[j]->opt_long); |
334 | if (neg == neg_nomatch && negmatch (po, i, optstr, optlen)) | 333 | if (neg == neg_nomatch && negmatch (po, j, optstr, optlen)) |
335 | fprintf (stderr, "%s%s%s\n", | 334 | fprintf (stderr, "%s%s%s\n", |
336 | po->po_long_opt_start, | 335 | po->po_long_opt_start, |
337 | po->po_negation, | 336 | po->po_negation, |
338 | po->po_optv[i]->opt_long); | 337 | po->po_optv[j]->opt_long); |
339 | } | ||
340 | } | 338 | } |
341 | } | 339 | } |
342 | } | 340 | } |
341 | |||
343 | 342 | ||
344 | switch (found) | 343 | switch (found) |
345 | { | 344 | { |
... | @@ -612,6 +611,29 @@ parse (struct mu_parseopt *po) | ... | @@ -612,6 +611,29 @@ parse (struct mu_parseopt *po) |
612 | return 0; | 611 | return 0; |
613 | } | 612 | } |
614 | 613 | ||
614 | #define LONGOPT(po, i) po->po_optv[po->po_longidx[i]]->opt_long | ||
615 | |||
616 | static void | ||
617 | sort_longidx (struct mu_parseopt *po) | ||
618 | { | ||
619 | /* Sort the po_longidx array so that its elements produce lexicographically | ||
620 | ascending list of long options. | ||
621 | Given relatively small number of command line options, simple insertion | ||
622 | sort is used. | ||
623 | */ | ||
624 | size_t i, j; | ||
625 | |||
626 | for (i = 1; i < po->po_longcnt; i++) | ||
627 | { | ||
628 | for (j = i; j > 0 && strcmp (LONGOPT (po, j-1), LONGOPT (po, j)) > 0; j--) | ||
629 | { | ||
630 | size_t tmp = po->po_longidx[j]; | ||
631 | po->po_longidx[j] = po->po_longidx[j-1]; | ||
632 | po->po_longidx[j-1] = tmp; | ||
633 | } | ||
634 | } | ||
635 | } | ||
636 | |||
615 | /* Initialize structure mu_parseopt with given options and flags. */ | 637 | /* Initialize structure mu_parseopt with given options and flags. */ |
616 | static int | 638 | static int |
617 | parseopt_init (struct mu_parseopt *po, struct mu_option **options, | 639 | parseopt_init (struct mu_parseopt *po, struct mu_option **options, |
... | @@ -716,6 +738,20 @@ parseopt_init (struct mu_parseopt *po, struct mu_option **options, | ... | @@ -716,6 +738,20 @@ parseopt_init (struct mu_parseopt *po, struct mu_option **options, |
716 | } | 738 | } |
717 | } | 739 | } |
718 | 740 | ||
741 | j = 0; | ||
742 | for (i = 0; i < po->po_optc; i++) | ||
743 | if (MU_OPTION_IS_VALID_LONG_OPTION (po->po_optv[i])) | ||
744 | j++; | ||
745 | po->po_longcnt = j; | ||
746 | |||
747 | po->po_longidx = mu_calloc (j + 1, sizeof (po->po_longidx[0])); | ||
748 | j = 0; | ||
749 | for (i = 0; i < po->po_optc; i++) | ||
750 | if (MU_OPTION_IS_VALID_LONG_OPTION (po->po_optv[i])) | ||
751 | po->po_longidx[j++] = i; | ||
752 | |||
753 | sort_longidx (po); | ||
754 | |||
719 | po->po_ind = 0; | 755 | po->po_ind = 0; |
720 | po->po_opterr = 0; | 756 | po->po_opterr = 0; |
721 | po->po_optlist = NULL; | 757 | po->po_optlist = NULL; |
... | @@ -772,6 +808,7 @@ void | ... | @@ -772,6 +808,7 @@ void |
772 | mu_parseopt_free (struct mu_parseopt *popt) | 808 | mu_parseopt_free (struct mu_parseopt *popt) |
773 | { | 809 | { |
774 | free (popt->po_optv); | 810 | free (popt->po_optv); |
811 | free (popt->po_longidx); | ||
775 | mu_list_destroy (&popt->po_optlist); | 812 | mu_list_destroy (&popt->po_optlist); |
776 | } | 813 | } |
777 | 814 | ... | ... |
... | @@ -138,6 +138,8 @@ TESTSUITE_AT = \ | ... | @@ -138,6 +138,8 @@ TESTSUITE_AT = \ |
138 | parseopt23.at\ | 138 | parseopt23.at\ |
139 | parseopt24.at\ | 139 | parseopt24.at\ |
140 | parseopt25.at\ | 140 | parseopt25.at\ |
141 | parseopt26.at\ | ||
142 | parseopt27.at\ | ||
141 | parseopt_help00.at\ | 143 | parseopt_help00.at\ |
142 | parseopt_help01.at\ | 144 | parseopt_help01.at\ |
143 | parseopt_help02.at\ | 145 | parseopt_help02.at\ | ... | ... |
... | @@ -27,6 +27,8 @@ int jobs = 0; | ... | @@ -27,6 +27,8 @@ int jobs = 0; |
27 | int x_option; | 27 | int x_option; |
28 | int a_option; | 28 | int a_option; |
29 | int d_option; | 29 | int d_option; |
30 | int debug_level_value; | ||
31 | char *debug_info_value; | ||
30 | 32 | ||
31 | struct mu_option group_a[] = { | 33 | struct mu_option group_a[] = { |
32 | MU_OPTION_GROUP("Group A"), | 34 | MU_OPTION_GROUP("Group A"), |
... | @@ -43,6 +45,7 @@ struct mu_option group_a[] = { | ... | @@ -43,6 +45,7 @@ struct mu_option group_a[] = { |
43 | { "all", 'a', NULL, MU_OPTION_DEFAULT, | 45 | { "all", 'a', NULL, MU_OPTION_DEFAULT, |
44 | "no arguments to this one", | 46 | "no arguments to this one", |
45 | mu_c_bool, &a_option }, | 47 | mu_c_bool, &a_option }, |
48 | { "debug-all", 0, NULL, MU_OPTION_ALIAS }, | ||
46 | MU_OPTION_END | 49 | MU_OPTION_END |
47 | }; | 50 | }; |
48 | 51 | ||
... | @@ -61,7 +64,18 @@ struct mu_option group_b[] = { | ... | @@ -61,7 +64,18 @@ struct mu_option group_b[] = { |
61 | MU_OPTION_END | 64 | MU_OPTION_END |
62 | }; | 65 | }; |
63 | 66 | ||
64 | struct mu_option *optv[] = { group_a, group_b, NULL }; | 67 | struct mu_option group_c[] = { |
68 | MU_OPTION_GROUP("Group C"), | ||
69 | { "debug-level", 0, "NUM", MU_OPTION_DEFAULT, | ||
70 | "debug level option", | ||
71 | mu_c_int, &debug_level_value }, | ||
72 | { "debug-info", 0, "S", MU_OPTION_DEFAULT, | ||
73 | "debug information", | ||
74 | mu_c_string, &debug_info_value }, | ||
75 | MU_OPTION_END | ||
76 | }; | ||
77 | |||
78 | struct mu_option *optv[] = { group_a, group_b, group_c, NULL }; | ||
65 | 79 | ||
66 | static void | 80 | static void |
67 | version_hook (struct mu_parseopt *po, mu_stream_t str) | 81 | version_hook (struct mu_parseopt *po, mu_stream_t str) |
... | @@ -207,6 +221,9 @@ main (int argc, char *argv[]) | ... | @@ -207,6 +221,9 @@ main (int argc, char *argv[]) |
207 | printf ("find_value=%s\n", S(find_value)); | 221 | printf ("find_value=%s\n", S(find_value)); |
208 | printf ("d_option=%d\n", d_option); | 222 | printf ("d_option=%d\n", d_option); |
209 | printf ("jobs=%d\n", jobs); | 223 | printf ("jobs=%d\n", jobs); |
224 | |||
225 | printf ("debug_level_value=%d\n", debug_level_value); | ||
226 | printf ("debug_info_value=%s\n", S(debug_info_value)); | ||
210 | 227 | ||
211 | printf ("argv:\n"); | 228 | printf ("argv:\n"); |
212 | for (i = 0; i < argc; i++) | 229 | for (i = 0; i < argc; i++) | ... | ... |
... | @@ -29,6 +29,8 @@ a_option=0 | ... | @@ -29,6 +29,8 @@ a_option=0 |
29 | find_value=(null) | 29 | find_value=(null) |
30 | d_option=0 | 30 | d_option=0 |
31 | jobs=0 | 31 | jobs=0 |
32 | debug_level_value=0 | ||
33 | debug_info_value=(null) | ||
32 | argv: | 34 | argv: |
33 | 0: more | 35 | 0: more |
34 | 1: arguments | 36 | 1: arguments |
... | @@ -49,6 +51,8 @@ a_option=0 | ... | @@ -49,6 +51,8 @@ a_option=0 |
49 | find_value=(null) | 51 | find_value=(null) |
50 | d_option=0 | 52 | d_option=0 |
51 | jobs=0 | 53 | jobs=0 |
54 | debug_level_value=0 | ||
55 | debug_info_value=(null) | ||
52 | argv: | 56 | argv: |
53 | 0: more | 57 | 0: more |
54 | 1: arguments | 58 | 1: arguments | ... | ... |
libmailutils/tests/parseopt26.at
0 → 100644
1 | # This file is part of GNU Mailutils. -*- Autotest -*- | ||
2 | # Copyright (C) 2016-2017 Free Software Foundation, Inc. | ||
3 | # | ||
4 | # GNU Mailutils is free software; you can redistribute it and/or | ||
5 | # modify it under the terms of the GNU General Public License as | ||
6 | # published by the Free Software Foundation; either version 3, or (at | ||
7 | # your option) any later version. | ||
8 | # | ||
9 | # GNU Mailutils is distributed in the hope that it will be useful, but | ||
10 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | # General Public License for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License | ||
15 | # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | AT_SETUP([ambiguous abbreviated long options (2)]) | ||
18 | AT_KEYWORDS([parseopt parseopt_long parseopt_long_abbr parseopt_long_ambig parseopt26]) | ||
19 | AT_CHECK([ | ||
20 | PARSEOPT_DEFAULT | ||
21 | parseopt --debug- command line arguments | ||
22 | ], | ||
23 | [1], | ||
24 | [], | ||
25 | [parseopt: option '--debug-' is ambiguous; possibilities: | ||
26 | --debug-all | ||
27 | --debug-info | ||
28 | --debug-level | ||
29 | ]) | ||
30 | AT_CLEANUP |
libmailutils/tests/parseopt27.at
0 → 100644
1 | # This file is part of GNU Mailutils. -*- Autotest -*- | ||
2 | # Copyright (C) 2016-2017 Free Software Foundation, Inc. | ||
3 | # | ||
4 | # GNU Mailutils is free software; you can redistribute it and/or | ||
5 | # modify it under the terms of the GNU General Public License as | ||
6 | # published by the Free Software Foundation; either version 3, or (at | ||
7 | # your option) any later version. | ||
8 | # | ||
9 | # GNU Mailutils is distributed in the hope that it will be useful, but | ||
10 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | # General Public License for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License | ||
15 | # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | AT_SETUP([ambiguous abbreviated long options (3)]) | ||
18 | AT_KEYWORDS([parseopt parseopt_long parseopt_long_abbr parseopt_long_ambig parseopt27]) | ||
19 | AT_CHECK([ | ||
20 | PARSEOPT_DEFAULT | ||
21 | parseopt --debug-i command line arguments | ||
22 | ], | ||
23 | [0], | ||
24 | [rc=0 | ||
25 | file_name=(null) | ||
26 | opt_value=initial | ||
27 | x_option=0 | ||
28 | a_option=0 | ||
29 | find_value=(null) | ||
30 | d_option=0 | ||
31 | jobs=0 | ||
32 | debug_level_value=0 | ||
33 | debug_info_value=command | ||
34 | argv: | ||
35 | 0: line | ||
36 | 1: arguments | ||
37 | ]) | ||
38 | AT_CLEANUP |
... | @@ -24,7 +24,7 @@ parseopt --help | ... | @@ -24,7 +24,7 @@ parseopt --help |
24 | [[Usage: parseopt [OPTION...] | 24 | [[Usage: parseopt [OPTION...] |
25 | 25 | ||
26 | Group A | 26 | Group A |
27 | -a, --all no arguments to this one | 27 | -a, --all, --debug-all no arguments to this one |
28 | -f, --file=FILE set file name | 28 | -f, --file=FILE set file name |
29 | -o, --optional[=FILE] optional argument | 29 | -o, --optional[=FILE] optional argument |
30 | -x short-only option | 30 | -x short-only option |
... | @@ -34,6 +34,10 @@ parseopt --help | ... | @@ -34,6 +34,10 @@ parseopt --help |
34 | -F, --find=VALUE find VALUE | 34 | -F, --find=VALUE find VALUE |
35 | -j, --jobs=N sets numeric value | 35 | -j, --jobs=N sets numeric value |
36 | 36 | ||
37 | Group C | ||
38 | --debug-info=S debug information | ||
39 | --debug-level=NUM debug level option | ||
40 | |||
37 | -?, --help give this help list | 41 | -?, --help give this help list |
38 | --usage give a short usage message | 42 | --usage give a short usage message |
39 | 43 | ... | ... |
... | @@ -15,14 +15,15 @@ | ... | @@ -15,14 +15,15 @@ |
15 | # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. | 15 | # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | ||
17 | AT_SETUP([standard usage output]) | 17 | AT_SETUP([standard usage output]) |
18 | AT_KEYWORDS([parseopt parseopt_help parseopt_help00]) | 18 | AT_KEYWORDS([parseopt parseopt_help parseopt_help01]) |
19 | AT_CHECK([ | 19 | AT_CHECK([ |
20 | PARSEOPT_DEFAULT | 20 | PARSEOPT_DEFAULT |
21 | parseopt --usage | 21 | parseopt --usage |
22 | ], | 22 | ], |
23 | [0], | 23 | [0], |
24 | [[Usage: parseopt [-advx?] [-f FILE] [-F VALUE] [-j N] [-o[FILE]] [--all] | 24 | [[Usage: parseopt [-advx?] [-f FILE] [-F VALUE] [-j N] [-o[FILE]] [--all] |
25 | [--debug] [--file=FILE] [--find=VALUE] [--help] [--jobs=N] | 25 | [--debug] [--debug-all] [--debug-info=S] [--debug-level=NUM] |
26 | [--file=FILE] [--find=VALUE] [--help] [--jobs=N] | ||
26 | [--optional[=FILE]] [--usage] [--verbose] | 27 | [--optional[=FILE]] [--usage] [--verbose] |
27 | ]]) | 28 | ]]) |
28 | AT_CLEANUP | 29 | AT_CLEANUP | ... | ... |
... | @@ -24,7 +24,7 @@ MU_PARSEOPT_PROG_NAME=newname parseopt --help | ... | @@ -24,7 +24,7 @@ MU_PARSEOPT_PROG_NAME=newname parseopt --help |
24 | [[Usage: newname [OPTION...] | 24 | [[Usage: newname [OPTION...] |
25 | 25 | ||
26 | Group A | 26 | Group A |
27 | -a, --all no arguments to this one | 27 | -a, --all, --debug-all no arguments to this one |
28 | -f, --file=FILE set file name | 28 | -f, --file=FILE set file name |
29 | -o, --optional[=FILE] optional argument | 29 | -o, --optional[=FILE] optional argument |
30 | -x short-only option | 30 | -x short-only option |
... | @@ -34,6 +34,10 @@ MU_PARSEOPT_PROG_NAME=newname parseopt --help | ... | @@ -34,6 +34,10 @@ MU_PARSEOPT_PROG_NAME=newname parseopt --help |
34 | -F, --find=VALUE find VALUE | 34 | -F, --find=VALUE find VALUE |
35 | -j, --jobs=N sets numeric value | 35 | -j, --jobs=N sets numeric value |
36 | 36 | ||
37 | Group C | ||
38 | --debug-info=S debug information | ||
39 | --debug-level=NUM debug level option | ||
40 | |||
37 | -?, --help give this help list | 41 | -?, --help give this help list |
38 | --usage give a short usage message | 42 | --usage give a short usage message |
39 | 43 | ... | ... |
... | @@ -25,7 +25,7 @@ MU_PARSEOPT_PROG_DOC="Tests option parsing" parseopt --help | ... | @@ -25,7 +25,7 @@ MU_PARSEOPT_PROG_DOC="Tests option parsing" parseopt --help |
25 | Tests option parsing | 25 | Tests option parsing |
26 | 26 | ||
27 | Group A | 27 | Group A |
28 | -a, --all no arguments to this one | 28 | -a, --all, --debug-all no arguments to this one |
29 | -f, --file=FILE set file name | 29 | -f, --file=FILE set file name |
30 | -o, --optional[=FILE] optional argument | 30 | -o, --optional[=FILE] optional argument |
31 | -x short-only option | 31 | -x short-only option |
... | @@ -35,6 +35,10 @@ Tests option parsing | ... | @@ -35,6 +35,10 @@ Tests option parsing |
35 | -F, --find=VALUE find VALUE | 35 | -F, --find=VALUE find VALUE |
36 | -j, --jobs=N sets numeric value | 36 | -j, --jobs=N sets numeric value |
37 | 37 | ||
38 | Group C | ||
39 | --debug-info=S debug information | ||
40 | --debug-level=NUM debug level option | ||
41 | |||
38 | -?, --help give this help list | 42 | -?, --help give this help list |
39 | --usage give a short usage message | 43 | --usage give a short usage message |
40 | 44 | ... | ... |
... | @@ -24,7 +24,7 @@ MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS" parseopt --help | ... | @@ -24,7 +24,7 @@ MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS" parseopt --help |
24 | [Usage: parseopt [[OPTION...]] SOME MORE ARGS | 24 | [Usage: parseopt [[OPTION...]] SOME MORE ARGS |
25 | 25 | ||
26 | Group A | 26 | Group A |
27 | -a, --all no arguments to this one | 27 | -a, --all, --debug-all no arguments to this one |
28 | -f, --file=FILE set file name | 28 | -f, --file=FILE set file name |
29 | -o, --optional[[=FILE]] optional argument | 29 | -o, --optional[[=FILE]] optional argument |
30 | -x short-only option | 30 | -x short-only option |
... | @@ -34,6 +34,10 @@ MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS" parseopt --help | ... | @@ -34,6 +34,10 @@ MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS" parseopt --help |
34 | -F, --find=VALUE find VALUE | 34 | -F, --find=VALUE find VALUE |
35 | -j, --jobs=N sets numeric value | 35 | -j, --jobs=N sets numeric value |
36 | 36 | ||
37 | Group C | ||
38 | --debug-info=S debug information | ||
39 | --debug-level=NUM debug level option | ||
40 | |||
37 | -?, --help give this help list | 41 | -?, --help give this help list |
38 | --usage give a short usage message | 42 | --usage give a short usage message |
39 | 43 | ... | ... |
... | @@ -24,7 +24,7 @@ MU_PARSEOPT_BUG_ADDRESS='gray@gnu.org' parseopt --help | ... | @@ -24,7 +24,7 @@ MU_PARSEOPT_BUG_ADDRESS='gray@gnu.org' parseopt --help |
24 | [Usage: parseopt [[OPTION...]] | 24 | [Usage: parseopt [[OPTION...]] |
25 | 25 | ||
26 | Group A | 26 | Group A |
27 | -a, --all no arguments to this one | 27 | -a, --all, --debug-all no arguments to this one |
28 | -f, --file=FILE set file name | 28 | -f, --file=FILE set file name |
29 | -o, --optional[[=FILE]] optional argument | 29 | -o, --optional[[=FILE]] optional argument |
30 | -x short-only option | 30 | -x short-only option |
... | @@ -34,6 +34,10 @@ MU_PARSEOPT_BUG_ADDRESS='gray@gnu.org' parseopt --help | ... | @@ -34,6 +34,10 @@ MU_PARSEOPT_BUG_ADDRESS='gray@gnu.org' parseopt --help |
34 | -F, --find=VALUE find VALUE | 34 | -F, --find=VALUE find VALUE |
35 | -j, --jobs=N sets numeric value | 35 | -j, --jobs=N sets numeric value |
36 | 36 | ||
37 | Group C | ||
38 | --debug-info=S debug information | ||
39 | --debug-level=NUM debug level option | ||
40 | |||
37 | -?, --help give this help list | 41 | -?, --help give this help list |
38 | --usage give a short usage message | 42 | --usage give a short usage message |
39 | 43 | ... | ... |
... | @@ -24,7 +24,7 @@ MU_PARSEOPT_PACKAGE_NAME='GNU Mailutils' MU_PARSEOPT_PACKAGE_URL='http://mailuti | ... | @@ -24,7 +24,7 @@ MU_PARSEOPT_PACKAGE_NAME='GNU Mailutils' MU_PARSEOPT_PACKAGE_URL='http://mailuti |
24 | [[Usage: parseopt [OPTION...] | 24 | [[Usage: parseopt [OPTION...] |
25 | 25 | ||
26 | Group A | 26 | Group A |
27 | -a, --all no arguments to this one | 27 | -a, --all, --debug-all no arguments to this one |
28 | -f, --file=FILE set file name | 28 | -f, --file=FILE set file name |
29 | -o, --optional[=FILE] optional argument | 29 | -o, --optional[=FILE] optional argument |
30 | -x short-only option | 30 | -x short-only option |
... | @@ -34,6 +34,10 @@ MU_PARSEOPT_PACKAGE_NAME='GNU Mailutils' MU_PARSEOPT_PACKAGE_URL='http://mailuti | ... | @@ -34,6 +34,10 @@ MU_PARSEOPT_PACKAGE_NAME='GNU Mailutils' MU_PARSEOPT_PACKAGE_URL='http://mailuti |
34 | -F, --find=VALUE find VALUE | 34 | -F, --find=VALUE find VALUE |
35 | -j, --jobs=N sets numeric value | 35 | -j, --jobs=N sets numeric value |
36 | 36 | ||
37 | Group C | ||
38 | --debug-info=S debug information | ||
39 | --debug-level=NUM debug level option | ||
40 | |||
37 | -?, --help give this help list | 41 | -?, --help give this help list |
38 | --usage give a short usage message | 42 | --usage give a short usage message |
39 | 43 | ... | ... |
... | @@ -31,7 +31,7 @@ MU_PARSEOPT_PROG_DOC="Tests option parsing"\ | ... | @@ -31,7 +31,7 @@ MU_PARSEOPT_PROG_DOC="Tests option parsing"\ |
31 | Tests option parsing | 31 | Tests option parsing |
32 | 32 | ||
33 | Group A | 33 | Group A |
34 | -a, --all no arguments to this one | 34 | -a, --all, --debug-all no arguments to this one |
35 | -f, --file=FILE set file name | 35 | -f, --file=FILE set file name |
36 | -o, --optional[=FILE] optional argument | 36 | -o, --optional[=FILE] optional argument |
37 | -x short-only option | 37 | -x short-only option |
... | @@ -41,6 +41,10 @@ Tests option parsing | ... | @@ -41,6 +41,10 @@ Tests option parsing |
41 | -F, --find=VALUE find VALUE | 41 | -F, --find=VALUE find VALUE |
42 | -j, --jobs=N sets numeric value | 42 | -j, --jobs=N sets numeric value |
43 | 43 | ||
44 | Group C | ||
45 | --debug-info=S debug information | ||
46 | --debug-level=NUM debug level option | ||
47 | |||
44 | -?, --help give this help list | 48 | -?, --help give this help list |
45 | --usage give a short usage message | 49 | --usage give a short usage message |
46 | 50 | ... | ... |
... | @@ -25,7 +25,7 @@ ARGP_HELP_FMT=dup-args,no-dup-args-note,short-opt-col=1,opt-doc-col=32,header-co | ... | @@ -25,7 +25,7 @@ ARGP_HELP_FMT=dup-args,no-dup-args-note,short-opt-col=1,opt-doc-col=32,header-co |
25 | [[Usage: parseopt [OPTION...] | 25 | [[Usage: parseopt [OPTION...] |
26 | 26 | ||
27 | Group A | 27 | Group A |
28 | -a, --all no arguments to this one | 28 | -a, --all, --debug-all no arguments to this one |
29 | -f FILE, --file=FILE set file name | 29 | -f FILE, --file=FILE set file name |
30 | -o[FILE], --optional[=FILE] optional argument | 30 | -o[FILE], --optional[=FILE] optional argument |
31 | -x short-only option | 31 | -x short-only option |
... | @@ -35,6 +35,10 @@ ARGP_HELP_FMT=dup-args,no-dup-args-note,short-opt-col=1,opt-doc-col=32,header-co | ... | @@ -35,6 +35,10 @@ ARGP_HELP_FMT=dup-args,no-dup-args-note,short-opt-col=1,opt-doc-col=32,header-co |
35 | -F VALUE, --find=VALUE find VALUE | 35 | -F VALUE, --find=VALUE find VALUE |
36 | -j N, --jobs=N sets numeric value | 36 | -j N, --jobs=N sets numeric value |
37 | 37 | ||
38 | Group C | ||
39 | --debug-info=S debug information | ||
40 | --debug-level=NUM debug level option | ||
41 | |||
38 | -?, --help give this help list | 42 | -?, --help give this help list |
39 | --usage give a short usage message | 43 | --usage give a short usage message |
40 | 44 | ... | ... |
... | @@ -23,7 +23,8 @@ ARGP_HELP_FMT=rmargin=62,usage-indent=1\ | ... | @@ -23,7 +23,8 @@ ARGP_HELP_FMT=rmargin=62,usage-indent=1\ |
23 | ], | 23 | ], |
24 | [0], | 24 | [0], |
25 | [[Usage: parseopt [-advx?] [-f FILE] [-F VALUE] [-j N] | 25 | [[Usage: parseopt [-advx?] [-f FILE] [-F VALUE] [-j N] |
26 | [-o[FILE]] [--all] [--debug] [--file=FILE] [--find=VALUE] | 26 | [-o[FILE]] [--all] [--debug] [--debug-all] [--debug-info=S] |
27 | [--help] [--jobs=N] [--optional[=FILE]] [--usage] [--verbose] | 27 | [--debug-level=NUM] [--file=FILE] [--find=VALUE] [--help] |
28 | [--jobs=N] [--optional[=FILE]] [--usage] [--verbose] | ||
28 | ]]) | 29 | ]]) |
29 | AT_CLEANUP | 30 | AT_CLEANUP | ... | ... |
... | @@ -22,7 +22,8 @@ MU_PARSEOPT_VERSION_HOOK=1 parseopt --usage | ... | @@ -22,7 +22,8 @@ MU_PARSEOPT_VERSION_HOOK=1 parseopt --usage |
22 | ], | 22 | ], |
23 | [0], | 23 | [0], |
24 | [[Usage: parseopt [-advVx?] [-f FILE] [-F VALUE] [-j N] [-o[FILE]] [--all] | 24 | [[Usage: parseopt [-advVx?] [-f FILE] [-F VALUE] [-j N] [-o[FILE]] [--all] |
25 | [--debug] [--file=FILE] [--find=VALUE] [--help] [--jobs=N] | 25 | [--debug] [--debug-all] [--debug-info=S] [--debug-level=NUM] |
26 | [--file=FILE] [--find=VALUE] [--help] [--jobs=N] | ||
26 | [--optional[=FILE]] [--usage] [--verbose] [--version] | 27 | [--optional[=FILE]] [--usage] [--verbose] [--version] |
27 | ]]) | 28 | ]]) |
28 | AT_CLEANUP | 29 | AT_CLEANUP | ... | ... |
... | @@ -24,7 +24,7 @@ MU_PARSEOPT_VERSION_HOOK=1 parseopt --help | ... | @@ -24,7 +24,7 @@ MU_PARSEOPT_VERSION_HOOK=1 parseopt --help |
24 | [[Usage: parseopt [OPTION...] | 24 | [[Usage: parseopt [OPTION...] |
25 | 25 | ||
26 | Group A | 26 | Group A |
27 | -a, --all no arguments to this one | 27 | -a, --all, --debug-all no arguments to this one |
28 | -f, --file=FILE set file name | 28 | -f, --file=FILE set file name |
29 | -o, --optional[=FILE] optional argument | 29 | -o, --optional[=FILE] optional argument |
30 | -x short-only option | 30 | -x short-only option |
... | @@ -34,6 +34,10 @@ MU_PARSEOPT_VERSION_HOOK=1 parseopt --help | ... | @@ -34,6 +34,10 @@ MU_PARSEOPT_VERSION_HOOK=1 parseopt --help |
34 | -F, --find=VALUE find VALUE | 34 | -F, --find=VALUE find VALUE |
35 | -j, --jobs=N sets numeric value | 35 | -j, --jobs=N sets numeric value |
36 | 36 | ||
37 | Group C | ||
38 | --debug-info=S debug information | ||
39 | --debug-level=NUM debug level option | ||
40 | |||
37 | -?, --help give this help list | 41 | -?, --help give this help list |
38 | --usage give a short usage message | 42 | --usage give a short usage message |
39 | -V, --version print program version | 43 | -V, --version print program version | ... | ... |
... | @@ -26,7 +26,7 @@ MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS|ALTERNATIVE ARGS|ANOTHER ARGS" parseopt -- | ... | @@ -26,7 +26,7 @@ MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS|ALTERNATIVE ARGS|ANOTHER ARGS" parseopt -- |
26 | or: parseopt [[OPTION...]] ANOTHER ARGS | 26 | or: parseopt [[OPTION...]] ANOTHER ARGS |
27 | 27 | ||
28 | Group A | 28 | Group A |
29 | -a, --all no arguments to this one | 29 | -a, --all, --debug-all no arguments to this one |
30 | -f, --file=FILE set file name | 30 | -f, --file=FILE set file name |
31 | -o, --optional[[=FILE]] optional argument | 31 | -o, --optional[[=FILE]] optional argument |
32 | -x short-only option | 32 | -x short-only option |
... | @@ -36,6 +36,10 @@ MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS|ALTERNATIVE ARGS|ANOTHER ARGS" parseopt -- | ... | @@ -36,6 +36,10 @@ MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS|ALTERNATIVE ARGS|ANOTHER ARGS" parseopt -- |
36 | -F, --find=VALUE find VALUE | 36 | -F, --find=VALUE find VALUE |
37 | -j, --jobs=N sets numeric value | 37 | -j, --jobs=N sets numeric value |
38 | 38 | ||
39 | Group C | ||
40 | --debug-info=S debug information | ||
41 | --debug-level=NUM debug level option | ||
42 | |||
39 | -?, --help give this help list | 43 | -?, --help give this help list |
40 | --usage give a short usage message | 44 | --usage give a short usage message |
41 | 45 | ... | ... |
... | @@ -129,6 +129,8 @@ m4_include([parseopt22.at]) | ... | @@ -129,6 +129,8 @@ m4_include([parseopt22.at]) |
129 | m4_include([parseopt23.at]) | 129 | m4_include([parseopt23.at]) |
130 | m4_include([parseopt24.at]) | 130 | m4_include([parseopt24.at]) |
131 | m4_include([parseopt25.at]) | 131 | m4_include([parseopt25.at]) |
132 | m4_include([parseopt26.at]) | ||
133 | m4_include([parseopt27.at]) | ||
132 | 134 | ||
133 | AT_BANNER([Command line help output]) | 135 | AT_BANNER([Command line help output]) |
134 | m4_include([parseopt_help00.at]) | 136 | m4_include([parseopt_help00.at]) | ... | ... |
-
Please register or sign in to post a comment