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([ ...@@ -1506,6 +1506,7 @@ AC_CONFIG_FILES([
1506 libmailutils/address/Makefile 1506 libmailutils/address/Makefile
1507 libmailutils/sockaddr/Makefile 1507 libmailutils/sockaddr/Makefile
1508 libmailutils/cidr/Makefile 1508 libmailutils/cidr/Makefile
1509 libmailutils/cli/Makefile
1509 libmailutils/cfg/Makefile 1510 libmailutils/cfg/Makefile
1510 libmailutils/datetime/Makefile 1511 libmailutils/datetime/Makefile
1511 libmailutils/diag/Makefile 1512 libmailutils/diag/Makefile
......
...@@ -36,6 +36,7 @@ pkginclude_HEADERS = \ ...@@ -36,6 +36,7 @@ pkginclude_HEADERS = \
36 cctype.h\ 36 cctype.h\
37 cfg.h\ 37 cfg.h\
38 cidr.h\ 38 cidr.h\
39 cli.h\
39 cstr.h\ 40 cstr.h\
40 datetime.h\ 41 datetime.h\
41 daemon.h\ 42 daemon.h\
......
...@@ -79,6 +79,8 @@ struct mu_cfg_parse_hints ...@@ -79,6 +79,8 @@ struct mu_cfg_parse_hints
79 char *site_rcfile; 79 char *site_rcfile;
80 char *custom_rcfile; 80 char *custom_rcfile;
81 char *program; 81 char *program;
82 struct mu_cfg_tree *append_tree;
83 void *data;
82 }; 84 };
83 85
84 struct mu_cfg_tree 86 struct mu_cfg_tree
...@@ -238,6 +240,7 @@ int mu_config_register_plain_section (const char *parent_path, ...@@ -238,6 +240,7 @@ int mu_config_register_plain_section (const char *parent_path,
238 #define MU_CFG_FMT_LOCUS 0x080 240 #define MU_CFG_FMT_LOCUS 0x080
239 #define MU_CFG_FMT_VALUE_ONLY 0x100 241 #define MU_CFG_FMT_VALUE_ONLY 0x100
240 #define MU_CFG_FMT_PARAM_PATH 0x200 242 #define MU_CFG_FMT_PARAM_PATH 0x200
243 #define MU_PARSE_CONFIG_LINT 0x400
241 244
242 #ifdef MU_CFG_COMPATIBILITY 245 #ifdef MU_CFG_COMPATIBILITY
243 # define MU_CFG_DEPRECATED 246 # define MU_CFG_DEPRECATED
......
1 /* opt.h -- general-purpose command line option parser
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
18 #ifndef _MAILUTILS_CLI_H
19 #define _MAILUTILS_CLI_H
20 #include <stdio.h>
21 #include <mailutils/types.h>
22 #include <mailutils/cfg.h>
23 #include <mailutils/opt.h>
24
25 typedef void (*mu_cli_capa_commit_fp) (void *);
26
27 struct mu_cli_capa
28 {
29 char *name;
30 struct mu_option *opt;
31 struct mu_cfg_param *cfg;
32 mu_cfg_section_fp parser;
33 mu_cli_capa_commit_fp commit;
34 };
35
36 void mu_cli_capa_init (void);
37 void mu_cli_capa_register (struct mu_cli_capa *capa);
38 void mu_cli_capa_apply (char const *name, mu_list_t opts, mu_list_t commits);
39
40 struct mu_cli_setup
41 {
42 struct mu_option **optv;
43 struct mu_cfg_param *cfg;
44 char *prog_doc;
45 char *prog_args;
46 };
47
48 void mu_version_func (struct mu_parseopt *po, FILE *stream);
49 void mu_cli (int argc, char **argv, struct mu_cli_setup *setup,
50 char **capa, void *data,
51 int *ret_argc, char ***ret_argv);
52
53 char *mu_site_config_file (void);
54
55 #endif
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
29 extern "C" { 29 extern "C" {
30 #endif 30 #endif
31 31
32 extern const char *mu_program_name; 32 extern char *mu_program_name;
33 extern const char *mu_full_program_name; 33 extern char *mu_full_program_name;
34 34
35 #define MU_DIAG_EMERG MU_LOG_EMERG 35 #define MU_DIAG_EMERG MU_LOG_EMERG
36 #define MU_DIAG_ALERT MU_LOG_ALERT 36 #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) ...@@ -103,7 +103,7 @@ extern int mu_locker_set_default_flags (int flags, enum mu_locker_set_mode mode)
103 extern void mu_locker_set_default_retry_timeout (time_t to); 103 extern void mu_locker_set_default_retry_timeout (time_t to);
104 extern void mu_locker_set_default_retry_count (size_t n); 104 extern void mu_locker_set_default_retry_count (size_t n);
105 extern void mu_locker_set_default_expire_timeout (time_t t); 105 extern void mu_locker_set_default_expire_timeout (time_t t);
106 extern int mu_locker_set_default_external_program (char *path); 106 extern int mu_locker_set_default_external_program (char const *path);
107 107
108 /* A flags of 0 means that the default will be used. */ 108 /* A flags of 0 means that the default will be used. */
109 extern int mu_locker_create (mu_locker_t *, const char *filename, int flags); 109 extern int mu_locker_create (mu_locker_t *, const char *filename, int flags);
......
...@@ -23,10 +23,10 @@ ...@@ -23,10 +23,10 @@
23 #include <mailutils/util.h> 23 #include <mailutils/util.h>
24 #include <mailutils/cctype.h> 24 #include <mailutils/cctype.h>
25 25
26 extern char *mu_progname; 26 extern char *mu_program_name;
27 extern char *mu_absprogname; 27 extern char *mu_full_program_name;
28 28
29 void mu_set_progname (char const *arg); 29 void mu_set_program_name (char const *arg);
30 30
31 #define MU_OPTION_DEFAULT 0 31 #define MU_OPTION_DEFAULT 0
32 #define MU_OPTION_ARG_OPTIONAL 0x01 32 #define MU_OPTION_ARG_OPTIONAL 0x01
...@@ -118,7 +118,7 @@ struct mu_parseopt ...@@ -118,7 +118,7 @@ struct mu_parseopt
118 struct mu_option **po_optv; /* Array of ptrs to option structures */ 118 struct mu_option **po_optv; /* Array of ptrs to option structures */
119 int po_flags; 119 int po_flags;
120 120
121 char *po_data; /* Call-specific data */ 121 void *po_data; /* Call-specific data */
122 122
123 int po_exit_error; /* Exit on error with this code */ 123 int po_exit_error; /* Exit on error with this code */
124 124
...@@ -131,8 +131,9 @@ struct mu_parseopt ...@@ -131,8 +131,9 @@ struct mu_parseopt
131 char const *po_package_url; 131 char const *po_package_url;
132 char const *po_extra_info; 132 char const *po_extra_info;
133 133
134 void (*po_help_hook) (FILE *stream); /* FIXME: should take mu_stream_t ?*/ 134 /* FIXME: should these take mu_stream_t ?*/
135 void (*po_version_hook) (FILE *stream); 135 void (*po_help_hook) (struct mu_parseopt *po, FILE *stream);
136 void (*po_version_hook) (struct mu_parseopt *po, FILE *stream);
136 137
137 /* Output data */ 138 /* Output data */
138 int po_ind; /* Index of the next option */ 139 int po_ind; /* Index of the next option */
...@@ -162,6 +163,7 @@ struct mu_parseopt ...@@ -162,6 +163,7 @@ struct mu_parseopt
162 int mu_parseopt (struct mu_parseopt *p, 163 int mu_parseopt (struct mu_parseopt *p,
163 int argc, char **argv, struct mu_option **optv, 164 int argc, char **argv, struct mu_option **optv,
164 int flags); 165 int flags);
166 void mu_parseopt_error (struct mu_parseopt *po, char const *fmt, ...);
165 167
166 int mu_parseopt_apply (struct mu_parseopt *p); 168 int mu_parseopt_apply (struct mu_parseopt *p);
167 void mu_parseopt_free (struct mu_parseopt *p); 169 void mu_parseopt_free (struct mu_parseopt *p);
......
...@@ -28,7 +28,7 @@ extern mu_stream_t mu_strin; ...@@ -28,7 +28,7 @@ extern mu_stream_t mu_strin;
28 extern mu_stream_t mu_strout; 28 extern mu_stream_t mu_strout;
29 extern mu_stream_t mu_strerr; 29 extern mu_stream_t mu_strerr;
30 30
31 extern const char *mu_program_name; 31 extern char *mu_program_name;
32 32
33 #define MU_STRERR_STDERR 0 33 #define MU_STRERR_STDERR 0
34 #define MU_STRERR_SYSLOG 1 34 #define MU_STRERR_SYSLOG 1
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 # <http://www.gnu.org/licenses/>. 17 # <http://www.gnu.org/licenses/>.
18 18
19 SUBDIRS = \ 19 SUBDIRS = \
20 auth base address list sockaddr cidr cfg diag\ 20 auth base address list sockaddr cidr cfg cli diag\
21 filter mailbox mailer mime msgset opt server string stream stdstream\ 21 filter mailbox mailer mime msgset opt server string stream stdstream\
22 property url imapio datetime . tests 22 property url imapio datetime . tests
23 23
...@@ -33,6 +33,7 @@ libmailutils_la_LIBADD = \ ...@@ -33,6 +33,7 @@ libmailutils_la_LIBADD = \
33 sockaddr/libsockaddr.la\ 33 sockaddr/libsockaddr.la\
34 cidr/libcidr.la\ 34 cidr/libcidr.la\
35 cfg/libcfg.la\ 35 cfg/libcfg.la\
36 cli/libcli.la\
36 datetime/libdatetime.la\ 37 datetime/libdatetime.la\
37 diag/libdiag.la\ 38 diag/libdiag.la\
38 filter/libfilter.la\ 39 filter/libfilter.la\
......
...@@ -242,7 +242,7 @@ mu_locker_set_default_expire_timeout (time_t t) ...@@ -242,7 +242,7 @@ mu_locker_set_default_expire_timeout (time_t t)
242 } 242 }
243 243
244 int 244 int
245 mu_locker_set_default_external_program (char *path) 245 mu_locker_set_default_external_program (char const *path)
246 { 246 {
247 char *p = strdup (path); 247 char *p = strdup (path);
248 if (!p) 248 if (!p)
......
...@@ -463,7 +463,7 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree, ...@@ -463,7 +463,7 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree,
463 void *target_ptr) 463 void *target_ptr)
464 { 464 {
465 int rc = 0; 465 int rc = 0;
466 466 struct mu_cfg_cont *cont;
467 if (!parse_tree) 467 if (!parse_tree)
468 return 0; 468 return 0;
469 if (hints && (hints->flags & MU_PARSE_CONFIG_DUMP)) 469 if (hints && (hints->flags & MU_PARSE_CONFIG_DUMP))
...@@ -477,13 +477,9 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree, ...@@ -477,13 +477,9 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree,
477 mu_stream_destroy (&stream); 477 mu_stream_destroy (&stream);
478 } 478 }
479 479
480 if (root_container) 480 cont = mu_build_container (progparam);
481 { 481 rc = mu_cfg_scan_tree (parse_tree, &cont->v.section, target_ptr, NULL);
482 struct mu_cfg_cont *cont = mu_build_container (progparam);
483 rc = mu_cfg_scan_tree (parse_tree, &cont->v.section, target_ptr,
484 NULL);
485 mu_config_destroy_container (&cont); 482 mu_config_destroy_container (&cont);
486 }
487 483
488 return rc; 484 return rc;
489 } 485 }
......
...@@ -330,10 +330,16 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags) ...@@ -330,10 +330,16 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags)
330 int rc; 330 int rc;
331 char *full_name = mu_tilde_expansion (file, MU_HIERARCHY_DELIMITER, NULL); 331 char *full_name = mu_tilde_expansion (file, MU_HIERARCHY_DELIMITER, NULL);
332 332
333 if (flags & MU_PARSE_CONFIG_VERBOSE)
334 mu_diag_output (MU_DIAG_INFO, _("opening configuration file %s"),
335 full_name);
333 if (stat (full_name, &st)) 336 if (stat (full_name, &st))
334 { 337 {
335 if (errno != ENOENT) 338 if (errno != ENOENT)
336 mu_error (_("cannot stat `%s': %s"), full_name, mu_strerror (errno)); 339 mu_error (_("cannot stat `%s': %s"), full_name, mu_strerror (errno));
340 else if (flags & MU_PARSE_CONFIG_VERBOSE)
341 mu_diag_output (MU_DIAG_INFO, _("configuration file %s doesn't exist"),
342 full_name);
337 free (full_name); 343 free (full_name);
338 return ENOENT; 344 return ENOENT;
339 } 345 }
......
...@@ -1590,6 +1590,9 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints) ...@@ -1590,6 +1590,9 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints)
1590 } 1590 }
1591 } 1591 }
1592 1592
1593 if (hints->append_tree)
1594 mu_cfg_tree_union (&tree, &hints->append_tree);
1595
1593 *ptree = tree; 1596 *ptree = tree;
1594 return rc; 1597 return rc;
1595 } 1598 }
......
1 # GNU Mailutils -- a suite of utilities for electronic mail
2 # Copyright (C) 2016 Free Software Foundation, Inc.
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 3 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General
15 # Public License along with this library. If not, see
16 # <http://www.gnu.org/licenses/>.
17
18 noinst_LTLIBRARIES = libcli.la
19
20 libcli_la_SOURCES = \
21 capa.c\
22 cli.c\
23 stdcapa.c
24
25 AM_CPPFLAGS = \
26 @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
1 /* capa.c -- CLI capabilities for GNU Mailutils
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 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <stdlib.h>
21 #include <string.h>
22 #include <mailutils/cli.h>
23 #include <mailutils/list.h>
24 #include <mailutils/alloc.h>
25 #include <mailutils/nls.h>
26
27 static mu_list_t capa_list;
28
29 static void
30 capa_free (void *ptr)
31 {
32 struct mu_cli_capa *cp = ptr;
33 free (cp->name);
34 free (cp);
35 }
36
37 void
38 mu_cli_capa_register (struct mu_cli_capa *capa)
39 {
40 struct mu_cli_capa *cp = mu_alloc (sizeof (*cp));
41 cp->name = mu_strdup (capa->name);
42 cp->opt = capa->opt;
43 cp->cfg = capa->cfg;
44 cp->parser = capa->parser;
45 cp->commit = capa->commit;
46 if (!capa_list)
47 {
48 mu_list_create (&capa_list);
49 mu_list_set_destroy_item (capa_list, capa_free);
50 }
51 mu_list_append (capa_list, cp);
52 }
53
54 struct capa_apply
55 {
56 char const *name;
57 mu_list_t opts;
58 mu_list_t commits;
59 int found;
60 };
61
62 static int
63 capa_apply (void *item, void *data)
64 {
65 struct mu_cli_capa *cp = item;
66 struct capa_apply *ap = data;
67
68 if (strcmp (cp->name, ap->name) == 0)
69 {
70 ap->found = 1;
71 if (cp->opt)
72 mu_list_append (ap->opts, cp->opt);
73 if (cp->commit)
74 mu_list_append (ap->commits, cp->commit);
75 if (cp->parser || cp->cfg)
76 mu_config_root_register_section (NULL, cp->name, NULL,
77 cp->parser, cp->cfg);
78 }
79 return 0;
80 }
81
82 void
83 mu_cli_capa_apply (char const *name, mu_list_t opts, mu_list_t commits)
84 {
85 struct capa_apply app;
86 app.name = name;
87 app.opts = opts;
88 app.commits = commits;
89 app.found = 0;
90 mu_list_foreach (capa_list, capa_apply, &app);
91 if (!app.found)
92 mu_error (_("INTERNAL ERROR at %s:%d: unknown standard capability `%s'"),
93 __FILE__, __LINE__, name);
94 }
95
96
...@@ -30,32 +30,6 @@ ...@@ -30,32 +30,6 @@
30 #include <mailutils/stdstream.h> 30 #include <mailutils/stdstream.h>
31 #include <mailutils/stream.h> 31 #include <mailutils/stream.h>
32 32
33 const char *mu_program_name;
34 const char *mu_full_program_name;
35
36 void
37 mu_set_program_name (const char *name)
38 {
39 const char *progname;
40
41 mu_full_program_name = name;
42 if (!name)
43 progname = name;
44 else
45 {
46 progname = strrchr (name, '/');
47 if (progname)
48 progname++;
49 else
50 progname = name;
51
52 if (strlen (progname) > 3 && memcmp (progname, "lt-", 3) == 0)
53 progname += 3;
54 }
55
56 mu_program_name = progname;
57 }
58
59 void 33 void
60 mu_diag_init () 34 mu_diag_init ()
61 { 35 {
......
...@@ -155,7 +155,7 @@ init_usage_vars (struct mu_parseopt *po) ...@@ -155,7 +155,7 @@ init_usage_vars (struct mu_parseopt *po)
155 fmt = getenv ("ARGP_HELP_FMT"); 155 fmt = getenv ("ARGP_HELP_FMT");
156 if (!fmt) 156 if (!fmt)
157 return; 157 return;
158 ws.ws_delim=","; 158 ws.ws_delim = ",";
159 if (mu_wordsplit (fmt, &ws, 159 if (mu_wordsplit (fmt, &ws,
160 MU_WRDSF_DELIM | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD 160 MU_WRDSF_DELIM | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD
161 | MU_WRDSF_WS | MU_WRDSF_SHOWERR)) 161 | MU_WRDSF_WS | MU_WRDSF_SHOWERR))
...@@ -346,20 +346,20 @@ mu_program_help (struct mu_parseopt *po) ...@@ -346,20 +346,20 @@ mu_program_help (struct mu_parseopt *po)
346 mu_option_describe_options (po->po_optv, po->po_optc); 346 mu_option_describe_options (po->po_optv, po->po_optc);
347 347
348 if (po->po_help_hook) 348 if (po->po_help_hook)
349 po->po_help_hook (stdout); 349 po->po_help_hook (po, stdout);
350 350
351 if (po->po_bug_address) 351 if (po->po_bug_address)
352 /* TRANSLATORS: The placeholder indicates the bug-reporting address 352 /* TRANSLATORS: The placeholder indicates the bug-reporting address
353 for this package. Please add _another line_ saying 353 for this package. Please add _another line_ saying
354 "Report translation bugs to <...>\n" with the address for translation 354 "Report translation bugs to <...>\n" with the address for translation
355 bugs (typically your translation team's web or email address). */ 355 bugs (typically your translation team's web or email address). */
356 printf (_("Report bugs to %s.\n"), po->po_bug_address); 356 printf (_("Report bugs to <%s>.\n"), po->po_bug_address);
357 357
358 if (po->po_package_name && po->po_package_url) 358 if (po->po_package_name && po->po_package_url)
359 printf (_("%s home page: <%s>\n"), 359 printf (_("%s home page: <%s>\n"),
360 po->po_package_name, po->po_package_url); 360 po->po_package_name, po->po_package_url);
361 if (po->po_flags & MU_PARSEOPT_EXTRA_INFO) 361 if (po->po_flags & MU_PARSEOPT_EXTRA_INFO)
362 print_option_descr (po->po_extra_info, 0, rmargin); 362 print_option_descr (_(po->po_extra_info), 0, rmargin);
363 } 363 }
364 364
365 static struct mu_option **option_tab; 365 static struct mu_option **option_tab;
......
...@@ -85,7 +85,7 @@ fn_usage (struct mu_parseopt *po, struct mu_option *opt, char const *unused) ...@@ -85,7 +85,7 @@ fn_usage (struct mu_parseopt *po, struct mu_option *opt, char const *unused)
85 static void 85 static void
86 fn_version (struct mu_parseopt *po, struct mu_option *opt, char const *unused) 86 fn_version (struct mu_parseopt *po, struct mu_option *opt, char const *unused)
87 { 87 {
88 po->po_version_hook (stdout); 88 po->po_version_hook (po, stdout);
89 exit (EXIT_SUCCESS); 89 exit (EXIT_SUCCESS);
90 } 90 }
91 91
...@@ -107,8 +107,8 @@ struct mu_option mu_version_options[] = { ...@@ -107,8 +107,8 @@ struct mu_option mu_version_options[] = {
107 }; 107 };
108 108
109 /* Output error message */ 109 /* Output error message */
110 static void 110 void
111 parse_error (struct mu_parseopt *po, char const *fmt, ...) 111 mu_parseopt_error (struct mu_parseopt *po, char const *fmt, ...)
112 { 112 {
113 va_list ap; 113 va_list ap;
114 114
...@@ -176,7 +176,7 @@ find_short_option (struct mu_parseopt *po, int chr) ...@@ -176,7 +176,7 @@ find_short_option (struct mu_parseopt *po, int chr)
176 && po->po_optv[i]->opt_short == chr) 176 && po->po_optv[i]->opt_short == chr)
177 return option_unalias (po, i); 177 return option_unalias (po, i);
178 } 178 }
179 parse_error (po, _("unrecognized option '-%c'"), chr); 179 mu_parseopt_error (po, _("unrecognized option '-%c'"), chr);
180 return NULL; 180 return NULL;
181 } 181 }
182 182
...@@ -209,7 +209,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr, ...@@ -209,7 +209,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr,
209 case 1: 209 case 1:
210 if (po->po_flags & MU_PARSEOPT_IGNORE_ERRORS) 210 if (po->po_flags & MU_PARSEOPT_IGNORE_ERRORS)
211 return NULL; 211 return NULL;
212 parse_error (po, 212 mu_parseopt_error (po,
213 _("option '--%*.*s' is ambiguous; possibilities:"), 213 _("option '--%*.*s' is ambiguous; possibilities:"),
214 optlen, optlen, optstr); 214 optlen, optlen, optstr);
215 fprintf (stderr, "--%s\n", po->po_optv[ind]->opt_long); 215 fprintf (stderr, "--%s\n", po->po_optv[ind]->opt_long);
...@@ -224,7 +224,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr, ...@@ -224,7 +224,7 @@ find_long_option (struct mu_parseopt *po, char const *optstr,
224 switch (found) 224 switch (found)
225 { 225 {
226 case 0: 226 case 0:
227 parse_error (po, _("unrecognized option '--%s'"), optstr); 227 mu_parseopt_error (po, _("unrecognized option '--%s'"), optstr);
228 break; 228 break;
229 229
230 case 1: 230 case 1:
...@@ -303,7 +303,7 @@ next_opt (struct mu_parseopt *po) ...@@ -303,7 +303,7 @@ next_opt (struct mu_parseopt *po)
303 break; 303 break;
304 if (!(po->po_flags & MU_PARSEOPT_IN_ORDER)) 304 if (!(po->po_flags & MU_PARSEOPT_IN_ORDER))
305 { 305 {
306 if (!po->po_permuted) 306 if (!po->po_permuted && po->po_arg_count == 0)
307 po->po_arg_start = po->po_ind - 1; 307 po->po_arg_start = po->po_ind - 1;
308 po->po_arg_count++; 308 po->po_arg_count++;
309 continue; 309 continue;
...@@ -405,11 +405,11 @@ parse (struct mu_parseopt *po) ...@@ -405,11 +405,11 @@ parse (struct mu_parseopt *po)
405 else 405 else
406 { 406 {
407 if (long_opt) 407 if (long_opt)
408 parse_error (po, 408 mu_parseopt_error (po,
409 _("option '--%s' requires an argument"), 409 _("option '--%s' requires an argument"),
410 long_opt); 410 long_opt);
411 else 411 else
412 parse_error (po, 412 mu_parseopt_error (po,
413 _("option '-%c' requires an argument"), 413 _("option '-%c' requires an argument"),
414 po->po_chr); 414 po->po_chr);
415 po->po_opterr = po->po_ind; 415 po->po_opterr = po->po_ind;
...@@ -428,7 +428,7 @@ parse (struct mu_parseopt *po) ...@@ -428,7 +428,7 @@ parse (struct mu_parseopt *po)
428 && po->po_cur[0] 428 && po->po_cur[0]
429 && !(po->po_flags & MU_OPTION_ARG_OPTIONAL)) 429 && !(po->po_flags & MU_OPTION_ARG_OPTIONAL))
430 { 430 {
431 parse_error (po, 431 mu_parseopt_error (po,
432 _("option '--%s' doesn't allow an argument"), 432 _("option '--%s' doesn't allow an argument"),
433 long_opt); 433 long_opt);
434 po->po_opterr = po->po_ind; 434 po->po_opterr = po->po_ind;
...@@ -661,9 +661,9 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt, ...@@ -661,9 +661,9 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt,
661 errtext = mu_strerror (rc); 661 errtext = mu_strerror (rc);
662 662
663 if (opt->opt_long) 663 if (opt->opt_long)
664 parse_error (po, "--%s: %s", opt->opt_long, errtext); 664 mu_parseopt_error (po, "--%s: %s", opt->opt_long, errtext);
665 else 665 else
666 parse_error (po, "-%c: %s", opt->opt_short, errtext); 666 mu_parseopt_error (po, "-%c: %s", opt->opt_short, errtext);
667 free (errmsg); 667 free (errmsg);
668 668
669 if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT)) 669 if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT))
......
...@@ -22,16 +22,16 @@ ...@@ -22,16 +22,16 @@
22 #include <mailutils/alloc.h> 22 #include <mailutils/alloc.h>
23 #include <mailutils/opt.h> 23 #include <mailutils/opt.h>
24 24
25 char *mu_progname; 25 char *mu_program_name;
26 char *mu_absprogname; 26 char *mu_full_program_name;
27 27
28 void 28 void
29 mu_set_progname (char const *arg) 29 mu_set_program_name (const char *arg)
30 { 30 {
31 char *p; 31 char *p;
32 32
33 free (mu_absprogname); 33 free (mu_full_program_name);
34 mu_absprogname = mu_strdup (arg); 34 mu_full_program_name = mu_strdup (arg);
35 35
36 p = strrchr (arg, '/'); 36 p = strrchr (arg, '/');
37 if (p) 37 if (p)
...@@ -40,6 +40,6 @@ mu_set_progname (char const *arg) ...@@ -40,6 +40,6 @@ mu_set_progname (char const *arg)
40 p = (char*) arg; 40 p = (char*) arg;
41 if (strlen (p) > 3 && memcmp (p, "lt-", 3) == 0) 41 if (strlen (p) > 3 && memcmp (p, "lt-", 3) == 0)
42 p += 3; 42 p += 3;
43 free (mu_progname); 43 free (mu_program_name);
44 mu_progname = mu_strdup (p); 44 mu_program_name = mu_strdup (p);
45 } 45 }
......
...@@ -27,6 +27,7 @@ strftime ...@@ -27,6 +27,7 @@ strftime
27 strin 27 strin
28 strout 28 strout
29 strtoc 29 strtoc
30 tcli
30 tempfile 31 tempfile
31 url-comp 32 url-comp
32 url-parse 33 url-parse
......
...@@ -64,6 +64,7 @@ noinst_PROGRAMS = \ ...@@ -64,6 +64,7 @@ noinst_PROGRAMS = \
64 strout\ 64 strout\
65 strtoc\ 65 strtoc\
66 tempfile\ 66 tempfile\
67 tcli\
67 url-comp\ 68 url-comp\
68 url-parse\ 69 url-parse\
69 wicket\ 70 wicket\
......
...@@ -64,7 +64,7 @@ struct mu_option group_b[] = { ...@@ -64,7 +64,7 @@ struct mu_option group_b[] = {
64 struct mu_option *optv[] = { group_a, group_b, NULL }; 64 struct mu_option *optv[] = { group_a, group_b, NULL };
65 65
66 static void 66 static void
67 version_func (FILE *fp) 67 version_hook (struct mu_parseopt *po, FILE *fp)
68 { 68 {
69 fputs ("version hook called\n", fp); 69 fputs ("version hook called\n", fp);
70 } 70 }
...@@ -144,7 +144,7 @@ main (int argc, char *argv[]) ...@@ -144,7 +144,7 @@ main (int argc, char *argv[])
144 } 144 }
145 } 145 }
146 if (flags & MU_PARSEOPT_VERSION_HOOK) 146 if (flags & MU_PARSEOPT_VERSION_HOOK)
147 po.po_version_hook = version_func; 147 po.po_version_hook = version_hook;
148 } 148 }
149 149
150 rc = mu_parseopt (&po, argc, argv, optv, flags); 150 rc = mu_parseopt (&po, argc, argv, optv, flags);
......
...@@ -35,4 +35,24 @@ argv: ...@@ -35,4 +35,24 @@ argv:
35 2: follow 35 2: follow
36 3: options 36 3: options
37 ]) 37 ])
38
39 AT_CHECK([
40 PARSEOPT_DEFAULT
41 parseopt --file=file more arguments follow -x -o options
42 ],
43 [0],
44 [rc=0
45 file_name=file
46 opt_value=(null)
47 x_option=1
48 a_option=0
49 find_value=(null)
50 d_option=0
51 jobs=0
52 argv:
53 0: more
54 1: arguments
55 2: follow
56 3: options
57 ])
38 AT_CLEANUP 58 AT_CLEANUP
......
...@@ -18,7 +18,7 @@ AT_SETUP([MU_PARSEOPT_BUG_ADDRESS]) ...@@ -18,7 +18,7 @@ AT_SETUP([MU_PARSEOPT_BUG_ADDRESS])
18 AT_KEYWORDS([parseopt parseopt_help parseopt_help05]) 18 AT_KEYWORDS([parseopt parseopt_help parseopt_help05])
19 AT_CHECK([ 19 AT_CHECK([
20 PARSEOPT_DEFAULT 20 PARSEOPT_DEFAULT
21 MU_PARSEOPT_BUG_ADDRESS='<gray@gnu.org>' parseopt --help 21 MU_PARSEOPT_BUG_ADDRESS='gray@gnu.org' parseopt --help
22 ], 22 ],
23 [0], 23 [0],
24 [Usage: parseopt [[OPTION]]... 24 [Usage: parseopt [[OPTION]]...
......
...@@ -20,7 +20,7 @@ AT_CHECK([ ...@@ -20,7 +20,7 @@ AT_CHECK([
20 PARSEOPT_DEFAULT 20 PARSEOPT_DEFAULT
21 MU_PARSEOPT_PROG_DOC="Tests option parsing"\ 21 MU_PARSEOPT_PROG_DOC="Tests option parsing"\
22 MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS"\ 22 MU_PARSEOPT_PROG_ARGS="SOME MORE ARGS"\
23 MU_PARSEOPT_BUG_ADDRESS='<gray@gnu.org>'\ 23 MU_PARSEOPT_BUG_ADDRESS='gray@gnu.org'\
24 MU_PARSEOPT_PACKAGE_NAME='GNU Mailutils'\ 24 MU_PARSEOPT_PACKAGE_NAME='GNU Mailutils'\
25 MU_PARSEOPT_PACKAGE_URL='http://mailutils.org'\ 25 MU_PARSEOPT_PACKAGE_URL='http://mailutils.org'\
26 MU_PARSEOPT_EXTRA_INFO='General help using GNU software: <http://www.gnu.org/gethelp/>'\ 26 MU_PARSEOPT_EXTRA_INFO='General help using GNU software: <http://www.gnu.org/gethelp/>'\
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2016 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU 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 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <mailutils/mailutils.h>
21 #include <mailutils/cli.h>
22
23 int dtrt_option;
24
25 struct mu_option group_a[] = {
26 { "dtrt", 'd', "VALUE", MU_OPTION_DEFAULT,
27 "do the right thing",
28 mu_c_int, &dtrt_option },
29 MU_OPTION_END
30 };
31
32 struct mu_option *options[] = { group_a, NULL };
33
34 static struct mu_cfg_param config[] = {
35 { "do-the-right-thing", mu_c_int, &dtrt_option, 0, NULL,
36 "do the right thing" },
37 { NULL }
38 };
39
40 struct mu_cli_setup cli = {
41 options,
42 config,
43 "Tests standard command line interface",
44 "ARGUMENTS"
45 };
46
47 static char **
48 getcapa (void)
49 {
50 struct mu_wordsplit ws;
51 char *p;
52
53 p = getenv ("MU_CLI_CAPA");
54 if (!p)
55 return NULL;
56 ws.ws_delim = ",";
57 if (mu_wordsplit (p, &ws,
58 MU_WRDSF_DELIM | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD
59 | MU_WRDSF_WS | MU_WRDSF_SHOWERR))
60 exit (1);
61 return ws.ws_wordv;
62 }
63
64 int
65 main (int argc, char **argv)
66 {
67 int i;
68
69 mu_cli (argc, argv, &cli, getcapa (), NULL, &argc, &argv);
70 printf ("DTRT=%d\n", dtrt_option);
71 printf ("%d arguments:\n", argc);
72 for (i = 0; i < argc; i++)
73 printf ("%d: %s\n", i, argv[i]);
74 return 0;
75 }
...@@ -19,22 +19,27 @@ ...@@ -19,22 +19,27 @@
19 #ifdef HAVE_CONFIG_H 19 #ifdef HAVE_CONFIG_H
20 # include <config.h> 20 # include <config.h>
21 #endif 21 #endif
22 #include <stdlib.h>
22 #include <sieve-priv.h> 23 #include <sieve-priv.h>
23 #include <string.h> 24 #include <string.h>
25 #include <mailutils/cli.h>
24 26
25 mu_list_t mu_sieve_include_path = NULL; 27 mu_list_t mu_sieve_include_path = NULL;
26 mu_list_t mu_sieve_library_path = NULL; 28 mu_list_t mu_sieve_library_path = NULL;
27 mu_list_t mu_sieve_library_path_prefix = NULL; 29 mu_list_t mu_sieve_library_path_prefix = NULL;
28
29 mu_debug_handle_t mu_sieve_debug_handle; 30 mu_debug_handle_t mu_sieve_debug_handle;
30 31
32 //FIXME: provide definition (from gocs.h)
33 static struct mu_gocs_sieve sieve_settings;
34
31 void 35 void
32 mu_sieve_debug_init () 36 mu_sieve_debug_init (void)
33 { 37 {
34 if (!mu_sieve_debug_handle) 38 if (!mu_sieve_debug_handle)
35 mu_sieve_debug_handle = mu_debug_register_category ("sieve"); 39 mu_sieve_debug_handle = mu_debug_register_category ("sieve");
36 } 40 }
37 41
42 /*FIXME: REMOVE BEGIN */
38 static int 43 static int
39 _path_append (void *item, void *data) 44 _path_append (void *item, void *data)
40 { 45 {
...@@ -81,3 +86,161 @@ mu_sieve_module_init (enum mu_gocs_op op, void *data) ...@@ -81,3 +86,161 @@ mu_sieve_module_init (enum mu_gocs_op op, void *data)
81 mu_sieve_debug_init (); 86 mu_sieve_debug_init ();
82 return 0; 87 return 0;
83 } 88 }
89 /* FIXME: REMOVE END */
90
91 static int
92 cb_clear_library_path (void *data, mu_config_value_t *val)
93 {
94 int flag;
95
96 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
97 return 1;
98 if (mu_str_to_c (val->v.string, mu_c_bool, &flag, NULL))
99 {
100 mu_error (_("not a boolean"));
101 return 1;
102 }
103 if (flag)
104 sieve_settings.clearflags |= MU_SIEVE_CLEAR_LIBRARY_PATH;
105 return 0;
106 }
107
108 static int
109 cb_clear_include_path (void *data, mu_config_value_t *val)
110 {
111 int flag;
112
113 if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
114 return 1;
115 if (mu_str_to_c (val->v.string, mu_c_bool, &flag, NULL))
116 {
117 mu_error (_("not a boolean"));
118 return 1;
119 }
120 if (flag)
121 sieve_settings.clearflags |= MU_SIEVE_CLEAR_INCLUDE_PATH;
122 return 0;
123 }
124
125 static int
126 _add_path (const char *arg, void *data)
127 {
128 mu_list_t *plist = data;
129
130 if (!*plist)
131 {
132 int rc = mu_list_create (plist);
133 if (rc)
134 {
135 mu_error (_("cannot create list: %s"), mu_strerror (rc));
136 exit (1);
137 }
138 mu_list_set_destroy_item (*plist, mu_list_free_item);
139 }
140 return mu_string_split (arg, ":", *plist);
141 }
142
143 static int
144 cb_include_path (void *data, mu_config_value_t *val)
145 {
146 return mu_cfg_string_value_cb (val, _add_path,
147 &sieve_settings.include_path);
148 }
149
150 static int
151 cb_library_path (void *data, mu_config_value_t *val)
152 {
153 return mu_cfg_string_value_cb (val, _add_path,
154 &sieve_settings.library_path);
155 }
156
157 static int
158 cb_library_path_prefix (void *data, mu_config_value_t *val)
159 {
160 return mu_cfg_string_value_cb (val, _add_path,
161 &sieve_settings.library_path_prefix);
162 }
163
164 static struct mu_cfg_param mu_sieve_param[] = {
165 { "clear-library-path", mu_cfg_callback, NULL, 0, cb_clear_library_path,
166 N_("Clear library search path.") },
167 { "clear-include-path", mu_cfg_callback, NULL, 0, cb_clear_include_path,
168 N_("Clear include search path.") },
169 { "library-path", mu_cfg_callback, NULL, 0, cb_library_path,
170 N_("Add directories to the library search path. Argument is a "
171 "colon-separated list of directories."),
172 N_("list") },
173 { "library-path-prefix", mu_cfg_callback, NULL, 0, cb_library_path_prefix,
174 N_("Add directories to the beginning of the library search path. "
175 "Argument is a colon-separated list of directories."),
176 N_("list") },
177 { "include-path", mu_cfg_callback, NULL, 0, cb_include_path,
178 N_("Add directories to the include search path. Argument is a "
179 "colon-separated list of directories."),
180 N_("list") },
181 { NULL }
182 };
183
184 /* New capability support */
185 static void
186 cli_includedir (struct mu_parseopt *po, struct mu_option *opt,
187 char const *arg)
188 {
189 _add_path (arg, &sieve_settings.include_path);
190 }
191
192 static void
193 cli_libdir (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
194 {
195 _add_path (arg, &sieve_settings.library_path);
196 }
197
198 static void
199 cli_libdir_prefix (struct mu_parseopt *po, struct mu_option *opt,
200 char const *arg)
201 {
202 _add_path (arg, &sieve_settings.library_path_prefix);
203 }
204
205 static void
206 cli_clear_include_path (struct mu_parseopt *po, struct mu_option *opt,
207 char const *arg)
208 {
209 sieve_settings.clearflags |= MU_SIEVE_CLEAR_INCLUDE_PATH;
210 }
211
212 static void
213 cli_clear_library_path (struct mu_parseopt *po, struct mu_option *opt,
214 char const *arg)
215 {
216 sieve_settings.clearflags |= MU_SIEVE_CLEAR_LIBRARY_PATH;
217 }
218
219 static struct mu_option sieve_option[] = {
220 MU_OPTION_GROUP (N_("Sieve options")),
221 { "includedir", 'I', N_("DIR"), MU_OPTION_DEFAULT,
222 N_("append DIR to the list of directories searched for include files"),
223 mu_c_string, NULL, cli_includedir },
224 { "libdir", 'L', N_("DIR"), MU_OPTION_DEFAULT,
225 N_("append DIR to the list of directories searched for library files"),
226 mu_c_string, NULL, cli_libdir },
227 { "libdir-prefix", 0, N_("DIR"), MU_OPTION_DEFAULT,
228 N_("add DIR to the beginning of the list of directories searched for "
229 "library files"),
230 mu_c_string, NULL, cli_libdir_prefix },
231 { "clear-include-path", 0, NULL, MU_OPTION_DEFAULT,
232 N_("clear Sieve include path"),
233 mu_c_string, NULL, cli_clear_include_path },
234 { "clear-library-path", 0, NULL, MU_OPTION_DEFAULT,
235 N_("clear Sieve library path"),
236 mu_c_string, NULL, cli_clear_library_path },
237 { "clearpath", 0, NULL, MU_OPTION_ALIAS },
238 MU_OPTION_END
239 };
240
241 struct mu_cli_capa mu_cli_capa_sieve = {
242 "sieve",
243 sieve_option,
244 mu_sieve_param,
245 NULL, NULL
246 };
......