Commit e1f5e01f e1f5e01f24e9b102f0f806b3af9cb47a7f4daca7 by Sergey Poznyakoff

Re-do configuration tree support using mu_list_t.

* include/mailutils/cfg.h (mu_cfg_node)
<next,node>: Remove members.
<nodes>: New member.
(mu_cfg_tree)<head,tail>: Remove.
<nodes>: New member.
(mu_cfg_iter_closure): New struct.
(mu_cfg_preorder): Change prototype.
(mu_cfg_postorder): Remove.
(mu_cfg_create_node_list): New proto.
(mu_cfg_tree_create_node): Change signature.
(mu_cfg_tree_add_nodelist): New proto.
(mu_cfg_find_node): Change signature.
* include/mailutils/libargp.h (mu_argp_node_list): Remove struct.
(mu_argp_node_list_init, mu_argp_node_list_add)
(mu_argp_node_list_new, mu_argp_node_list_finish): Change signature.
* libmu_argp/cmdline.c (mu_argp_node_list_init, mu_argp_node_list_add)
(mu_argp_node_list_new, mu_argp_node_list_finish): Take mu_list_t as
the nodelist argument.

* mailbox/cfg_parser.y (parse_head,parse_tail): Remove.
(parse_node_list): New static, used instead of the above.
All uses updated.
(mu_cfg_alloc_node): Last argument is mu_list_t.
(mu_cfg_create_node_list): New function.
(mu_cfg_tree_postprocess): Rewrite.
(mu_cfg_preorder): Rewrite.
(mu_cfg_postorder): Remove.
(mu_cfg_destroy_tree): Use mu_list_destroy to free
the node list.
(mu_cfg_scan_tree): Update calls to mu_cfg_preorder.
(mu_cfg_tree_add_node): Rewrite.
(mu_cfg_tree_add_nodelist): New function.
(mu_cfg_find_node): Change type of the first argument.
(mu_cfg_create_subtree): Rewrite.

* mailbox/cfg_format.c (mu_cfg_format_parse_tree)
(mu_cfg_format_node): Use new mu_cfg_preorder function.

