Commit bc73fc65 bc73fc65600b6021dfe7a9fa1fba7e9b823993e2 by Sergey Poznyakoff

Introduce new CLI/configuration code for mailutils applications.

The new API is to replace libmu_cfg and libmu_argp.  A smooth transition
is scheduled, during which the two APIs will coexist,

* configure.ac: Build libmailutils/cli/Makefile
* include/mailutils/cli.h: New file.
* include/mailutils/Makefile.am: Add cli.h
* libmailutils/cli/Makefile.am: New file.
* libmailutils/cli/capa.c: New file.
* libmailutils/cli/cli.c: New file.
* libmailutils/cli/stdcapa.c: New file.
* libmailutils/Makefile.am (SUBDIRS): Add cli.

* include/mailutils/cfg.h (mu_cfg_parse_hints): New members: append_tree
and data.
(MU_PARSE_CONFIG_LINT): New flag.
* include/mailutils/diag.h (mu_program_name)
(mu_full_program_name): Remove const qualifier.
* include/mailutils/locker.h (mu_locker_set_default_external_program):
Argument is const.
* libmailutils/base/locker.c: Likewise.

* include/mailutils/opt.h (mu_progname, mu_absprogname): Replace
with mu_program_name and mu_full_program_name.
(mu_set_progname): Rename to mu_set_program_name.
(mu_parseopt) <po_data>: Change type to void *.
(po_help_hook, po_version_hook): Change signatures.
(mu_parseopt_error): New function.
* libmailutils/opt/progname.c (mu_progname, mu_absprogname): Replace
with mu_program_name and mu_full_program_name.
(mu_set_progname): Rename to mu_set_program_name.
* libmailutils/opt/help.c: Minor changes
* libmailutils/opt/opt.c (parse_error): Rename to mu_parse_error (extern).
(next_opt): Fix permutations.
* libmailutils/tests/parseopt.c: Reflect changes.
* libmailutils/tests/parseopt17.at: Improve test case
* libmailutils/tests/parseopt_help05.at: Reflect changes.
* libmailutils/tests/parseopt_help07.at: Reflect changes.

* include/mailutils/stdstream.h (mu_program_name): Remove qualifier.

* libmailutils/cfg/driver.c (mu_cfg_tree_reduce): Remove useless condition

