Commit dc62b399 dc62b3998f0fe8ce0f131e269b130831093264fb by Sergey Poznyakoff

Improve configuration file handling.

* include/mailutils/cfg.h (mu_cfg_parse_hints):
Rename site_rcfile to site_file, custom_rcfile to custom_file.
Remove append_tree and data fields.
(MU_PARSE_CONFIG_GLOBAL,MU_CFG_PARSE_PROGRAM): Remove.
(MU_PARSE_CONFIG_VERBOSE): Rename to MU_CF_VERBOSE.
(MU_PARSE_CONFIG_DUMP): Rename to MU_CF_DUMP.
(MU_CFG_FMT_LOCUS): Rename to MU_CF_FMT_LOCUS.
(MU_CFG_FMT_VALUE_ONLY): Rename to MU_CF_FMT_VALUE_ONLY.
(MU_CFG_FMT_PARAM_PATH): Rename to MU_CF_FMT_PARAM_PATH.

(MU_CFG_COMPATIBILITY,MU_CFG_DEPRECATED): Remove.
(mu_parse_config, mu_get_config): Remove deprecated functions.

* libmailutils/cli/cli.c (mu_general_help_text): New global.
(app_data): New struct.
(init_options): Construct configuration option group depending on
which configuration files are in use.
(mu_cli_ext): Don't use per-user configuration files for servers.
Pass pointer to app_data structure as po.po_data
(mu_cli): Set MU_CFHINT_PER_USER_FILE flag by default.

* mail/testsuite/lib/mail.exp: Rewrite invocation of the mu_init command.
* include/mailutils/cli.h (mu_cli_setup) <server>: New field.

* comsat/comsat.c (cli): Mark as server.
(main): Bugfix: pass pointer to server to mu_cli.
* imap4d/imap4d.c (cli): Mark as server.
* pop3d/pop3d.c: Likewise.

* comsat/tests/testsuite.at: Use the --no-site-config
option.
* imap4d/tests/testsuite.at: Likewise.

* libmailutils/cfg/driver.c: Update.
* libmailutils/cfg/format.c: Update.
* libmailutils/cfg/lexer.l: Update.
* libmailutils/cfg/parser.y: Update.
* mu/acl.c: Update.

* pop3d/testsuite/lib/pop3d.exp: Likewise.

* mu/mu.c: Don't read configuration files.
* mu/query.c: Fix args_doc

