Commit af83aaff af83aaff0e41587fcdbe78983b6e116e442f17a1 by Sergey Poznyakoff

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.
1 parent d56b8243
...@@ -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
......