* libmu_argp/common.c: Update calls to mu_argp_node_ functions.
* libmu_argp/auth.c: Likewise.
* comsat/comsat.c: Likewise.
* config/mailutils-config.c: Likewise.
* dotlock/dotlock.c: Likewise.
* imap4d/imap4d.c: Likewise.
* libmu_argp/sieve.c: Likewise.
* libmu_argp/tls.c: Likewise.
* maidag/maidag.c: Likewise.
* mimeview/mimeview.c: Likewise.
* movemail/movemail.c: Likewise.
* pop3d/pop3d.c: Likewise.
* readmsg/readmsg.c: Likewise.
* sieve/sieve.c: Likewise.
1 parent afce403c
...@@ -147,7 +147,7 @@ struct mu_cfg_param comsat_cfg_param[] = { ...@@ -147,7 +147,7 @@ struct mu_cfg_param comsat_cfg_param[] = {
147 static error_t 147 static error_t
148 comsatd_parse_opt (int key, char *arg, struct argp_state *state) 148 comsatd_parse_opt (int key, char *arg, struct argp_state *state)
149 { 149 {
150 static struct mu_argp_node_list lst; 150 static mu_list_t lst;
151 151
152 switch (key) 152 switch (key)
153 { 153 {
...@@ -179,17 +179,17 @@ _("The old configuration file format and the --config command\n" ...@@ -179,17 +179,17 @@ _("The old configuration file format and the --config command\n"
179 exit (0); 179 exit (0);
180 180
181 case 'd': 181 case 'd':
182 mu_argp_node_list_new (&lst, "mode", "daemon"); 182 mu_argp_node_list_new (lst, "mode", "daemon");
183 if (arg) 183 if (arg)
184 mu_argp_node_list_new (&lst, "max-children", arg); 184 mu_argp_node_list_new (lst, "max-children", arg);
185 break; 185 break;
186 186
187 case 'i': 187 case 'i':
188 mu_argp_node_list_new (&lst, "mode", "inetd"); 188 mu_argp_node_list_new (lst, "mode", "inetd");
189 break; 189 break;
190 190
191 case OPT_FOREGROUND: 191 case OPT_FOREGROUND:
192 mu_argp_node_list_new (&lst, "foreground", "yes"); 192 mu_argp_node_list_new (lst, "foreground", "yes");
193 break; 193 break;
194 194
195 case 't': 195 case 't':
...@@ -201,7 +201,7 @@ _("The old configuration file format and the --config command\n" ...@@ -201,7 +201,7 @@ _("The old configuration file format and the --config command\n"
201 break; 201 break;
202 202
203 case ARGP_KEY_FINI: 203 case ARGP_KEY_FINI:
204 mu_argp_node_list_finish (&lst, NULL, NULL); 204 mu_argp_node_list_finish (lst, NULL, NULL);
205 break; 205 break;
206 206
207 default: 207 default:
......
...@@ -356,7 +356,7 @@ main (int argc, char **argv) ...@@ -356,7 +356,7 @@ main (int argc, char **argv)
356 char *path = *argv; 356 char *path = *argv;
357 mu_cfg_node_t *node; 357 mu_cfg_node_t *node;
358 358
359 if (mu_cfg_find_node (tree->head, path, &node) == 0) 359 if (mu_cfg_find_node (tree, path, &node) == 0)
360 { 360 {
361 mu_cfg_format_node (stream, node, fmtflags); 361 mu_cfg_format_node (stream, node, fmtflags);
362 } 362 }
......
...@@ -77,12 +77,12 @@ static int debug; ...@@ -77,12 +77,12 @@ static int debug;
77 static error_t 77 static error_t
78 parse_opt (int key, char *arg, struct argp_state *state) 78 parse_opt (int key, char *arg, struct argp_state *state)
79 { 79 {
80 static struct mu_argp_node_list lst; 80 static mu_list_t lst;
81 81
82 switch (key) 82 switch (key)
83 { 83 {
84 case 'd': 84 case 'd':
85 mu_argp_node_list_new (&lst, "debug", "yes"); 85 mu_argp_node_list_new (lst, "debug", "yes");
86 break; 86 break;
87 87
88 case 'u': 88 case 'u':
...@@ -91,11 +91,11 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -91,11 +91,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
91 91
92 case 'r': 92 case 'r':
93 if (arg) 93 if (arg)
94 mu_argp_node_list_new (&lst, "retry", arg); 94 mu_argp_node_list_new (lst, "retry", arg);
95 break; 95 break;
96 96
97 case 'f': 97 case 'f':
98 mu_argp_node_list_new (&lst, "force", arg ? arg : "0"); 98 mu_argp_node_list_new (lst, "force", arg ? arg : "0");
99 break; 99 break;
100 100
101 case ARGP_KEY_ARG: 101 case ARGP_KEY_ARG:
...@@ -114,7 +114,7 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -114,7 +114,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
114 break; 114 break;
115 115
116 case ARGP_KEY_FINI: 116 case ARGP_KEY_FINI:
117 mu_argp_node_list_finish (&lst, NULL, NULL); 117 mu_argp_node_list_finish (lst, NULL, NULL);
118 break; 118 break;
119 119
120 default: 120 default:
......
...@@ -101,22 +101,22 @@ static int imap4d_mainloop (int, FILE *, FILE *); ...@@ -101,22 +101,22 @@ static int imap4d_mainloop (int, FILE *, FILE *);
101 static error_t 101 static error_t
102 imap4d_parse_opt (int key, char *arg, struct argp_state *state) 102 imap4d_parse_opt (int key, char *arg, struct argp_state *state)
103 { 103 {
104 static struct mu_argp_node_list lst; 104 static mu_list_t lst;
105 105
106 switch (key) 106 switch (key)
107 { 107 {
108 case 'd': 108 case 'd':
109 mu_argp_node_list_new (&lst, "mode", "daemon"); 109 mu_argp_node_list_new (lst, "mode", "daemon");
110 if (arg) 110 if (arg)
111 mu_argp_node_list_new (&lst, "max-children", arg); 111 mu_argp_node_list_new (lst, "max-children", arg);
112 break; 112 break;
113 113
114 case 'i': 114 case 'i':
115 mu_argp_node_list_new (&lst, "mode", "inetd"); 115 mu_argp_node_list_new (lst, "mode", "inetd");
116 break; 116 break;
117 117
118 case OPT_FOREGROUND: 118 case OPT_FOREGROUND:
119 mu_argp_node_list_new (&lst, "foreground", "yes"); 119 mu_argp_node_list_new (lst, "foreground", "yes");
120 break; 120 break;
121 121
122 case OPT_PREAUTH: 122 case OPT_PREAUTH:
...@@ -128,7 +128,7 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) ...@@ -128,7 +128,7 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state)
128 break; 128 break;
129 129
130 case ARGP_KEY_FINI: 130 case ARGP_KEY_FINI:
131 mu_argp_node_list_finish (&lst, NULL, NULL); 131 mu_argp_node_list_finish (lst, NULL, NULL);
132 break; 132 break;
133 133
134 default: 134 default:
......
...@@ -70,17 +70,16 @@ struct mu_cfg_locus ...@@ -70,17 +70,16 @@ struct mu_cfg_locus
70 70
71 struct mu_cfg_node 71 struct mu_cfg_node
72 { 72 {
73 mu_cfg_node_t *next;
74 mu_cfg_locus_t locus; 73 mu_cfg_locus_t locus;
75 enum mu_cfg_node_type type; 74 enum mu_cfg_node_type type;
76 char *tag; 75 char *tag;
77 mu_config_value_t *label; 76 mu_config_value_t *label;
78 mu_cfg_node_t *node; 77 mu_list_t nodes; /* a list of mu_cfg_node_t */
79 }; 78 };
80 79
81 struct mu_cfg_tree 80 struct mu_cfg_tree
82 { 81 {
83 mu_cfg_node_t *head, *tail; 82 mu_list_t nodes; /* a list of mu_cfg_node_t */
84 mu_debug_t debug; 83 mu_debug_t debug;
85 mu_opool_t pool; 84 mu_opool_t pool;
86 }; 85 };
...@@ -107,14 +106,16 @@ void mu_cfg_format_error (mu_debug_t debug, size_t, const char *fmt, ...) ...@@ -107,14 +106,16 @@ void mu_cfg_format_error (mu_debug_t debug, size_t, const char *fmt, ...)
107 106
108 typedef int (*mu_cfg_iter_func_t) (const mu_cfg_node_t *node, void *data); 107 typedef int (*mu_cfg_iter_func_t) (const mu_cfg_node_t *node, void *data);
109 108
109 struct mu_cfg_iter_closure
110 {
111 mu_cfg_iter_func_t beg;
112 mu_cfg_iter_func_t end;
113 void *data;
114 };
115
110 void mu_cfg_destroy_tree (mu_cfg_tree_t **tree); 116 void mu_cfg_destroy_tree (mu_cfg_tree_t **tree);
111 117
112 int mu_cfg_preorder (mu_cfg_node_t *node, 118 int mu_cfg_preorder (mu_list_t nodelist, struct mu_cfg_iter_closure *);
113 mu_cfg_iter_func_t fun, mu_cfg_iter_func_t endfun,
114 void *data);
115 int mu_cfg_postorder (mu_cfg_node_t *node,
116 mu_cfg_iter_func_t fun, mu_cfg_iter_func_t endfun,
117 void *data);
118 119
119 120
120 /* Table-driven parsing */ 121 /* Table-driven parsing */
...@@ -227,6 +228,8 @@ int mu_create_canned_section (char *name, struct mu_cfg_section **psection); ...@@ -227,6 +228,8 @@ int mu_create_canned_section (char *name, struct mu_cfg_section **psection);
227 int mu_create_canned_param (char *name, struct mu_cfg_param **pparam); 228 int mu_create_canned_param (char *name, struct mu_cfg_param **pparam);
228 struct mu_cfg_cont *mu_get_canned_container (const char *name); 229 struct mu_cfg_cont *mu_get_canned_container (const char *name);
229 230
231 int mu_cfg_create_node_list (mu_list_t *plist);
232
230 int mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections, 233 int mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
231 void *target, void *call_data); 234 void *target, void *call_data);
232 235
...@@ -300,10 +303,11 @@ mu_cfg_node_t *mu_cfg_tree_create_node (struct mu_cfg_tree *tree, ...@@ -300,10 +303,11 @@ mu_cfg_node_t *mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
300 const mu_cfg_locus_t *loc, 303 const mu_cfg_locus_t *loc,
301 const char *tag, 304 const char *tag,
302 const char *label, 305 const char *label,
303 mu_cfg_node_t *node); 306 mu_list_t nodelist);
304 void mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node); 307 void mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node);
308 void mu_cfg_tree_add_nodelist (mu_cfg_tree_t *tree, mu_list_t nodelist);
305 309
306 int mu_cfg_find_node (mu_cfg_node_t *tree, const char *path, 310 int mu_cfg_find_node (mu_cfg_tree_t *tree, const char *path,
307 mu_cfg_node_t **pnode); 311 mu_cfg_node_t **pnode);
308 int mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode); 312 int mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode);
309 313
......
...@@ -83,17 +83,10 @@ error_t mu_argp_parse (const struct argp *myargp, ...@@ -83,17 +83,10 @@ error_t mu_argp_parse (const struct argp *myargp,
83 int *arg_index, 83 int *arg_index,
84 void *input) __attribute__ ((deprecated)); 84 void *input) __attribute__ ((deprecated));
85 85
86 struct mu_argp_node_list 86 void mu_argp_node_list_init (mu_list_t *);
87 { 87 void mu_argp_node_list_add (mu_list_t, mu_cfg_node_t *);
88 int count; 88 void mu_argp_node_list_new (mu_list_t, const char *, const char *);
89 mu_cfg_node_t *head, *tail; 89 void mu_argp_node_list_finish (mu_list_t, char *, char *);
90 };
91
92 void mu_argp_node_list_init (struct mu_argp_node_list *);
93 void mu_argp_node_list_add (struct mu_argp_node_list *, mu_cfg_node_t *);
94 void mu_argp_node_list_new (struct mu_argp_node_list *,
95 const char *, const char *);
96 void mu_argp_node_list_finish (struct mu_argp_node_list *, char *, char *);
97 90
98 #ifdef __cplusplus 91 #ifdef __cplusplus
99 } 92 }
......
...@@ -68,7 +68,7 @@ auth_set_debug () ...@@ -68,7 +68,7 @@ auth_set_debug ()
68 static error_t 68 static error_t
69 mu_auth_argp_parser (int key, char *arg, struct argp_state *state) 69 mu_auth_argp_parser (int key, char *arg, struct argp_state *state)
70 { 70 {
71 static struct mu_argp_node_list lst; 71 static mu_list_t lst;
72 72
73 switch (key) 73 switch (key)
74 { 74 {
...@@ -77,7 +77,7 @@ mu_auth_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -77,7 +77,7 @@ mu_auth_argp_parser (int key, char *arg, struct argp_state *state)
77 break; 77 break;
78 78
79 case ARGP_KEY_FINI: 79 case ARGP_KEY_FINI:
80 mu_argp_node_list_finish (&lst, "auth", NULL); 80 mu_argp_node_list_finish (lst, "auth", NULL);
81 break; 81 break;
82 82
83 case OPT_DEBUG_AUTH: 83 case OPT_DEBUG_AUTH:
......
...@@ -56,53 +56,57 @@ mu_libargp_init () ...@@ -56,53 +56,57 @@ mu_libargp_init ()
56 } 56 }
57 57
58 void 58 void
59 mu_argp_node_list_init (struct mu_argp_node_list *lst) 59 mu_argp_node_list_init (mu_list_t *plist)
60 { 60 {
61 lst->count = 0; 61 int rc = mu_cfg_create_node_list (plist);
62 lst->head = lst->tail = NULL; 62 if (rc)
63 {
64 mu_diag_funcall (MU_DIAG_ERROR, "mu_cfg_create_node_list", NULL, rc);
65 abort ();
66 }
63 } 67 }
64 68
65 void 69 void
66 mu_argp_node_list_add (struct mu_argp_node_list *lst, mu_cfg_node_t *node) 70 mu_argp_node_list_add (mu_list_t lst, mu_cfg_node_t *node)
67 { 71 {
68 lst->count++; 72 int rc = mu_list_append (lst, node);
69 if (lst->tail) 73 if (rc)
70 lst->tail->next = node; 74 {
71 else 75 mu_diag_funcall (MU_DIAG_ERROR, "mu_list_append", NULL, rc);
72 lst->head = node; 76 abort ();
73 lst->tail = node; 77 }
74 } 78 }
75 79
76 void 80 void
77 mu_argp_node_list_new (struct mu_argp_node_list *lst, 81 mu_argp_node_list_new (mu_list_t lst, const char *tag, const char *label)
78 const char *tag, const char *label)
79 { 82 {
80 mu_cfg_node_t *node; 83 mu_cfg_node_t *node;
81 mu_cfg_locus_t loc = { "command line", 0 }; 84 mu_cfg_locus_t loc = { "command line", 0 };
82 85
83 loc.line = lst->count; 86 mu_list_count (lst, &loc.line);
84 node = mu_cfg_tree_create_node (mu_argp_tree, mu_cfg_node_param, 87 node = mu_cfg_tree_create_node (mu_argp_tree, mu_cfg_node_param,
85 &loc, tag, label, NULL); 88 &loc, tag, label, NULL);
86 mu_argp_node_list_add (lst, node); 89 mu_argp_node_list_add (lst, node);
87 } 90 }
88 91
89 void 92 void
90 mu_argp_node_list_finish (struct mu_argp_node_list *lst, char *tag, 93 mu_argp_node_list_finish (mu_list_t lst, char *tag, char *label)
91 char *label)
92 { 94 {
93 mu_cfg_node_t *node; 95 if (mu_list_is_empty (lst))
94
95 if (!lst->head)
96 return; 96 return;
97 if (tag) 97 if (tag)
98 node = mu_cfg_tree_create_node (mu_argp_tree, 98 {
99 mu_cfg_node_statement, 99 mu_cfg_node_t *node = mu_cfg_tree_create_node (mu_argp_tree,
100 NULL, 100 mu_cfg_node_statement,
101 tag, label, 101 NULL,
102 lst->head); 102 tag, label,
103 lst);
104 mu_cfg_tree_add_node (mu_argp_tree, node);
105 }
103 else 106 else
104 node = lst->head; 107 {
105 mu_cfg_tree_add_node (mu_argp_tree, node); 108 mu_cfg_tree_add_nodelist (mu_argp_tree, lst);
106 mu_argp_node_list_init (lst); 109 mu_list_destroy (&lst);
110 }
107 } 111 }
108 112
......
...@@ -157,13 +157,13 @@ static struct argp_option mu_logging_argp_option[] = { ...@@ -157,13 +157,13 @@ static struct argp_option mu_logging_argp_option[] = {
157 static error_t 157 static error_t
158 mu_logging_argp_parser (int key, char *arg, struct argp_state *state) 158 mu_logging_argp_parser (int key, char *arg, struct argp_state *state)
159 { 159 {
160 static struct mu_argp_node_list lst; 160 static mu_list_t lst;
161 161
162 switch (key) 162 switch (key)
163 { 163 {
164 /* log */ 164 /* log */
165 case OPT_LOG_FACILITY: 165 case OPT_LOG_FACILITY:
166 mu_argp_node_list_new (&lst, "facility", arg); 166 mu_argp_node_list_new (lst, "facility", arg);
167 break; 167 break;
168 168
169 case ARGP_KEY_INIT: 169 case ARGP_KEY_INIT:
...@@ -171,7 +171,7 @@ mu_logging_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -171,7 +171,7 @@ mu_logging_argp_parser (int key, char *arg, struct argp_state *state)
171 break; 171 break;
172 172
173 case ARGP_KEY_FINI: 173 case ARGP_KEY_FINI:
174 mu_argp_node_list_finish (&lst, "logging", NULL); 174 mu_argp_node_list_finish (lst, "logging", NULL);
175 break; 175 break;
176 176
177 default: 177 default:
...@@ -254,13 +254,13 @@ static struct argp_option mu_mailer_argp_option[] = { ...@@ -254,13 +254,13 @@ static struct argp_option mu_mailer_argp_option[] = {
254 static error_t 254 static error_t
255 mu_mailer_argp_parser (int key, char *arg, struct argp_state *state) 255 mu_mailer_argp_parser (int key, char *arg, struct argp_state *state)
256 { 256 {
257 static struct mu_argp_node_list lst; 257 static mu_list_t lst;
258 258
259 switch (key) 259 switch (key)
260 { 260 {
261 /* mailer */ 261 /* mailer */
262 case 'M': 262 case 'M':
263 mu_argp_node_list_new (&lst, "url", arg); 263 mu_argp_node_list_new (lst, "url", arg);
264 break; 264 break;
265 265
266 case ARGP_KEY_INIT: 266 case ARGP_KEY_INIT:
...@@ -268,7 +268,7 @@ mu_mailer_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -268,7 +268,7 @@ mu_mailer_argp_parser (int key, char *arg, struct argp_state *state)
268 break; 268 break;
269 269
270 case ARGP_KEY_FINI: 270 case ARGP_KEY_FINI:
271 mu_argp_node_list_finish (&lst, "mailer", NULL); 271 mu_argp_node_list_finish (lst, "mailer", NULL);
272 break; 272 break;
273 273
274 default: 274 default:
...@@ -306,17 +306,17 @@ static struct argp_option mu_debug_argp_options[] = ...@@ -306,17 +306,17 @@ static struct argp_option mu_debug_argp_options[] =
306 static error_t 306 static error_t
307 mu_debug_argp_parser (int key, char *arg, struct argp_state *state) 307 mu_debug_argp_parser (int key, char *arg, struct argp_state *state)
308 { 308 {
309 static struct mu_argp_node_list lst; 309 static mu_list_t lst;
310 310
311 switch (key) 311 switch (key)
312 { 312 {
313 case OPT_DEBUG_LEVEL: 313 case OPT_DEBUG_LEVEL:
314 mu_global_debug_from_string (arg, "command line"); 314 mu_global_debug_from_string (arg, "command line");
315 /*mu_argp_node_list_new (&lst, "level", arg);*/ 315 /*mu_argp_node_list_new (lst, "level", arg);*/
316 break; 316 break;
317 317
318 case OPT_LINE_INFO: 318 case OPT_LINE_INFO:
319 mu_argp_node_list_new (&lst, "line-info", "yes"); 319 mu_argp_node_list_new (lst, "line-info", "yes");
320 break; 320 break;
321 321
322 case ARGP_KEY_INIT: 322 case ARGP_KEY_INIT:
...@@ -324,7 +324,7 @@ mu_debug_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -324,7 +324,7 @@ mu_debug_argp_parser (int key, char *arg, struct argp_state *state)
324 break; 324 break;
325 325
326 case ARGP_KEY_FINI: 326 case ARGP_KEY_FINI:
327 mu_argp_node_list_finish (&lst, "debug", NULL); 327 mu_argp_node_list_finish (lst, "debug", NULL);
328 break; 328 break;
329 329
330 default: 330 default:
......
...@@ -44,24 +44,24 @@ static struct argp_option sieve_argp_option[] = { ...@@ -44,24 +44,24 @@ static struct argp_option sieve_argp_option[] = {
44 static error_t 44 static error_t
45 sieve_argp_parser (int key, char *arg, struct argp_state *state) 45 sieve_argp_parser (int key, char *arg, struct argp_state *state)
46 { 46 {
47 static struct mu_argp_node_list lst; 47 static mu_list_t lst;
48 48
49 switch (key) 49 switch (key)
50 { 50 {
51 case 'I': 51 case 'I':
52 mu_argp_node_list_new (&lst, "include-path", arg); 52 mu_argp_node_list_new (lst, "include-path", arg);
53 break; 53 break;
54 54
55 case 'L': 55 case 'L':
56 mu_argp_node_list_new (&lst, "library-path", arg); 56 mu_argp_node_list_new (lst, "library-path", arg);
57 break; 57 break;
58 58
59 case OPT_CLEAR_INCLUDE_PATH: 59 case OPT_CLEAR_INCLUDE_PATH:
60 mu_argp_node_list_new (&lst, "clear-include-path", "yes"); 60 mu_argp_node_list_new (lst, "clear-include-path", "yes");
61 break; 61 break;
62 62
63 case OPT_CLEAR_LIBRARY_PATH: 63 case OPT_CLEAR_LIBRARY_PATH:
64 mu_argp_node_list_new (&lst, "clear-library-path", "yes"); 64 mu_argp_node_list_new (lst, "clear-library-path", "yes");
65 break; 65 break;
66 66
67 case ARGP_KEY_INIT: 67 case ARGP_KEY_INIT:
...@@ -69,7 +69,7 @@ sieve_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -69,7 +69,7 @@ sieve_argp_parser (int key, char *arg, struct argp_state *state)
69 break; 69 break;
70 70
71 case ARGP_KEY_FINI: 71 case ARGP_KEY_FINI:
72 mu_argp_node_list_finish (&lst, "sieve", NULL); 72 mu_argp_node_list_finish (lst, "sieve", NULL);
73 break; 73 break;
74 74
75 default: 75 default:
......
...@@ -35,12 +35,12 @@ static struct argp_option _tls_argp_options[] = { ...@@ -35,12 +35,12 @@ static struct argp_option _tls_argp_options[] = {
35 static error_t 35 static error_t
36 _tls_argp_parser (int key, char *arg, struct argp_state *state) 36 _tls_argp_parser (int key, char *arg, struct argp_state *state)
37 { 37 {
38 static struct mu_argp_node_list lst; 38 static mu_list_t lst;
39 39
40 switch (key) 40 switch (key)
41 { 41 {
42 case OPT_TLS: 42 case OPT_TLS:
43 mu_argp_node_list_new (&lst, "enable", arg ? arg : "yes"); 43 mu_argp_node_list_new (lst, "enable", arg ? arg : "yes");
44 break; 44 break;
45 45
46 case ARGP_KEY_INIT: 46 case ARGP_KEY_INIT:
...@@ -48,7 +48,7 @@ _tls_argp_parser (int key, char *arg, struct argp_state *state) ...@@ -48,7 +48,7 @@ _tls_argp_parser (int key, char *arg, struct argp_state *state)
48 break; 48 break;
49 49
50 case ARGP_KEY_FINI: 50 case ARGP_KEY_FINI:
51 mu_argp_node_list_finish (&lst, "tls", NULL); 51 mu_argp_node_list_finish (lst, "tls", NULL);
52 break; 52 break;
53 53
54 default: 54 default:
......
...@@ -184,32 +184,32 @@ set_debug_flags (mu_debug_t debug, const char *arg) ...@@ -184,32 +184,32 @@ set_debug_flags (mu_debug_t debug, const char *arg)
184 static error_t 184 static error_t
185 parse_opt (int key, char *arg, struct argp_state *state) 185 parse_opt (int key, char *arg, struct argp_state *state)
186 { 186 {
187 static struct mu_argp_node_list lst; 187 static mu_list_t lst;
188 188
189 switch (key) 189 switch (key)
190 { 190 {
191 case 'd': 191 case 'd':
192 mu_argp_node_list_new (&lst, "mode", "daemon"); 192 mu_argp_node_list_new (lst, "mode", "daemon");
193 if (arg) 193 if (arg)
194 mu_argp_node_list_new (&lst, "max-children", arg); 194 mu_argp_node_list_new (lst, "max-children", arg);
195 break; 195 break;
196 196
197 case 'i': 197 case 'i':
198 mu_argp_node_list_new (&lst, "mode", "inetd"); 198 mu_argp_node_list_new (lst, "mode", "inetd");
199 break; 199 break;
200 200
201 case FOREGROUND_OPTION: 201 case FOREGROUND_OPTION:
202 mu_argp_node_list_new (&lst, "foreground", "yes"); 202 mu_argp_node_list_new (lst, "foreground", "yes");
203 break; 203 break;
204 204
205 case MESSAGE_ID_HEADER_OPTION: 205 case MESSAGE_ID_HEADER_OPTION:
206 mu_argp_node_list_new (&lst, "message-id-header", arg); 206 mu_argp_node_list_new (lst, "message-id-header", arg);
207 break; 207 break;
208 208
209 case LMTP_OPTION: 209 case LMTP_OPTION:
210 mu_argp_node_list_new (&lst, "lmtp", "yes"); 210 mu_argp_node_list_new (lst, "lmtp", "yes");
211 if (arg) 211 if (arg)
212 mu_argp_node_list_new (&lst, "listen", arg); 212 mu_argp_node_list_new (lst, "listen", arg);
213 break; 213 break;
214 214
215 case 'r': 215 case 'r':
...@@ -242,11 +242,11 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -242,11 +242,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
242 break; 242 break;
243 243
244 case 'x': 244 case 'x':
245 mu_argp_node_list_new (&lst, "debug", arg ? arg : D_DEFAULT); 245 mu_argp_node_list_new (lst, "debug", arg ? arg : D_DEFAULT);
246 break; 246 break;
247 247
248 case STDERR_OPTION: 248 case STDERR_OPTION:
249 mu_argp_node_list_new (&lst, "stderr", "yes"); 249 mu_argp_node_list_new (lst, "stderr", "yes");
250 break; 250 break;
251 251
252 case URL_OPTION: 252 case URL_OPTION:
...@@ -258,7 +258,7 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -258,7 +258,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
258 break; 258 break;
259 259
260 case ARGP_KEY_FINI: 260 case ARGP_KEY_FINI:
261 mu_argp_node_list_finish (&lst, NULL, NULL); 261 mu_argp_node_list_finish (lst, NULL, NULL);
262 break; 262 break;
263 263
264 case ARGP_KEY_ERROR: 264 case ARGP_KEY_ERROR:
......
...@@ -186,13 +186,18 @@ format_node_end (const mu_cfg_node_t *node, void *data) ...@@ -186,13 +186,18 @@ format_node_end (const mu_cfg_node_t *node, void *data)
186 void 186 void
187 mu_cfg_format_parse_tree (mu_stream_t stream, mu_cfg_tree_t *tree, int flags) 187 mu_cfg_format_parse_tree (mu_stream_t stream, mu_cfg_tree_t *tree, int flags)
188 { 188 {
189 struct mu_cfg_iter_closure clos;
189 struct tree_print t; 190 struct tree_print t;
191
190 t.flags = flags; 192 t.flags = flags;
191 t.level = 0; 193 t.level = 0;
192 t.stream = stream; 194 t.stream = stream;
193 t.buf = NULL; 195 t.buf = NULL;
194 t.bufsize = 0; 196 t.bufsize = 0;
195 mu_cfg_preorder (tree->head, format_node, format_node_end, &t); 197 clos.beg = format_node;
198 clos.end = format_node_end;
199 clos.data = &t;
200 mu_cfg_preorder (tree->nodes, &clos);
196 free (t.buf); 201 free (t.buf);
197 } 202 }
198 203
...@@ -200,6 +205,7 @@ void ...@@ -200,6 +205,7 @@ void
200 mu_cfg_format_node (mu_stream_t stream, const mu_cfg_node_t *node, int flags) 205 mu_cfg_format_node (mu_stream_t stream, const mu_cfg_node_t *node, int flags)
201 { 206 {
202 struct tree_print t; 207 struct tree_print t;
208
203 t.flags = flags; 209 t.flags = flags;
204 t.level = 0; 210 t.level = 0;
205 t.stream = stream; 211 t.stream = stream;
...@@ -208,7 +214,11 @@ mu_cfg_format_node (mu_stream_t stream, const mu_cfg_node_t *node, int flags) ...@@ -208,7 +214,11 @@ mu_cfg_format_node (mu_stream_t stream, const mu_cfg_node_t *node, int flags)
208 format_node (node, &t); 214 format_node (node, &t);
209 if (node->type == mu_cfg_node_statement) 215 if (node->type == mu_cfg_node_statement)
210 { 216 {
211 mu_cfg_preorder (node->node, format_node, format_node_end, &t); 217 struct mu_cfg_iter_closure clos;
218 clos.beg = format_node;
219 clos.end = format_node_end;
220 clos.data = &t;
221 mu_cfg_preorder (node->nodes, &clos);
212 format_node_end (node, &t); 222 format_node_end (node, &t);
213 } 223 }
214 } 224 }
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
38 #include <mailutils/mutil.h> 38 #include <mailutils/mutil.h>
39 39
40 int mu_cfg_parser_verbose; 40 int mu_cfg_parser_verbose;
41 static mu_cfg_node_t *parse_head, *parse_tail; 41 static mu_list_t /* of mu_cfg_node_t */ parse_node_list;
42 mu_cfg_locus_t mu_cfg_locus; 42 mu_cfg_locus_t mu_cfg_locus;
43 size_t mu_cfg_error_count; 43 size_t mu_cfg_error_count;
44 44
...@@ -75,7 +75,7 @@ config_value_dup (mu_config_value_t *src) ...@@ -75,7 +75,7 @@ config_value_dup (mu_config_value_t *src)
75 static mu_cfg_node_t * 75 static mu_cfg_node_t *
76 mu_cfg_alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc, 76 mu_cfg_alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc,
77 const char *tag, mu_config_value_t *label, 77 const char *tag, mu_config_value_t *label,
78 mu_cfg_node_t *node) 78 mu_list_t nodelist)
79 { 79 {
80 char *p; 80 char *p;
81 mu_cfg_node_t *np; 81 mu_cfg_node_t *np;
...@@ -87,8 +87,7 @@ mu_cfg_alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc, ...@@ -87,8 +87,7 @@ mu_cfg_alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc,
87 np->tag = p; 87 np->tag = p;
88 strcpy (p, tag); 88 strcpy (p, tag);
89 np->label = label; 89 np->label = label;
90 np->node = node; 90 np->nodes = nodelist;
91 np->next = NULL;
92 return np; 91 return np;
93 } 92 }
94 93
...@@ -179,12 +178,44 @@ debug_print_node (mu_cfg_node_t *node) ...@@ -179,12 +178,44 @@ debug_print_node (mu_cfg_node_t *node)
179 } 178 }
180 } 179 }
181 180
181 static void
182 free_node_item (void *item)
183 {
184 mu_cfg_node_t *node = item;
185
186 switch (node->type)
187 {
188 case mu_cfg_node_statement:
189 mu_list_destroy (&node->nodes);
190 break;
191
192 case mu_cfg_node_undefined: /* hmm... */
193 case mu_cfg_node_param:
194 break;
195 }
196 mu_cfg_free_node (node);
197 }
198
199 int
200 mu_cfg_create_node_list (mu_list_t *plist)
201 {
202 int rc;
203 mu_list_t list;
204
205 rc = mu_list_create (&list);
206 if (rc)
207 return rc;
208 mu_list_set_destroy_item (list, free_node_item);
209 *plist = list;
210 return 0;
211 }
212
182 %} 213 %}
183 214
184 %union { 215 %union {
185 mu_cfg_node_t node; 216 mu_cfg_node_t node;
186 mu_cfg_node_t *pnode; 217 mu_cfg_node_t *pnode;
187 struct { mu_cfg_node_t *head, *tail; } nodelist; 218 mu_list_t /* of mu_cfg_node_t */ nodelist;
188 char *string; 219 char *string;
189 mu_config_value_t value, *pvalue; 220 mu_config_value_t value, *pvalue;
190 mu_list_t list; 221 mu_list_t list;
...@@ -205,21 +236,19 @@ debug_print_node (mu_cfg_node_t *node) ...@@ -205,21 +236,19 @@ debug_print_node (mu_cfg_node_t *node)
205 236
206 input : stmtlist 237 input : stmtlist
207 { 238 {
208 parse_head = $1.head; 239 parse_node_list = $1;
209 parse_tail = $1.tail;
210 } 240 }
211 ; 241 ;
212 242
213 stmtlist: stmt 243 stmtlist: stmt
214 { 244 {
215 $$.head = $$.tail = $1; 245 mu_cfg_create_node_list (&$$);
216 debug_print_node ($1); 246 mu_list_append ($$, $1);
217 } 247 }
218 | stmtlist stmt 248 | stmtlist stmt
219 { 249 {
250 mu_list_append ($1, $2);
220 $$ = $1; 251 $$ = $1;
221 $$.tail->next = $2;
222 $$.tail = $2;
223 debug_print_node ($2); 252 debug_print_node ($2);
224 } 253 }
225 ; 254 ;
...@@ -246,8 +275,7 @@ block : ident tag '{' '}' opt_sc ...@@ -246,8 +275,7 @@ block : ident tag '{' '}' opt_sc
246 | ident tag '{' stmtlist '}' opt_sc 275 | ident tag '{' stmtlist '}' opt_sc
247 { 276 {
248 $$ = mu_cfg_alloc_node (mu_cfg_node_statement, &$1.locus, 277 $$ = mu_cfg_alloc_node (mu_cfg_node_statement, &$1.locus,
249 $1.name, $2, 278 $1.name, $2, $4);
250 $4.head);
251 279
252 } 280 }
253 ; 281 ;
...@@ -443,10 +471,9 @@ mu_cfg_parse (mu_cfg_tree_t **ptree) ...@@ -443,10 +471,9 @@ mu_cfg_parse (mu_cfg_tree_t **ptree)
443 tree = mu_alloc (sizeof (*tree)); 471 tree = mu_alloc (sizeof (*tree));
444 tree->debug = _mu_cfg_debug; 472 tree->debug = _mu_cfg_debug;
445 _mu_cfg_debug = NULL; 473 _mu_cfg_debug = NULL;
446 tree->head = parse_head; 474 tree->nodes = parse_node_list;
447 tree->tail = parse_tail;
448 tree->pool = mu_cfg_lexer_pool (); 475 tree->pool = mu_cfg_lexer_pool ();
449 parse_head = parse_tail = NULL; 476 parse_node_list = NULL;
450 *ptree = tree; 477 *ptree = tree;
451 return rc; 478 return rc;
452 } 479 }
...@@ -479,12 +506,9 @@ mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb) ...@@ -479,12 +506,9 @@ mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb)
479 return rc; 506 return rc;
480 507
481 /* Link node lists */ 508 /* Link node lists */
482 if (a->tail) 509 mu_list_append_list (a->nodes, b->nodes);
483 a->tail->next = b->head; 510 mu_list_destroy (&b->nodes);
484 else 511
485 a->head = b->head;
486 a->tail = b->tail;
487
488 mu_debug_destroy (&b->debug, mu_debug_get_owner (b->debug)); 512 mu_debug_destroy (&b->debug, mu_debug_get_owner (b->debug));
489 free (b); 513 free (b);
490 *pb = NULL; 514 *pb = NULL;
...@@ -539,11 +563,20 @@ do_include (const char *name, int flags, mu_cfg_locus_t *loc) ...@@ -539,11 +563,20 @@ do_include (const char *name, int flags, mu_cfg_locus_t *loc)
539 int 563 int
540 mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags) 564 mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags)
541 { 565 {
542 mu_cfg_node_t *prev, *node; 566 int rc;
567 mu_iterator_t itr;
543 568
544 for (prev = NULL, node = tree->head; node; ) 569 if (!tree->nodes)
570 return 0;
571 rc = mu_list_get_iterator (tree->nodes, &itr);
572 if (rc)
573 return rc;
574 for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
575 mu_iterator_next (itr))
545 { 576 {
546 mu_cfg_node_t *next = node->next; 577 mu_cfg_node_t *node;
578
579 mu_iterator_current (itr, (void**) &node);
547 580
548 if (node->type == mu_cfg_node_statement) 581 if (node->type == mu_cfg_node_statement)
549 { 582 {
...@@ -554,180 +587,90 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags) ...@@ -554,180 +587,90 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags)
554 { 587 {
555 if (strcmp (node->label->v.string, mu_program_name) == 0) 588 if (strcmp (node->label->v.string, mu_program_name) == 0)
556 { 589 {
557 mu_cfg_node_t *p;
558
559 /* Move all nodes from this block to the topmost 590 /* Move all nodes from this block to the topmost
560 level */ 591 level */
561 if (prev) 592 mu_iterator_ctl (itr, mu_itrctl_insert_list,
562 prev->next = node->node; 593 node->nodes);
563 else 594 mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
564 tree->head = node->node; 595 /*FIXME:mu_cfg_free_node (node);*/
565 p = node->node;
566 mu_cfg_free_node (node);
567 for (node = prev->next; node->next; node = node->next)
568 ;
569 node->next = next;
570 } 596 }
571 } 597 }
572 else 598 else
573 { 599 {
574 mu_cfg_perror (tree->debug, &node->locus, 600 mu_cfg_perror (tree->debug, &node->locus,
575 _("argument to `program' is not a string")); 601 _("argument to `program' is not a string"));
576 if (prev) 602 mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
577 prev->next = next;
578 else
579 tree->head = next;
580 mu_cfg_free_node (node);
581 } 603 }
582 } 604 }
583 } 605 }
584 else if (node->type == mu_cfg_node_param && 606 else if (node->type == mu_cfg_node_param &&
585 strcmp (node->tag, "include") == 0) 607 strcmp (node->tag, "include") == 0)
586 { 608 {
587 /* Remove node from the list */
588 if (prev)
589 prev->next = next;
590 else
591 tree->head = next;
592
593 if (node->label->type == MU_CFG_STRING) 609 if (node->label->type == MU_CFG_STRING)
594 { 610 {
595 mu_cfg_tree_t *t = do_include (node->label->v.string, flags, 611 mu_cfg_tree_t *t = do_include (node->label->v.string, flags,
596 &node->locus); 612 &node->locus);
597 if (t) 613 if (t)
598 { 614 {
599 if (prev) 615 /* Merge the new tree into the current point and
600 prev->next = t->head; 616 destroy the rest of it */
601 else 617 mu_iterator_ctl (itr, mu_itrctl_insert_list, t->nodes);
602 tree->head = t->head;
603
604 t->tail->next = next;
605
606 /* FIXME: check return value */
607 mu_opool_union (&tree->pool, &t->pool); 618 mu_opool_union (&tree->pool, &t->pool);
608 mu_debug_destroy (&t->debug, NULL); 619 mu_cfg_destroy_tree (&t);
609 free (t);
610 } 620 }
611 } 621 }
612 else 622 else
613 mu_cfg_perror (tree->debug, &node->locus, 623 mu_cfg_perror (tree->debug, &node->locus,
614 _("argument to `include' is not a string")); 624 _("argument to `include' is not a string"));
615 mu_cfg_free_node (node); 625 /* Remove node from the list */
626 mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
616 } 627 }
617
618 prev = node;
619 node = next;
620 } 628 }
621 return 0; 629 return 0;
622 } 630 }
623 631
624 static int 632 static int
625 _mu_cfg_preorder_recursive (mu_cfg_node_t *node, 633 _mu_cfg_preorder_recursive (void *item, void *cbdata)
626 mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end,
627 void *data)
628 {
629 switch (node->type)
630 {
631 case mu_cfg_node_undefined:
632 abort ();
633
634 case mu_cfg_node_statement:
635 switch (beg (node, data))
636 {
637 case MU_CFG_ITER_OK:
638 if (mu_cfg_preorder (node->node, beg, end, data))
639 return MU_CFG_ITER_STOP;
640 if (end && end (node, data) == MU_CFG_ITER_STOP)
641 return MU_CFG_ITER_STOP;
642 break;
643
644 case MU_CFG_ITER_SKIP:
645 break;
646
647 case MU_CFG_ITER_STOP:
648 return MU_CFG_ITER_STOP;
649 }
650 break;
651
652 case mu_cfg_node_param:
653 return beg (node, data);
654 }
655 return MU_CFG_ITER_OK;
656 }
657
658 int
659 mu_cfg_preorder(mu_cfg_node_t *node,
660 mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, void *data)
661 { 634 {
662 for (; node; node = node->next) 635 mu_cfg_node_t *node = item;
663 if (_mu_cfg_preorder_recursive(node, beg, end, data) == MU_CFG_ITER_STOP) 636 struct mu_cfg_iter_closure *clos = cbdata;
664 return 1;
665 return 0;
666 }
667 637
668 static int
669 _mu_cfg_postorder_recursive(mu_cfg_node_t *node,
670 mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end,
671 void *data)
672 {
673 switch (node->type) 638 switch (node->type)
674 { 639 {
675 case mu_cfg_node_undefined: 640 case mu_cfg_node_undefined:
676 abort (); 641 abort ();
677 642
678 case mu_cfg_node_statement: 643 case mu_cfg_node_statement:
679 switch (beg (node, data)) 644 switch (clos->beg (node, clos->data))
680 { 645 {
681 case MU_CFG_ITER_OK: 646 case MU_CFG_ITER_OK:
682 if (mu_cfg_postorder (node->node, beg, end, data)) 647 if (mu_cfg_preorder (node->nodes, clos))
683 return MU_CFG_ITER_STOP; 648 return 1;
684 if (end && end (node, data) == MU_CFG_ITER_STOP) 649 if (clos->end && clos->end (node, clos->data) == MU_CFG_ITER_STOP)
685 return MU_CFG_ITER_STOP; 650 return 1;
686 break; 651 break;
687 652
688 case MU_CFG_ITER_SKIP: 653 case MU_CFG_ITER_SKIP:
689 break; 654 break;
690 655
691 case MU_CFG_ITER_STOP: 656 case MU_CFG_ITER_STOP:
692 return MU_CFG_ITER_STOP; 657 return 1;
693 } 658 }
694 break; 659 break;
695 660
696 case mu_cfg_node_param: 661 case mu_cfg_node_param:
697 return beg (node, data); 662 return clos->beg (node, clos->data) == MU_CFG_ITER_STOP;
698 } 663 }
699 return 0; 664 return 0;
700 } 665 }
701 666
702 int 667 int
703 mu_cfg_postorder (mu_cfg_node_t *node, 668 mu_cfg_preorder (mu_list_t nodelist, struct mu_cfg_iter_closure *clos)
704 mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, void *data)
705 { 669 {
706 if (!node) 670 return mu_list_do (nodelist, _mu_cfg_preorder_recursive, clos);
707 return 1;
708 if (node->next
709 && mu_cfg_postorder (node->next, beg, end, data) == MU_CFG_ITER_STOP)
710 return 1;
711 return _mu_cfg_postorder_recursive (node, beg, end, data)
712 == MU_CFG_ITER_STOP;
713 } 671 }
714 672
715 673
716 static int
717 free_section (const mu_cfg_node_t *node, void *data)
718 {
719 if (node->type == mu_cfg_node_statement)
720 free ((void *) node);
721 return MU_CFG_ITER_OK;
722 }
723
724 static int
725 free_param (const mu_cfg_node_t *node, void *data)
726 {
727 if (node->type == mu_cfg_node_param)
728 free ((void*) node);
729 return MU_CFG_ITER_OK;
730 }
731 674
732 void 675 void
733 mu_cfg_destroy_tree (mu_cfg_tree_t **ptree) 676 mu_cfg_destroy_tree (mu_cfg_tree_t **ptree)
...@@ -735,7 +678,7 @@ mu_cfg_destroy_tree (mu_cfg_tree_t **ptree) ...@@ -735,7 +678,7 @@ mu_cfg_destroy_tree (mu_cfg_tree_t **ptree)
735 if (ptree && *ptree) 678 if (ptree && *ptree)
736 { 679 {
737 mu_cfg_tree_t *tree = *ptree; 680 mu_cfg_tree_t *tree = *ptree;
738 mu_cfg_postorder (tree->head, free_param, free_section, NULL); 681 mu_list_destroy (&tree->nodes);
739 mu_opool_destroy (&tree->pool); 682 mu_opool_destroy (&tree->pool);
740 *ptree = NULL; 683 *ptree = NULL;
741 } 684 }
...@@ -1423,11 +1366,14 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections, ...@@ -1423,11 +1366,14 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
1423 { 1366 {
1424 mu_debug_t debug = NULL; 1367 mu_debug_t debug = NULL;
1425 struct scan_tree_data dat; 1368 struct scan_tree_data dat;
1369 struct mu_cfg_iter_closure clos;
1370
1426 dat.tree = tree; 1371 dat.tree = tree;
1427 dat.list = NULL; 1372 dat.list = NULL;
1428 dat.error = 0; 1373 dat.error = 0;
1429 dat.call_data = data; 1374 dat.call_data = data;
1430 dat.target = target; 1375 dat.target = target;
1376
1431 if (!tree->debug) 1377 if (!tree->debug)
1432 { 1378 {
1433 mu_diag_get_debug (&debug); 1379 mu_diag_get_debug (&debug);
...@@ -1435,7 +1381,10 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections, ...@@ -1435,7 +1381,10 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
1435 } 1381 }
1436 if (push_section (&dat, sections)) 1382 if (push_section (&dat, sections))
1437 return 1; 1383 return 1;
1438 mu_cfg_preorder (tree->head, _scan_tree_helper, _scan_tree_end_helper, &dat); 1384 clos.beg = _scan_tree_helper;
1385 clos.end = _scan_tree_end_helper;
1386 clos.data = &dat;
1387 mu_cfg_preorder (tree->nodes, &clos);
1439 if (debug) 1388 if (debug)
1440 { 1389 {
1441 mu_debug_set_locus (debug, NULL, 0); 1390 mu_debug_set_locus (debug, NULL, 0);
...@@ -1501,7 +1450,7 @@ mu_cfg_tree_create_node (struct mu_cfg_tree *tree, ...@@ -1501,7 +1450,7 @@ mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
1501 enum mu_cfg_node_type type, 1450 enum mu_cfg_node_type type,
1502 const mu_cfg_locus_t *loc, 1451 const mu_cfg_locus_t *loc,
1503 const char *tag, const char *label, 1452 const char *tag, const char *label,
1504 mu_cfg_node_t *node) 1453 mu_list_t nodelist)
1505 { 1454 {
1506 char *p; 1455 char *p;
1507 mu_cfg_node_t *np; 1456 mu_cfg_node_t *np;
...@@ -1528,24 +1477,32 @@ mu_cfg_tree_create_node (struct mu_cfg_tree *tree, ...@@ -1528,24 +1477,32 @@ mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
1528 } 1477 }
1529 else 1478 else
1530 np->label = NULL; 1479 np->label = NULL;
1531 np->node = node; 1480 np->nodes = nodelist;
1532 np->next = NULL;
1533 return np; 1481 return np;
1534 } 1482 }
1535 1483
1536 void 1484 void
1537 mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node) 1485 mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node)
1538 { 1486 {
1539 if (!tree->head) 1487 if (!node)
1540 tree->head = node; 1488 return;
1541 else 1489 if (!tree->nodes)
1542 { 1490 /* FIXME: return code? */
1543 mu_cfg_node_t *p; 1491 mu_cfg_create_node_list (&tree->nodes);
1544 for (p = tree->head; p->next; p = p->next) 1492 mu_list_append (tree->nodes, node);
1545 ; 1493 }
1546 p->next = node; 1494
1547 } 1495 void
1496 mu_cfg_tree_add_nodelist (mu_cfg_tree_t *tree, mu_list_t nodelist)
1497 {
1498 if (!nodelist)
1499 return;
1500 if (!tree->nodes)
1501 /* FIXME: return code? */
1502 mu_cfg_create_node_list (&tree->nodes);
1503 mu_list_append_list (tree->nodes, nodelist);
1548 } 1504 }
1505
1549 1506
1550 /* Return 1 if configuration value A equals B */ 1507 /* Return 1 if configuration value A equals B */
1551 int 1508 int
...@@ -1740,10 +1697,11 @@ node_finder (const mu_cfg_node_t *node, void *data) ...@@ -1740,10 +1697,11 @@ node_finder (const mu_cfg_node_t *node, void *data)
1740 } 1697 }
1741 1698
1742 int 1699 int
1743 mu_cfg_find_node (mu_cfg_node_t *tree, const char *path, mu_cfg_node_t **pval) 1700 mu_cfg_find_node (mu_cfg_tree_t *tree, const char *path, mu_cfg_node_t **pval)
1744 { 1701 {
1745 int rc; 1702 int rc;
1746 struct find_data data; 1703 struct find_data data;
1704 struct mu_cfg_iter_closure clos;
1747 1705
1748 rc = mu_argcv_get_np (path, strlen (path), 1706 rc = mu_argcv_get_np (path, strlen (path),
1749 MU_CFG_PATH_DELIM_STR, NULL, 1707 MU_CFG_PATH_DELIM_STR, NULL,
...@@ -1752,7 +1710,11 @@ mu_cfg_find_node (mu_cfg_node_t *tree, const char *path, mu_cfg_node_t **pval) ...@@ -1752,7 +1710,11 @@ mu_cfg_find_node (mu_cfg_node_t *tree, const char *path, mu_cfg_node_t **pval)
1752 return rc; 1710 return rc;
1753 data.tag = 0; 1711 data.tag = 0;
1754 parse_tag (&data); 1712 parse_tag (&data);
1755 rc = mu_cfg_preorder (tree, node_finder, NULL, &data); 1713
1714 clos.beg = node_finder;
1715 clos.end = NULL;
1716 clos.data = &data;
1717 rc = mu_cfg_preorder (tree->nodes, &clos);
1756 destroy_value (data.label); 1718 destroy_value (data.label);
1757 if (rc) 1719 if (rc)
1758 { 1720 {
...@@ -1784,6 +1746,7 @@ mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode) ...@@ -1784,6 +1746,7 @@ mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode)
1784 1746
1785 for (i = argc - 1; i >= 0; i--) 1747 for (i = argc - 1; i >= 0; i--)
1786 { 1748 {
1749 mu_list_t nodelist = NULL;
1787 char *p = strrchr (argv[i], '='); 1750 char *p = strrchr (argv[i], '=');
1788 mu_config_value_t *label = NULL; 1751 mu_config_value_t *label = NULL;
1789 1752
...@@ -1795,8 +1758,13 @@ mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode) ...@@ -1795,8 +1758,13 @@ mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode)
1795 if (i == argc - 1) 1758 if (i == argc - 1)
1796 type = mu_cfg_node_param; 1759 type = mu_cfg_node_param;
1797 } 1760 }
1798 1761
1799 node = mu_cfg_alloc_node (type, &locus, argv[i], label, node); 1762 if (node)
1763 {
1764 mu_cfg_create_node_list (&nodelist);
1765 mu_list_append (nodelist, node);
1766 }
1767 node = mu_cfg_alloc_node (type, &locus, argv[i], label, nodelist);
1800 } 1768 }
1801 1769
1802 mu_argcv_free (argc, argv); 1770 mu_argcv_free (argc, argv);
......
...@@ -93,7 +93,7 @@ set_debug_flags (mu_debug_t debug, const char *arg) ...@@ -93,7 +93,7 @@ set_debug_flags (mu_debug_t debug, const char *arg)
93 static error_t 93 static error_t
94 parse_opt (int key, char *arg, struct argp_state *state) 94 parse_opt (int key, char *arg, struct argp_state *state)
95 { 95 {
96 static struct mu_argp_node_list lst; 96 static mu_list_t lst;
97 97
98 switch (key) 98 switch (key)
99 { 99 {
...@@ -108,7 +108,7 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -108,7 +108,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
108 case ARGP_KEY_FINI: 108 case ARGP_KEY_FINI:
109 if (dry_run && !debug_level) 109 if (dry_run && !debug_level)
110 debug_level = 1; 110 debug_level = 1;
111 mu_argp_node_list_finish (&lst, NULL, NULL); 111 mu_argp_node_list_finish (lst, NULL, NULL);
112 break; 112 break;
113 113
114 case 'a': 114 case 'a':
...@@ -117,7 +117,7 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -117,7 +117,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
117 break; 117 break;
118 118
119 case 'd': 119 case 'd':
120 mu_argp_node_list_new (&lst, "debug", arg ? arg : "9"); 120 mu_argp_node_list_new (lst, "debug", arg ? arg : "9");
121 break; 121 break;
122 122
123 case 'h': 123 case 'h':
...@@ -129,11 +129,11 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -129,11 +129,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
129 break; 129 break;
130 130
131 case 't': 131 case 't':
132 mu_argp_node_list_new (&lst, "mimetypes", arg); 132 mu_argp_node_list_new (lst, "mimetypes", arg);
133 break; 133 break;
134 134
135 case OPT_METAMAIL: 135 case OPT_METAMAIL:
136 mu_argp_node_list_new (&lst, "metamail", arg ? arg : "metamail"); 136 mu_argp_node_list_new (lst, "metamail", arg ? arg : "metamail");
137 break; 137 break;
138 138
139 default: 139 default:
......
...@@ -111,24 +111,24 @@ mu_kwd_t method_kwd[] = { ...@@ -111,24 +111,24 @@ mu_kwd_t method_kwd[] = {
111 static error_t 111 static error_t
112 parse_opt (int key, char *arg, struct argp_state *state) 112 parse_opt (int key, char *arg, struct argp_state *state)
113 { 113 {
114 static struct mu_argp_node_list lst; 114 static mu_list_t lst;
115 115
116 switch (key) 116 switch (key)
117 { 117 {
118 case 'r': 118 case 'r':
119 mu_argp_node_list_new (&lst, "reverse", "yes"); 119 mu_argp_node_list_new (lst, "reverse", "yes");
120 break; 120 break;
121 121
122 case 'p': 122 case 'p':
123 mu_argp_node_list_new (&lst, "preserve", "yes"); 123 mu_argp_node_list_new (lst, "preserve", "yes");
124 break; 124 break;
125 125
126 case 'P': 126 case 'P':
127 mu_argp_node_list_new (&lst, "mailbox-ownership", arg); 127 mu_argp_node_list_new (lst, "mailbox-ownership", arg);
128 break; 128 break;
129 129
130 case 'u': 130 case 'u':
131 mu_argp_node_list_new (&lst, "uidl", "yes"); 131 mu_argp_node_list_new (lst, "uidl", "yes");
132 break; 132 break;
133 133
134 case 'v': 134 case 'v':
...@@ -136,7 +136,7 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -136,7 +136,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
136 break; 136 break;
137 137
138 case OPT_EMACS: 138 case OPT_EMACS:
139 mu_argp_node_list_new (&lst, "emacs", "yes"); 139 mu_argp_node_list_new (lst, "emacs", "yes");
140 break; 140 break;
141 141
142 case ARGP_KEY_INIT: 142 case ARGP_KEY_INIT:
...@@ -144,7 +144,7 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -144,7 +144,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
144 break; 144 break;
145 145
146 case ARGP_KEY_FINI: 146 case ARGP_KEY_FINI:
147 mu_argp_node_list_finish (&lst, NULL, NULL); 147 mu_argp_node_list_finish (lst, NULL, NULL);
148 break; 148 break;
149 149
150 default: 150 default:
......
...@@ -146,22 +146,22 @@ static const char *pop3d_argp_capa[] = { ...@@ -146,22 +146,22 @@ static const char *pop3d_argp_capa[] = {
146 static error_t 146 static error_t
147 pop3d_parse_opt (int key, char *arg, struct argp_state *astate) 147 pop3d_parse_opt (int key, char *arg, struct argp_state *astate)
148 { 148 {
149 static struct mu_argp_node_list lst; 149 static mu_list_t lst;
150 150
151 switch (key) 151 switch (key)
152 { 152 {
153 case 'd': 153 case 'd':
154 mu_argp_node_list_new (&lst, "mode", "daemon"); 154 mu_argp_node_list_new (lst, "mode", "daemon");
155 if (arg) 155 if (arg)
156 mu_argp_node_list_new (&lst, "max-children", arg); 156 mu_argp_node_list_new (lst, "max-children", arg);
157 break; 157 break;
158 158
159 case 'i': 159 case 'i':
160 mu_argp_node_list_new (&lst, "mode", "inetd"); 160 mu_argp_node_list_new (lst, "mode", "inetd");
161 break; 161 break;
162 162
163 case OPT_FOREGROUND: 163 case OPT_FOREGROUND:
164 mu_argp_node_list_new (&lst, "foreground", "yes"); 164 mu_argp_node_list_new (lst, "foreground", "yes");
165 break; 165 break;
166 166
167 case ARGP_KEY_INIT: 167 case ARGP_KEY_INIT:
...@@ -169,7 +169,7 @@ pop3d_parse_opt (int key, char *arg, struct argp_state *astate) ...@@ -169,7 +169,7 @@ pop3d_parse_opt (int key, char *arg, struct argp_state *astate)
169 break; 169 break;
170 170
171 case ARGP_KEY_FINI: 171 case ARGP_KEY_FINI:
172 mu_argp_node_list_finish (&lst, NULL, NULL); 172 mu_argp_node_list_finish (lst, NULL, NULL);
173 break; 173 break;
174 174
175 default: 175 default:
......
...@@ -79,7 +79,7 @@ int show_all = 0; ...@@ -79,7 +79,7 @@ int show_all = 0;
79 static error_t 79 static error_t
80 readmsg_parse_opt (int key, char *arg, struct argp_state *astate) 80 readmsg_parse_opt (int key, char *arg, struct argp_state *astate)
81 { 81 {
82 static struct mu_argp_node_list lst; 82 static mu_list_t lst;
83 83
84 switch (key) 84 switch (key)
85 { 85 {
...@@ -88,27 +88,27 @@ readmsg_parse_opt (int key, char *arg, struct argp_state *astate) ...@@ -88,27 +88,27 @@ readmsg_parse_opt (int key, char *arg, struct argp_state *astate)
88 break; 88 break;
89 89
90 case 'h': 90 case 'h':
91 mu_argp_node_list_new (&lst, "header", "yes"); 91 mu_argp_node_list_new (lst, "header", "yes");
92 break; 92 break;
93 93
94 case 'f': 94 case 'f':
95 mu_argp_node_list_new (&lst, "folder", arg); 95 mu_argp_node_list_new (lst, "folder", arg);
96 break; 96 break;
97 97
98 case 'w': 98 case 'w':
99 mu_argp_node_list_new (&lst, "weedlist", arg); 99 mu_argp_node_list_new (lst, "weedlist", arg);
100 break; 100 break;
101 101
102 case 'n': 102 case 'n':
103 mu_argp_node_list_new (&lst, "no-header", "yes"); 103 mu_argp_node_list_new (lst, "no-header", "yes");
104 break; 104 break;
105 105
106 case 'p': 106 case 'p':
107 mu_argp_node_list_new (&lst, "form-feeds", "yes"); 107 mu_argp_node_list_new (lst, "form-feeds", "yes");
108 break; 108 break;
109 109
110 case 'a': 110 case 'a':
111 mu_argp_node_list_new (&lst, "show-all-match", "yes"); 111 mu_argp_node_list_new (lst, "show-all-match", "yes");
112 break; 112 break;
113 113
114 case ARGP_KEY_INIT: 114 case ARGP_KEY_INIT:
...@@ -117,8 +117,8 @@ readmsg_parse_opt (int key, char *arg, struct argp_state *astate) ...@@ -117,8 +117,8 @@ readmsg_parse_opt (int key, char *arg, struct argp_state *astate)
117 117
118 case ARGP_KEY_FINI: 118 case ARGP_KEY_FINI:
119 if (dbug) 119 if (dbug)
120 mu_argp_node_list_new (&lst, "debug", mu_umaxtostr (0, dbug)); 120 mu_argp_node_list_new (lst, "debug", mu_umaxtostr (0, dbug));
121 mu_argp_node_list_finish (&lst, NULL, NULL); 121 mu_argp_node_list_finish (lst, NULL, NULL);
122 break; 122 break;
123 123
124 default: 124 default:
......
...@@ -172,12 +172,12 @@ mu_compat_printer (void *data, mu_log_level_t level, const char *buf) ...@@ -172,12 +172,12 @@ mu_compat_printer (void *data, mu_log_level_t level, const char *buf)
172 static error_t 172 static error_t
173 parser (int key, char *arg, struct argp_state *state) 173 parser (int key, char *arg, struct argp_state *state)
174 { 174 {
175 static struct mu_argp_node_list lst; 175 static mu_list_t lst;
176 176
177 switch (key) 177 switch (key)
178 { 178 {
179 case 'e': 179 case 'e':
180 mu_argp_node_list_new (&lst, "email", arg); 180 mu_argp_node_list_new (lst, "email", arg);
181 break; 181 break;
182 182
183 case 'n': 183 case 'n':
...@@ -185,7 +185,7 @@ parser (int key, char *arg, struct argp_state *state) ...@@ -185,7 +185,7 @@ parser (int key, char *arg, struct argp_state *state)
185 break; 185 break;
186 186
187 case 'k': 187 case 'k':
188 mu_argp_node_list_new (&lst, "keep-going", "yes"); 188 mu_argp_node_list_new (lst, "keep-going", "yes");
189 break; 189 break;
190 190
191 case 'c': 191 case 'c':
...@@ -197,23 +197,23 @@ parser (int key, char *arg, struct argp_state *state) ...@@ -197,23 +197,23 @@ parser (int key, char *arg, struct argp_state *state)
197 break; 197 break;
198 198
199 case 'f': 199 case 'f':
200 mu_argp_node_list_new (&lst, "mbox-url", arg); 200 mu_argp_node_list_new (lst, "mbox-url", arg);
201 break; 201 break;
202 202
203 case 't': 203 case 't':
204 mu_argp_node_list_new (&lst, "ticket", arg); 204 mu_argp_node_list_new (lst, "ticket", arg);
205 break; 205 break;
206 206
207 case 'd': 207 case 'd':
208 mu_argp_node_list_new (&lst, "debug", arg ? arg : D_DEFAULT); 208 mu_argp_node_list_new (lst, "debug", arg ? arg : D_DEFAULT);
209 break; 209 break;
210 210
211 case 'v': 211 case 'v':
212 mu_argp_node_list_new (&lst, "verbose", "yes"); 212 mu_argp_node_list_new (lst, "verbose", "yes");
213 break; 213 break;
214 214
215 case ARG_LINE_INFO: 215 case ARG_LINE_INFO:
216 mu_argp_node_list_new (&lst, "line-info", 216 mu_argp_node_list_new (lst, "line-info",
217 is_true_p (arg) ? "yes" : "no"); 217 is_true_p (arg) ? "yes" : "no");
218 break; 218 break;
219 219
...@@ -236,7 +236,7 @@ parser (int key, char *arg, struct argp_state *state) ...@@ -236,7 +236,7 @@ parser (int key, char *arg, struct argp_state *state)
236 break; 236 break;
237 237
238 case ARGP_KEY_FINI: 238 case ARGP_KEY_FINI:
239 mu_argp_node_list_finish (&lst, NULL, NULL); 239 mu_argp_node_list_finish (lst, NULL, NULL);
240 break; 240 break;
241 241
242 default: 242 default:
......