Commit 4dda9b21 4dda9b21c67b6d03b852f57325cd0c88d266b463 by Sergey Poznyakoff

Introduce "parser hints", to provide better control over configuration parsing.

* include/mailutils/cfg.h (mu_cfg_parse_hints): New struct.
(mu_cfg_tree_postprocess): Change signature.  Last argument is
struct mu_cfg_parse_hints *.
(MU_CFG_PARSE_SITE_RCFILE,MU_CFG_PARSE_CUSTOM_RCFILE)
(MU_CFG_PARSE_PROGRAM): New flags.
(mu_cfg_parse_config): New proto.
* libmailutils/cfg/lexer.l (mu_get_config): Fix call to
mu_cfg_tree_postprocess.

* libmailutils/cfg/parser.y (do_include): Takes hints as 2nd argument.
(mu_cfg_tree_postprocess): Likewise.
(mu_cfg_parse_config): New function.

* libmu_cfg/init.c (mu_libcfg_parse_config): Rewrite as a wrapper
over mu_cfg_parse_config.
* libmu_argp/muinit.c (mu_app_init): Update.

* mu/query.c: New option --program.
(mutool_query): Use mu_cfg_parse_config interface.
1 parent d19d346f
......@@ -72,6 +72,14 @@ struct mu_cfg_node
struct mu_cfg_node *parent; /* parent node */
};
struct mu_cfg_parse_hints
{
int flags;
char *site_rcfile;
char *custom_rcfile;
char *program;
};
struct mu_cfg_tree
{
mu_list_t nodes; /* a list of mu_cfg_node_t */
......@@ -80,7 +88,8 @@ struct mu_cfg_tree
int mu_cfg_parse (mu_cfg_tree_t **ptree);
int mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb);
int mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags);
int mu_cfg_tree_postprocess (mu_cfg_tree_t *tree,
struct mu_cfg_parse_hints *hints);
extern struct mu_locus mu_cfg_locus;
......@@ -231,10 +240,16 @@ int mu_config_register_plain_section (const char *parent_path,
const char *ident,
struct mu_cfg_param *params);
#define MU_PARSE_CONFIG_GLOBAL 0x1
#define MU_PARSE_CONFIG_VERBOSE 0x2
#define MU_PARSE_CONFIG_DUMP 0x4
#define MU_PARSE_CONFIG_PLAIN 0x8
#define MU_PARSE_CONFIG_GLOBAL 0x001
#define MU_PARSE_CONFIG_VERBOSE 0x002
#define MU_PARSE_CONFIG_DUMP 0x004
#define MU_PARSE_CONFIG_PLAIN 0x008
#define MU_CFG_PARSE_SITE_RCFILE 0x010
#define MU_CFG_PARSE_CUSTOM_RCFILE 0x020
#define MU_CFG_PARSE_PROGRAM 0x040
#define MU_CFG_FMT_LOCUS 0x080
#define MU_CFG_FMT_VALUE_ONLY 0x100
#define MU_CFG_FMT_PARAM_PATH 0x200
#ifdef MU_CFG_COMPATIBILITY
# define MU_CFG_DEPRECATED
......@@ -251,10 +266,6 @@ int mu_cfg_parse_boolean (const char *str, int *res);
extern int mu_cfg_parser_verbose;
extern size_t mu_cfg_error_count;
#define MU_CFG_FMT_LOCUS 0x01
#define MU_CFG_FMT_VALUE_ONLY 0x02
#define MU_CFG_FMT_PARAM_PATH 0x04
void mu_cfg_format_docstring (mu_stream_t stream, const char *docstring,
int level);
void mu_cfg_format_parse_tree (mu_stream_t stream, struct mu_cfg_tree *tree,
......@@ -295,6 +306,9 @@ int mu_cfg_find_node (mu_cfg_tree_t *tree, const char *path,
mu_cfg_node_t **pnode);
int mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode);
int mu_cfg_parse_config (mu_cfg_tree_t **ptree,
struct mu_cfg_parse_hints *hints);
#ifdef __cplusplus
}
#endif
......
......@@ -387,7 +387,12 @@ mu_get_config (const char *file, const char *progname,
int rc = mu_cfg_parse_file (&parse_tree, file, flags);
if (rc == 0)
{
rc = mu_cfg_tree_postprocess (parse_tree, flags);
struct mu_cfg_parse_hints hints;
hints.flags = flags | MU_CFG_PARSE_PROGRAM;
hints.program = progname;
rc = mu_cfg_tree_postprocess (parse_tree, &hints);
if (rc == 0)
rc = mu_cfg_tree_reduce (parse_tree, progname, progparam, flags,
target_ptr);
......
......@@ -165,16 +165,16 @@ mu_app_init (struct argp *myargp, const char **capa,
rc = mu_libcfg_parse_config (&parse_tree);
if (rc == 0)
{
int cfgflags = MU_PARSE_CONFIG_PLAIN;
struct mu_cfg_parse_hints hints = { MU_PARSE_CONFIG_PLAIN };
if (mu_cfg_parser_verbose)
cfgflags |= MU_PARSE_CONFIG_VERBOSE;
hints.flags |= MU_PARSE_CONFIG_VERBOSE;
if (mu_cfg_parser_verbose > 1)
cfgflags |= MU_PARSE_CONFIG_DUMP;
mu_cfg_tree_postprocess (mu_argp_tree, cfgflags);
hints.flags |= MU_PARSE_CONFIG_DUMP;
mu_cfg_tree_postprocess (mu_argp_tree, &hints);
mu_cfg_tree_union (&parse_tree, &mu_argp_tree);
rc = mu_cfg_tree_reduce (parse_tree, mu_program_name, cfg_param,
cfgflags, data);
hints.flags, data);
}
if (mu_rcfile_lint)
......
......@@ -88,77 +88,34 @@ mu_libcfg_init (char **cnames)
int
mu_libcfg_parse_config (mu_cfg_tree_t **ptree)
{
int flags = 0;
int rc = 0;
mu_cfg_tree_t *tree = NULL, *tmp;
struct mu_cfg_parse_hints hints;
memset (&hints, 0, sizeof (hints));
if (mu_cfg_parser_verbose)
flags |= MU_PARSE_CONFIG_VERBOSE;
hints.flags |= MU_PARSE_CONFIG_VERBOSE;
if (mu_cfg_parser_verbose > 1)
flags |= MU_PARSE_CONFIG_DUMP;
hints.flags |= MU_PARSE_CONFIG_DUMP;
if (mu_load_site_rcfile)
{
rc = mu_cfg_parse_file (&tmp, MU_CONFIG_FILE, flags);
if (rc == ENOMEM)
{
mu_error ("%s", mu_strerror (rc));
return rc;
}
else if (rc == 0)
{
mu_cfg_tree_postprocess (tmp, flags | MU_PARSE_CONFIG_GLOBAL);
mu_cfg_tree_union (&tree, &tmp);
}
hints.flags |= MU_CFG_PARSE_SITE_RCFILE;
hints.site_rcfile = MU_CONFIG_FILE;
}
if (mu_load_user_rcfile && mu_program_name)
{
size_t size = 3 + strlen (mu_program_name) + 1;
char *file_name = malloc (size);
if (file_name)
{
strcpy (file_name, "~/.");
strcat (file_name, mu_program_name);
rc = mu_cfg_parse_file (&tmp, file_name, flags);
if (rc == ENOMEM)
{
mu_error ("%s", mu_strerror (rc));
mu_cfg_destroy_tree (&tree);
return rc;
}
else if (rc == 0)
{
mu_cfg_tree_postprocess (tmp, flags);
mu_cfg_tree_union (&tree, &tmp);
}
else if (rc == ENOENT)
rc = 0;
free (file_name);
}
hints.flags |= MU_CFG_PARSE_PROGRAM;
hints.program = (char*) mu_program_name;
}
if (mu_load_rcfile)
{
rc = mu_cfg_parse_file (&tmp, mu_load_rcfile, flags);
if (rc)
{
mu_error (_("errors parsing file %s: %s"), mu_load_rcfile,
mu_strerror (rc));
mu_cfg_destroy_tree (&tree);
return rc;
}
else
{
mu_cfg_tree_postprocess (tmp, flags);
mu_cfg_tree_union (&tree, &tmp);
}
hints.flags |= MU_CFG_PARSE_CUSTOM_RCFILE;
hints.custom_rcfile = mu_load_rcfile;
}
*ptree = tree;
return rc;
return mu_cfg_parse_config (ptree, &hints);
}
......
......@@ -28,8 +28,8 @@ static char query_doc[] = N_("mu query - query configuration values.");
char query_docstring[] = N_("query configuration values");
static char query_args_doc[] = N_("path [path...]");
char *file_name;
int fmtflags = 0;
static char *file_name;
static struct mu_cfg_parse_hints hints;
enum {
VALUE_OPTION = 256,
......@@ -43,6 +43,9 @@ static struct argp_option query_options[] = {
{ "value", VALUE_OPTION, NULL, 0,
N_("display parameter values only"),
0 },
{ "program", 'p', N_("NAME"), 0,
N_("set program name for configuration lookup"),
0 },
{ "path", PATH_OPTION, NULL, 0,
N_("display parameters as paths") },
{ "verbose", 'v', NULL, 0,
......@@ -59,16 +62,21 @@ query_parse_opt (int key, char *arg, struct argp_state *state)
file_name = arg;
break;
case 'p':
hints.flags |= MU_CFG_PARSE_PROGRAM;
hints.program = arg;
break;
case 'v':
fmtflags |= MU_CFG_FMT_LOCUS;
hints.flags |= MU_CFG_FMT_LOCUS;
break;
case VALUE_OPTION:
fmtflags |= MU_CFG_FMT_VALUE_ONLY;
hints.flags |= MU_CFG_FMT_VALUE_ONLY;
break;
case PATH_OPTION:
fmtflags |= MU_CFG_FMT_PARAM_PATH;
hints.flags |= MU_CFG_FMT_PARAM_PATH;
break;
default:
......@@ -105,14 +113,10 @@ mutool_query (int argc, char **argv)
return 1;
}
if (file_name)
{
mu_load_site_rcfile = 0;
mu_load_user_rcfile = 0;
mu_load_rcfile = file_name;
}
hints.flags |= MU_CFG_PARSE_SITE_RCFILE | MU_PARSE_CONFIG_GLOBAL;
hints.site_rcfile = file_name ? file_name : MU_CONFIG_FILE;
if (mu_libcfg_parse_config (&tree))
if (mu_cfg_parse_config (&tree, &hints))
return 1;
if (!tree)
return 0;
......@@ -122,7 +126,7 @@ mutool_query (int argc, char **argv)
mu_cfg_node_t *node;
if (mu_cfg_find_node (tree, path, &node) == 0)
mu_cfg_format_node (mu_strout, node, fmtflags);
mu_cfg_format_node (mu_strout, node, hints.flags);
}
return 0;
}
......