Fix some incompatibilities in the previous commit.
* dotlock/dotlock.c (force): Change type to unsigned. Provide default value for --force. (cli): Set exit codes and extra docstring. * include/mailutils/cli.h (mu_cli_setup): New members: prog_extra_doc, ex_usage, ex_config. * include/mailutils/opt.h (mu_parseopt_getcolumn) (mu_parseopt_fmt_text): New prototypes. * libmailutils/cli/cli.c (extra_help_hook): New hook. (mu_cli): Set up customized exit codes. Pass pointer to struct mu_cli_setup in hints.data. All uses changed. Set up help hook if setup->prog_extra_doc is defined. * libmailutils/opt/help.c (mu_parseopt_getcolumn): New function. (print_option_descr): Honor explicit newlines. (mu_parseopt_fmt_text): New function. * mimeview/mimeview.c (cli): Provide extra docs. * sieve/sieve.c: Likewise.
Showing
7 changed files
with
115 additions
and
30 deletions
... | @@ -31,9 +31,33 @@ static const char *file; | ... | @@ -31,9 +31,33 @@ static const char *file; |
31 | static int unlock; | 31 | static int unlock; |
32 | static int flags; | 32 | static int flags; |
33 | static int retries; | 33 | static int retries; |
34 | static time_t force; | 34 | static unsigned force; |
35 | static int debug; | 35 | static int debug; |
36 | 36 | ||
37 | static void | ||
38 | cli_force (struct mu_parseopt *po, struct mu_option *opt, char const *arg) | ||
39 | { | ||
40 | if (arg) | ||
41 | { | ||
42 | int rc; | ||
43 | char *errmsg; | ||
44 | rc = mu_str_to_c (arg, opt->opt_type, opt->opt_ptr, &errmsg); | ||
45 | if (rc) | ||
46 | { | ||
47 | if (opt->opt_long) | ||
48 | mu_parseopt_error (po, "--%s: %s", opt->opt_long, | ||
49 | errmsg ? errmsg : mu_strerror (rc)); | ||
50 | else | ||
51 | mu_parseopt_error (po, "-%c: %s", opt->opt_short, | ||
52 | errmsg ? errmsg : mu_strerror (rc)); | ||
53 | free (errmsg); | ||
54 | exit (po->po_exit_error); | ||
55 | } | ||
56 | } | ||
57 | else | ||
58 | *(unsigned*)opt->opt_ptr = 1; | ||
59 | } | ||
60 | |||
37 | static struct mu_option dotlock_options[] = { | 61 | static struct mu_option dotlock_options[] = { |
38 | { "unlock", 'u', NULL, MU_OPTION_DEFAULT, | 62 | { "unlock", 'u', NULL, MU_OPTION_DEFAULT, |
39 | N_("unlock"), | 63 | N_("unlock"), |
... | @@ -41,7 +65,7 @@ static struct mu_option dotlock_options[] = { | ... | @@ -41,7 +65,7 @@ static struct mu_option dotlock_options[] = { |
41 | 65 | ||
42 | { "force", 'f', N_("MINUTES"), MU_OPTION_ARG_OPTIONAL, | 66 | { "force", 'f', N_("MINUTES"), MU_OPTION_ARG_OPTIONAL, |
43 | N_("forcibly break an existing lock older than a certain time"), | 67 | N_("forcibly break an existing lock older than a certain time"), |
44 | mu_c_time, &force },//FIXME: Default value | 68 | mu_c_uint, &force, cli_force }, |
45 | 69 | ||
46 | { "retry", 'r', N_("RETRIES"), MU_OPTION_ARG_OPTIONAL, | 70 | { "retry", 'r', N_("RETRIES"), MU_OPTION_ARG_OPTIONAL, |
47 | N_("retry the lock a few times"), | 71 | N_("retry the lock a few times"), |
... | @@ -68,12 +92,11 @@ static struct mu_cli_setup cli = { | ... | @@ -68,12 +92,11 @@ static struct mu_cli_setup cli = { |
68 | options, | 92 | options, |
69 | dotlock_cfg_param, | 93 | dotlock_cfg_param, |
70 | N_("GNU dotlock -- lock mail spool files."), | 94 | N_("GNU dotlock -- lock mail spool files."), |
71 | //FIXME: | 95 | N_("FILE"), |
72 | /* | ||
73 | N_("Returns 0 on success, 3 if locking the file fails because\ | 96 | N_("Returns 0 on success, 3 if locking the file fails because\ |
74 | it's already locked, and 1 if some other kind of error occurred."); | 97 | it's already locked, and 1 if some other kind of error occurred."), |
75 | */ | 98 | MU_DL_EX_ERROR, |
76 | N_("FILE") | 99 | MU_DL_EX_ERROR |
77 | }; | 100 | }; |
78 | 101 | ||
79 | 102 | ||
... | @@ -99,8 +122,6 @@ main (int argc, char *argv[]) | ... | @@ -99,8 +122,6 @@ main (int argc, char *argv[]) |
99 | if (setegid (usergid) < 0) | 122 | if (setegid (usergid) < 0) |
100 | return MU_DL_EX_ERROR; | 123 | return MU_DL_EX_ERROR; |
101 | 124 | ||
102 | /* FIXME: Force mu_cli to exit with MU_DL_EX_ERROR on errors? */ | ||
103 | |||
104 | mu_cli (argc, argv, &cli, capa, NULL, &argc, &argv); | 125 | mu_cli (argc, argv, &cli, capa, NULL, &argc, &argv); |
105 | 126 | ||
106 | switch (argc) | 127 | switch (argc) | ... | ... |
... | @@ -39,10 +39,15 @@ void mu_cli_capa_apply (char const *name, mu_list_t opts, mu_list_t commits); | ... | @@ -39,10 +39,15 @@ void mu_cli_capa_apply (char const *name, mu_list_t opts, mu_list_t commits); |
39 | 39 | ||
40 | struct mu_cli_setup | 40 | struct mu_cli_setup |
41 | { | 41 | { |
42 | struct mu_option **optv; | 42 | struct mu_option **optv; /* Command-line options */ |
43 | struct mu_cfg_param *cfg; | 43 | struct mu_cfg_param *cfg; /* Configuration parameters */ |
44 | char *prog_doc; | 44 | char *prog_doc; /* Program documentation string */ |
45 | char *prog_args; | 45 | char *prog_args; /* Program arguments string */ |
46 | char *prog_extra_doc; /* Extra documentation. This will be | ||
47 | displayed after options. */ | ||
48 | int ex_usage; /* If not 0, exit code on usage errors */ | ||
49 | int ex_config; /* If not 0, exit code on configuration | ||
50 | errors */ | ||
46 | }; | 51 | }; |
47 | 52 | ||
48 | void mu_version_func (struct mu_parseopt *po, FILE *stream); | 53 | void mu_version_func (struct mu_parseopt *po, FILE *stream); | ... | ... |
... | @@ -168,6 +168,9 @@ void mu_parseopt_error (struct mu_parseopt *po, char const *fmt, ...); | ... | @@ -168,6 +168,9 @@ void mu_parseopt_error (struct mu_parseopt *po, char const *fmt, ...); |
168 | int mu_parseopt_apply (struct mu_parseopt *p); | 168 | int mu_parseopt_apply (struct mu_parseopt *p); |
169 | void mu_parseopt_free (struct mu_parseopt *p); | 169 | void mu_parseopt_free (struct mu_parseopt *p); |
170 | 170 | ||
171 | unsigned mu_parseopt_getcolumn (const char *name); | ||
172 | void mu_parseopt_fmt_text (const char *text, size_t col); | ||
173 | |||
171 | void mu_option_describe_options (struct mu_option **optbuf, size_t optcnt); | 174 | void mu_option_describe_options (struct mu_option **optbuf, size_t optcnt); |
172 | void mu_program_help (struct mu_parseopt *p); | 175 | void mu_program_help (struct mu_parseopt *p); |
173 | void mu_program_usage (struct mu_parseopt *p); | 176 | void mu_program_usage (struct mu_parseopt *p); | ... | ... |
... | @@ -77,7 +77,17 @@ There is NO WARRANTY, to the extent permitted by law.\n\ | ... | @@ -77,7 +77,17 @@ There is NO WARRANTY, to the extent permitted by law.\n\ |
77 | 77 | ||
78 | static char gnu_general_help_url[] = | 78 | static char gnu_general_help_url[] = |
79 | N_("General help using GNU software: <http://www.gnu.org/gethelp/>"); | 79 | N_("General help using GNU software: <http://www.gnu.org/gethelp/>"); |
80 | 80 | ||
81 | static void | ||
82 | extra_help_hook (struct mu_parseopt *po, FILE *stream) | ||
83 | { | ||
84 | struct mu_cfg_parse_hints *hints = po->po_data; | ||
85 | struct mu_cli_setup *setup = hints->data; | ||
86 | char *extra_doc = _(setup->prog_extra_doc); | ||
87 | /* FIXME: mu_parseopt help output should get FILE * argument */ | ||
88 | mu_parseopt_fmt_text (extra_doc, 0); | ||
89 | fputc ('\n', stdout); | ||
90 | } | ||
81 | 91 | ||
82 | static void | 92 | static void |
83 | change_progname (struct mu_parseopt *po, struct mu_option *opt, | 93 | change_progname (struct mu_parseopt *po, struct mu_option *opt, |
... | @@ -235,8 +245,12 @@ show_config_help (struct mu_parseopt *po, struct mu_option *opt, | ... | @@ -235,8 +245,12 @@ show_config_help (struct mu_parseopt *po, struct mu_option *opt, |
235 | mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL, | 245 | mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL, |
236 | dummy_include_param, NULL); | 246 | dummy_include_param, NULL); |
237 | if (hints->data) | 247 | if (hints->data) |
238 | mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL, | 248 | { |
239 | hints->data, NULL); | 249 | struct mu_cli_setup *setup = hints->data; |
250 | mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL, | ||
251 | setup->cfg, NULL); | ||
252 | } | ||
253 | |||
240 | mu_cfg_format_container (stream, cont); | 254 | mu_cfg_format_container (stream, cont); |
241 | mu_config_destroy_container (&cont); | 255 | mu_config_destroy_container (&cont); |
242 | 256 | ||
... | @@ -325,6 +339,12 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, | ... | @@ -325,6 +339,12 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, |
325 | struct mu_cfg_parse_hints hints; | 339 | struct mu_cfg_parse_hints hints; |
326 | struct mu_option **optv; | 340 | struct mu_option **optv; |
327 | mu_list_t com_list; | 341 | mu_list_t com_list; |
342 | |||
343 | /* Set up defaults */ | ||
344 | if (setup->ex_usage == 0) | ||
345 | setup->ex_usage = EX_USAGE; | ||
346 | if (setup->ex_config == 0) | ||
347 | setup->ex_config = EX_CONFIG; | ||
328 | 348 | ||
329 | /* Set program name */ | 349 | /* Set program name */ |
330 | mu_set_program_name (argv[0]); | 350 | mu_set_program_name (argv[0]); |
... | @@ -346,7 +366,7 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, | ... | @@ -346,7 +366,7 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, |
346 | hints.flags |= MU_CFG_PARSE_PROGRAM; | 366 | hints.flags |= MU_CFG_PARSE_PROGRAM; |
347 | hints.program = (char*) mu_program_name; | 367 | hints.program = (char*) mu_program_name; |
348 | 368 | ||
349 | hints.data = setup->cfg; | 369 | hints.data = setup; |
350 | 370 | ||
351 | /* Initialize po */ | 371 | /* Initialize po */ |
352 | if (setup->prog_doc) | 372 | if (setup->prog_doc) |
... | @@ -376,10 +396,16 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, | ... | @@ -376,10 +396,16 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, |
376 | po.po_version_hook = mu_version_func; | 396 | po.po_version_hook = mu_version_func; |
377 | flags |= MU_PARSEOPT_VERSION_HOOK; | 397 | flags |= MU_PARSEOPT_VERSION_HOOK; |
378 | 398 | ||
399 | if (setup->prog_extra_doc) | ||
400 | { | ||
401 | po.po_help_hook = extra_help_hook; | ||
402 | flags |= MU_PARSEOPT_HELP_HOOK; | ||
403 | } | ||
404 | |||
379 | po.po_data = &hints; | 405 | po.po_data = &hints; |
380 | flags |= MU_PARSEOPT_DATA; | 406 | flags |= MU_PARSEOPT_DATA; |
381 | 407 | ||
382 | po.po_exit_error = EX_USAGE; | 408 | po.po_exit_error = setup->ex_usage; |
383 | 409 | ||
384 | optv = init_options (capa, setup, &com_list); | 410 | optv = init_options (capa, setup, &com_list); |
385 | 411 | ||
... | @@ -398,13 +424,13 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, | ... | @@ -398,13 +424,13 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, |
398 | mu_parseopt_error (&po, "%s", _("unexpected arguments")); | 424 | mu_parseopt_error (&po, "%s", _("unexpected arguments")); |
399 | 425 | ||
400 | if (mu_cfg_parse_config (&parse_tree, &hints)) | 426 | if (mu_cfg_parse_config (&parse_tree, &hints)) |
401 | exit (EX_CONFIG); | 427 | exit (setup->ex_config); |
402 | 428 | ||
403 | if (mu_cfg_tree_reduce (parse_tree, &hints, setup->cfg, data)) | 429 | if (mu_cfg_tree_reduce (parse_tree, &hints, setup->cfg, data)) |
404 | exit (EX_CONFIG); | 430 | exit (setup->ex_config); |
405 | 431 | ||
406 | if (mu_cfg_error_count) //FIXME | 432 | if (mu_cfg_error_count) |
407 | exit (EX_CONFIG); | 433 | exit (setup->ex_config); |
408 | 434 | ||
409 | mu_parseopt_apply (&po); | 435 | mu_parseopt_apply (&po); |
410 | 436 | ... | ... |
... | @@ -63,6 +63,23 @@ static struct usage_var | ... | @@ -63,6 +63,23 @@ static struct usage_var |
63 | { NULL } | 63 | { NULL } |
64 | }; | 64 | }; |
65 | 65 | ||
66 | unsigned | ||
67 | mu_parseopt_getcolumn (const char *name) | ||
68 | { | ||
69 | struct usage_var *p; | ||
70 | unsigned retval = 0; | ||
71 | for (p = usage_var; p->name; p++) | ||
72 | { | ||
73 | if (strcmp (p->name, name) == 0) | ||
74 | { | ||
75 | if (p->valptr) | ||
76 | retval = *p->valptr; | ||
77 | break; | ||
78 | } | ||
79 | } | ||
80 | return retval; | ||
81 | } | ||
82 | |||
66 | static void | 83 | static void |
67 | set_usage_var (struct mu_parseopt *po, char const *id) | 84 | set_usage_var (struct mu_parseopt *po, char const *id) |
68 | { | 85 | { |
... | @@ -195,6 +212,11 @@ print_option_descr (const char *descr, size_t lmargin, size_t rmargin) | ... | @@ -195,6 +212,11 @@ print_option_descr (const char *descr, size_t lmargin, size_t rmargin) |
195 | if (descr[i] == 0) | 212 | if (descr[i] == 0) |
196 | break; | 213 | break; |
197 | } | 214 | } |
215 | else if (descr[i] == '\n') | ||
216 | { | ||
217 | s = i; | ||
218 | break; | ||
219 | } | ||
198 | } | 220 | } |
199 | fwrite (descr, 1, s, stdout); | 221 | fwrite (descr, 1, s, stdout); |
200 | fputc ('\n', stdout); | 222 | fputc ('\n', stdout); |
... | @@ -207,6 +229,12 @@ print_option_descr (const char *descr, size_t lmargin, size_t rmargin) | ... | @@ -207,6 +229,12 @@ print_option_descr (const char *descr, size_t lmargin, size_t rmargin) |
207 | } | 229 | } |
208 | } | 230 | } |
209 | 231 | ||
232 | void | ||
233 | mu_parseopt_fmt_text (const char *text, size_t col) | ||
234 | { | ||
235 | print_option_descr (text, col, rmargin); | ||
236 | } | ||
237 | |||
210 | 238 | ||
211 | static size_t | 239 | static size_t |
212 | print_opt_arg (struct mu_option *opt, int delim) | 240 | print_opt_arg (struct mu_option *opt, int delim) | ... | ... |
... | @@ -144,15 +144,11 @@ struct mu_cli_setup cli = { | ... | @@ -144,15 +144,11 @@ struct mu_cli_setup cli = { |
144 | options, | 144 | options, |
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 | //FIXME: | 147 | N_("FILE [FILE ...]"), |
148 | /* | 148 | N_("Debug flags are:\n\ |
149 | N_("Default mime.types file is ") DEFAULT_CUPS_CONFDIR "/mime.types" | ||
150 | N_("\n\nDebug flags are:\n\ | ||
151 | g - Mime.types parser traces\n\ | 149 | g - Mime.types parser traces\n\ |
152 | l - Mime.types lexical analyzer traces\n\ | 150 | l - Mime.types lexical analyzer traces\n\ |
153 | 0-9 - Set debugging level\n"); | 151 | 0-9 - Set debugging level\n") |
154 | */ | ||
155 | N_("FILE [FILE ...]") | ||
156 | }; | 152 | }; |
157 | 153 | ||
158 | static char *capa[] = { | 154 | static char *capa[] = { | ... | ... |
... | @@ -247,7 +247,13 @@ static struct mu_cli_setup cli = { | ... | @@ -247,7 +247,13 @@ static struct mu_cli_setup cli = { |
247 | options, | 247 | options, |
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 | N_("Debug flags:\n\ | ||
252 | g - main parser traces\n\ | ||
253 | T - mailutils traces (same as --debug-level=sieve.trace0-trace1)\n\ | ||
254 | P - network protocols (same as --debug-level=sieve.=prot)\n\ | ||
255 | t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\ | ||
256 | i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n") | ||
251 | }; | 257 | }; |
252 | 258 | ||
253 | static void | 259 | static void | ... | ... |
-
Please register or sign in to post a comment