* libmailutils/cfg/lexer.l (mu_cfg_parse_file): Additional info messages.
* libmailutils/cfg/parser.y (mu_cfg_parse_config): Join in
the append_tree.
* libmailutils/diag/diag.c (mu_program_name, mu_full_program_name)
(mu_set_program_name): Remove. Declared elsewhere.
* libmu_sieve/conf.c: Add new configuration code. Mark old text for
removal.
* libmailutils/tests/tcli.c: New program.
* libmailutils/tests/Makefile.am: Add tcli.c
1 parent 6e814733
......@@ -1506,6 +1506,7 @@ AC_CONFIG_FILES([
libmailutils/address/Makefile
libmailutils/sockaddr/Makefile
libmailutils/cidr/Makefile
libmailutils/cli/Makefile
libmailutils/cfg/Makefile
libmailutils/datetime/Makefile
libmailutils/diag/Makefile
......
......@@ -36,6 +36,7 @@ pkginclude_HEADERS = \
cctype.h\
cfg.h\
cidr.h\
cli.h\
cstr.h\
datetime.h\
daemon.h\
......
......@@ -79,6 +79,8 @@ struct mu_cfg_parse_hints
char *site_rcfile;
char *custom_rcfile;
char *program;
struct mu_cfg_tree *append_tree;
void *data;
};
struct mu_cfg_tree
......@@ -238,7 +240,8 @@ int mu_config_register_plain_section (const char *parent_path,
#define MU_CFG_FMT_LOCUS 0x080
#define MU_CFG_FMT_VALUE_ONLY 0x100
#define MU_CFG_FMT_PARAM_PATH 0x200
#define MU_PARSE_CONFIG_LINT 0x400
#ifdef MU_CFG_COMPATIBILITY
# define MU_CFG_DEPRECATED
#else
......
/* opt.h -- general-purpose command line option parser
Copyright (C) 2016 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3, or (at
your option) any later version.
GNU Mailutils is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MAILUTILS_CLI_H
#define _MAILUTILS_CLI_H
#include <stdio.h>
#include <mailutils/types.h>
#include <mailutils/cfg.h>
#include <mailutils/opt.h>
typedef void (*mu_cli_capa_commit_fp) (void *);
struct mu_cli_capa
{
char *name;
struct mu_option *opt;
struct mu_cfg_param *cfg;
mu_cfg_section_fp parser;
mu_cli_capa_commit_fp commit;
};
void mu_cli_capa_init (void);
void mu_cli_capa_register (struct mu_cli_capa *capa);
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;
};
void mu_version_func (struct mu_parseopt *po, FILE *stream);
void mu_cli (int argc, char **argv, struct mu_cli_setup *setup,
char **capa, void *data,
int *ret_argc, char ***ret_argv);
char *mu_site_config_file (void);
#endif
......@@ -29,8 +29,8 @@
extern "C" {
#endif
extern const char *mu_program_name;
extern const char *mu_full_program_name;
extern char *mu_program_name;
extern char *mu_full_program_name;
#define MU_DIAG_EMERG MU_LOG_EMERG
#define MU_DIAG_ALERT MU_LOG_ALERT
......
......@@ -103,7 +103,7 @@ extern int mu_locker_set_default_flags (int flags, enum mu_locker_set_mode mode)
extern void mu_locker_set_default_retry_timeout (time_t to);
extern void mu_locker_set_default_retry_count (size_t n);
extern void mu_locker_set_default_expire_timeout (time_t t);
extern int mu_locker_set_default_external_program (char *path);
extern int mu_locker_set_default_external_program (char const *path);
/* A flags of 0 means that the default will be used. */
extern int mu_locker_create (mu_locker_t *, const char *filename, int flags);
......
......@@ -23,10 +23,10 @@
#include <mailutils/util.h>
#include <mailutils/cctype.h>
extern char *mu_progname;
extern char *mu_absprogname;
extern char *mu_program_name;
extern char *mu_full_program_name;
void mu_set_progname (char const *arg);
void mu_set_program_name (char const *arg);
#define MU_OPTION_DEFAULT 0
#define MU_OPTION_ARG_OPTIONAL 0x01
......@@ -118,7 +118,7 @@ struct mu_parseopt
struct mu_option **po_optv; /* Array of ptrs to option structures */
int po_flags;
char *po_data; /* Call-specific data */
void *po_data; /* Call-specific data */
int po_exit_error; /* Exit on error with this code */
......@@ -130,9 +130,10 @@ struct mu_parseopt
char const *po_package_name;
char const *po_package_url;
char const *po_extra_info;
void (*po_help_hook) (FILE *stream); /* FIXME: should take mu_stream_t ?*/
void (*po_version_hook) (FILE *stream);
/* FIXME: should these take mu_stream_t ?*/
void (*po_help_hook) (struct mu_parseopt *po, FILE *stream);
void (*po_version_hook) (struct mu_parseopt *po, FILE *stream);
/* Output data */
int po_ind; /* Index of the next option */
......@@ -162,6 +163,7 @@ struct mu_parseopt
int mu_parseopt (struct mu_parseopt *p,
int argc, char **argv, struct mu_option **optv,
int flags);
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);
......
......@@ -28,7 +28,7 @@ extern mu_stream_t mu_strin;
extern mu_stream_t mu_strout;
extern mu_stream_t mu_strerr;
extern const char *mu_program_name;
extern char *mu_program_name;
#define MU_STRERR_STDERR 0
#define MU_STRERR_SYSLOG 1
......
......@@ -17,7 +17,7 @@
# <http://www.gnu.org/licenses/>.
SUBDIRS = \
auth base address list sockaddr cidr cfg diag\
auth base address list sockaddr cidr cfg cli diag\
filter mailbox mailer mime msgset opt server string stream stdstream\
property url imapio datetime . tests
......@@ -33,6 +33,7 @@ libmailutils_la_LIBADD = \
sockaddr/libsockaddr.la\
cidr/libcidr.la\
cfg/libcfg.la\
cli/libcli.la\
datetime/libdatetime.la\
diag/libdiag.la\
filter/libfilter.la\
......
......@@ -242,7 +242,7 @@ mu_locker_set_default_expire_timeout (time_t t)
}
int
mu_locker_set_default_external_program (char *path)
mu_locker_set_default_external_program (char const *path)
{
char *p = strdup (path);
if (!p)
......
......@@ -463,7 +463,7 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree,
void *target_ptr)
{
int rc = 0;
struct mu_cfg_cont *cont;
if (!parse_tree)
return 0;
if (hints && (hints->flags & MU_PARSE_CONFIG_DUMP))
......@@ -477,13 +477,9 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree,
mu_stream_destroy (&stream);
}
if (root_container)
{
struct mu_cfg_cont *cont = mu_build_container (progparam);
rc = mu_cfg_scan_tree (parse_tree, &cont->v.section, target_ptr,
NULL);
mu_config_destroy_container (&cont);
}
cont = mu_build_container (progparam);
rc = mu_cfg_scan_tree (parse_tree, &cont->v.section, target_ptr, NULL);
mu_config_destroy_container (&cont);
return rc;
}
......
......@@ -330,10 +330,16 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags)
int rc;
char *full_name = mu_tilde_expansion (file, MU_HIERARCHY_DELIMITER, NULL);
if (flags & MU_PARSE_CONFIG_VERBOSE)
mu_diag_output (MU_DIAG_INFO, _("opening configuration file %s"),
full_name);
if (stat (full_name, &st))
{
if (errno != ENOENT)
mu_error (_("cannot stat `%s': %s"), full_name, mu_strerror (errno));
else if (flags & MU_PARSE_CONFIG_VERBOSE)
mu_diag_output (MU_DIAG_INFO, _("configuration file %s doesn't exist"),
full_name);
free (full_name);
return ENOENT;
}
......
......@@ -1589,7 +1589,10 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints)
mu_cfg_tree_union (&tree, &tmp);
}
}
if (hints->append_tree)
mu_cfg_tree_union (&tree, &hints->append_tree);
*ptree = tree;
return rc;
}
......
# GNU Mailutils -- a suite of utilities for electronic mail
# Copyright (C) 2016 Free Software Foundation, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General
# Public License along with this library. If not, see
# <http://www.gnu.org/licenses/>.
noinst_LTLIBRARIES = libcli.la
libcli_la_SOURCES = \
capa.c\
cli.c\
stdcapa.c
AM_CPPFLAGS = \
@MU_LIB_COMMON_INCLUDES@ -I/libmailutils
/* capa.c -- CLI capabilities for GNU Mailutils
Copyright (C) 2016 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3, or (at
your option) any later version.
GNU Mailutils is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <mailutils/cli.h>
#include <mailutils/list.h>
#include <mailutils/alloc.h>
#include <mailutils/nls.h>
static mu_list_t capa_list;
static void
capa_free (void *ptr)
{
struct mu_cli_capa *cp = ptr;
free (cp->name);
free (cp);
}
void
mu_cli_capa_register (struct mu_cli_capa *capa)
{
struct mu_cli_capa *cp = mu_alloc (sizeof (*cp));
cp->name = mu_strdup (capa->name);
cp->opt = capa->opt;
cp->cfg = capa->cfg;
cp->parser = capa->parser;
cp->commit = capa->commit;
if (!capa_list)
{
mu_list_create (&capa_list);
mu_list_set_destroy_item (capa_list, capa_free);
}
mu_list_append (capa_list, cp);
}
struct capa_apply
{
char const *name;
mu_list_t opts;
mu_list_t commits;
int found;
};
static int
capa_apply (void *item, void *data)
{
struct mu_cli_capa *cp = item;
struct capa_apply *ap = data;
if (strcmp (cp->name, ap->name) == 0)
{
ap->found = 1;
if (cp->opt)
mu_list_append (ap->opts, cp->opt);
if (cp->commit)
mu_list_append (ap->commits, cp->commit);
if (cp->parser || cp->cfg)
mu_config_root_register_section (NULL, cp->name, NULL,
cp->parser, cp->cfg);
}
return 0;
}
void
mu_cli_capa_apply (char const *name, mu_list_t opts, mu_list_t commits)
{
struct capa_apply app;
app.name = name;
app.opts = opts;
app.commits = commits;
app.found = 0;
mu_list_foreach (capa_list, capa_apply, &app);
if (!app.found)
mu_error (_("INTERNAL ERROR at %s:%d: unknown standard capability `%s'"),
__FILE__, __LINE__, name);
}
......@@ -30,32 +30,6 @@
#include <mailutils/stdstream.h>
#include <mailutils/stream.h>
const char *mu_program_name;
const char *mu_full_program_name;
void
mu_set_program_name (const char *name)
{
const char *progname;
mu_full_program_name = name;
if (!name)
progname = name;
else
{
progname = strrchr (name, '/');
if (progname)
progname++;
else
progname = name;
if (strlen (progname) > 3 && memcmp (progname, "lt-", 3) == 0)
progname += 3;
}
mu_program_name = progname;
}
void
mu_diag_init ()
{
......
......@@ -155,7 +155,7 @@ init_usage_vars (struct mu_parseopt *po)
fmt = getenv ("ARGP_HELP_FMT");
if (!fmt)
return;
ws.ws_delim=",";
ws.ws_delim = ",";
if (mu_wordsplit (fmt, &ws,
MU_WRDSF_DELIM | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD
| MU_WRDSF_WS | MU_WRDSF_SHOWERR))
......@@ -346,20 +346,20 @@ mu_program_help (struct mu_parseopt *po)
mu_option_describe_options (po->po_optv, po->po_optc);
if (po->po_help_hook)
po->po_help_hook (stdout);
po->po_help_hook (po, stdout);
if (po->po_bug_address)
/* TRANSLATORS: The placeholder indicates the bug-reporting address
for this package. Please add _another line_ saying
"Report translation bugs to <...>\n" with the address for translation
bugs (typically your translation team's web or email address). */
printf (_("Report bugs to %s.\n"), po->po_bug_address);
printf (_("Report bugs to <%s>.\n"), po->po_bug_address);
if (po->po_package_name && po->po_package_url)
printf (_("%s home page: <%s>\n"),
po->po_package_name, po->po_package_url);
if (po->po_flags & MU_PARSEOPT_EXTRA_INFO)
print_option_descr (po->po_extra_info, 0, rmargin);
print_option_descr (_(po->po_extra_info), 0, rmargin);
}
static struct mu_option **option_tab;
......
......@@ -85,7 +85,7 @@ fn_usage (struct mu_parseopt *po, struct mu_option *opt, char const *unused)
static void
fn_version (struct mu_parseopt *po, struct mu_option *opt, char const *unused)
{
po->po_version_hook (stdout);
po->po_version_hook (po, stdout);
exit (EXIT_SUCCESS);
}
......@@ -107,8 +107,8 @@ struct mu_option mu_version_options[] = {
};
/* Output error message */
static void
parse_error (struct mu_parseopt *po, char const *fmt, ...)
void
mu_parseopt_error (struct mu_parseopt *po, char const *fmt, ...)
{
va_list ap;
......@@ -176,7 +176,7 @@ find_short_option (struct mu_parseopt *po, int chr)
&& po->po_optv[i]->opt_short == chr)
return option_unalias (po, i);
}
parse_error (po, _("unrecognized option '-%c'"), chr);
mu_parseopt_error (po, _("unrecognized option '-%c'"), chr);
return NULL;
}
......@@ -209,7 +209,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr,
case 1:
if (po->po_flags & MU_PARSEOPT_IGNORE_ERRORS)
return NULL;
parse_error (po,
mu_parseopt_error (po,
_("option '--%*.*s' is ambiguous; possibilities:"),
optlen, optlen, optstr);
fprintf (stderr, "--%s\n", po->po_optv[ind]->opt_long);
......@@ -224,7 +224,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr,
switch (found)
{
case 0:
parse_error (po, _("unrecognized option '--%s'"), optstr);
mu_parseopt_error (po, _("unrecognized option '--%s'"), optstr);
break;
case 1:
......@@ -303,7 +303,7 @@ next_opt (struct mu_parseopt *po)
break;
if (!(po->po_flags & MU_PARSEOPT_IN_ORDER))
{
if (!po->po_permuted)
if (!po->po_permuted && po->po_arg_count == 0)
po->po_arg_start = po->po_ind - 1;
po->po_arg_count++;
continue;
......@@ -405,11 +405,11 @@ parse (struct mu_parseopt *po)
else
{
if (long_opt)
parse_error (po,
mu_parseopt_error (po,
_("option '--%s' requires an argument"),
long_opt);
else
parse_error (po,
mu_parseopt_error (po,
_("option '-%c' requires an argument"),
po->po_chr);
po->po_opterr = po->po_ind;
......@@ -428,7 +428,7 @@ parse (struct mu_parseopt *po)
&& po->po_cur[0]
&& !(po->po_flags & MU_OPTION_ARG_OPTIONAL))
{
parse_error (po,
mu_parseopt_error (po,
_("option '--%s' doesn't allow an argument"),
long_opt);
po->po_opterr = po->po_ind;
......@@ -661,9 +661,9 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt,
errtext = mu_strerror (rc);
if (opt->opt_long)
parse_error (po, "--%s: %s", opt->opt_long, errtext);
mu_parseopt_error (po, "--%s: %s", opt->opt_long, errtext);
else
parse_error (po, "-%c: %s", opt->opt_short, errtext);
mu_parseopt_error (po, "-%c: %s", opt->opt_short, errtext);
free (errmsg);
if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT))
......
......@@ -22,16 +22,16 @@
#include <mailutils/alloc.h>
#include <mailutils/opt.h>
char *mu_progname;
char *mu_absprogname;
char *mu_program_name;
char *mu_full_program_name;
void
mu_set_progname (char const *arg)
mu_set_program_name (const char *arg)
{
char *p;
free (mu_absprogname);
mu_absprogname = mu_strdup (arg);
free (mu_full_program_name);
mu_full_program_name = mu_strdup (arg);
p = strrchr (arg, '/');
if (p)
......@@ -40,6 +40,6 @@ mu_set_progname (char const *arg)
p = (char*) arg;
if (strlen (p) > 3 && memcmp (p, "lt-", 3) == 0)
p += 3;
free (mu_progname);
mu_progname = mu_strdup (p);
free (mu_program_name);
mu_program_name = mu_strdup (p);
}
......
......@@ -27,6 +27,7 @@ strftime
strin
strout
strtoc
tcli
tempfile
url-comp
url-parse
......
......@@ -64,6 +64,7 @@ noinst_PROGRAMS = \
strout\
strtoc\
tempfile\
tcli\
url-comp\
url-parse\
wicket\
......
......@@ -64,7 +64,7 @@ struct mu_option group_b[] = {
struct mu_option *optv[] = { group_a, group_b, NULL };
static void
version_func (FILE *fp)
version_hook (struct mu_parseopt *po, FILE *fp)
{
fputs ("version hook called\n", fp);
}
......@@ -144,7 +144,7 @@ main (int argc, char *argv[])
}
}
if (flags & MU_PARSEOPT_VERSION_HOOK)
po.po_version_hook = version_func;
po.po_version_hook = version_hook;
}
rc = mu_parseopt (&po, argc, argv, optv, flags);
......
......@@ -35,4 +35,24 @@ argv:
2: follow
3: options
])
AT_CHECK([
PARSEOPT_DEFAULT
parseopt --file=file more arguments follow -x -o options
],
[0],
[rc=0
file_name=file
opt_value=(null)
x_option=1
a_option=0
find_value=(null)
d_option=0
jobs=0
argv:
0: more
1: arguments
2: follow
3: options
])
AT_CLEANUP
......
......@@ -18,7 +18,7 @@ AT_SETUP([MU_PARSEOPT_BUG_ADDRESS])
AT_KEYWORDS([parseopt parseopt_help parseopt_help05])
AT_CHECK([
PARSEOPT_DEFAULT
MU_PARSEOPT_BUG_ADDRESS='<gray@gnu.org>' parseopt --help
MU_PARSEOPT_BUG_ADDRESS='gray@gnu.org' parseopt --help
],
[0],
[Usage: parseopt [[OPTION]]...
......
......@@ -20,7 +20,7 @@ AT_CHECK([
PARSEOPT_DEFAULT
MU_PARSEOPT_PROG_DOC="Tests option parsing"\
MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS"\
MU_PARSEOPT_BUG_ADDRESS='<gray@gnu.org>'\
MU_PARSEOPT_BUG_ADDRESS='gray@gnu.org'\
MU_PARSEOPT_PACKAGE_NAME='GNU Mailutils'\
MU_PARSEOPT_PACKAGE_URL='http://mailutils.org'\
MU_PARSEOPT_EXTRA_INFO='General help using GNU software: <http://www.gnu.org/gethelp/>'\
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2016 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <mailutils/mailutils.h>
#include <mailutils/cli.h>
int dtrt_option;
struct mu_option group_a[] = {
{ "dtrt", 'd', "VALUE", MU_OPTION_DEFAULT,
"do the right thing",
mu_c_int, &dtrt_option },
MU_OPTION_END
};
struct mu_option *options[] = { group_a, NULL };
static struct mu_cfg_param config[] = {
{ "do-the-right-thing", mu_c_int, &dtrt_option, 0, NULL,
"do the right thing" },
{ NULL }
};
struct mu_cli_setup cli = {
options,
config,
"Tests standard command line interface",
"ARGUMENTS"
};
static char **
getcapa (void)
{
struct mu_wordsplit ws;
char *p;
p = getenv ("MU_CLI_CAPA");
if (!p)
return NULL;
ws.ws_delim = ",";
if (mu_wordsplit (p, &ws,
MU_WRDSF_DELIM | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD
| MU_WRDSF_WS | MU_WRDSF_SHOWERR))
exit (1);
return ws.ws_wordv;
}
int
main (int argc, char **argv)
{
int i;
mu_cli (argc, argv, &cli, getcapa (), NULL, &argc, &argv);
printf ("DTRT=%d\n", dtrt_option);
printf ("%d arguments:\n", argc);
for (i = 0; i < argc; i++)
printf ("%d: %s\n", i, argv[i]);
return 0;
}
......@@ -18,23 +18,28 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#endif
#include <stdlib.h>
#include <sieve-priv.h>
#include <string.h>
#include <mailutils/cli.h>
mu_list_t mu_sieve_include_path = NULL;
mu_list_t mu_sieve_library_path = NULL;
mu_list_t mu_sieve_library_path_prefix = NULL;
mu_debug_handle_t mu_sieve_debug_handle;
//FIXME: provide definition (from gocs.h)
static struct mu_gocs_sieve sieve_settings;
void
mu_sieve_debug_init ()
mu_sieve_debug_init (void)
{
if (!mu_sieve_debug_handle)
mu_sieve_debug_handle = mu_debug_register_category ("sieve");
}
/*FIXME: REMOVE BEGIN */
static int
_path_append (void *item, void *data)
{
......@@ -73,7 +78,7 @@ mu_sieve_module_init (enum mu_gocs_op op, void *data)
mu_list_destroy (&mu_sieve_library_path_prefix);
}
mu_list_foreach (p->library_path_prefix, _path_append,
&mu_sieve_library_path_prefix);
&mu_sieve_library_path_prefix);
mu_list_foreach (p->library_path, _path_append, &mu_sieve_library_path);
mu_list_destroy (&p->library_path);
mu_list_destroy (&p->library_path_prefix);
......@@ -81,3 +86,161 @@ mu_sieve_module_init (enum mu_gocs_op op, void *data)
mu_sieve_debug_init ();
return 0;
}
/* FIXME: REMOVE END */
static int
cb_clear_library_path (void *data, mu_config_value_t *val)
{
int flag;
if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
return 1;
if (mu_str_to_c (val->v.string, mu_c_bool, &flag, NULL))
{
mu_error (_("not a boolean"));
return 1;
}
if (flag)
sieve_settings.clearflags |= MU_SIEVE_CLEAR_LIBRARY_PATH;
return 0;
}
static int
cb_clear_include_path (void *data, mu_config_value_t *val)
{
int flag;
if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
return 1;
if (mu_str_to_c (val->v.string, mu_c_bool, &flag, NULL))
{
mu_error (_("not a boolean"));
return 1;
}
if (flag)
sieve_settings.clearflags |= MU_SIEVE_CLEAR_INCLUDE_PATH;
return 0;
}
static int
_add_path (const char *arg, void *data)
{
mu_list_t *plist = data;
if (!*plist)
{
int rc = mu_list_create (plist);
if (rc)
{
mu_error (_("cannot create list: %s"), mu_strerror (rc));
exit (1);
}
mu_list_set_destroy_item (*plist, mu_list_free_item);
}
return mu_string_split (arg, ":", *plist);
}
static int
cb_include_path (void *data, mu_config_value_t *val)
{
return mu_cfg_string_value_cb (val, _add_path,
&sieve_settings.include_path);
}
static int
cb_library_path (void *data, mu_config_value_t *val)
{
return mu_cfg_string_value_cb (val, _add_path,
&sieve_settings.library_path);
}
static int
cb_library_path_prefix (void *data, mu_config_value_t *val)
{
return mu_cfg_string_value_cb (val, _add_path,
&sieve_settings.library_path_prefix);
}
static struct mu_cfg_param mu_sieve_param[] = {
{ "clear-library-path", mu_cfg_callback, NULL, 0, cb_clear_library_path,
N_("Clear library search path.") },
{ "clear-include-path", mu_cfg_callback, NULL, 0, cb_clear_include_path,
N_("Clear include search path.") },
{ "library-path", mu_cfg_callback, NULL, 0, cb_library_path,
N_("Add directories to the library search path. Argument is a "
"colon-separated list of directories."),
N_("list") },
{ "library-path-prefix", mu_cfg_callback, NULL, 0, cb_library_path_prefix,
N_("Add directories to the beginning of the library search path. "
"Argument is a colon-separated list of directories."),
N_("list") },
{ "include-path", mu_cfg_callback, NULL, 0, cb_include_path,
N_("Add directories to the include search path. Argument is a "
"colon-separated list of directories."),
N_("list") },
{ NULL }
};
/* New capability support */
static void
cli_includedir (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
_add_path (arg, &sieve_settings.include_path);
}
static void
cli_libdir (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
_add_path (arg, &sieve_settings.library_path);
}
static void
cli_libdir_prefix (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
_add_path (arg, &sieve_settings.library_path_prefix);
}
static void
cli_clear_include_path (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
sieve_settings.clearflags |= MU_SIEVE_CLEAR_INCLUDE_PATH;
}
static void
cli_clear_library_path (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
sieve_settings.clearflags |= MU_SIEVE_CLEAR_LIBRARY_PATH;
}
static struct mu_option sieve_option[] = {
MU_OPTION_GROUP (N_("Sieve options")),
{ "includedir", 'I', N_("DIR"), MU_OPTION_DEFAULT,
N_("append DIR to the list of directories searched for include files"),
mu_c_string, NULL, cli_includedir },
{ "libdir", 'L', N_("DIR"), MU_OPTION_DEFAULT,
N_("append DIR to the list of directories searched for library files"),
mu_c_string, NULL, cli_libdir },
{ "libdir-prefix", 0, N_("DIR"), MU_OPTION_DEFAULT,
N_("add DIR to the beginning of the list of directories searched for "
"library files"),
mu_c_string, NULL, cli_libdir_prefix },
{ "clear-include-path", 0, NULL, MU_OPTION_DEFAULT,
N_("clear Sieve include path"),
mu_c_string, NULL, cli_clear_include_path },
{ "clear-library-path", 0, NULL, MU_OPTION_DEFAULT,
N_("clear Sieve library path"),
mu_c_string, NULL, cli_clear_library_path },
{ "clearpath", 0, NULL, MU_OPTION_ALIAS },
MU_OPTION_END
};
struct mu_cli_capa mu_cli_capa_sieve = {
"sieve",
sieve_option,
mu_sieve_param,
NULL, NULL
};
......