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.
Showing
6 changed files
with
65 additions
and
85 deletions
... | @@ -72,6 +72,14 @@ struct mu_cfg_node | ... | @@ -72,6 +72,14 @@ struct mu_cfg_node |
72 | struct mu_cfg_node *parent; /* parent node */ | 72 | struct mu_cfg_node *parent; /* parent node */ |
73 | }; | 73 | }; |
74 | 74 | ||
75 | struct mu_cfg_parse_hints | ||
76 | { | ||
77 | int flags; | ||
78 | char *site_rcfile; | ||
79 | char *custom_rcfile; | ||
80 | char *program; | ||
81 | }; | ||
82 | |||
75 | struct mu_cfg_tree | 83 | struct mu_cfg_tree |
76 | { | 84 | { |
77 | mu_list_t nodes; /* a list of mu_cfg_node_t */ | 85 | mu_list_t nodes; /* a list of mu_cfg_node_t */ |
... | @@ -80,7 +88,8 @@ struct mu_cfg_tree | ... | @@ -80,7 +88,8 @@ struct mu_cfg_tree |
80 | 88 | ||
81 | int mu_cfg_parse (mu_cfg_tree_t **ptree); | 89 | int mu_cfg_parse (mu_cfg_tree_t **ptree); |
82 | int mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb); | 90 | int mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb); |
83 | int mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags); | 91 | int mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, |
92 | struct mu_cfg_parse_hints *hints); | ||
84 | 93 | ||
85 | extern struct mu_locus mu_cfg_locus; | 94 | extern struct mu_locus mu_cfg_locus; |
86 | 95 | ||
... | @@ -231,10 +240,16 @@ int mu_config_register_plain_section (const char *parent_path, | ... | @@ -231,10 +240,16 @@ int mu_config_register_plain_section (const char *parent_path, |
231 | const char *ident, | 240 | const char *ident, |
232 | struct mu_cfg_param *params); | 241 | struct mu_cfg_param *params); |
233 | 242 | ||
234 | #define MU_PARSE_CONFIG_GLOBAL 0x1 | 243 | #define MU_PARSE_CONFIG_GLOBAL 0x001 |
235 | #define MU_PARSE_CONFIG_VERBOSE 0x2 | 244 | #define MU_PARSE_CONFIG_VERBOSE 0x002 |
236 | #define MU_PARSE_CONFIG_DUMP 0x4 | 245 | #define MU_PARSE_CONFIG_DUMP 0x004 |
237 | #define MU_PARSE_CONFIG_PLAIN 0x8 | 246 | #define MU_PARSE_CONFIG_PLAIN 0x008 |
247 | #define MU_CFG_PARSE_SITE_RCFILE 0x010 | ||
248 | #define MU_CFG_PARSE_CUSTOM_RCFILE 0x020 | ||
249 | #define MU_CFG_PARSE_PROGRAM 0x040 | ||
250 | #define MU_CFG_FMT_LOCUS 0x080 | ||
251 | #define MU_CFG_FMT_VALUE_ONLY 0x100 | ||
252 | #define MU_CFG_FMT_PARAM_PATH 0x200 | ||
238 | 253 | ||
239 | #ifdef MU_CFG_COMPATIBILITY | 254 | #ifdef MU_CFG_COMPATIBILITY |
240 | # define MU_CFG_DEPRECATED | 255 | # define MU_CFG_DEPRECATED |
... | @@ -251,10 +266,6 @@ int mu_cfg_parse_boolean (const char *str, int *res); | ... | @@ -251,10 +266,6 @@ int mu_cfg_parse_boolean (const char *str, int *res); |
251 | extern int mu_cfg_parser_verbose; | 266 | extern int mu_cfg_parser_verbose; |
252 | extern size_t mu_cfg_error_count; | 267 | extern size_t mu_cfg_error_count; |
253 | 268 | ||
254 | #define MU_CFG_FMT_LOCUS 0x01 | ||
255 | #define MU_CFG_FMT_VALUE_ONLY 0x02 | ||
256 | #define MU_CFG_FMT_PARAM_PATH 0x04 | ||
257 | |||
258 | void mu_cfg_format_docstring (mu_stream_t stream, const char *docstring, | 269 | void mu_cfg_format_docstring (mu_stream_t stream, const char *docstring, |
259 | int level); | 270 | int level); |
260 | void mu_cfg_format_parse_tree (mu_stream_t stream, struct mu_cfg_tree *tree, | 271 | 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, | ... | @@ -295,6 +306,9 @@ int mu_cfg_find_node (mu_cfg_tree_t *tree, const char *path, |
295 | mu_cfg_node_t **pnode); | 306 | mu_cfg_node_t **pnode); |
296 | int mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode); | 307 | int mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode); |
297 | 308 | ||
309 | int mu_cfg_parse_config (mu_cfg_tree_t **ptree, | ||
310 | struct mu_cfg_parse_hints *hints); | ||
311 | |||
298 | #ifdef __cplusplus | 312 | #ifdef __cplusplus |
299 | } | 313 | } |
300 | #endif | 314 | #endif | ... | ... |
... | @@ -387,7 +387,12 @@ mu_get_config (const char *file, const char *progname, | ... | @@ -387,7 +387,12 @@ mu_get_config (const char *file, const char *progname, |
387 | int rc = mu_cfg_parse_file (&parse_tree, file, flags); | 387 | int rc = mu_cfg_parse_file (&parse_tree, file, flags); |
388 | if (rc == 0) | 388 | if (rc == 0) |
389 | { | 389 | { |
390 | rc = mu_cfg_tree_postprocess (parse_tree, flags); | 390 | struct mu_cfg_parse_hints hints; |
391 | |||
392 | hints.flags = flags | MU_CFG_PARSE_PROGRAM; | ||
393 | hints.program = progname; | ||
394 | |||
395 | rc = mu_cfg_tree_postprocess (parse_tree, &hints); | ||
391 | if (rc == 0) | 396 | if (rc == 0) |
392 | rc = mu_cfg_tree_reduce (parse_tree, progname, progparam, flags, | 397 | rc = mu_cfg_tree_reduce (parse_tree, progname, progparam, flags, |
393 | target_ptr); | 398 | target_ptr); | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -165,16 +165,16 @@ mu_app_init (struct argp *myargp, const char **capa, | ... | @@ -165,16 +165,16 @@ mu_app_init (struct argp *myargp, const char **capa, |
165 | rc = mu_libcfg_parse_config (&parse_tree); | 165 | rc = mu_libcfg_parse_config (&parse_tree); |
166 | if (rc == 0) | 166 | if (rc == 0) |
167 | { | 167 | { |
168 | int cfgflags = MU_PARSE_CONFIG_PLAIN; | 168 | struct mu_cfg_parse_hints hints = { MU_PARSE_CONFIG_PLAIN }; |
169 | 169 | ||
170 | if (mu_cfg_parser_verbose) | 170 | if (mu_cfg_parser_verbose) |
171 | cfgflags |= MU_PARSE_CONFIG_VERBOSE; | 171 | hints.flags |= MU_PARSE_CONFIG_VERBOSE; |
172 | if (mu_cfg_parser_verbose > 1) | 172 | if (mu_cfg_parser_verbose > 1) |
173 | cfgflags |= MU_PARSE_CONFIG_DUMP; | 173 | hints.flags |= MU_PARSE_CONFIG_DUMP; |
174 | mu_cfg_tree_postprocess (mu_argp_tree, cfgflags); | 174 | mu_cfg_tree_postprocess (mu_argp_tree, &hints); |
175 | mu_cfg_tree_union (&parse_tree, &mu_argp_tree); | 175 | mu_cfg_tree_union (&parse_tree, &mu_argp_tree); |
176 | rc = mu_cfg_tree_reduce (parse_tree, mu_program_name, cfg_param, | 176 | rc = mu_cfg_tree_reduce (parse_tree, mu_program_name, cfg_param, |
177 | cfgflags, data); | 177 | hints.flags, data); |
178 | } | 178 | } |
179 | 179 | ||
180 | if (mu_rcfile_lint) | 180 | if (mu_rcfile_lint) | ... | ... |
... | @@ -88,77 +88,34 @@ mu_libcfg_init (char **cnames) | ... | @@ -88,77 +88,34 @@ mu_libcfg_init (char **cnames) |
88 | int | 88 | int |
89 | mu_libcfg_parse_config (mu_cfg_tree_t **ptree) | 89 | mu_libcfg_parse_config (mu_cfg_tree_t **ptree) |
90 | { | 90 | { |
91 | int flags = 0; | 91 | struct mu_cfg_parse_hints hints; |
92 | int rc = 0; | 92 | |
93 | mu_cfg_tree_t *tree = NULL, *tmp; | 93 | memset (&hints, 0, sizeof (hints)); |
94 | 94 | ||
95 | if (mu_cfg_parser_verbose) | 95 | if (mu_cfg_parser_verbose) |
96 | flags |= MU_PARSE_CONFIG_VERBOSE; | 96 | hints.flags |= MU_PARSE_CONFIG_VERBOSE; |
97 | if (mu_cfg_parser_verbose > 1) | 97 | if (mu_cfg_parser_verbose > 1) |
98 | flags |= MU_PARSE_CONFIG_DUMP; | 98 | hints.flags |= MU_PARSE_CONFIG_DUMP; |
99 | 99 | ||
100 | if (mu_load_site_rcfile) | 100 | if (mu_load_site_rcfile) |
101 | { | 101 | { |
102 | rc = mu_cfg_parse_file (&tmp, MU_CONFIG_FILE, flags); | 102 | hints.flags |= MU_CFG_PARSE_SITE_RCFILE; |
103 | 103 | hints.site_rcfile = MU_CONFIG_FILE; | |
104 | if (rc == ENOMEM) | ||
105 | { | ||
106 | mu_error ("%s", mu_strerror (rc)); | ||
107 | return rc; | ||
108 | } | ||
109 | else if (rc == 0) | ||
110 | { | ||
111 | mu_cfg_tree_postprocess (tmp, flags | MU_PARSE_CONFIG_GLOBAL); | ||
112 | mu_cfg_tree_union (&tree, &tmp); | ||
113 | } | ||
114 | } | 104 | } |
115 | 105 | ||
116 | if (mu_load_user_rcfile && mu_program_name) | 106 | if (mu_load_user_rcfile && mu_program_name) |
117 | { | 107 | { |
118 | size_t size = 3 + strlen (mu_program_name) + 1; | 108 | hints.flags |= MU_CFG_PARSE_PROGRAM; |
119 | char *file_name = malloc (size); | 109 | hints.program = (char*) mu_program_name; |
120 | if (file_name) | ||
121 | { | ||
122 | strcpy (file_name, "~/."); | ||
123 | strcat (file_name, mu_program_name); | ||
124 | |||
125 | rc = mu_cfg_parse_file (&tmp, file_name, flags); | ||
126 | if (rc == ENOMEM) | ||
127 | { | ||
128 | mu_error ("%s", mu_strerror (rc)); | ||
129 | mu_cfg_destroy_tree (&tree); | ||
130 | return rc; | ||
131 | } | ||
132 | else if (rc == 0) | ||
133 | { | ||
134 | mu_cfg_tree_postprocess (tmp, flags); | ||
135 | mu_cfg_tree_union (&tree, &tmp); | ||
136 | } | ||
137 | else if (rc == ENOENT) | ||
138 | rc = 0; | ||
139 | free (file_name); | ||
140 | } | ||
141 | } | 110 | } |
142 | 111 | ||
143 | if (mu_load_rcfile) | 112 | if (mu_load_rcfile) |
144 | { | 113 | { |
145 | rc = mu_cfg_parse_file (&tmp, mu_load_rcfile, flags); | 114 | hints.flags |= MU_CFG_PARSE_CUSTOM_RCFILE; |
146 | if (rc) | 115 | hints.custom_rcfile = mu_load_rcfile; |
147 | { | ||
148 | mu_error (_("errors parsing file %s: %s"), mu_load_rcfile, | ||
149 | mu_strerror (rc)); | ||
150 | mu_cfg_destroy_tree (&tree); | ||
151 | return rc; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | mu_cfg_tree_postprocess (tmp, flags); | ||
156 | mu_cfg_tree_union (&tree, &tmp); | ||
157 | } | ||
158 | } | 116 | } |
159 | 117 | ||
160 | *ptree = tree; | 118 | return mu_cfg_parse_config (ptree, &hints); |
161 | return rc; | ||
162 | } | 119 | } |
163 | 120 | ||
164 | 121 | ... | ... |
... | @@ -28,8 +28,8 @@ static char query_doc[] = N_("mu query - query configuration values."); | ... | @@ -28,8 +28,8 @@ static char query_doc[] = N_("mu query - query configuration values."); |
28 | char query_docstring[] = N_("query configuration values"); | 28 | char query_docstring[] = N_("query configuration values"); |
29 | static char query_args_doc[] = N_("path [path...]"); | 29 | static char query_args_doc[] = N_("path [path...]"); |
30 | 30 | ||
31 | char *file_name; | 31 | static char *file_name; |
32 | int fmtflags = 0; | 32 | static struct mu_cfg_parse_hints hints; |
33 | 33 | ||
34 | enum { | 34 | enum { |
35 | VALUE_OPTION = 256, | 35 | VALUE_OPTION = 256, |
... | @@ -43,6 +43,9 @@ static struct argp_option query_options[] = { | ... | @@ -43,6 +43,9 @@ static struct argp_option query_options[] = { |
43 | { "value", VALUE_OPTION, NULL, 0, | 43 | { "value", VALUE_OPTION, NULL, 0, |
44 | N_("display parameter values only"), | 44 | N_("display parameter values only"), |
45 | 0 }, | 45 | 0 }, |
46 | { "program", 'p', N_("NAME"), 0, | ||
47 | N_("set program name for configuration lookup"), | ||
48 | 0 }, | ||
46 | { "path", PATH_OPTION, NULL, 0, | 49 | { "path", PATH_OPTION, NULL, 0, |
47 | N_("display parameters as paths") }, | 50 | N_("display parameters as paths") }, |
48 | { "verbose", 'v', NULL, 0, | 51 | { "verbose", 'v', NULL, 0, |
... | @@ -59,16 +62,21 @@ query_parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -59,16 +62,21 @@ query_parse_opt (int key, char *arg, struct argp_state *state) |
59 | file_name = arg; | 62 | file_name = arg; |
60 | break; | 63 | break; |
61 | 64 | ||
65 | case 'p': | ||
66 | hints.flags |= MU_CFG_PARSE_PROGRAM; | ||
67 | hints.program = arg; | ||
68 | break; | ||
69 | |||
62 | case 'v': | 70 | case 'v': |
63 | fmtflags |= MU_CFG_FMT_LOCUS; | 71 | hints.flags |= MU_CFG_FMT_LOCUS; |
64 | break; | 72 | break; |
65 | 73 | ||
66 | case VALUE_OPTION: | 74 | case VALUE_OPTION: |
67 | fmtflags |= MU_CFG_FMT_VALUE_ONLY; | 75 | hints.flags |= MU_CFG_FMT_VALUE_ONLY; |
68 | break; | 76 | break; |
69 | 77 | ||
70 | case PATH_OPTION: | 78 | case PATH_OPTION: |
71 | fmtflags |= MU_CFG_FMT_PARAM_PATH; | 79 | hints.flags |= MU_CFG_FMT_PARAM_PATH; |
72 | break; | 80 | break; |
73 | 81 | ||
74 | default: | 82 | default: |
... | @@ -105,14 +113,10 @@ mutool_query (int argc, char **argv) | ... | @@ -105,14 +113,10 @@ mutool_query (int argc, char **argv) |
105 | return 1; | 113 | return 1; |
106 | } | 114 | } |
107 | 115 | ||
108 | if (file_name) | 116 | hints.flags |= MU_CFG_PARSE_SITE_RCFILE | MU_PARSE_CONFIG_GLOBAL; |
109 | { | 117 | hints.site_rcfile = file_name ? file_name : MU_CONFIG_FILE; |
110 | mu_load_site_rcfile = 0; | ||
111 | mu_load_user_rcfile = 0; | ||
112 | mu_load_rcfile = file_name; | ||
113 | } | ||
114 | 118 | ||
115 | if (mu_libcfg_parse_config (&tree)) | 119 | if (mu_cfg_parse_config (&tree, &hints)) |
116 | return 1; | 120 | return 1; |
117 | if (!tree) | 121 | if (!tree) |
118 | return 0; | 122 | return 0; |
... | @@ -122,7 +126,7 @@ mutool_query (int argc, char **argv) | ... | @@ -122,7 +126,7 @@ mutool_query (int argc, char **argv) |
122 | mu_cfg_node_t *node; | 126 | mu_cfg_node_t *node; |
123 | 127 | ||
124 | if (mu_cfg_find_node (tree, path, &node) == 0) | 128 | if (mu_cfg_find_node (tree, path, &node) == 0) |
125 | mu_cfg_format_node (mu_strout, node, fmtflags); | 129 | mu_cfg_format_node (mu_strout, node, hints.flags); |
126 | } | 130 | } |
127 | return 0; | 131 | return 0; |
128 | } | 132 | } | ... | ... |
-
Please register or sign in to post a comment