* testsuite/lib/mailutils.exp (mu_init): Change option handling.
Set --no-config option by default.
1 parent b4c787e6
...@@ -194,11 +194,11 @@ struct mu_cfg_param comsat_cfg_param[] = { ...@@ -194,11 +194,11 @@ struct mu_cfg_param comsat_cfg_param[] = {
194 static char const *alt_args[] = { N_("--test MBOX-URL MSG-QID"), NULL }; 194 static char const *alt_args[] = { N_("--test MBOX-URL MSG-QID"), NULL };
195 195
196 static struct mu_cli_setup cli = { 196 static struct mu_cli_setup cli = {
197 options, 197 .optv = options,
198 comsat_cfg_param, 198 .cfg =comsat_cfg_param,
199 N_("GNU comsatd -- notify users about incoming mail"), 199 .prog_doc = N_("GNU comsatd -- notify users about incoming mail"),
200 "", 200 .prog_alt_args = alt_args,
201 alt_args, 201 .server = 1
202 }; 202 };
203 203
204 static char *capa[] = { 204 static char *capa[] = {
...@@ -568,7 +568,7 @@ main (int argc, char **argv) ...@@ -568,7 +568,7 @@ main (int argc, char **argv)
568 568
569 save_argv = argv; 569 save_argv = argv;
570 570
571 mu_cli (argc, argv, &cli, capa, NULL, &argc, &argv); 571 mu_cli (argc, argv, &cli, capa, server, &argc, &argv);
572 572
573 if (test_mode) 573 if (test_mode)
574 { 574 {
......
...@@ -22,7 +22,7 @@ m4_pushdef([BIFF_MBOX],[`pwd`/mailbox]) ...@@ -22,7 +22,7 @@ m4_pushdef([BIFF_MBOX],[`pwd`/mailbox])
22 22
23 dnl ------------------------------------------------------------ 23 dnl ------------------------------------------------------------
24 dnl comsatcmd 24 dnl comsatcmd
25 m4_pushdef([comsatcmd],[comsatd --no-site --no-user --file ./biff.rc dnl 25 m4_pushdef([comsatcmd],[comsatd --no-site-config --file ./biff.rc dnl
26 --set logging.syslog=no --test]) 26 --set logging.syslog=no --test])
27 27
28 dnl ------------------------------------------------------------ 28 dnl ------------------------------------------------------------
......
...@@ -449,9 +449,10 @@ static struct mu_cfg_param imap4d_cfg_param[] = { ...@@ -449,9 +449,10 @@ static struct mu_cfg_param imap4d_cfg_param[] = {
449 }; 449 };
450 450
451 struct mu_cli_setup cli = { 451 struct mu_cli_setup cli = {
452 options, 452 .optv = options,
453 imap4d_cfg_param, 453 .cfg = imap4d_cfg_param,
454 N_("GNU imap4d -- the IMAP4D daemon.") 454 .prog_doc = N_("GNU imap4d -- the IMAP4D daemon."),
455 .server = 1
455 }; 456 };
456 457
457 int 458 int
...@@ -659,7 +660,7 @@ get_client_address (int fd, struct sockaddr_in *pcs) ...@@ -659,7 +660,7 @@ get_client_address (int fd, struct sockaddr_in *pcs)
659 } 660 }
660 661
661 static int 662 static int
662 set_strerr_flt () 663 set_strerr_flt (void)
663 { 664 {
664 mu_stream_t flt, trans[2]; 665 mu_stream_t flt, trans[2];
665 int rc; 666 int rc;
...@@ -700,7 +701,7 @@ set_strerr_flt () ...@@ -700,7 +701,7 @@ set_strerr_flt ()
700 } 701 }
701 702
702 static void 703 static void
703 clr_strerr_flt () 704 clr_strerr_flt (void)
704 { 705 {
705 mu_stream_t flt, trans[2]; 706 mu_stream_t flt, trans[2];
706 int rc; 707 int rc;
......
...@@ -20,7 +20,6 @@ m4_define([IMAP4D_HOMEDIR]) ...@@ -20,7 +20,6 @@ m4_define([IMAP4D_HOMEDIR])
20 20
21 m4_define([IMAP4D_DEFAULT_OPTIONS],[dnl 21 m4_define([IMAP4D_DEFAULT_OPTIONS],[dnl
22 --no-site-config dnl 22 --no-site-config dnl
23 --no-user-config dnl
24 --test dnl 23 --test dnl
25 --set logging.syslog=0 dnl 24 --set logging.syslog=0 dnl
26 --set logging.severity=notice dnl 25 --set logging.severity=notice dnl
......
...@@ -72,17 +72,43 @@ struct mu_cfg_node ...@@ -72,17 +72,43 @@ struct mu_cfg_node
72 mu_list_t nodes; /* a list of mu_cfg_node_t */ 72 mu_list_t nodes; /* a list of mu_cfg_node_t */
73 struct mu_cfg_node *parent; /* parent node */ 73 struct mu_cfg_node *parent; /* parent node */
74 }; 74 };
75 75
76 struct mu_cfg_parse_hints 76 struct mu_cfg_parse_hints
77 { 77 {
78 int flags; 78 int flags;
79 char *site_rcfile; 79 char *site_file;
80 char *custom_rcfile; 80 char *custom_file;
81 char *program; 81 char *program;
82 struct mu_cfg_tree *append_tree;
83 void *data;
84 }; 82 };
85 83
84 /* Bit constants for the flags field of struct mu_cfg_parse_hints */
85 /* Parse site-wide configuration file hints.site_file */
86 #define MU_CFHINT_SITE_FILE 0x0001
87 /* Parse custom configuration file hints.custom_file */
88 #define MU_CFHINT_CUSTOM_FILE 0x0002
89 /* The hints.program field is set. The "program PROGNAME" section
90 will be processed, if PROGNAME is the same as hints.program.
91 If include statement is used with the directory name DIR as its
92 argument, the file DIR/PROGNAME will be looked up and read in,
93 if it exists. */
94 #define MU_CFHINT_PROGRAM 0x0004
95
96 /* If MU_CFHINT_PROGRAM is set, look for the file ~/.PROGNAME after parsing
97 site-wide configuration */
98 #define MU_CFHINT_PER_USER_FILE 0x0008
99
100 /* Verbosely log files being processed */
101 #define MU_CF_VERBOSE 0x0010
102 /* Dump the pare tree on stderr */
103 #define MU_CF_DUMP 0x0020
104
105 /* Format location of the statement */
106 #define MU_CF_FMT_LOCUS 0x0100
107 /* Print only value */
108 #define MU_CF_FMT_VALUE_ONLY 0x0200
109 /* Print full parameter path */
110 #define MU_CF_FMT_PARAM_PATH 0x0400
111
86 struct mu_cfg_tree 112 struct mu_cfg_tree
87 { 113 {
88 mu_list_t nodes; /* a list of mu_cfg_node_t */ 114 mu_list_t nodes; /* a list of mu_cfg_node_t */
...@@ -140,9 +166,6 @@ struct mu_cfg_param ...@@ -140,9 +166,6 @@ struct mu_cfg_param
140 const char *argname; 166 const char *argname;
141 }; 167 };
142 168
143 #define MU_TARGET_REF(f) &f, 0
144 #define MU_TARGET_OFF(s,f) NULL, mu_offsetof(s,f)
145
146 enum mu_cfg_section_stage 169 enum mu_cfg_section_stage
147 { 170 {
148 mu_cfg_section_start, 171 mu_cfg_section_start,
...@@ -230,29 +253,7 @@ int mu_config_register_plain_section (const char *parent_path, ...@@ -230,29 +253,7 @@ int mu_config_register_plain_section (const char *parent_path,
230 const char *ident, 253 const char *ident,
231 struct mu_cfg_param *params); 254 struct mu_cfg_param *params);
232 255
233 #define MU_PARSE_CONFIG_GLOBAL 0x001
234 #define MU_PARSE_CONFIG_VERBOSE 0x002
235 #define MU_PARSE_CONFIG_DUMP 0x004
236 #define MU_PARSE_CONFIG_PLAIN 0x008
237 #define MU_CFG_PARSE_SITE_RCFILE 0x010
238 #define MU_CFG_PARSE_CUSTOM_RCFILE 0x020
239 #define MU_CFG_PARSE_PROGRAM 0x040
240 #define MU_CFG_FMT_LOCUS 0x080
241 #define MU_CFG_FMT_VALUE_ONLY 0x100
242 #define MU_CFG_FMT_PARAM_PATH 0x200
243 #define MU_PARSE_CONFIG_LINT 0x400
244 #define MU_CFG_APPEND_TREE 0x800
245 256
246 #ifdef MU_CFG_COMPATIBILITY
247 # define MU_CFG_DEPRECATED
248 #else
249 # define MU_CFG_DEPRECATED MU_DEPRECATED
250 #endif
251
252 int mu_parse_config (const char *file, const char *progname,
253 struct mu_cfg_param *progparam, int flags,
254 void *target_ptr) MU_CFG_DEPRECATED;
255
256 extern int mu_cfg_parser_verbose; 257 extern int mu_cfg_parser_verbose;
257 extern size_t mu_cfg_error_count; 258 extern size_t mu_cfg_error_count;
258 259
...@@ -279,10 +280,6 @@ int mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, ...@@ -279,10 +280,6 @@ int mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file,
279 int flags); 280 int flags);
280 281
281 282
282 int mu_get_config (const char *file, const char *progname,
283 struct mu_cfg_param *progparam, int flags,
284 void *target_ptr) MU_CFG_DEPRECATED;
285
286 int mu_cfg_tree_create (struct mu_cfg_tree **ptree); 283 int mu_cfg_tree_create (struct mu_cfg_tree **ptree);
287 mu_cfg_node_t *mu_cfg_tree_create_node (struct mu_cfg_tree *tree, 284 mu_cfg_node_t *mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
288 enum mu_cfg_node_type type, 285 enum mu_cfg_node_type type,
......
...@@ -50,11 +50,14 @@ struct mu_cli_setup ...@@ -50,11 +50,14 @@ struct mu_cli_setup
50 int ex_usage; /* If not 0, exit code on usage errors */ 50 int ex_usage; /* If not 0, exit code on usage errors */
51 int ex_config; /* If not 0, exit code on configuration 51 int ex_config; /* If not 0, exit code on configuration
52 errors */ 52 errors */
53 int inorder; 53 int inorder:1; /* Don't permute options and arguments */
54 int server:1; /* This is a server: don't read per-user
55 configuration files */
54 void (*prog_doc_hook) (mu_stream_t); 56 void (*prog_doc_hook) (mu_stream_t);
55 }; 57 };
56 58
57 extern const char mu_version_copyright[]; 59 extern const char mu_version_copyright[];
60 extern const char mu_general_help_text[];
58 61
59 void mu_version_hook (struct mu_parseopt *po, mu_stream_t stream); 62 void mu_version_hook (struct mu_parseopt *po, mu_stream_t stream);
60 void mu_cli (int argc, char **argv, struct mu_cli_setup *setup, 63 void mu_cli (int argc, char **argv, struct mu_cli_setup *setup,
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
27 #include <ctype.h> 27 #include <ctype.h>
28 #include <mailutils/argcv.h> 28 #include <mailutils/argcv.h>
29 #include <mailutils/nls.h> 29 #include <mailutils/nls.h>
30 #define MU_CFG_COMPATIBILITY /* This source uses deprecated cfg interfaces */
31 #include <mailutils/cfg.h> 30 #include <mailutils/cfg.h>
32 #include <mailutils/errno.h> 31 #include <mailutils/errno.h>
33 #include <mailutils/error.h> 32 #include <mailutils/error.h>
...@@ -466,14 +465,14 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree, ...@@ -466,14 +465,14 @@ mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree,
466 struct mu_cfg_cont *cont; 465 struct mu_cfg_cont *cont;
467 if (!parse_tree) 466 if (!parse_tree)
468 return 0; 467 return 0;
469 if (hints && (hints->flags & MU_PARSE_CONFIG_DUMP)) 468 if (hints && (hints->flags & MU_CF_DUMP))
470 { 469 {
471 int yes = 1; 470 int yes = 1;
472 mu_stream_t stream; 471 mu_stream_t stream;
473 472
474 mu_stdio_stream_create (&stream, MU_STDERR_FD, 0); 473 mu_stdio_stream_create (&stream, MU_STDERR_FD, 0);
475 mu_stream_ioctl (stream, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes); 474 mu_stream_ioctl (stream, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
476 mu_cfg_format_parse_tree (stream, parse_tree, MU_CFG_FMT_LOCUS); 475 mu_cfg_format_parse_tree (stream, parse_tree, MU_CF_FMT_LOCUS);
477 mu_stream_destroy (&stream); 476 mu_stream_destroy (&stream);
478 } 477 }
479 478
...@@ -492,29 +491,6 @@ mu_format_config_tree (mu_stream_t stream, struct mu_cfg_param *progparam) ...@@ -492,29 +491,6 @@ mu_format_config_tree (mu_stream_t stream, struct mu_cfg_param *progparam)
492 mu_config_destroy_container (&cont); 491 mu_config_destroy_container (&cont);
493 } 492 }
494 493
495 int
496 mu_parse_config (const char *file, const char *progname,
497 struct mu_cfg_param *progparam, int flags,
498 void *target_ptr)
499 {
500 int rc;
501 char *full_name = mu_tilde_expansion (file, MU_HIERARCHY_DELIMITER, NULL);
502 if (full_name)
503 {
504 if (access (full_name, R_OK) == 0)
505 {
506 rc = mu_get_config (full_name, progname, progparam, flags,
507 target_ptr);
508 }
509 else
510 rc = ENOENT;
511 free (full_name);
512 }
513 else
514 rc = ENOMEM;
515 return rc;
516 }
517
518 static const char * 494 static const char *
519 _first_value_ptr (mu_config_value_t *val) 495 _first_value_ptr (mu_config_value_t *val)
520 { 496 {
......
...@@ -152,7 +152,7 @@ format_node (const mu_cfg_node_t *node, void *data) ...@@ -152,7 +152,7 @@ format_node (const mu_cfg_node_t *node, void *data)
152 { 152 {
153 struct tree_print *tp = data; 153 struct tree_print *tp = data;
154 154
155 if ((tp->flags & MU_CFG_FMT_LOCUS) && node->locus.mu_file) 155 if ((tp->flags & MU_CF_FMT_LOCUS) && node->locus.mu_file)
156 mu_stream_printf (tp->stream, "# %lu \"%s\"\n", 156 mu_stream_printf (tp->stream, "# %lu \"%s\"\n",
157 (unsigned long) node->locus.mu_line, 157 (unsigned long) node->locus.mu_line,
158 node->locus.mu_file); 158 node->locus.mu_file);
...@@ -165,7 +165,7 @@ format_node (const mu_cfg_node_t *node, void *data) ...@@ -165,7 +165,7 @@ format_node (const mu_cfg_node_t *node, void *data)
165 break; 165 break;
166 166
167 case mu_cfg_node_statement: 167 case mu_cfg_node_statement:
168 if (tp->flags & MU_CFG_FMT_PARAM_PATH) 168 if (tp->flags & MU_CF_FMT_PARAM_PATH)
169 return MU_CFG_ITER_OK; 169 return MU_CFG_ITER_OK;
170 else 170 else
171 { 171 {
...@@ -181,9 +181,9 @@ format_node (const mu_cfg_node_t *node, void *data) ...@@ -181,9 +181,9 @@ format_node (const mu_cfg_node_t *node, void *data)
181 break; 181 break;
182 182
183 case mu_cfg_node_param: 183 case mu_cfg_node_param:
184 if (tp->flags & MU_CFG_FMT_VALUE_ONLY) 184 if (tp->flags & MU_CF_FMT_VALUE_ONLY)
185 format_value (tp, node->label); 185 format_value (tp, node->label);
186 else if (tp->flags & MU_CFG_FMT_PARAM_PATH) 186 else if (tp->flags & MU_CF_FMT_PARAM_PATH)
187 { 187 {
188 format_path (tp, node, ':'); 188 format_path (tp, node, ':');
189 mu_stream_write (tp->stream, " ", 1, NULL); 189 mu_stream_write (tp->stream, " ", 1, NULL);
...@@ -209,7 +209,7 @@ static int ...@@ -209,7 +209,7 @@ static int
209 format_node_end (const mu_cfg_node_t *node, void *data) 209 format_node_end (const mu_cfg_node_t *node, void *data)
210 { 210 {
211 struct tree_print *tp = data; 211 struct tree_print *tp = data;
212 if (!(tp->flags & MU_CFG_FMT_PARAM_PATH)) 212 if (!(tp->flags & MU_CF_FMT_PARAM_PATH))
213 { 213 {
214 tp->level--; 214 tp->level--;
215 format_level (tp->stream, tp->level); 215 format_level (tp->stream, tp->level);
...@@ -242,7 +242,7 @@ mu_cfg_format_node (mu_stream_t stream, const mu_cfg_node_t *node, int flags) ...@@ -242,7 +242,7 @@ mu_cfg_format_node (mu_stream_t stream, const mu_cfg_node_t *node, int flags)
242 struct tree_print t; 242 struct tree_print t;
243 243
244 if (node->type == mu_cfg_node_statement) 244 if (node->type == mu_cfg_node_statement)
245 flags &= ~MU_CFG_FMT_VALUE_ONLY; 245 flags &= ~MU_CF_FMT_VALUE_ONLY;
246 t.flags = flags; 246 t.flags = flags;
247 t.level = 0; 247 t.level = 0;
248 t.stream = stream; 248 t.stream = stream;
......
...@@ -330,14 +330,14 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags) ...@@ -330,14 +330,14 @@ 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) 333 if (flags & MU_CF_VERBOSE)
334 mu_diag_output (MU_DIAG_INFO, _("opening configuration file %s"), 334 mu_diag_output (MU_DIAG_INFO, _("opening configuration file %s"),
335 full_name); 335 full_name);
336 if (stat (full_name, &st)) 336 if (stat (full_name, &st))
337 { 337 {
338 if (errno != ENOENT) 338 if (errno != ENOENT)
339 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) 340 else if (flags & MU_CF_VERBOSE)
341 mu_diag_output (MU_DIAG_INFO, _("configuration file %s doesn't exist"), 341 mu_diag_output (MU_DIAG_INFO, _("configuration file %s doesn't exist"),
342 full_name); 342 full_name);
343 free (full_name); 343 free (full_name);
...@@ -345,7 +345,7 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags) ...@@ -345,7 +345,7 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags)
345 } 345 }
346 else if (!S_ISREG (st.st_mode)) 346 else if (!S_ISREG (st.st_mode))
347 { 347 {
348 if (flags & MU_PARSE_CONFIG_VERBOSE) 348 if (flags & MU_CF_VERBOSE)
349 mu_diag_output (MU_DIAG_INFO, _("%s: not a regular file"), full_name); 349 mu_diag_output (MU_DIAG_INFO, _("%s: not a regular file"), full_name);
350 free (full_name); 350 free (full_name);
351 return ENOENT; 351 return ENOENT;
...@@ -360,7 +360,7 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags) ...@@ -360,7 +360,7 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags)
360 return errno; 360 return errno;
361 } 361 }
362 362
363 if (flags & MU_PARSE_CONFIG_VERBOSE) 363 if (flags & MU_CF_VERBOSE)
364 mu_diag_output (MU_DIAG_INFO, _("parsing file `%s'"), full_name); 364 mu_diag_output (MU_DIAG_INFO, _("parsing file `%s'"), full_name);
365 365
366 mu_cfg_set_lex_debug (); 366 mu_cfg_set_lex_debug ();
...@@ -379,37 +379,13 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags) ...@@ -379,37 +379,13 @@ mu_cfg_parse_file (mu_cfg_tree_t **return_tree, const char *file, int flags)
379 yyrestart (fp); 379 yyrestart (fp);
380 rc = mu_cfg_parse (return_tree); 380 rc = mu_cfg_parse (return_tree);
381 fclose (fp); 381 fclose (fp);
382 if (flags & MU_PARSE_CONFIG_VERBOSE) 382 if (flags & MU_CF_VERBOSE)
383 mu_diag_output (MU_DIAG_INFO, _("finished parsing file `%s'"), 383 mu_diag_output (MU_DIAG_INFO, _("finished parsing file `%s'"),
384 mu_cfg_locus.mu_file); 384 mu_cfg_locus.mu_file);
385 385
386 return rc == 0 ? 0 : MU_ERR_FAILURE; 386 return rc == 0 ? 0 : MU_ERR_FAILURE;
387 } 387 }
388 388
389 /* FIXME: Deprecated interface */
390 int
391 mu_get_config (const char *file, const char *progname,
392 struct mu_cfg_param *progparam, int flags, void *target_ptr)
393 {
394 mu_cfg_tree_t *parse_tree;
395 int rc = mu_cfg_parse_file (&parse_tree, file, flags);
396 if (rc == 0)
397 {
398 struct mu_cfg_parse_hints hints;
399
400 hints.flags = flags | MU_CFG_PARSE_PROGRAM;
401 hints.program = (char*)progname;
402
403 rc = mu_cfg_tree_postprocess (parse_tree, &hints);
404 if (rc == 0)
405 rc = mu_cfg_tree_reduce (parse_tree, &hints, progparam, target_ptr);
406 mu_cfg_destroy_tree (&parse_tree);
407 }
408
409 return rc == 0 ? 0 : MU_ERR_FAILURE;
410 }
411
412
413 mu_opool_t 389 mu_opool_t
414 mu_cfg_lexer_pool () 390 mu_cfg_lexer_pool ()
415 { 391 {
......
...@@ -501,8 +501,7 @@ do_include (const char *name, struct mu_cfg_parse_hints *hints, ...@@ -501,8 +501,7 @@ do_include (const char *name, struct mu_cfg_parse_hints *hints,
501 501
502 if (S_ISDIR (sb.st_mode)) 502 if (S_ISDIR (sb.st_mode))
503 { 503 {
504 if ((hints->flags & (MU_PARSE_CONFIG_GLOBAL|MU_CFG_PARSE_PROGRAM)) == 504 if (hints->flags & MU_CFHINT_PROGRAM)
505 (MU_PARSE_CONFIG_GLOBAL|MU_CFG_PARSE_PROGRAM))
506 { 505 {
507 char *file = mu_make_file_name (name, hints->program); 506 char *file = mu_make_file_name (name, hints->program);
508 rc = mu_cfg_parse_file (&tree, file, hints->flags); 507 rc = mu_cfg_parse_file (&tree, file, hints->flags);
...@@ -515,7 +514,7 @@ do_include (const char *name, struct mu_cfg_parse_hints *hints, ...@@ -515,7 +514,7 @@ do_include (const char *name, struct mu_cfg_parse_hints *hints,
515 if (rc == 0 && tree) 514 if (rc == 0 && tree)
516 { 515 {
517 struct mu_cfg_parse_hints xhints = *hints; 516 struct mu_cfg_parse_hints xhints = *hints;
518 xhints.flags &= ~MU_PARSE_CONFIG_GLOBAL; 517 xhints.flags &= ~MU_CFHINT_PROGRAM;
519 mu_cfg_tree_postprocess (tree, &xhints); 518 mu_cfg_tree_postprocess (tree, &xhints);
520 } 519 }
521 } 520 }
...@@ -538,8 +537,7 @@ do_include (const char *name, struct mu_cfg_parse_hints *hints, ...@@ -538,8 +537,7 @@ do_include (const char *name, struct mu_cfg_parse_hints *hints,
538 } 537 }
539 538
540 int 539 int
541 mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, 540 mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, struct mu_cfg_parse_hints *hints)
542 struct mu_cfg_parse_hints *hints)
543 { 541 {
544 int rc; 542 int rc;
545 mu_iterator_t itr; 543 mu_iterator_t itr;
...@@ -558,13 +556,12 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, ...@@ -558,13 +556,12 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree,
558 556
559 if (node->type == mu_cfg_node_statement) 557 if (node->type == mu_cfg_node_statement)
560 { 558 {
561 if ((hints->flags & MU_PARSE_CONFIG_GLOBAL) && 559 if ((hints->flags & MU_CFHINT_PROGRAM) &&
562 strcmp (node->tag, "program") == 0) 560 strcmp (node->tag, "program") == 0)
563 { 561 {
564 if (node->label->type == MU_CFG_STRING) 562 if (node->label->type == MU_CFG_STRING)
565 { 563 {
566 if ((hints->flags & MU_CFG_PARSE_PROGRAM) 564 if (strcmp (node->label->v.string, hints->program) == 0)
567 && strcmp (node->label->v.string, hints->program) == 0)
568 { 565 {
569 /* Reset the parent node */ 566 /* Reset the parent node */
570 mu_list_foreach (node->nodes, _node_set_parent, 567 mu_list_foreach (node->nodes, _node_set_parent,
...@@ -1527,10 +1524,11 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints) ...@@ -1527,10 +1524,11 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints)
1527 { 1524 {
1528 int rc = 0; 1525 int rc = 0;
1529 mu_cfg_tree_t *tree = NULL, *tmp; 1526 mu_cfg_tree_t *tree = NULL, *tmp;
1527 struct mu_cfg_parse_hints xhints;
1530 1528
1531 if ((hints->flags & MU_CFG_PARSE_SITE_RCFILE) && hints->site_rcfile) 1529 if ((hints->flags & MU_CFHINT_SITE_FILE) && hints->site_file)
1532 { 1530 {
1533 rc = mu_cfg_parse_file (&tmp, hints->site_rcfile, hints->flags); 1531 rc = mu_cfg_parse_file (&tmp, hints->site_file, hints->flags);
1534 1532
1535 if (rc == ENOMEM) 1533 if (rc == ENOMEM)
1536 { 1534 {
...@@ -1539,14 +1537,16 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints) ...@@ -1539,14 +1537,16 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints)
1539 } 1537 }
1540 else if (rc == 0) 1538 else if (rc == 0)
1541 { 1539 {
1542 struct mu_cfg_parse_hints xhints = *hints; 1540 mu_cfg_tree_postprocess (tmp, hints);
1543 xhints.flags |= MU_PARSE_CONFIG_GLOBAL;
1544 mu_cfg_tree_postprocess (tmp, &xhints);
1545 mu_cfg_tree_union (&tree, &tmp); 1541 mu_cfg_tree_union (&tree, &tmp);
1546 } 1542 }
1547 } 1543 }
1544
1545 xhints = *hints;
1546 xhints.flags &= ~MU_CFHINT_PROGRAM;
1548 1547
1549 if ((hints->flags & MU_CFG_PARSE_PROGRAM) && hints->program) 1548 if ((hints->flags & MU_CFHINT_PER_USER_FILE)
1549 && (hints->flags & MU_CFHINT_PROGRAM))
1550 { 1550 {
1551 size_t size = 3 + strlen (hints->program) + 1; 1551 size_t size = 3 + strlen (hints->program) + 1;
1552 char *file_name = malloc (size); 1552 char *file_name = malloc (size);
...@@ -1555,7 +1555,7 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints) ...@@ -1555,7 +1555,7 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints)
1555 strcpy (file_name, "~/."); 1555 strcpy (file_name, "~/.");
1556 strcat (file_name, hints->program); 1556 strcat (file_name, hints->program);
1557 1557
1558 rc = mu_cfg_parse_file (&tmp, file_name, hints->flags); 1558 rc = mu_cfg_parse_file (&tmp, file_name, xhints.flags);
1559 if (rc == ENOMEM) 1559 if (rc == ENOMEM)
1560 { 1560 {
1561 mu_error ("%s", mu_strerror (rc)); 1561 mu_error ("%s", mu_strerror (rc));
...@@ -1564,7 +1564,7 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints) ...@@ -1564,7 +1564,7 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints)
1564 } 1564 }
1565 else if (rc == 0) 1565 else if (rc == 0)
1566 { 1566 {
1567 mu_cfg_tree_postprocess (tmp, hints); 1567 mu_cfg_tree_postprocess (tmp, &xhints);
1568 mu_cfg_tree_union (&tree, &tmp); 1568 mu_cfg_tree_union (&tree, &tmp);
1569 } 1569 }
1570 else if (rc == ENOENT) 1570 else if (rc == ENOENT)
...@@ -1573,26 +1573,23 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints) ...@@ -1573,26 +1573,23 @@ mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints)
1573 } 1573 }
1574 } 1574 }
1575 1575
1576 if ((hints->flags & MU_CFG_PARSE_CUSTOM_RCFILE) && hints->custom_rcfile) 1576 if ((hints->flags & MU_CFHINT_CUSTOM_FILE) && hints->custom_file)
1577 { 1577 {
1578 rc = mu_cfg_parse_file (&tmp, hints->custom_rcfile, hints->flags); 1578 rc = mu_cfg_parse_file (&tmp, hints->custom_file, xhints.flags);
1579 if (rc) 1579 if (rc)
1580 { 1580 {
1581 mu_error (_("errors parsing file %s: %s"), hints->custom_rcfile, 1581 mu_error (_("errors parsing file %s: %s"), hints->custom_file,
1582 mu_strerror (rc)); 1582 mu_strerror (rc));
1583 mu_cfg_destroy_tree (&tree); 1583 mu_cfg_destroy_tree (&tree);
1584 return rc; 1584 return rc;
1585 } 1585 }
1586 else 1586 else
1587 { 1587 {
1588 mu_cfg_tree_postprocess (tmp, hints); 1588 mu_cfg_tree_postprocess (tmp, &xhints);
1589 mu_cfg_tree_union (&tree, &tmp); 1589 mu_cfg_tree_union (&tree, &tmp);
1590 } 1590 }
1591 } 1591 }
1592 1592
1593 if (hints->flags & MU_CFG_APPEND_TREE)
1594 mu_cfg_tree_union (&tree, &hints->append_tree);
1595
1596 *ptree = tree; 1593 *ptree = tree;
1597 return rc; 1594 return rc;
1598 } 1595 }
......
...@@ -76,23 +76,29 @@ There is NO WARRANTY, to the extent permitted by law.\n\ ...@@ -76,23 +76,29 @@ There is NO WARRANTY, to the extent permitted by law.\n\
76 ")); 76 "));
77 } 77 }
78 78
79 static char gnu_general_help_url[] = 79 const char mu_general_help_text[] =
80 N_("General help using GNU software: <http://www.gnu.org/gethelp/>"); 80 N_("General help using GNU software: <http://www.gnu.org/gethelp/>");
81 81
82 struct app_data
83 {
84 struct mu_cli_setup *setup;
85 struct mu_cfg_parse_hints *hints;
86 struct mu_cfg_tree *append_tree;
87 int lint;
88 };
89
82 static void 90 static void
83 extra_help_hook (struct mu_parseopt *po, mu_stream_t stream) 91 extra_help_hook (struct mu_parseopt *po, mu_stream_t stream)
84 { 92 {
85 struct mu_cfg_parse_hints *hints = po->po_data; 93 struct app_data *dp = po->po_data;
86 struct mu_cli_setup *setup = hints->data; 94 mu_stream_printf (stream, "%s\n", gettext (dp->setup->prog_extra_doc));
87 mu_stream_printf (stream, "%s\n", _(setup->prog_extra_doc));
88 } 95 }
89 96
90 static void 97 static void
91 prog_doc_hook (struct mu_parseopt *po, mu_stream_t stream) 98 prog_doc_hook (struct mu_parseopt *po, mu_stream_t stream)
92 { 99 {
93 struct mu_cfg_parse_hints *hints = po->po_data; 100 struct app_data *dp = po->po_data;
94 struct mu_cli_setup *setup = hints->data; 101 dp->setup->prog_doc_hook (stream);
95 setup->prog_doc_hook (stream);
96 } 102 }
97 103
98 static void 104 static void
...@@ -100,87 +106,108 @@ change_progname (struct mu_parseopt *po, struct mu_option *opt, ...@@ -100,87 +106,108 @@ change_progname (struct mu_parseopt *po, struct mu_option *opt,
100 char const *arg) 106 char const *arg)
101 { 107 {
102 po->po_prog_name = mu_strdup (arg); 108 po->po_prog_name = mu_strdup (arg);
109 free (mu_program_name);
110 mu_program_name = mu_strdup (arg);
103 } 111 }
104 112
105 static void 113 static void
106 no_user_config (struct mu_parseopt *po, struct mu_option *opt, 114 no_user_config (struct mu_parseopt *po, struct mu_option *opt,
107 char const *arg) 115 char const *arg)
108 { 116 {
109 struct mu_cfg_parse_hints *hints = po->po_data; 117 struct app_data *dp = po->po_data;
110 hints->flags &= ~MU_CFG_PARSE_PROGRAM; 118 dp->hints->flags &= ~MU_CFHINT_PER_USER_FILE;
111 } 119 }
112 120
113 static void 121 static void
114 no_site_config (struct mu_parseopt *po, struct mu_option *opt, 122 no_site_config (struct mu_parseopt *po, struct mu_option *opt,
115 char const *arg) 123 char const *arg)
116 { 124 {
117 struct mu_cfg_parse_hints *hints = po->po_data; 125 struct app_data *dp = po->po_data;
118 hints->flags &= ~MU_CFG_PARSE_SITE_RCFILE; 126 dp->hints->flags &= ~MU_CFHINT_SITE_FILE;
127 }
128
129 static void
130 no_config (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
131 {
132 struct app_data *dp = po->po_data;
133 dp->hints->flags &= ~(MU_CFHINT_SITE_FILE|MU_CFHINT_PER_USER_FILE);
119 } 134 }
120 135
121 static void 136 static void
122 config_file (struct mu_parseopt *po, struct mu_option *opt, 137 config_file (struct mu_parseopt *po, struct mu_option *opt,
123 char const *arg) 138 char const *arg)
124 { 139 {
125 struct mu_cfg_parse_hints *hints = po->po_data; 140 struct app_data *dp = po->po_data;
126 hints->flags |= MU_CFG_PARSE_CUSTOM_RCFILE; 141 dp->hints->flags = (dp->hints->flags
127 hints->custom_rcfile = mu_strdup (arg); 142 & ~(MU_CFHINT_SITE_FILE|MU_CFHINT_PROGRAM))
143 | MU_CFHINT_CUSTOM_FILE;
144 dp->hints->custom_file = mu_strdup (arg);
128 } 145 }
129 146
130 static void 147 static void
131 config_verbose (struct mu_parseopt *po, struct mu_option *opt, 148 config_verbose (struct mu_parseopt *po, struct mu_option *opt,
132 char const *arg) 149 char const *arg)
133 { 150 {
134 struct mu_cfg_parse_hints *hints = po->po_data; 151 struct app_data *dp = po->po_data;
135 if (hints->flags & MU_PARSE_CONFIG_VERBOSE) 152 if (dp->hints->flags & MU_CF_VERBOSE)
136 hints->flags |= MU_PARSE_CONFIG_DUMP; 153 dp->hints->flags |= MU_CF_DUMP;
137 else 154 else
138 hints->flags |= MU_PARSE_CONFIG_VERBOSE; 155 dp->hints->flags |= MU_CF_VERBOSE;
139 } 156 }
140 157
141 static void 158 static void
142 config_lint (struct mu_parseopt *po, struct mu_option *opt, 159 config_lint (struct mu_parseopt *po, struct mu_option *opt,
143 char const *arg) 160 char const *arg)
144 { 161 {
145 struct mu_cfg_parse_hints *hints = po->po_data; 162 struct app_data *dp = po->po_data;
146 hints->flags |= MU_PARSE_CONFIG_VERBOSE|MU_PARSE_CONFIG_LINT; 163 dp->lint = 1;
164 dp->hints->flags |= MU_CF_VERBOSE;
147 } 165 }
148 166
149 static void 167 static void
150 param_set (struct mu_parseopt *po, struct mu_option *opt, char const *arg) 168 param_set (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
151 { 169 {
152 struct mu_cfg_parse_hints *hints = po->po_data; 170 struct app_data *dp = po->po_data;
153 mu_cfg_node_t *node; 171 mu_cfg_node_t *node;
154 int rc = mu_cfg_create_subtree (arg, &node); 172 int rc = mu_cfg_create_subtree (arg, &node);
155 if (rc) 173 if (rc)
156 mu_parseopt_error (po, "%s: cannot create node: %s", 174 mu_parseopt_error (po, "%s: cannot create node: %s",
157 arg, mu_strerror (rc)); 175 arg, mu_strerror (rc));
158 if (!(hints->flags & MU_CFG_APPEND_TREE)) 176 if (!dp->append_tree)
159 { 177 {
160 mu_cfg_tree_create (&hints->append_tree); 178 mu_cfg_tree_create (&dp->append_tree);
161 hints->flags |= MU_CFG_APPEND_TREE;
162 } 179 }
163 mu_cfg_tree_add_node (hints->append_tree, node); 180 mu_cfg_tree_add_node (dp->append_tree, node);
164 } 181 }
165 182
166 struct mu_option mu_common_options[] = { 183 struct mu_option mu_common_options[] = {
167 MU_OPTION_GROUP(N_("Common options")), 184 /* MU_OPTION_GROUP(N_("Common options")),*/
168 { "program-name", 0, N_("NAME"), MU_OPTION_IMMEDIATE|MU_OPTION_HIDDEN, 185 { "program-name", 0, N_("NAME"), MU_OPTION_IMMEDIATE|MU_OPTION_HIDDEN,
169 N_("set program name"), 186 N_("set program name"),
170 mu_c_string, NULL, change_progname }, 187 mu_c_string, NULL, change_progname },
188 MU_OPTION_END
189 };
190
191 struct mu_option mu_config_option_header =
192 MU_OPTION_GROUP (N_("Configuration handling"));
171 193
172 { "no-user-config", 0, NULL, MU_OPTION_IMMEDIATE, 194 struct mu_option mu_site_config_options[] = {
173 N_("do not load user configuration file"),
174 mu_c_string, NULL, no_user_config },
175 { "no-user-rcfile", 0, NULL, MU_OPTION_ALIAS },
176
177 { "no-site-config", 0, NULL, MU_OPTION_IMMEDIATE, 195 { "no-site-config", 0, NULL, MU_OPTION_IMMEDIATE,
178 N_("do not load site-wide configuration file"), 196 N_("do not load site-wide configuration file"),
179 mu_c_string, NULL, no_site_config }, 197 mu_c_string, NULL, no_site_config },
180 { "no-site-rcfile", 0, NULL, MU_OPTION_ALIAS }, 198 { "no-site-rcfile", 0, NULL, MU_OPTION_ALIAS },
199 MU_OPTION_END
200 };
201
202 struct mu_option mu_no_config_option = {
203 "no-config", 0, NULL, MU_OPTION_IMMEDIATE,
204 N_("do not load site and user configuration files"),
205 mu_c_string, NULL, no_config
206 };
181 207
208 struct mu_option mu_config_options[] = {
182 { "config-file", 0, N_("FILE"), MU_OPTION_IMMEDIATE, 209 { "config-file", 0, N_("FILE"), MU_OPTION_IMMEDIATE,
183 N_("load this configuration file"), 210 N_("load this configuration file; implies --no-config"),
184 mu_c_string, NULL, config_file }, 211 mu_c_string, NULL, config_file },
185 { "rcfile", 0, NULL, MU_OPTION_ALIAS }, 212 { "rcfile", 0, NULL, MU_OPTION_ALIAS },
186 213
...@@ -197,7 +224,15 @@ struct mu_option mu_common_options[] = { ...@@ -197,7 +224,15 @@ struct mu_option mu_common_options[] = {
197 { "set", 0, N_("PARAM=VALUE"), MU_OPTION_IMMEDIATE, 224 { "set", 0, N_("PARAM=VALUE"), MU_OPTION_IMMEDIATE,
198 N_("set configuration parameter"), 225 N_("set configuration parameter"),
199 mu_c_string, NULL, param_set }, 226 mu_c_string, NULL, param_set },
200 227
228 MU_OPTION_END
229 };
230
231 struct mu_option mu_user_config_options[] = {
232 { "no-user-config", 0, NULL, MU_OPTION_IMMEDIATE,
233 N_("do not load user configuration file"),
234 mu_c_string, NULL, no_user_config },
235 { "no-user-rcfile", 0, NULL, MU_OPTION_ALIAS },
201 MU_OPTION_END 236 MU_OPTION_END
202 }; 237 };
203 238
...@@ -213,7 +248,7 @@ static void ...@@ -213,7 +248,7 @@ static void
213 show_config_help (struct mu_parseopt *po, struct mu_option *opt, 248 show_config_help (struct mu_parseopt *po, struct mu_option *opt,
214 char const *unused) 249 char const *unused)
215 { 250 {
216 struct mu_cfg_parse_hints *hints = po->po_data; 251 struct app_data *dp = po->po_data;
217 252
218 char *comment; 253 char *comment;
219 mu_stream_t stream; 254 mu_stream_t stream;
...@@ -253,11 +288,10 @@ show_config_help (struct mu_parseopt *po, struct mu_option *opt, ...@@ -253,11 +288,10 @@ show_config_help (struct mu_parseopt *po, struct mu_option *opt,
253 cont = mu_config_clone_root_container (); 288 cont = mu_config_clone_root_container ();
254 mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL, 289 mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL,
255 dummy_include_param, NULL); 290 dummy_include_param, NULL);
256 if (hints->data) 291 if (dp->setup)
257 { 292 {
258 struct mu_cli_setup *setup = hints->data;
259 mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL, 293 mu_config_container_register_section (&cont, NULL, NULL, NULL, NULL,
260 setup->cfg, NULL); 294 dp->setup->cfg, NULL);
261 } 295 }
262 296
263 mu_cfg_format_container (stream, cont); 297 mu_cfg_format_container (stream, cont);
...@@ -267,11 +301,15 @@ show_config_help (struct mu_parseopt *po, struct mu_option *opt, ...@@ -267,11 +301,15 @@ show_config_help (struct mu_parseopt *po, struct mu_option *opt,
267 exit (0); 301 exit (0);
268 } 302 }
269 303
270 struct mu_option mu_extra_help_options[] = { 304 static struct mu_option mu_extra_help_options[] = {
271 MU_OPTION_GROUP (N_("Informational options")), 305 MU_OPTION_GROUP (N_("Informational options")),
272 { "show-config-options", 0, NULL, MU_OPTION_IMMEDIATE, 306 { "show-config-options", 0, NULL, MU_OPTION_IMMEDIATE,
273 N_("show compilation options"), 307 N_("show compilation options"),
274 mu_c_string, NULL, show_comp_defaults }, 308 mu_c_string, NULL, show_comp_defaults },
309 MU_OPTION_END
310 };
311
312 static struct mu_option mu_config_help_options[] = {
275 { "config-help", 0, NULL, MU_OPTION_IMMEDIATE, 313 { "config-help", 0, NULL, MU_OPTION_IMMEDIATE,
276 N_("show configuration file summary"), 314 N_("show configuration file summary"),
277 mu_c_string, NULL, show_config_help }, 315 mu_c_string, NULL, show_config_help },
...@@ -288,9 +326,38 @@ add_opt_group (void *item, void *data) ...@@ -288,9 +326,38 @@ add_opt_group (void *item, void *data)
288 return 0; 326 return 0;
289 } 327 }
290 328
329 #define CONFIG_ENABLED \
330 (MU_CFHINT_SITE_FILE | MU_CFHINT_CUSTOM_FILE | MU_CFHINT_PER_USER_FILE)
331
332 static void
333 opool_add_option (mu_opool_t pool, struct mu_option *opt)
334 {
335 mu_opool_append (pool, opt, sizeof *opt);
336 }
337
338 static void
339 opool_add_options (mu_opool_t pool, struct mu_option *opt)
340 {
341 while (!MU_OPTION_IS_END (opt))
342 {
343 opool_add_option (pool, opt);
344 opt++;
345 }
346 }
347
348 static struct mu_option *
349 opool_end_option (mu_opool_t pool)
350 {
351 struct mu_option end = MU_OPTION_END;
352 opool_add_option (pool, &end);
353 return mu_opool_finish (pool, NULL);
354 }
355
291 /* Build the list of option groups and configuration sections */ 356 /* Build the list of option groups and configuration sections */
292 static struct mu_option ** 357 static struct mu_option **
293 init_options (char **capa, struct mu_cli_setup *setup, 358 init_options (mu_opool_t pool,
359 char **capa, struct mu_cli_setup *setup,
360 struct mu_cfg_parse_hints const *hints,
294 mu_list_t *ret_comlist) 361 mu_list_t *ret_comlist)
295 { 362 {
296 size_t i, s; 363 size_t i, s;
...@@ -316,8 +383,41 @@ init_options (char **capa, struct mu_cli_setup *setup, ...@@ -316,8 +383,41 @@ init_options (char **capa, struct mu_cli_setup *setup,
316 *ret_comlist = comlist; 383 *ret_comlist = comlist;
317 384
318 mu_list_append (oplist, mu_common_options); 385 mu_list_append (oplist, mu_common_options);
319 mu_list_append (oplist, mu_extra_help_options); 386
387 /* Construct configuration option section */
388 if (hints->flags & CONFIG_ENABLED)
389 {
390 opool_add_option (pool, &mu_config_option_header);
391 opool_add_options (pool, mu_config_options);
392 if (hints->flags & MU_CFHINT_SITE_FILE)
393 {
394 opool_add_options (pool, mu_site_config_options);
395 if (hints->flags & MU_CFHINT_PER_USER_FILE)
396 {
397 opool_add_options (pool, mu_user_config_options);
398 opool_add_option (pool, &mu_no_config_option);
399 }
400 else
401 {
402 struct mu_option opt = mu_no_config_option;
403 opt.opt_flags = MU_OPTION_ALIAS;
404 opool_add_option (pool, &opt);
405 }
406 }
407 else if (hints->flags & MU_CFHINT_PER_USER_FILE)
408 {
409 struct mu_option opt = mu_no_config_option;
410 opool_add_options (pool, mu_user_config_options);
411 opt.opt_flags = MU_OPTION_ALIAS;
412 opool_add_option (pool, &opt);
413 }
414 mu_list_append (oplist, opool_end_option (pool));
415 }
320 416
417 mu_list_append (oplist, mu_extra_help_options);
418 if (hints->flags & CONFIG_ENABLED)
419 mu_list_append (oplist, mu_config_help_options);
420
321 mu_list_count (oplist, &s); 421 mu_list_count (oplist, &s);
322 422
323 po.po_optv = mu_calloc (s + 1, sizeof (po.po_optv[0])); 423 po.po_optv = mu_calloc (s + 1, sizeof (po.po_optv[0]));
...@@ -367,6 +467,8 @@ mu_cli_ext (int argc, char **argv, ...@@ -367,6 +467,8 @@ mu_cli_ext (int argc, char **argv,
367 char const *dfl_args[DFLARGC]; 467 char const *dfl_args[DFLARGC];
368 char **args = NULL; 468 char **args = NULL;
369 size_t argcnt; 469 size_t argcnt;
470 struct app_data appd;
471 mu_opool_t pool;
370 472
371 /* Set up defaults */ 473 /* Set up defaults */
372 if (setup->ex_usage == 0) 474 if (setup->ex_usage == 0)
...@@ -375,10 +477,11 @@ mu_cli_ext (int argc, char **argv, ...@@ -375,10 +477,11 @@ mu_cli_ext (int argc, char **argv,
375 setup->ex_config = EX_CONFIG; 477 setup->ex_config = EX_CONFIG;
376 478
377 hints = *cfhint; 479 hints = *cfhint;
378 hints.data = setup; 480 if (setup->server)
481 hints.flags &= ~MU_CFHINT_PER_USER_FILE;
379 482
380 /* Set program name */ 483 /* Set program name */
381 if (hints.flags & MU_CFG_PARSE_PROGRAM) 484 if (hints.flags & MU_CFHINT_PROGRAM)
382 { 485 {
383 if (!mu_log_tag) 486 if (!mu_log_tag)
384 mu_log_tag = (char*)hints.program; 487 mu_log_tag = (char*)hints.program;
...@@ -389,7 +492,7 @@ mu_cli_ext (int argc, char **argv, ...@@ -389,7 +492,7 @@ mu_cli_ext (int argc, char **argv,
389 if (!mu_log_tag) 492 if (!mu_log_tag)
390 mu_log_tag = (char*)mu_program_name; 493 mu_log_tag = (char*)mu_program_name;
391 hints.program = (char*) mu_program_name; 494 hints.program = (char*) mu_program_name;
392 hints.flags |= MU_CFG_PARSE_PROGRAM; 495 hints.flags |= MU_CFHINT_PROGRAM;
393 } 496 }
394 497
395 /* Initialize standard streams */ 498 /* Initialize standard streams */
...@@ -478,12 +581,17 @@ mu_cli_ext (int argc, char **argv, ...@@ -478,12 +581,17 @@ mu_cli_ext (int argc, char **argv,
478 if (flags & MU_PARSEOPT_NEGATION) 581 if (flags & MU_PARSEOPT_NEGATION)
479 po.po_negation = pohint->po_negation; 582 po.po_negation = pohint->po_negation;
480 583
481 po.po_data = &hints; 584 appd.setup = setup;
585 appd.hints = &hints;
586 appd.append_tree = NULL;
587 appd.lint = 0;
588 po.po_data = &appd;
482 flags |= MU_PARSEOPT_DATA; 589 flags |= MU_PARSEOPT_DATA;
483 590
484 po.po_exit_error = setup->ex_usage; 591 po.po_exit_error = setup->ex_usage;
485 592
486 optv = init_options (capa, setup, &com_list); 593 mu_opool_create (&pool, MU_OPOOL_ENOMEMABRT);
594 optv = init_options (pool, capa, setup, &hints, &com_list);
487 595
488 if (mu_parseopt (&po, argc, argv, optv, flags)) 596 if (mu_parseopt (&po, argc, argv, optv, flags))
489 exit (po.po_exit_error); 597 exit (po.po_exit_error);
...@@ -502,6 +610,9 @@ mu_cli_ext (int argc, char **argv, ...@@ -502,6 +610,9 @@ mu_cli_ext (int argc, char **argv,
502 if (mu_cfg_parse_config (&parse_tree, &hints)) 610 if (mu_cfg_parse_config (&parse_tree, &hints))
503 exit (setup->ex_config); 611 exit (setup->ex_config);
504 612
613 if (appd.append_tree)
614 mu_cfg_tree_union (&parse_tree, &appd.append_tree);
615
505 if (mu_cfg_tree_reduce (parse_tree, &hints, setup->cfg, data)) 616 if (mu_cfg_tree_reduce (parse_tree, &hints, setup->cfg, data))
506 exit (setup->ex_config); 617 exit (setup->ex_config);
507 618
...@@ -513,15 +624,14 @@ mu_cli_ext (int argc, char **argv, ...@@ -513,15 +624,14 @@ mu_cli_ext (int argc, char **argv,
513 mu_list_foreach (com_list, run_commit, NULL); 624 mu_list_foreach (com_list, run_commit, NULL);
514 mu_list_destroy (&com_list); 625 mu_list_destroy (&com_list);
515 626
516 if (hints.flags & MU_PARSE_CONFIG_LINT)
517 exit (0);
518
519 mu_cfg_destroy_tree (&parse_tree); 627 mu_cfg_destroy_tree (&parse_tree);
520 free (optv); 628 free (optv);
521
522 free (args); 629 free (args);
523 630 mu_parseopt_free (&po);
524 mu_parseopt_free (&po); 631 mu_opool_destroy (&pool);
632
633 if (appd.lint)
634 exit (0);
525 } 635 }
526 636
527 void 637 void
...@@ -543,14 +653,14 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa, ...@@ -543,14 +653,14 @@ mu_cli (int argc, char **argv, struct mu_cli_setup *setup, char **capa,
543 pohint.po_bug_address = PACKAGE_BUGREPORT; 653 pohint.po_bug_address = PACKAGE_BUGREPORT;
544 pohint.po_flags |= MU_PARSEOPT_BUG_ADDRESS; 654 pohint.po_flags |= MU_PARSEOPT_BUG_ADDRESS;
545 655
546 pohint.po_extra_info = gnu_general_help_url; 656 pohint.po_extra_info = mu_general_help_text;
547 pohint.po_flags |= MU_PARSEOPT_EXTRA_INFO; 657 pohint.po_flags |= MU_PARSEOPT_EXTRA_INFO;
548 658
549 pohint.po_version_hook = mu_version_hook; 659 pohint.po_version_hook = mu_version_hook;
550 pohint.po_flags |= MU_PARSEOPT_VERSION_HOOK; 660 pohint.po_flags |= MU_PARSEOPT_VERSION_HOOK;
551 661
552 cfhint.site_rcfile = mu_site_config_file (); 662 cfhint.site_file = mu_site_config_file ();
553 cfhint.flags = MU_CFG_PARSE_SITE_RCFILE; 663 cfhint.flags = MU_CFHINT_SITE_FILE | MU_CFHINT_PER_USER_FILE;
554 664
555 mu_cli_ext (argc, argv, setup, &pohint, &cfhint, capa, data, 665 mu_cli_ext (argc, argv, setup, &pohint, &cfhint, capa, data,
556 ret_argc, ret_argv); 666 ret_argc, ret_argv);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
18 18
19 source $top_srcdir/testsuite/lib/mailutils.exp 19 source $top_srcdir/testsuite/lib/mailutils.exp
20 20
21 mu_init "--nosum --norc" 21 mu_init --nosum --norc
22 22
23 #FIXME: this doesn't work with remote testing 23 #FIXME: this doesn't work with remote testing
24 set env(MAILRC) $MU_RC_DIR/mail.rc 24 set env(MAILRC) $MU_RC_DIR/mail.rc
......
...@@ -58,8 +58,8 @@ mutool_acl (int argc, char **argv) ...@@ -58,8 +58,8 @@ mutool_acl (int argc, char **argv)
58 } 58 }
59 59
60 memset (&hints, 0, sizeof (hints)); 60 memset (&hints, 0, sizeof (hints));
61 hints.flags = MU_CFG_PARSE_CUSTOM_RCFILE; 61 hints.flags = MU_CFHINT_CUSTOM_FILE;
62 hints.custom_rcfile = input_file_name; 62 hints.custom_file = input_file_name;
63 63
64 mu_acl_cfg_init (); 64 mu_acl_cfg_init ();
65 if (mu_cfg_parse_config (&tree, &hints)) 65 if (mu_cfg_parse_config (&tree, &hints))
......
...@@ -43,7 +43,20 @@ int ...@@ -43,7 +43,20 @@ int
43 main (int argc, char **argv) 43 main (int argc, char **argv)
44 { 44 {
45 mutool_action_t action; 45 mutool_action_t action;
46 46 static struct mu_parseopt pohint = {
47 .po_flags = MU_PARSEOPT_PACKAGE_NAME
48 | MU_PARSEOPT_PACKAGE_URL
49 | MU_PARSEOPT_BUG_ADDRESS
50 | MU_PARSEOPT_EXTRA_INFO
51 | MU_PARSEOPT_VERSION_HOOK,
52 .po_package_name = PACKAGE_NAME,
53 .po_package_url = PACKAGE_URL,
54 .po_bug_address = PACKAGE_BUGREPORT,
55 .po_extra_info = mu_general_help_text,
56 .po_version_hook = mu_version_hook,
57 };
58 struct mu_cfg_parse_hints cfhint = { .flags = 0 };
59
47 /* Native Language Support */ 60 /* Native Language Support */
48 MU_APP_INIT_NLS (); 61 MU_APP_INIT_NLS ();
49 MU_AUTH_REGISTER_ALL_MODULES (); 62 MU_AUTH_REGISTER_ALL_MODULES ();
...@@ -51,7 +64,7 @@ main (int argc, char **argv) ...@@ -51,7 +64,7 @@ main (int argc, char **argv)
51 /* Register the desired mailbox formats. */ 64 /* Register the desired mailbox formats. */
52 mu_register_all_mbox_formats (); 65 mu_register_all_mbox_formats ();
53 66
54 mu_cli (argc, argv, &cli, capa, NULL, &argc, &argv); 67 mu_cli_ext (argc, argv, &cli, &pohint, &cfhint, capa, NULL, &argc, &argv);
55 68
56 if (argc < 1) 69 if (argc < 1)
57 { 70 {
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 #include "mu.h" 17 #include "mu.h"
18 18
19 char query_docstring[] = N_("query configuration values"); 19 char query_docstring[] = N_("query configuration values");
20 static char query_args_doc[] = N_("path [path...]"); 20 static char query_args_doc[] = N_("PATH [PATH...]");
21 21
22 static char *file_name; 22 static char *file_name;
23 int value_option; 23 int value_option;
...@@ -59,21 +59,21 @@ mutool_query (int argc, char **argv) ...@@ -59,21 +59,21 @@ mutool_query (int argc, char **argv)
59 return 1; 59 return 1;
60 } 60 }
61 61
62 hints.flags = MU_CFG_PARSE_SITE_RCFILE | MU_PARSE_CONFIG_GLOBAL; 62 hints.flags = MU_CFHINT_SITE_FILE;
63 hints.site_rcfile = file_name ? file_name : mu_site_config_file (); 63 hints.site_file = file_name ? file_name : mu_site_config_file ();
64 64
65 if (progname) 65 if (progname)
66 { 66 {
67 hints.flags |= MU_CFG_PARSE_PROGRAM; 67 hints.flags |= MU_CFHINT_PROGRAM;
68 hints.program = progname; 68 hints.program = progname;
69 } 69 }
70 70
71 if (verbose_option) 71 if (verbose_option)
72 hints.flags |= MU_CFG_FMT_LOCUS; 72 hints.flags |= MU_CF_FMT_LOCUS;
73 if (value_option) 73 if (value_option)
74 hints.flags |= MU_CFG_FMT_VALUE_ONLY; 74 hints.flags |= MU_CF_FMT_VALUE_ONLY;
75 if (path_option) 75 if (path_option)
76 hints.flags |= MU_CFG_FMT_PARAM_PATH; 76 hints.flags |= MU_CF_FMT_PARAM_PATH;
77 77
78 if (mu_cfg_parse_config (&tree, &hints)) 78 if (mu_cfg_parse_config (&tree, &hints))
79 return 1; 79 return 1;
......
...@@ -317,9 +317,10 @@ static char *capa[] = { ...@@ -317,9 +317,10 @@ static char *capa[] = {
317 }; 317 };
318 318
319 struct mu_cli_setup cli = { 319 struct mu_cli_setup cli = {
320 options, 320 .optv = options,
321 pop3d_cfg_param, 321 .cfg = pop3d_cfg_param,
322 N_("GNU pop3d -- the POP3 daemon."), 322 .prog_doc = N_("GNU pop3d -- the POP3 daemon."),
323 .server = 1
323 }; 324 };
324 325
325 int 326 int
......
...@@ -17,9 +17,8 @@ ...@@ -17,9 +17,8 @@
17 # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. 17 # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
18 18
19 source $top_srcdir/testsuite/lib/mailutils.exp 19 source $top_srcdir/testsuite/lib/mailutils.exp
20
21 20
22 mu_init "--rcfile=$objdir/pop3d.rc" 21 mu_init "--config-file=$objdir/pop3d.rc"
23 mu_version 22 mu_version
24 if ![mu_check_capability ENABLE_VIRTUAL_DOMAINS] { 23 if ![mu_check_capability ENABLE_VIRTUAL_DOMAINS] {
25 clone_output "WARNING: Support for virtual domains not compiled in" 24 clone_output "WARNING: Support for virtual domains not compiled in"
......
...@@ -148,14 +148,25 @@ proc mu_init {args} { ...@@ -148,14 +148,25 @@ proc mu_init {args} {
148 set MU_SPOOL_DIR "$MU_DATA_DIR/spool" 148 set MU_SPOOL_DIR "$MU_DATA_DIR/spool"
149 set MU_FOLDER_DIR "$MU_DATA_DIR/folder" 149 set MU_FOLDER_DIR "$MU_DATA_DIR/folder"
150 150
151 if {[llength $args] == 1 && [lindex $args 0] == "-noflags"} { 151 lappend flags "--no-config" "--set mailbox.mail-spool=\"'$MU_SPOOL_DIR'\""
152 set MU_TOOL_FLAGS "--no-site-rcfile --no-user-rcfile" 152 set i 0
153 } else { 153 for {} {$i < [llength $args]} {incr i} {
154 set MU_TOOL_FLAGS "--set mailbox.mail-spool=\"'$MU_SPOOL_DIR'\" --no-site-rcfile --no-user-rcfile" 154 switch -- [lindex $args $i] {
155 for {set i 0} {$i < [llength $args]} {incr i} { 155 -noflags {
156 append MU_TOOL_FLAGS " [lindex $args $i]" 156 unset flags
157 }
158 -- {
159 incr i
160 break
161 }
162 default {
163
164 break
165 }
157 } 166 }
158 } 167 }
168 lappend flags {*}[lrange $args $i end]
169 set MU_TOOL_FLAGS [join $flags { }]
159 } 170 }
160 } 171 }
161 172
......