diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-03-05 11:07:24 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-03-05 11:07:40 +0200 |
commit | 4dda9b21c67b6d03b852f57325cd0c88d266b463 (patch) | |
tree | bde48723f61ab58c8a8ab0be7afc0a13fe5a6b49 | |
parent | d19d346f9e9822aa541c4860483045ecf4bea336 (diff) | |
download | mailutils-4dda9b21c67b6d03b852f57325cd0c88d266b463.tar.gz mailutils-4dda9b21c67b6d03b852f57325cd0c88d266b463.tar.bz2 |
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.
-rw-r--r-- | include/mailutils/cfg.h | 32 | ||||
-rw-r--r-- | libmailutils/cfg/lexer.l | 7 | ||||
-rw-r--r-- | libmailutils/cfg/parser.y | 310 | ||||
-rw-r--r-- | libmu_argp/muinit.c | 10 | ||||
-rw-r--r-- | libmu_cfg/init.c | 71 | ||||
-rw-r--r-- | mu/query.c | 30 |
6 files changed, 262 insertions, 198 deletions
diff --git a/include/mailutils/cfg.h b/include/mailutils/cfg.h index 4af5ad55c..a27eb5cbd 100644 --- a/include/mailutils/cfg.h +++ b/include/mailutils/cfg.h @@ -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 diff --git a/libmailutils/cfg/lexer.l b/libmailutils/cfg/lexer.l index 4e3755eef..9f2c719a7 100644 --- a/libmailutils/cfg/lexer.l +++ b/libmailutils/cfg/lexer.l @@ -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); diff --git a/libmailutils/cfg/parser.y b/libmailutils/cfg/parser.y index 72c028ce1..397e80fb1 100644 --- a/libmailutils/cfg/parser.y +++ b/libmailutils/cfg/parser.y @@ -289,16 +289,16 @@ vallist : vlist ; vlist : value - { - int rc = mu_list_create (&$$); - if (rc) - { - mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, - _("cannot create list: %s"), - mu_strerror (rc)); - abort (); - } - mu_list_append ($$, config_value_dup (&$1)); /* FIXME */ + { + int rc = mu_list_create (&$$); + if (rc) + { + mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, + _("cannot create list: %s"), + mu_strerror (rc)); + abort (); + } + mu_list_append ($$, config_value_dup (&$1)); /* FIXME */ } | vlist value { @@ -480,7 +480,8 @@ mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb) } static mu_cfg_tree_t * -do_include (const char *name, int flags, struct mu_locus *loc) +do_include (const char *name, struct mu_cfg_parse_hints *hints, + struct mu_locus *loc) { struct stat sb; char *tmpname = NULL; @@ -498,21 +499,26 @@ do_include (const char *name, int flags, struct mu_locus *loc) if (stat (name, &sb) == 0) { int rc = 0; - + if (S_ISDIR (sb.st_mode)) { - if (flags & MU_PARSE_CONFIG_GLOBAL) + if ((hints->flags & (MU_PARSE_CONFIG_GLOBAL|MU_CFG_PARSE_PROGRAM)) == + (MU_PARSE_CONFIG_GLOBAL|MU_CFG_PARSE_PROGRAM)) { - char *file = mu_make_file_name (name, mu_program_name); - rc = mu_cfg_parse_file (&tree, file, flags); + char *file = mu_make_file_name (name, hints->program); + rc = mu_cfg_parse_file (&tree, file, hints->flags); free (file); } } else - rc = mu_cfg_parse_file (&tree, name, flags); - + rc = mu_cfg_parse_file (&tree, name, hints->flags); + if (rc == 0 && tree) - mu_cfg_tree_postprocess (tree, flags & ~MU_PARSE_CONFIG_GLOBAL); + { + struct mu_cfg_parse_hints xhints = *hints; + xhints.flags &= ~MU_PARSE_CONFIG_GLOBAL; + mu_cfg_tree_postprocess (tree, &xhints); + } } else if (errno == ENOENT) { @@ -527,17 +533,18 @@ do_include (const char *name, int flags, struct mu_locus *loc) mu_strerror (errno)); mu_cfg_error_count++; } - + free (tmpname); return tree; } - + int -mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags) +mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, + struct mu_cfg_parse_hints *hints) { int rc; mu_iterator_t itr; - + if (!tree->nodes) return 0; rc = mu_list_get_iterator (tree->nodes, &itr); @@ -547,18 +554,22 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags) mu_iterator_next (itr)) { mu_cfg_node_t *node; - + mu_iterator_current (itr, (void**) &node); - + if (node->type == mu_cfg_node_statement) { - if ((flags & MU_PARSE_CONFIG_GLOBAL) && + if ((hints->flags & MU_PARSE_CONFIG_GLOBAL) && strcmp (node->tag, "program") == 0) { if (node->label->type == MU_CFG_STRING) { - if (strcmp (node->label->v.string, mu_program_name) == 0) + if ((hints->flags & MU_CFG_PARSE_PROGRAM) + && strcmp (node->label->v.string, hints->program) == 0) { + /* Reset the parent node */ + mu_list_do (node->nodes, _node_set_parent, + node->parent); /* Move all nodes from this block to the topmost level */ mu_iterator_ctl (itr, mu_itrctl_insert_list, @@ -581,7 +592,8 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags) { if (node->label->type == MU_CFG_STRING) { - mu_cfg_tree_t *t = do_include (node->label->v.string, flags, + mu_cfg_tree_t *t = do_include (node->label->v.string, + hints, &node->locus); if (t) { @@ -598,7 +610,7 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags) _("argument to `include' is not a string")); mu_cfg_error_count++; } - + /* Remove node from the list */ mu_iterator_ctl (itr, mu_itrctl_delete, NULL); } @@ -611,12 +623,12 @@ _mu_cfg_preorder_recursive (void *item, void *cbdata) { mu_cfg_node_t *node = item; struct mu_cfg_iter_closure *clos = cbdata; - + switch (node->type) { case mu_cfg_node_undefined: abort (); - + case mu_cfg_node_statement: switch (clos->beg (node, clos->data)) { @@ -626,15 +638,15 @@ _mu_cfg_preorder_recursive (void *item, void *cbdata) if (clos->end && clos->end (node, clos->data) == MU_CFG_ITER_STOP) return 1; break; - + case MU_CFG_ITER_SKIP: break; - + case MU_CFG_ITER_STOP: return 1; } break; - + case mu_cfg_node_param: return clos->beg (node, clos->data) == MU_CFG_ITER_STOP; } @@ -684,17 +696,17 @@ find_container (mu_list_t list, enum mu_cfg_cont_type type, { mu_iterator_t iter; struct mu_cfg_cont *ret = NULL; - + if (len == 0) len = strlen (ident); - + mu_list_get_iterator (list, &iter); for (mu_iterator_first (iter); !mu_iterator_is_done (iter); mu_iterator_next (iter)) { struct mu_cfg_cont *cont; mu_iterator_current (iter, (void**) &cont); - + if (cont->type == type && strlen (cont->v.ident) == len && memcmp (cont->v.ident, ident, len) == 0) @@ -771,7 +783,7 @@ pop_section (struct scan_tree_data *dat) #define STRTONUM(s, type, base, res, limit, d, loc) \ { \ type sum = 0; \ - \ + \ for (; *s; s++) \ { \ type x; \ @@ -794,7 +806,7 @@ pop_section (struct scan_tree_data *dat) else if (limit && x > limit) \ { \ mu_diag_at_locus (MU_LOG_ERROR, loc, \ - _("value out of allowed range")); \ + _("value out of allowed range")); \ mu_cfg_error_count++; \ return 1; \ } \ @@ -830,9 +842,9 @@ pop_section (struct scan_tree_data *dat) STRxTONUM (s, type, tmpres, 0, d, loc); \ if (*s) \ { \ - mu_diag_at_locus (MU_LOG_ERROR, loc, \ - _("not a number (stopped near `%s')"), \ - s); \ + mu_diag_at_locus (MU_LOG_ERROR, loc, \ + _("not a number (stopped near `%s')"), \ + s); \ mu_cfg_error_count++; \ return 1; \ } \ @@ -845,7 +857,7 @@ pop_section (struct scan_tree_data *dat) const char *s = str; \ int sign; \ unsigned type limit; \ - \ + \ if (*s == '-') \ { \ sign++; \ @@ -858,11 +870,11 @@ pop_section (struct scan_tree_data *dat) sign = 0; \ limit = TYPE_MAXIMUM (type); \ } \ - \ + \ STRxTONUM (s, unsigned type, tmpres, limit, d, loc); \ if (*s) \ { \ - mu_diag_at_locus (MU_LOG_ERROR, loc, \ + mu_diag_at_locus (MU_LOG_ERROR, loc, \ _("not a number (stopped near `%s')"), \ s); \ mu_cfg_error_count++; \ @@ -918,7 +930,7 @@ parse_cidr (struct scan_tree_data *sdata, const struct mu_locus *locus, unsigned long mask; char astr[16]; const char *p, *s; - + p = strchr (str, '/'); if (p) { @@ -940,7 +952,7 @@ parse_cidr (struct scan_tree_data *sdata, const struct mu_locus *locus, return 1; } addr.s_addr = ntohl (addr.s_addr); - + p++; s = p; STRxTONUM (s, unsigned long, mask, 0, sdata->tree->debug, locus); @@ -975,7 +987,7 @@ parse_cidr (struct scan_tree_data *sdata, const struct mu_locus *locus, int i; unsigned short x; addr.s_addr = 0; - + p = str; for (i = 0; i < 3; i++) { @@ -984,7 +996,7 @@ parse_cidr (struct scan_tree_data *sdata, const struct mu_locus *locus, break; addr.s_addr = (addr.s_addr << 8) + x; } - + if (*p) { mu_diag_at_locus (MU_LOG_ERROR, &mu_cfg_locus, @@ -993,12 +1005,12 @@ parse_cidr (struct scan_tree_data *sdata, const struct mu_locus *locus, mu_cfg_error_count++; return 1; } - + mask = i * 8; - + addr.s_addr <<= (4 - i) * 8; } - + res->addr = addr; res->mask = mask; return 0; @@ -1057,71 +1069,71 @@ valcvt (struct scan_tree_data *sdata, const struct mu_locus *locus, *(char**)tgt = s; break; } - + case mu_cfg_short: GETSNUM (val->v.string, short, *(short*)tgt, sdata->tree->debug, locus); break; - + case mu_cfg_ushort: GETUNUM (val->v.string, unsigned short, *(unsigned short*)tgt, sdata->tree->debug, locus); break; - + case mu_cfg_int: GETSNUM (val->v.string, int, *(int*)tgt, sdata->tree->debug, locus); break; - + case mu_cfg_uint: GETUNUM (val->v.string, unsigned int, *(unsigned int*)tgt, sdata->tree->debug, locus); break; - + case mu_cfg_long: GETSNUM (val->v.string, long, *(long*)tgt, sdata->tree->debug, locus); break; - + case mu_cfg_ulong: GETUNUM (val->v.string, unsigned long, *(unsigned long*)tgt, sdata->tree->debug, locus); break; - + case mu_cfg_size: GETUNUM (val->v.string, size_t, *(size_t*)tgt, sdata->tree->debug, locus); break; - + case mu_cfg_off: mu_diag_at_locus (MU_LOG_ERROR, locus, _("not implemented yet")); mu_cfg_error_count++; /* GETSNUM(node->tag_label, off_t, *(off_t*)tgt); */ return 1; - + case mu_cfg_time: GETUNUM (val->v.string, time_t, *(time_t*)tgt, sdata->tree->debug, locus); break; - + case mu_cfg_bool: if (parse_bool (sdata, locus, val->v.string, (int*) tgt)) return 1; break; - + case mu_cfg_ipv4: if (parse_ipv4 (sdata, locus, val->v.string, (struct in_addr *)tgt)) return 1; break; - + case mu_cfg_cidr: if (parse_cidr (sdata, locus, val->v.string, (mu_cfg_cidr_t *)tgt)) return 1; break; - + case mu_cfg_host: if (parse_host (sdata, locus, val->v.string, (struct in_addr *)tgt)) return 1; break; - + default: return 1; } @@ -1153,7 +1165,7 @@ static size_t config_type_size[] = { sizeof (struct in_addr), /* mu_cfg_host */ 0, /* mu_cfg_callback */ 0, /* mu_cfg_section */ -} ; +}; static int _set_fun (void *item, void *data) @@ -1162,7 +1174,7 @@ _set_fun (void *item, void *data) struct set_closure *clos = data; void *tgt; size_t size; - + if (clos->type >= MU_ARRAY_SIZE(config_type_size) || (size = config_type_size[clos->type]) == 0) { @@ -1172,7 +1184,7 @@ _set_fun (void *item, void *data) mu_cfg_error_count++; return 1; } - + tgt = mu_alloc (size); if (!tgt) { @@ -1180,7 +1192,7 @@ _set_fun (void *item, void *data) mu_cfg_error_count++; return 1; } - + if (valcvt (clos->sdata, clos->locus, &tgt, clos->type, val) == 0) mu_list_append (clos->list, tgt); return 0; @@ -1193,7 +1205,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) struct set_closure clos; struct mu_cfg_param *param = find_param (sdata->list->sec, node->tag, 0); - + if (!param) { mu_diag_at_locus (MU_LOG_ERROR, &node->locus, @@ -1202,7 +1214,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) mu_cfg_error_count++; return 1; } - + if (param->data) tgt = param->data; else if (sdata->list->sec->target) @@ -1218,7 +1230,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) "%s"), param->ident); abort (); } - + memset (&clos, 0, sizeof clos); clos.type = MU_CFG_TYPE (param->type); if (MU_CFG_IS_LIST (param->type)) @@ -1229,7 +1241,7 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) { case MU_CFG_LIST: break; - + case MU_CFG_STRING: { mu_list_t list; @@ -1239,14 +1251,14 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) node->label->v.list = list; } break; - + case MU_CFG_ARRAY: mu_diag_at_locus (MU_LOG_ERROR, &node->locus, - _("expected list, but found array")); + _("expected list, but found array")); mu_cfg_error_count++; return 1; } - + mu_list_create (&clos.list); mu_list_do (node->label->v.list, _set_fun, &clos); *(mu_list_t*)tgt = clos.list; @@ -1261,14 +1273,14 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) abort (); } mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, - MU_IOCTL_LOGSTREAM_SET_LOCUS, + MU_IOCTL_LOGSTREAM_SET_LOCUS, (void*) &node->locus); if (param->callback (tgt, node->label)) return 1; } else return valcvt (sdata, &node->locus, tgt, clos.type, node->label); - + return 0; } @@ -1278,12 +1290,12 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data) { struct scan_tree_data *sdata = data; struct mu_cfg_section *sec; - + switch (node->type) { case mu_cfg_node_undefined: abort (); - + case mu_cfg_node_statement: sec = find_subsection (sdata->list->sec, node->tag, 0); if (!sec) @@ -1305,7 +1317,7 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data) if (sec->parser) { mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, - MU_IOCTL_LOGSTREAM_SET_LOCUS, + MU_IOCTL_LOGSTREAM_SET_LOCUS, (void*) &node->locus); if (sec->parser (mu_cfg_section_start, node, sec->label, &sec->target, @@ -1317,7 +1329,7 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data) } push_section(sdata, sec); break; - + case mu_cfg_node_param: if (parse_param (sdata, node)) { @@ -1334,12 +1346,12 @@ _scan_tree_end_helper (const mu_cfg_node_t *node, void *data) { struct scan_tree_data *sdata = data; struct mu_cfg_section *sec; - + switch (node->type) { default: abort (); - + case mu_cfg_node_statement: sec = pop_section (sdata); if (sec && sec->parser) @@ -1358,7 +1370,7 @@ _scan_tree_end_helper (const mu_cfg_node_t *node, void *data) int mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections, - void *target, void *data) + void *target, void *data) { struct scan_tree_data dat; struct mu_cfg_iter_closure clos; @@ -1370,15 +1382,15 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections, dat.error = 0; dat.call_data = data; dat.target = target; - + mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, - MU_IOCTL_LOGSTREAM_GET_MODE, &save_mode); + MU_IOCTL_LOGSTREAM_GET_MODE, &save_mode); mode = save_mode | MU_LOGMODE_LOCUS; mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, - MU_IOCTL_LOGSTREAM_SET_MODE, &mode); + MU_IOCTL_LOGSTREAM_SET_MODE, &mode); mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, - MU_IOCTL_LOGSTREAM_GET_LOCUS, &save_locus); - + MU_IOCTL_LOGSTREAM_GET_LOCUS, &save_locus); + if (push_section (&dat, sections)) return 1; clos.beg = _scan_tree_helper; @@ -1386,11 +1398,11 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections, clos.data = &dat; mu_cfg_preorder (tree->nodes, &clos); pop_section (&dat); - + mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, - MU_IOCTL_LOGSTREAM_SET_MODE, &save_mode); + MU_IOCTL_LOGSTREAM_SET_MODE, &save_mode); mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, - MU_IOCTL_LOGSTREAM_SET_LOCUS, &save_locus); + MU_IOCTL_LOGSTREAM_SET_LOCUS, &save_locus); free (save_locus.mu_file); return dat.error; @@ -1405,19 +1417,19 @@ mu_cfg_find_section (struct mu_cfg_section *root_sec, struct mu_cfg_section *sec; size_t len; const char *p; - + while (*path == MU_CFG_PATH_DELIM) path++; - + if (*path == 0) return MU_ERR_NOENT; - + p = strchr (path, MU_CFG_PATH_DELIM); if (p) len = p - path; else len = strlen (path); - + sec = find_subsection (root_sec, path, len); if (!sec) return MU_ERR_NOENT; @@ -1452,7 +1464,7 @@ mu_cfg_tree_create_node (struct mu_cfg_tree *tree, mu_cfg_node_t *np; size_t size = sizeof *np + strlen (tag) + 1; mu_config_value_t val; - + np = mu_alloc (size); np->type = type; if (loc) @@ -1512,7 +1524,7 @@ mu_cfg_value_eq (mu_config_value_t *a, mu_config_value_t *b) if (a->v.string == NULL) return b->v.string == NULL; return strcmp (a->v.string, b->v.string) == 0; - + case MU_CFG_LIST: { int ret = 1; @@ -1524,7 +1536,7 @@ mu_cfg_value_eq (mu_config_value_t *a, mu_config_value_t *b) mu_list_count (b->v.list, &i); if (i != cnt) return 1; - + mu_list_get_iterator (a->v.list, &aitr); mu_list_get_iterator (b->v.list, &bitr); for (i = 0, @@ -1546,7 +1558,7 @@ mu_cfg_value_eq (mu_config_value_t *a, mu_config_value_t *b) mu_iterator_destroy (&bitr); return ret && i == cnt; } - + case MU_CFG_ARRAY: if (a->v.arg.c == b->v.arg.c) { @@ -1594,7 +1606,7 @@ split_cfg_path (const char *path, int *pargc, char ***pargv) path++; } ws.ws_delim = delim; - + if (mu_wordsplit (path, &ws, MU_WRDSF_DEFFLAGS|MU_WRDSF_DELIM)) { mu_error (_("cannot split line `%s': %s"), path, @@ -1607,10 +1619,10 @@ split_cfg_path (const char *path, int *pargc, char ***pargv) ws.ws_wordv = NULL; mu_wordsplit_free (&ws); } - + *pargc = argc; *pargv = argv; - + return 0; } @@ -1667,7 +1679,7 @@ parse_label (const char *str) if (len > 1 && str[0] == '(' && str[len-1] == ')') { mu_list_t lst; - + ws.ws_delim = ","; if (mu_wordsplit_len (str + 1, len - 2, &ws, MU_WRDSF_DEFFLAGS|MU_WRDSF_DELIM|MU_WRDSF_WS)) @@ -1676,7 +1688,7 @@ parse_label (const char *str) mu_wordsplit_strerror (&ws)); return NULL; } - + mu_list_create (&lst); mu_list_set_destroy_item (lst, destroy_value); for (i = 0; i < ws.ws_wordc; i++) @@ -1760,7 +1772,7 @@ mu_cfg_find_node (mu_cfg_tree_t *tree, const char *path, mu_cfg_node_t **pval) { int rc; struct find_data data; - + rc = split_cfg_path (path, &data.argc, &data.argv); if (rc) return rc; @@ -1768,9 +1780,9 @@ mu_cfg_find_node (mu_cfg_tree_t *tree, const char *path, mu_cfg_node_t **pval) if (data.argc) { struct mu_cfg_iter_closure clos; - + parse_tag (&data); - + clos.beg = node_finder; clos.end = NULL; clos.data = &data; @@ -1796,15 +1808,15 @@ mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode) enum mu_cfg_node_type type; mu_cfg_node_t *node = NULL; struct mu_locus locus; - + locus.mu_file = "<int>"; locus.mu_line = 0; locus.mu_col = 0; - + rc = split_cfg_path (path, &argc, &argv); if (rc) return rc; - + for (i = argc - 1; i >= 0; i--) { mu_list_t nodelist = NULL; @@ -1841,12 +1853,84 @@ mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode) node->parent = parent; node = parent; } - + mu_argcv_free (argc, argv); *pnode = node; return 0; } +int +mu_cfg_parse_config (mu_cfg_tree_t **ptree, struct mu_cfg_parse_hints *hints) +{ + int rc = 0; + mu_cfg_tree_t *tree = NULL, *tmp; + + if ((hints->flags & MU_CFG_PARSE_SITE_RCFILE) && hints->site_rcfile) + { + rc = mu_cfg_parse_file (&tmp, hints->site_rcfile, hints->flags); + + if (rc == ENOMEM) + { + mu_error ("%s", mu_strerror (rc)); + return rc; + } + else if (rc == 0) + { + struct mu_cfg_parse_hints xhints = *hints; + xhints.flags |= MU_PARSE_CONFIG_GLOBAL; + mu_cfg_tree_postprocess (tmp, &xhints); + mu_cfg_tree_union (&tree, &tmp); + } + } + + if ((hints->flags & MU_CFG_PARSE_PROGRAM) && hints->program) + { + size_t size = 3 + strlen (hints->program) + 1; + char *file_name = malloc (size); + if (file_name) + { + strcpy (file_name, "~/."); + strcat (file_name, hints->program); + + rc = mu_cfg_parse_file (&tmp, file_name, hints->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, hints); + mu_cfg_tree_union (&tree, &tmp); + } + else if (rc == ENOENT) + rc = 0; + free (file_name); + } + } + + if ((hints->flags & MU_CFG_PARSE_CUSTOM_RCFILE) && hints->custom_rcfile) + { + rc = mu_cfg_parse_file (&tmp, hints->custom_rcfile, hints->flags); + if (rc) + { + mu_error (_("errors parsing file %s: %s"), hints->custom_rcfile, + mu_strerror (rc)); + mu_cfg_destroy_tree (&tree); + return rc; + } + else + { + mu_cfg_tree_postprocess (tmp, hints); + mu_cfg_tree_union (&tree, &tmp); + } + } + + *ptree = tree; + return rc; +} + diff --git a/libmu_argp/muinit.c b/libmu_argp/muinit.c index a0c098db0..cd769ebaf 100644 --- a/libmu_argp/muinit.c +++ b/libmu_argp/muinit.c @@ -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) diff --git a/libmu_cfg/init.c b/libmu_cfg/init.c index 8bb35f3cb..142907585 100644 --- a/libmu_cfg/init.c +++ b/libmu_cfg/init.c @@ -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); } diff --git a/mu/query.c b/mu/query.c index d02c988e7..b089af0c3 100644 --- a/mu/query.c +++ b/mu/query.c @@ -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); |