Allow for multiple argument sets in help output.
Alternative invocations follow the main one, each on a separate line, preceded by " or: ". * include/mailutils/cli.h (mu_cli_setup) <prog_alt_args>: New member. * include/mailutils/opt.h (mu_parseopt) <po_prog_args>: Change type. (mu_program_usage): Change signature. * include/mailutils/stream.h (MU_IOCTL_WORDWRAP_GET_OFFSET): Rename to MU_IOCTL_WORDWRAP_GET_COLUMN. All uses changed. * libmailutils/cli/cli.c (mu_cli): Construct po.po_prog_args from prog_args and prog_alt_args. * libmailutils/opt/help.c (move_margin): Remove. (print_program_usage): New static function. (mu_program_usage): Second argument instructs how to display options. Main work is done by print_program_usage. (mu_program_help): Call print_program_usage. * libmailutils/opt/opt.c: Update. * libmailutils/stream/wordwrap.c (set_margin): Avoid unnecessary flushes. * libmailutils/tests/parseopt.c (MU_PARSEOPT_PROG_ARGS): Alternative argument sets are separated by the pipe sign. * libmailutils/tests/Makefile.am: Add new testcase. * libmailutils/tests/testsuite.at: Likewise. * libmailutils/tests/parseopt_help04.at: Add MU_PARSEOPT_PROG_ARGS to keywords. * libmailutils/tests/parseopt_help12.at: New file. * libmailutils/tests/tcli.c (cli): Add alternative arguments. * dotlock/dotlock.c: Update. * mimeview/mimeview.c: Likewise. * sieve/sieve.c: Likewise.
Showing
17 changed files
with
212 additions
and
49 deletions
... | @@ -93,6 +93,7 @@ static struct mu_cli_setup cli = { | ... | @@ -93,6 +93,7 @@ static struct mu_cli_setup cli = { |
93 | dotlock_cfg_param, | 93 | dotlock_cfg_param, |
94 | N_("GNU dotlock -- lock mail spool files."), | 94 | N_("GNU dotlock -- lock mail spool files."), |
95 | N_("FILE"), | 95 | N_("FILE"), |
96 | NULL, | ||
96 | N_("Returns 0 on success, 3 if locking the file fails because\ | 97 | N_("Returns 0 on success, 3 if locking the file fails because\ |
97 | it's already locked, and 1 if some other kind of error occurred."), | 98 | it's already locked, and 1 if some other kind of error occurred."), |
98 | MU_DL_EX_ERROR, | 99 | MU_DL_EX_ERROR, | ... | ... |
... | @@ -43,6 +43,7 @@ struct mu_cli_setup | ... | @@ -43,6 +43,7 @@ struct mu_cli_setup |
43 | struct mu_cfg_param *cfg; /* Configuration parameters */ | 43 | struct mu_cfg_param *cfg; /* Configuration parameters */ |
44 | char *prog_doc; /* Program documentation string */ | 44 | char *prog_doc; /* Program documentation string */ |
45 | char *prog_args; /* Program arguments string */ | 45 | char *prog_args; /* Program arguments string */ |
46 | char const **prog_alt_args; /* Alternative arguments string */ | ||
46 | char *prog_extra_doc; /* Extra documentation. This will be | 47 | char *prog_extra_doc; /* Extra documentation. This will be |
47 | displayed after options. */ | 48 | displayed after options. */ |
48 | int ex_usage; /* If not 0, exit code on usage errors */ | 49 | int ex_usage; /* If not 0, exit code on usage errors */ | ... | ... |
... | @@ -125,7 +125,7 @@ struct mu_parseopt | ... | @@ -125,7 +125,7 @@ struct mu_parseopt |
125 | /* Informational: */ | 125 | /* Informational: */ |
126 | char const *po_prog_name; | 126 | char const *po_prog_name; |
127 | char const *po_prog_doc; | 127 | char const *po_prog_doc; |
128 | char const *po_prog_args; | 128 | char const **po_prog_args; |
129 | char const *po_bug_address; | 129 | char const *po_bug_address; |
130 | char const *po_package_name; | 130 | char const *po_package_name; |
131 | char const *po_package_url; | 131 | char const *po_package_url; |
... | @@ -172,7 +172,7 @@ unsigned mu_parseopt_getcolumn (const char *name); | ... | @@ -172,7 +172,7 @@ unsigned mu_parseopt_getcolumn (const char *name); |
172 | void mu_option_describe_options (mu_stream_t str, | 172 | void mu_option_describe_options (mu_stream_t str, |
173 | struct mu_option **optbuf, size_t optcnt); | 173 | struct mu_option **optbuf, size_t optcnt); |
174 | void mu_program_help (struct mu_parseopt *p, mu_stream_t str); | 174 | void mu_program_help (struct mu_parseopt *p, mu_stream_t str); |
175 | void mu_program_usage (struct mu_parseopt *p, mu_stream_t str); | 175 | void mu_program_usage (struct mu_parseopt *p, int optsummary, mu_stream_t str); |
176 | void mu_program_version (struct mu_parseopt *po, mu_stream_t str); | 176 | void mu_program_version (struct mu_parseopt *po, mu_stream_t str); |
177 | 177 | ||
178 | void mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt, | 178 | void mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt, | ... | ... |
... | @@ -208,11 +208,16 @@ enum mu_buffer_type | ... | @@ -208,11 +208,16 @@ enum mu_buffer_type |
208 | ((n) == MU_TRANSPORT_INPUT || (n) == MU_TRANSPORT_OUTPUT) | 208 | ((n) == MU_TRANSPORT_INPUT || (n) == MU_TRANSPORT_OUTPUT) |
209 | 209 | ||
210 | /* Word wrapper streams */ | 210 | /* Word wrapper streams */ |
211 | /* Get left margin. */ | ||
211 | #define MU_IOCTL_WORDWRAP_GET_MARGIN 0 | 212 | #define MU_IOCTL_WORDWRAP_GET_MARGIN 0 |
213 | /* Set left margin */ | ||
212 | #define MU_IOCTL_WORDWRAP_SET_MARGIN 1 | 214 | #define MU_IOCTL_WORDWRAP_SET_MARGIN 1 |
215 | /* Shift left margin relative to current position */ | ||
213 | #define MU_IOCTL_WORDWRAP_MOVE_MARGIN 2 | 216 | #define MU_IOCTL_WORDWRAP_MOVE_MARGIN 2 |
217 | /* Set left margin for the next line */ | ||
214 | #define MU_IOCTL_WORDWRAP_SET_NEXT_MARGIN 3 | 218 | #define MU_IOCTL_WORDWRAP_SET_NEXT_MARGIN 3 |
215 | #define MU_IOCTL_WORDWRAP_GET_OFFSET 4 | 219 | /* Get current column */ |
220 | #define MU_IOCTL_WORDWRAP_GET_COLUMN 4 | ||
216 | 221 | ||
217 | struct mu_nullstream_pattern | 222 | struct mu_nullstream_pattern |
218 | { | 223 | { | ... | ... |
... | @@ -336,6 +336,10 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, | ... | @@ -336,6 +336,10 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, |
336 | struct mu_cfg_parse_hints hints; | 336 | struct mu_cfg_parse_hints hints; |
337 | struct mu_option **optv; | 337 | struct mu_option **optv; |
338 | mu_list_t com_list; | 338 | mu_list_t com_list; |
339 | #define DFLARGC 2 | ||
340 | char const *dfl_args[DFLARGC]; | ||
341 | char **args = NULL; | ||
342 | size_t argcnt; | ||
339 | 343 | ||
340 | /* Set up defaults */ | 344 | /* Set up defaults */ |
341 | if (setup->ex_usage == 0) | 345 | if (setup->ex_usage == 0) |
... | @@ -374,7 +378,28 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, | ... | @@ -374,7 +378,28 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, |
374 | 378 | ||
375 | if (setup->prog_args) | 379 | if (setup->prog_args) |
376 | { | 380 | { |
377 | po.po_prog_args = setup->prog_args; | 381 | size_t i; |
382 | argcnt = 1; | ||
383 | |||
384 | if (setup->prog_alt_args) | ||
385 | { | ||
386 | for (i = 0; setup->prog_alt_args[i]; i++) | ||
387 | argcnt++; | ||
388 | } | ||
389 | |||
390 | if (argcnt < DFLARGC) | ||
391 | po.po_prog_args = dfl_args; | ||
392 | else | ||
393 | { | ||
394 | args = mu_calloc (argcnt + 1, sizeof (args[0])); | ||
395 | po.po_prog_args = (char const **) args; | ||
396 | } | ||
397 | |||
398 | po.po_prog_args[0] = setup->prog_args; | ||
399 | for (i = 1; i < argcnt; i++) | ||
400 | po.po_prog_args[i] = setup->prog_alt_args[i-1]; | ||
401 | po.po_prog_args[i] = NULL; | ||
402 | |||
378 | flags |= MU_PARSEOPT_PROG_ARGS; | 403 | flags |= MU_PARSEOPT_PROG_ARGS; |
379 | } | 404 | } |
380 | 405 | ||
... | @@ -439,5 +464,8 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, | ... | @@ -439,5 +464,8 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, |
439 | 464 | ||
440 | mu_cfg_destroy_tree (&parse_tree); | 465 | mu_cfg_destroy_tree (&parse_tree); |
441 | free (optv); | 466 | free (optv); |
467 | |||
468 | free (args); | ||
469 | |||
442 | mu_parseopt_free (&po); | 470 | mu_parseopt_free (&po); |
443 | } | 471 | } | ... | ... |
... | @@ -204,16 +204,9 @@ static void | ... | @@ -204,16 +204,9 @@ static void |
204 | get_offset (mu_stream_t str, unsigned *offset) | 204 | get_offset (mu_stream_t str, unsigned *offset) |
205 | { | 205 | { |
206 | mu_stream_ioctl (str, MU_IOCTL_WORDWRAPSTREAM, | 206 | mu_stream_ioctl (str, MU_IOCTL_WORDWRAPSTREAM, |
207 | MU_IOCTL_WORDWRAP_GET_OFFSET, | 207 | MU_IOCTL_WORDWRAP_GET_COLUMN, |
208 | offset); | 208 | offset); |
209 | } | 209 | } |
210 | static void | ||
211 | move_margin (mu_stream_t str, int margin) | ||
212 | { | ||
213 | mu_stream_ioctl (str, MU_IOCTL_WORDWRAPSTREAM, | ||
214 | MU_IOCTL_WORDWRAP_MOVE_MARGIN, | ||
215 | &margin); | ||
216 | } | ||
217 | 210 | ||
218 | static void | 211 | static void |
219 | print_opt_arg (mu_stream_t str, struct mu_option *opt, int delim) | 212 | print_opt_arg (mu_stream_t str, struct mu_option *opt, int delim) |
... | @@ -333,6 +326,9 @@ mu_option_describe_options (mu_stream_t str, | ... | @@ -333,6 +326,9 @@ mu_option_describe_options (mu_stream_t str, |
333 | } | 326 | } |
334 | } | 327 | } |
335 | 328 | ||
329 | static void print_program_usage (struct mu_parseopt *po, int optsum, | ||
330 | mu_stream_t str); | ||
331 | |||
336 | void | 332 | void |
337 | mu_program_help (struct mu_parseopt *po, mu_stream_t outstr) | 333 | mu_program_help (struct mu_parseopt *po, mu_stream_t outstr) |
338 | { | 334 | { |
... | @@ -347,14 +343,7 @@ mu_program_help (struct mu_parseopt *po, mu_stream_t outstr) | ... | @@ -347,14 +343,7 @@ mu_program_help (struct mu_parseopt *po, mu_stream_t outstr) |
347 | abort ();//FIXME | 343 | abort ();//FIXME |
348 | } | 344 | } |
349 | 345 | ||
350 | mu_stream_printf (str, "%s", _("Usage:")); | 346 | print_program_usage (po, 0, str); |
351 | if (po->po_prog_name) | ||
352 | mu_stream_printf (str, " %s ", po->po_prog_name); | ||
353 | move_margin (str, 0); | ||
354 | mu_stream_printf (str, "[%s]...", _("OPTION")); | ||
355 | if (po->po_prog_args) | ||
356 | mu_stream_printf (str, " %s", gettext (po->po_prog_args)); | ||
357 | mu_stream_printf (str, "\n"); | ||
358 | 347 | ||
359 | if (po->po_prog_doc) | 348 | if (po->po_prog_doc) |
360 | { | 349 | { |
... | @@ -423,10 +412,9 @@ cmpidx_long (const void *a, const void *b) | ... | @@ -423,10 +412,9 @@ cmpidx_long (const void *a, const void *b) |
423 | return strcmp (ap->opt_long, bp->opt_long); | 412 | return strcmp (ap->opt_long, bp->opt_long); |
424 | } | 413 | } |
425 | 414 | ||
426 | void | 415 | static void |
427 | mu_program_usage (struct mu_parseopt *po, mu_stream_t outstr) | 416 | option_summary (struct mu_parseopt *po, mu_stream_t str) |
428 | { | 417 | { |
429 | int rc; | ||
430 | unsigned i; | 418 | unsigned i; |
431 | unsigned *idxbuf; | 419 | unsigned *idxbuf; |
432 | unsigned nidx; | 420 | unsigned nidx; |
... | @@ -434,23 +422,10 @@ mu_program_usage (struct mu_parseopt *po, mu_stream_t outstr) | ... | @@ -434,23 +422,10 @@ mu_program_usage (struct mu_parseopt *po, mu_stream_t outstr) |
434 | struct mu_option **optbuf = po->po_optv; | 422 | struct mu_option **optbuf = po->po_optv; |
435 | size_t optcnt = po->po_optc; | 423 | size_t optcnt = po->po_optc; |
436 | 424 | ||
437 | mu_stream_t str; | ||
438 | |||
439 | init_usage_vars (po); | ||
440 | |||
441 | rc = mu_wordwrap_stream_create (&str, outstr, 0, rmargin); | ||
442 | if (rc) | ||
443 | { | ||
444 | abort ();//FIXME | ||
445 | } | ||
446 | |||
447 | option_tab = optbuf; | 425 | option_tab = optbuf; |
448 | 426 | ||
449 | idxbuf = mu_calloc (optcnt, sizeof (idxbuf[0])); | 427 | idxbuf = mu_calloc (optcnt, sizeof (idxbuf[0])); |
450 | 428 | ||
451 | mu_stream_printf (str, "%s %s ", _("Usage:"), po->po_prog_name); | ||
452 | set_next_margin (str, usage_indent); | ||
453 | |||
454 | /* Print a list of short options without arguments. */ | 429 | /* Print a list of short options without arguments. */ |
455 | for (i = nidx = 0; i < optcnt; i++) | 430 | for (i = nidx = 0; i < optcnt; i++) |
456 | if (MU_OPTION_IS_VALID_SHORT_OPTION (optbuf[i]) && !optbuf[i]->opt_arg) | 431 | if (MU_OPTION_IS_VALID_SHORT_OPTION (optbuf[i]) && !optbuf[i]->opt_arg) |
... | @@ -517,12 +492,66 @@ mu_program_usage (struct mu_parseopt *po, mu_stream_t outstr) | ... | @@ -517,12 +492,66 @@ mu_program_usage (struct mu_parseopt *po, mu_stream_t outstr) |
517 | } | 492 | } |
518 | } | 493 | } |
519 | 494 | ||
495 | free (idxbuf); | ||
496 | } | ||
497 | |||
498 | static void | ||
499 | print_program_usage (struct mu_parseopt *po, int optsum, mu_stream_t str) | ||
500 | { | ||
501 | char const *usage_text; | ||
502 | char const **arg_text; | ||
503 | size_t i; | ||
504 | |||
505 | usage_text = _("Usage:"); | ||
506 | |||
520 | if (po->po_flags & MU_PARSEOPT_PROG_ARGS) | 507 | if (po->po_flags & MU_PARSEOPT_PROG_ARGS) |
521 | mu_stream_printf (str, " %s", _(po->po_prog_args)); | 508 | arg_text = po->po_prog_args; |
509 | else | ||
510 | arg_text = NULL; | ||
511 | i = 0; | ||
522 | 512 | ||
523 | mu_stream_destroy (&str); | 513 | do |
514 | { | ||
515 | mu_stream_printf (str, "%s %s ", usage_text, po->po_prog_name); | ||
516 | set_next_margin (str, usage_indent); | ||
524 | 517 | ||
525 | free (idxbuf); | 518 | if (optsum) |
519 | { | ||
520 | option_summary (po, str); | ||
521 | optsum = 0; | ||
522 | } | ||
523 | else | ||
524 | mu_stream_printf (str, "[%s]...", _("OPTION")); | ||
525 | |||
526 | if (arg_text) | ||
527 | { | ||
528 | mu_stream_printf (str, " %s\n", gettext (arg_text[i])); | ||
529 | if (i == 0) | ||
530 | usage_text = _("or: "); | ||
531 | set_margin (str, 2); | ||
532 | i++; | ||
533 | } | ||
534 | else | ||
535 | mu_stream_flush (str); | ||
536 | } | ||
537 | while (arg_text && arg_text[i]); | ||
538 | } | ||
539 | |||
540 | void | ||
541 | mu_program_usage (struct mu_parseopt *po, int optsum, mu_stream_t outstr) | ||
542 | { | ||
543 | int rc; | ||
544 | mu_stream_t str; | ||
545 | |||
546 | init_usage_vars (po); | ||
547 | |||
548 | rc = mu_wordwrap_stream_create (&str, outstr, 0, rmargin); | ||
549 | if (rc) | ||
550 | { | ||
551 | abort ();//FIXME | ||
552 | } | ||
553 | print_program_usage (po, optsum, str); | ||
554 | mu_stream_destroy (&str); | ||
526 | } | 555 | } |
527 | 556 | ||
528 | void | 557 | void | ... | ... |
... | @@ -87,7 +87,7 @@ fn_help (struct mu_parseopt *po, struct mu_option *opt, char const *unused) | ... | @@ -87,7 +87,7 @@ fn_help (struct mu_parseopt *po, struct mu_option *opt, char const *unused) |
87 | static void | 87 | static void |
88 | fn_usage (struct mu_parseopt *po, struct mu_option *opt, char const *unused) | 88 | fn_usage (struct mu_parseopt *po, struct mu_option *opt, char const *unused) |
89 | { | 89 | { |
90 | mu_program_usage (po, mu_strout); | 90 | mu_program_usage (po, 1, mu_strout); |
91 | exit (EXIT_SUCCESS); | 91 | exit (EXIT_SUCCESS); |
92 | } | 92 | } |
93 | 93 | ... | ... |
... | @@ -178,15 +178,17 @@ set_margin (mu_stream_t stream, unsigned lmargin, int off) | ... | @@ -178,15 +178,17 @@ set_margin (mu_stream_t stream, unsigned lmargin, int off) |
178 | if (lmargin >= str->right_margin) | 178 | if (lmargin >= str->right_margin) |
179 | return EINVAL; | 179 | return EINVAL; |
180 | 180 | ||
181 | str->left_margin = lmargin; | 181 | if (str->offset > str->left_margin |
182 | if (lmargin < str->offset || | 182 | && (lmargin < str->offset || str->buffer[str->offset - 1] == '\n')) |
183 | (str->offset > 0 && str->buffer[str->offset - 1] == '\n')) | ||
184 | { | 183 | { |
184 | str->left_margin = lmargin; | ||
185 | _wordwrap_flush (stream); | 185 | _wordwrap_flush (stream); |
186 | } | 186 | } |
187 | else if (lmargin > str->offset) | 187 | else |
188 | { | 188 | { |
189 | if (lmargin > str->offset) | ||
189 | memset (str->buffer + str->offset, ' ', lmargin - str->offset); | 190 | memset (str->buffer + str->offset, ' ', lmargin - str->offset); |
191 | str->left_margin = lmargin; | ||
190 | str->offset = lmargin; | 192 | str->offset = lmargin; |
191 | } | 193 | } |
192 | 194 | ||
... | @@ -236,7 +238,7 @@ _wordwrap_ctl (mu_stream_t stream, int code, int opcode, void *arg) | ... | @@ -236,7 +238,7 @@ _wordwrap_ctl (mu_stream_t stream, int code, int opcode, void *arg) |
236 | else | 238 | else |
237 | return set_margin (stream, str->offset, *(int*)arg); | 239 | return set_margin (stream, str->offset, *(int*)arg); |
238 | 240 | ||
239 | case MU_IOCTL_WORDWRAP_GET_OFFSET: | 241 | case MU_IOCTL_WORDWRAP_GET_COLUMN: |
240 | if (!arg) | 242 | if (!arg) |
241 | return EINVAL; | 243 | return EINVAL; |
242 | *(unsigned*)arg = str->offset; | 244 | *(unsigned*)arg = str->offset; | ... | ... |
... | @@ -18,6 +18,7 @@ imapio | ... | @@ -18,6 +18,7 @@ imapio |
18 | listop | 18 | listop |
19 | mailcap | 19 | mailcap |
20 | mimehdr | 20 | mimehdr |
21 | modmesg | ||
21 | modtofsaf | 22 | modtofsaf |
22 | msgset | 23 | msgset |
23 | parseopt | 24 | parseopt |
... | @@ -32,4 +33,5 @@ tempfile | ... | @@ -32,4 +33,5 @@ tempfile |
32 | url-comp | 33 | url-comp |
33 | url-parse | 34 | url-parse |
34 | wicket | 35 | wicket |
36 | wordwrap | ||
35 | wsp | 37 | wsp | ... | ... |
... | @@ -144,6 +144,7 @@ TESTSUITE_AT = \ | ... | @@ -144,6 +144,7 @@ TESTSUITE_AT = \ |
144 | parseopt_help09.at\ | 144 | parseopt_help09.at\ |
145 | parseopt_help10.at\ | 145 | parseopt_help10.at\ |
146 | parseopt_help11.at\ | 146 | parseopt_help11.at\ |
147 | parseopt_help12.at\ | ||
147 | prop.at\ | 148 | prop.at\ |
148 | scantime.at\ | 149 | scantime.at\ |
149 | strftime.at\ | 150 | strftime.at\ | ... | ... |
... | @@ -77,8 +77,43 @@ struct parseopt_param | ... | @@ -77,8 +77,43 @@ struct parseopt_param |
77 | int flag; | 77 | int flag; |
78 | mu_c_type_t type; | 78 | mu_c_type_t type; |
79 | size_t off; | 79 | size_t off; |
80 | void (*setfn) (struct parseopt_param *param, char const *val, void *target); | ||
80 | }; | 81 | }; |
81 | 82 | ||
83 | static void | ||
84 | set_prog_args (struct parseopt_param *param, char const *str, void *target) | ||
85 | { | ||
86 | char ***args_ptr = target; | ||
87 | char **args; | ||
88 | char *p; | ||
89 | size_t size, i; | ||
90 | |||
91 | size = 1; | ||
92 | for (i = 0; str[i]; i++) | ||
93 | if (str[i] == '\n') | ||
94 | size++; | ||
95 | |||
96 | args = mu_calloc (size + 1, sizeof (args[0])); | ||
97 | |||
98 | i = 0; | ||
99 | while (1) | ||
100 | { | ||
101 | size_t len = strcspn (str, "|"); | ||
102 | p = mu_alloc (len + 1); | ||
103 | memcpy (p, str, len); | ||
104 | p[len] = 0; | ||
105 | args[i++] = p; | ||
106 | str += len; | ||
107 | if (str[0]) | ||
108 | ++str; | ||
109 | else | ||
110 | break; | ||
111 | } | ||
112 | args[i] = NULL; | ||
113 | |||
114 | *args_ptr = args; | ||
115 | } | ||
116 | |||
82 | static struct parseopt_param parseopt_param[] = { | 117 | static struct parseopt_param parseopt_param[] = { |
83 | { "MU_PARSEOPT_ARGV0", MU_PARSEOPT_ARGV0, mu_c_void }, | 118 | { "MU_PARSEOPT_ARGV0", MU_PARSEOPT_ARGV0, mu_c_void }, |
84 | { "MU_PARSEOPT_IGNORE_ERRORS", MU_PARSEOPT_IGNORE_ERRORS, mu_c_void }, | 119 | { "MU_PARSEOPT_IGNORE_ERRORS", MU_PARSEOPT_IGNORE_ERRORS, mu_c_void }, |
... | @@ -93,7 +128,8 @@ static struct parseopt_param parseopt_param[] = { | ... | @@ -93,7 +128,8 @@ static struct parseopt_param parseopt_param[] = { |
93 | { "MU_PARSEOPT_PROG_DOC", MU_PARSEOPT_PROG_DOC, | 128 | { "MU_PARSEOPT_PROG_DOC", MU_PARSEOPT_PROG_DOC, |
94 | mu_c_string, mu_offsetof(struct mu_parseopt, po_prog_doc) }, | 129 | mu_c_string, mu_offsetof(struct mu_parseopt, po_prog_doc) }, |
95 | { "MU_PARSEOPT_PROG_ARGS", MU_PARSEOPT_PROG_ARGS, | 130 | { "MU_PARSEOPT_PROG_ARGS", MU_PARSEOPT_PROG_ARGS, |
96 | mu_c_string, mu_offsetof(struct mu_parseopt, po_prog_args) }, | 131 | mu_c_string, mu_offsetof(struct mu_parseopt, po_prog_args), |
132 | set_prog_args }, | ||
97 | { "MU_PARSEOPT_BUG_ADDRESS", MU_PARSEOPT_BUG_ADDRESS, | 133 | { "MU_PARSEOPT_BUG_ADDRESS", MU_PARSEOPT_BUG_ADDRESS, |
98 | mu_c_string, mu_offsetof(struct mu_parseopt, po_bug_address) }, | 134 | mu_c_string, mu_offsetof(struct mu_parseopt, po_bug_address) }, |
99 | { "MU_PARSEOPT_PACKAGE_NAME", MU_PARSEOPT_PACKAGE_NAME, | 135 | { "MU_PARSEOPT_PACKAGE_NAME", MU_PARSEOPT_PACKAGE_NAME, |
... | @@ -129,7 +165,11 @@ main (int argc, char *argv[]) | ... | @@ -129,7 +165,11 @@ main (int argc, char *argv[]) |
129 | if (val) | 165 | if (val) |
130 | { | 166 | { |
131 | flags |= param->flag; | 167 | flags |= param->flag; |
132 | if (param->type != mu_c_void) | 168 | if (param->setfn) |
169 | { | ||
170 | param->setfn (param, val, ((char*)&po + param->off)); | ||
171 | } | ||
172 | else if (param->type != mu_c_void) | ||
133 | { | 173 | { |
134 | char *errmsg; | 174 | char *errmsg; |
135 | int rc = mu_str_to_c (val, param->type, | 175 | int rc = mu_str_to_c (val, param->type, | ... | ... |
... | @@ -15,7 +15,7 @@ | ... | @@ -15,7 +15,7 @@ |
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([MU_PARSEOPT_PROG_ARGS]) | 17 | AT_SETUP([MU_PARSEOPT_PROG_ARGS]) |
18 | AT_KEYWORDS([parseopt parseopt_help parseopt_help04]) | 18 | AT_KEYWORDS([parseopt parseopt_help MU_PARSEOPT_PROG_ARGS parseopt_help04]) |
19 | AT_CHECK([ | 19 | AT_CHECK([ |
20 | PARSEOPT_DEFAULT | 20 | PARSEOPT_DEFAULT |
21 | MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS" parseopt --help | 21 | MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS" parseopt --help | ... | ... |
libmailutils/tests/parseopt_help12.at
0 → 100644
1 | # This file is part of GNU Mailutils. -*- Autotest -*- | ||
2 | # Copyright (C) 2016 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([MU_PARSEOPT_PROG_ARGS (alternative)]) | ||
18 | AT_KEYWORDS([parseopt parseopt_help MU_PARSEOPT_PROG_ARGS parseopt_help12]) | ||
19 | AT_CHECK([ | ||
20 | PARSEOPT_DEFAULT | ||
21 | MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS|ALTERNATIVE ARGS|ANOTHER ARGS" parseopt --help | ||
22 | ], | ||
23 | [0], | ||
24 | [Usage: parseopt [[OPTION]]... SOME MORE ARGS | ||
25 | or: parseopt [[OPTION]]... ALTERNATIVE ARGS | ||
26 | or: parseopt [[OPTION]]... ANOTHER ARGS | ||
27 | |||
28 | Group A | ||
29 | -a, --all no arguments to this one | ||
30 | -f, --file=FILE set file name | ||
31 | -o, --optional[[=FILE]] optional argument | ||
32 | -x short-only option | ||
33 | |||
34 | Group B | ||
35 | -d, -v, --debug, --verbose another option | ||
36 | -F, --find=VALUE find VALUE | ||
37 | -j, --jobs=N sets numeric value | ||
38 | |||
39 | -?, --help give this help list | ||
40 | --usage give a short usage message | ||
41 | |||
42 | Mandatory or optional arguments to long options are also mandatory or optional | ||
43 | for any corresponding short options. | ||
44 | |||
45 | ]) | ||
46 | AT_CLEANUP | ||
47 | |||
48 |
... | @@ -37,11 +37,14 @@ static struct mu_cfg_param config[] = { | ... | @@ -37,11 +37,14 @@ static struct mu_cfg_param config[] = { |
37 | { NULL } | 37 | { NULL } |
38 | }; | 38 | }; |
39 | 39 | ||
40 | char const *alt_args[] = { "ALT ARGUMENTS 1", "ALT ARGUMENTS 2", NULL }; | ||
41 | |||
40 | struct mu_cli_setup cli = { | 42 | struct mu_cli_setup cli = { |
41 | options, | 43 | options, |
42 | config, | 44 | config, |
43 | "Tests standard command line interface", | 45 | "Tests standard command line interface", |
44 | "ARGUMENTS" | 46 | "ARGUMENTS", |
47 | alt_args | ||
45 | }; | 48 | }; |
46 | 49 | ||
47 | static char ** | 50 | static char ** | ... | ... |
... | @@ -121,6 +121,7 @@ m4_include([parseopt_help08.at]) | ... | @@ -121,6 +121,7 @@ m4_include([parseopt_help08.at]) |
121 | m4_include([parseopt_help09.at]) | 121 | m4_include([parseopt_help09.at]) |
122 | m4_include([parseopt_help10.at]) | 122 | m4_include([parseopt_help10.at]) |
123 | m4_include([parseopt_help11.at]) | 123 | m4_include([parseopt_help11.at]) |
124 | m4_include([parseopt_help12.at]) | ||
124 | 125 | ||
125 | AT_BANNER([Standard streams]) | 126 | AT_BANNER([Standard streams]) |
126 | m4_include([strin.at]) | 127 | m4_include([strin.at]) | ... | ... |
... | @@ -145,6 +145,7 @@ struct mu_cli_setup cli = { | ... | @@ -145,6 +145,7 @@ struct mu_cli_setup cli = { |
145 | mimeview_cfg_param, | 145 | mimeview_cfg_param, |
146 | N_("GNU mimeview -- display files, using mailcap mechanism."), | 146 | N_("GNU mimeview -- display files, using mailcap mechanism."), |
147 | N_("FILE [FILE ...]"), | 147 | N_("FILE [FILE ...]"), |
148 | NULL, | ||
148 | N_("Debug flags are:\n\ | 149 | N_("Debug flags are:\n\ |
149 | g - Mime.types parser traces\n\ | 150 | g - Mime.types parser traces\n\ |
150 | l - Mime.types lexical analyzer traces\n\ | 151 | l - Mime.types lexical analyzer traces\n\ | ... | ... |
... | @@ -248,6 +248,7 @@ static struct mu_cli_setup cli = { | ... | @@ -248,6 +248,7 @@ static struct mu_cli_setup cli = { |
248 | sieve_cfg_param, | 248 | sieve_cfg_param, |
249 | N_("GNU sieve -- a mail filtering tool."), | 249 | N_("GNU sieve -- a mail filtering tool."), |
250 | "SCRIPT", | 250 | "SCRIPT", |
251 | NULL, | ||
251 | N_("Debug flags:\n\ | 252 | N_("Debug flags:\n\ |
252 | g - main parser traces\n\ | 253 | g - main parser traces\n\ |
253 | T - mailutils traces (same as --debug-level=sieve.trace0-trace1)\n\ | 254 | T - mailutils traces (same as --debug-level=sieve.trace0-trace1)\n\ | ... | ... |
-
Please register or sign in to post a comment