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;
static int unlock;
static int flags;
static int retries;
static time_t force;
static unsigned force;
static int debug;
static void
cli_force (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
if (arg)
{
int rc;
char *errmsg;
rc = mu_str_to_c (arg, opt->opt_type, opt->opt_ptr, &errmsg);
if (rc)
{
if (opt->opt_long)
mu_parseopt_error (po, "--%s: %s", opt->opt_long,
errmsg ? errmsg : mu_strerror (rc));
else
mu_parseopt_error (po, "-%c: %s", opt->opt_short,
errmsg ? errmsg : mu_strerror (rc));
free (errmsg);
exit (po->po_exit_error);
}
}
else
*(unsigned*)opt->opt_ptr = 1;
}
static struct mu_option dotlock_options[] = {
{ "unlock", 'u', NULL, MU_OPTION_DEFAULT,
N_("unlock"),
......@@ -41,7 +65,7 @@ static struct mu_option dotlock_options[] = {
{ "force", 'f', N_("MINUTES"), MU_OPTION_ARG_OPTIONAL,
N_("forcibly break an existing lock older than a certain time"),
mu_c_time, &force },//FIXME: Default value
mu_c_uint, &force, cli_force },
{ "retry", 'r', N_("RETRIES"), MU_OPTION_ARG_OPTIONAL,
N_("retry the lock a few times"),
......@@ -68,12 +92,11 @@ static struct mu_cli_setup cli = {
options,
dotlock_cfg_param,
N_("GNU dotlock -- lock mail spool files."),
//FIXME:
/*
N_("FILE"),
N_("Returns 0 on success, 3 if locking the file fails because\
it's already locked, and 1 if some other kind of error occurred.");
*/
N_("FILE")
it's already locked, and 1 if some other kind of error occurred."),
MU_DL_EX_ERROR,
MU_DL_EX_ERROR
};
......@@ -99,8 +122,6 @@ main (int argc, char *argv[])
if (setegid (usergid) < 0)
return MU_DL_EX_ERROR;
/* FIXME: Force mu_cli to exit with MU_DL_EX_ERROR on errors? */
mu_cli (argc, argv, &cli, capa, NULL, &argc, &argv);
switch (argc)
......
......@@ -39,10 +39,15 @@ void mu_cli_capa_apply (char const *name, mu_list_t opts, mu_list_t commits);
struct mu_cli_setup
{
struct mu_option **optv;
struct mu_cfg_param *cfg;
char *prog_doc;
char *prog_args;
struct mu_option **optv; /* Command-line options */
struct mu_cfg_param *cfg; /* Configuration parameters */
char *prog_doc; /* Program documentation string */
char *prog_args; /* Program arguments string */
char *prog_extra_doc; /* Extra documentation. This will be
displayed after options. */
int ex_usage; /* If not 0, exit code on usage errors */
int ex_config; /* If not 0, exit code on configuration
errors */
};
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, ...);
int mu_parseopt_apply (struct mu_parseopt *p);
void mu_parseopt_free (struct mu_parseopt *p);
unsigned mu_parseopt_getcolumn (const char *name);
void mu_parseopt_fmt_text (const char *text, size_t col);
void mu_option_describe_options (struct mu_option **optbuf, size_t optcnt);
void mu_program_help (struct mu_parseopt *p);
void mu_program_usage (struct mu_parseopt *p);
......
......@@ -77,7 +77,17 @@ There is NO WARRANTY, to the extent permitted by law.\n\
static char gnu_general_help_url[] =
N_("General help using GNU software: <http://www.gnu.org/gethelp/>");
static void
extra_help_hook (struct mu_parseopt *po, FILE *stream)
{
struct mu_cfg_parse_hints *hints = po->po_data;
struct mu_cli_setup *setup = hints->data;
char *extra_doc = _(setup->prog_extra_doc);
/* FIXME: mu_parseopt help output should get FILE * argument */
mu_parseopt_fmt_text (extra_doc, 0);
fputc ('\n', stdout);
}
static void
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,
mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL,
dummy_include_param, NULL);
if (hints->data)
mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL,
hints->data, NULL);
{
struct mu_cli_setup *setup = hints->data;
mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL,
setup->cfg, NULL);
}
mu_cfg_format_container (stream, cont);
mu_config_destroy_container (&cont);
......@@ -325,6 +339,12 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa,
struct mu_cfg_parse_hints hints;
struct mu_option **optv;
mu_list_t com_list;
/* Set up defaults */
if (setup->ex_usage == 0)
setup->ex_usage = EX_USAGE;
if (setup->ex_config == 0)
setup->ex_config = EX_CONFIG;
/* Set program name */
mu_set_program_name (argv[0]);
......@@ -346,7 +366,7 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa,
hints.flags |= MU_CFG_PARSE_PROGRAM;
hints.program = (char*) mu_program_name;
hints.data = setup->cfg;
hints.data = setup;
/* Initialize po */
if (setup->prog_doc)
......@@ -376,10 +396,16 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa,
po.po_version_hook = mu_version_func;
flags |= MU_PARSEOPT_VERSION_HOOK;
if (setup->prog_extra_doc)
{
po.po_help_hook = extra_help_hook;
flags |= MU_PARSEOPT_HELP_HOOK;
}
po.po_data = &hints;
flags |= MU_PARSEOPT_DATA;
po.po_exit_error = EX_USAGE;
po.po_exit_error = setup->ex_usage;
optv = init_options (capa, setup, &com_list);
......@@ -398,13 +424,13 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa,
mu_parseopt_error (&po, "%s", _("unexpected arguments"));
if (mu_cfg_parse_config (&parse_tree, &hints))
exit (EX_CONFIG);
exit (setup->ex_config);
if (mu_cfg_tree_reduce (parse_tree, &hints, setup->cfg, data))
exit (EX_CONFIG);
exit (setup->ex_config);
if (mu_cfg_error_count) //FIXME
exit (EX_CONFIG);
if (mu_cfg_error_count)
exit (setup->ex_config);
mu_parseopt_apply (&po);
......
......@@ -63,6 +63,23 @@ static struct usage_var
{ NULL }
};
unsigned
mu_parseopt_getcolumn (const char *name)
{
struct usage_var *p;
unsigned retval = 0;
for (p = usage_var; p->name; p++)
{
if (strcmp (p->name, name) == 0)
{
if (p->valptr)
retval = *p->valptr;
break;
}
}
return retval;
}
static void
set_usage_var (struct mu_parseopt *po, char const *id)
{
......@@ -195,6 +212,11 @@ print_option_descr (const char *descr, size_t lmargin, size_t rmargin)
if (descr[i] == 0)
break;
}
else if (descr[i] == '\n')
{
s = i;
break;
}
}
fwrite (descr, 1, s, stdout);
fputc ('\n', stdout);
......@@ -207,6 +229,12 @@ print_option_descr (const char *descr, size_t lmargin, size_t rmargin)
}
}
void
mu_parseopt_fmt_text (const char *text, size_t col)
{
print_option_descr (text, col, rmargin);
}
static size_t
print_opt_arg (struct mu_option *opt, int delim)
......
......@@ -144,15 +144,11 @@ struct mu_cli_setup cli = {
options,
mimeview_cfg_param,
N_("GNU mimeview -- display files, using mailcap mechanism."),
//FIXME:
/*
N_("Default mime.types file is ") DEFAULT_CUPS_CONFDIR "/mime.types"
N_("\n\nDebug flags are:\n\
N_("FILE [FILE ...]"),
N_("Debug flags are:\n\
g - Mime.types parser traces\n\
l - Mime.types lexical analyzer traces\n\
0-9 - Set debugging level\n");
*/
N_("FILE [FILE ...]")
0-9 - Set debugging level\n")
};
static char *capa[] = {
......
......@@ -247,7 +247,13 @@ static struct mu_cli_setup cli = {
options,
sieve_cfg_param,
N_("GNU sieve -- a mail filtering tool."),
"SCRIPT"
"SCRIPT",
N_("Debug flags:\n\
g - main parser traces\n\
T - mailutils traces (same as --debug-level=sieve.trace0-trace1)\n\
P - network protocols (same as --debug-level=sieve.=prot)\n\
t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\
i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n")
};
static void
......