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[] = {
static error_t
comsatd_parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
......@@ -179,17 +179,17 @@ _("The old configuration file format and the --config command\n"
exit (0);
case 'd':
mu_argp_node_list_new (&lst, "mode", "daemon");
mu_argp_node_list_new (lst, "mode", "daemon");
if (arg)
mu_argp_node_list_new (&lst, "max-children", arg);
mu_argp_node_list_new (lst, "max-children", arg);
break;
case 'i':
mu_argp_node_list_new (&lst, "mode", "inetd");
mu_argp_node_list_new (lst, "mode", "inetd");
break;
case OPT_FOREGROUND:
mu_argp_node_list_new (&lst, "foreground", "yes");
mu_argp_node_list_new (lst, "foreground", "yes");
break;
case 't':
......@@ -201,7 +201,7 @@ _("The old configuration file format and the --config command\n"
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
mu_argp_node_list_finish (lst, NULL, NULL);
break;
default:
......
......@@ -356,7 +356,7 @@ main (int argc, char **argv)
char *path = *argv;
mu_cfg_node_t *node;
if (mu_cfg_find_node (tree->head, path, &node) == 0)
if (mu_cfg_find_node (tree, path, &node) == 0)
{
mu_cfg_format_node (stream, node, fmtflags);
}
......
......@@ -77,12 +77,12 @@ static int debug;
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
case 'd':
mu_argp_node_list_new (&lst, "debug", "yes");
mu_argp_node_list_new (lst, "debug", "yes");
break;
case 'u':
......@@ -91,11 +91,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
case 'r':
if (arg)
mu_argp_node_list_new (&lst, "retry", arg);
mu_argp_node_list_new (lst, "retry", arg);
break;
case 'f':
mu_argp_node_list_new (&lst, "force", arg ? arg : "0");
mu_argp_node_list_new (lst, "force", arg ? arg : "0");
break;
case ARGP_KEY_ARG:
......@@ -114,7 +114,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
mu_argp_node_list_finish (lst, NULL, NULL);
break;
default:
......
......@@ -101,22 +101,22 @@ static int imap4d_mainloop (int, FILE *, FILE *);
static error_t
imap4d_parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
case 'd':
mu_argp_node_list_new (&lst, "mode", "daemon");
mu_argp_node_list_new (lst, "mode", "daemon");
if (arg)
mu_argp_node_list_new (&lst, "max-children", arg);
mu_argp_node_list_new (lst, "max-children", arg);
break;
case 'i':
mu_argp_node_list_new (&lst, "mode", "inetd");
mu_argp_node_list_new (lst, "mode", "inetd");
break;
case OPT_FOREGROUND:
mu_argp_node_list_new (&lst, "foreground", "yes");
mu_argp_node_list_new (lst, "foreground", "yes");
break;
case OPT_PREAUTH:
......@@ -128,7 +128,7 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
mu_argp_node_list_finish (lst, NULL, NULL);
break;
default:
......
......@@ -70,17 +70,16 @@ struct mu_cfg_locus
struct mu_cfg_node
{
mu_cfg_node_t *next;
mu_cfg_locus_t locus;
enum mu_cfg_node_type type;
char *tag;
mu_config_value_t *label;
mu_cfg_node_t *node;
mu_list_t nodes; /* a list of mu_cfg_node_t */
};
struct mu_cfg_tree
{
mu_cfg_node_t *head, *tail;
mu_list_t nodes; /* a list of mu_cfg_node_t */
mu_debug_t debug;
mu_opool_t pool;
};
......@@ -107,14 +106,16 @@ void mu_cfg_format_error (mu_debug_t debug, size_t, const char *fmt, ...)
typedef int (*mu_cfg_iter_func_t) (const mu_cfg_node_t *node, void *data);
struct mu_cfg_iter_closure
{
mu_cfg_iter_func_t beg;
mu_cfg_iter_func_t end;
void *data;
};
void mu_cfg_destroy_tree (mu_cfg_tree_t **tree);
int mu_cfg_preorder (mu_cfg_node_t *node,
mu_cfg_iter_func_t fun, mu_cfg_iter_func_t endfun,
void *data);
int mu_cfg_postorder (mu_cfg_node_t *node,
mu_cfg_iter_func_t fun, mu_cfg_iter_func_t endfun,
void *data);
int mu_cfg_preorder (mu_list_t nodelist, struct mu_cfg_iter_closure *);
/* Table-driven parsing */
......@@ -227,6 +228,8 @@ int mu_create_canned_section (char *name, struct mu_cfg_section **psection);
int mu_create_canned_param (char *name, struct mu_cfg_param **pparam);
struct mu_cfg_cont *mu_get_canned_container (const char *name);
int mu_cfg_create_node_list (mu_list_t *plist);
int mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
void *target, void *call_data);
......@@ -300,10 +303,11 @@ mu_cfg_node_t *mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
const mu_cfg_locus_t *loc,
const char *tag,
const char *label,
mu_cfg_node_t *node);
mu_list_t nodelist);
void mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node);
void mu_cfg_tree_add_nodelist (mu_cfg_tree_t *tree, mu_list_t nodelist);
int mu_cfg_find_node (mu_cfg_node_t *tree, const char *path,
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);
......
......@@ -83,17 +83,10 @@ error_t mu_argp_parse (const struct argp *myargp,
int *arg_index,
void *input) __attribute__ ((deprecated));
struct mu_argp_node_list
{
int count;
mu_cfg_node_t *head, *tail;
};
void mu_argp_node_list_init (struct mu_argp_node_list *);
void mu_argp_node_list_add (struct mu_argp_node_list *, mu_cfg_node_t *);
void mu_argp_node_list_new (struct mu_argp_node_list *,
const char *, const char *);
void mu_argp_node_list_finish (struct mu_argp_node_list *, char *, char *);
void mu_argp_node_list_init (mu_list_t *);
void mu_argp_node_list_add (mu_list_t, mu_cfg_node_t *);
void mu_argp_node_list_new (mu_list_t, const char *, const char *);
void mu_argp_node_list_finish (mu_list_t, char *, char *);
#ifdef __cplusplus
}
......
......@@ -68,7 +68,7 @@ auth_set_debug ()
static error_t
mu_auth_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
......@@ -77,7 +77,7 @@ mu_auth_argp_parser (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "auth", NULL);
mu_argp_node_list_finish (lst, "auth", NULL);
break;
case OPT_DEBUG_AUTH:
......
......@@ -56,53 +56,57 @@ mu_libargp_init ()
}
void
mu_argp_node_list_init (struct mu_argp_node_list *lst)
mu_argp_node_list_init (mu_list_t *plist)
{
lst->count = 0;
lst->head = lst->tail = NULL;
int rc = mu_cfg_create_node_list (plist);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_cfg_create_node_list", NULL, rc);
abort ();
}
}
void
mu_argp_node_list_add (struct mu_argp_node_list *lst, mu_cfg_node_t *node)
mu_argp_node_list_add (mu_list_t lst, mu_cfg_node_t *node)
{
lst->count++;
if (lst->tail)
lst->tail->next = node;
else
lst->head = node;
lst->tail = node;
int rc = mu_list_append (lst, node);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_list_append", NULL, rc);
abort ();
}
}
void
mu_argp_node_list_new (struct mu_argp_node_list *lst,
const char *tag, const char *label)
mu_argp_node_list_new (mu_list_t lst, const char *tag, const char *label)
{
mu_cfg_node_t *node;
mu_cfg_locus_t loc = { "command line", 0 };
loc.line = lst->count;
mu_list_count (lst, &loc.line);
node = mu_cfg_tree_create_node (mu_argp_tree, mu_cfg_node_param,
&loc, tag, label, NULL);
mu_argp_node_list_add (lst, node);
}
void
mu_argp_node_list_finish (struct mu_argp_node_list *lst, char *tag,
char *label)
mu_argp_node_list_finish (mu_list_t lst, char *tag, char *label)
{
mu_cfg_node_t *node;
if (!lst->head)
if (mu_list_is_empty (lst))
return;
if (tag)
node = mu_cfg_tree_create_node (mu_argp_tree,
mu_cfg_node_statement,
NULL,
tag, label,
lst->head);
{
mu_cfg_node_t *node = mu_cfg_tree_create_node (mu_argp_tree,
mu_cfg_node_statement,
NULL,
tag, label,
lst);
mu_cfg_tree_add_node (mu_argp_tree, node);
}
else
node = lst->head;
mu_cfg_tree_add_node (mu_argp_tree, node);
mu_argp_node_list_init (lst);
{
mu_cfg_tree_add_nodelist (mu_argp_tree, lst);
mu_list_destroy (&lst);
}
}
......
......@@ -157,13 +157,13 @@ static struct argp_option mu_logging_argp_option[] = {
static error_t
mu_logging_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
/* log */
case OPT_LOG_FACILITY:
mu_argp_node_list_new (&lst, "facility", arg);
mu_argp_node_list_new (lst, "facility", arg);
break;
case ARGP_KEY_INIT:
......@@ -171,7 +171,7 @@ mu_logging_argp_parser (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "logging", NULL);
mu_argp_node_list_finish (lst, "logging", NULL);
break;
default:
......@@ -254,13 +254,13 @@ static struct argp_option mu_mailer_argp_option[] = {
static error_t
mu_mailer_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
/* mailer */
case 'M':
mu_argp_node_list_new (&lst, "url", arg);
mu_argp_node_list_new (lst, "url", arg);
break;
case ARGP_KEY_INIT:
......@@ -268,7 +268,7 @@ mu_mailer_argp_parser (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "mailer", NULL);
mu_argp_node_list_finish (lst, "mailer", NULL);
break;
default:
......@@ -306,17 +306,17 @@ static struct argp_option mu_debug_argp_options[] =
static error_t
mu_debug_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
case OPT_DEBUG_LEVEL:
mu_global_debug_from_string (arg, "command line");
/*mu_argp_node_list_new (&lst, "level", arg);*/
/*mu_argp_node_list_new (lst, "level", arg);*/
break;
case OPT_LINE_INFO:
mu_argp_node_list_new (&lst, "line-info", "yes");
mu_argp_node_list_new (lst, "line-info", "yes");
break;
case ARGP_KEY_INIT:
......@@ -324,7 +324,7 @@ mu_debug_argp_parser (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "debug", NULL);
mu_argp_node_list_finish (lst, "debug", NULL);
break;
default:
......
......@@ -44,24 +44,24 @@ static struct argp_option sieve_argp_option[] = {
static error_t
sieve_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
case 'I':
mu_argp_node_list_new (&lst, "include-path", arg);
mu_argp_node_list_new (lst, "include-path", arg);
break;
case 'L':
mu_argp_node_list_new (&lst, "library-path", arg);
mu_argp_node_list_new (lst, "library-path", arg);
break;
case OPT_CLEAR_INCLUDE_PATH:
mu_argp_node_list_new (&lst, "clear-include-path", "yes");
mu_argp_node_list_new (lst, "clear-include-path", "yes");
break;
case OPT_CLEAR_LIBRARY_PATH:
mu_argp_node_list_new (&lst, "clear-library-path", "yes");
mu_argp_node_list_new (lst, "clear-library-path", "yes");
break;
case ARGP_KEY_INIT:
......@@ -69,7 +69,7 @@ sieve_argp_parser (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "sieve", NULL);
mu_argp_node_list_finish (lst, "sieve", NULL);
break;
default:
......
......@@ -35,12 +35,12 @@ static struct argp_option _tls_argp_options[] = {
static error_t
_tls_argp_parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
case OPT_TLS:
mu_argp_node_list_new (&lst, "enable", arg ? arg : "yes");
mu_argp_node_list_new (lst, "enable", arg ? arg : "yes");
break;
case ARGP_KEY_INIT:
......@@ -48,7 +48,7 @@ _tls_argp_parser (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, "tls", NULL);
mu_argp_node_list_finish (lst, "tls", NULL);
break;
default:
......
......@@ -184,32 +184,32 @@ set_debug_flags (mu_debug_t debug, const char *arg)
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
case 'd':
mu_argp_node_list_new (&lst, "mode", "daemon");
mu_argp_node_list_new (lst, "mode", "daemon");
if (arg)
mu_argp_node_list_new (&lst, "max-children", arg);
mu_argp_node_list_new (lst, "max-children", arg);
break;
case 'i':
mu_argp_node_list_new (&lst, "mode", "inetd");
mu_argp_node_list_new (lst, "mode", "inetd");
break;
case FOREGROUND_OPTION:
mu_argp_node_list_new (&lst, "foreground", "yes");
mu_argp_node_list_new (lst, "foreground", "yes");
break;
case MESSAGE_ID_HEADER_OPTION:
mu_argp_node_list_new (&lst, "message-id-header", arg);
mu_argp_node_list_new (lst, "message-id-header", arg);
break;
case LMTP_OPTION:
mu_argp_node_list_new (&lst, "lmtp", "yes");
mu_argp_node_list_new (lst, "lmtp", "yes");
if (arg)
mu_argp_node_list_new (&lst, "listen", arg);
mu_argp_node_list_new (lst, "listen", arg);
break;
case 'r':
......@@ -242,11 +242,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'x':
mu_argp_node_list_new (&lst, "debug", arg ? arg : D_DEFAULT);
mu_argp_node_list_new (lst, "debug", arg ? arg : D_DEFAULT);
break;
case STDERR_OPTION:
mu_argp_node_list_new (&lst, "stderr", "yes");
mu_argp_node_list_new (lst, "stderr", "yes");
break;
case URL_OPTION:
......@@ -258,7 +258,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
mu_argp_node_list_finish (lst, NULL, NULL);
break;
case ARGP_KEY_ERROR:
......
......@@ -186,13 +186,18 @@ format_node_end (const mu_cfg_node_t *node, void *data)
void
mu_cfg_format_parse_tree (mu_stream_t stream, mu_cfg_tree_t *tree, int flags)
{
struct mu_cfg_iter_closure clos;
struct tree_print t;
t.flags = flags;
t.level = 0;
t.stream = stream;
t.buf = NULL;
t.bufsize = 0;
mu_cfg_preorder (tree->head, format_node, format_node_end, &t);
clos.beg = format_node;
clos.end = format_node_end;
clos.data = &t;
mu_cfg_preorder (tree->nodes, &clos);
free (t.buf);
}
......@@ -200,6 +205,7 @@ void
mu_cfg_format_node (mu_stream_t stream, const mu_cfg_node_t *node, int flags)
{
struct tree_print t;
t.flags = flags;
t.level = 0;
t.stream = stream;
......@@ -208,7 +214,11 @@ mu_cfg_format_node (mu_stream_t stream, const mu_cfg_node_t *node, int flags)
format_node (node, &t);
if (node->type == mu_cfg_node_statement)
{
mu_cfg_preorder (node->node, format_node, format_node_end, &t);
struct mu_cfg_iter_closure clos;
clos.beg = format_node;
clos.end = format_node_end;
clos.data = &t;
mu_cfg_preorder (node->nodes, &clos);
format_node_end (node, &t);
}
}
......
......@@ -38,7 +38,7 @@
#include <mailutils/mutil.h>
int mu_cfg_parser_verbose;
static mu_cfg_node_t *parse_head, *parse_tail;
static mu_list_t /* of mu_cfg_node_t */ parse_node_list;
mu_cfg_locus_t mu_cfg_locus;
size_t mu_cfg_error_count;
......@@ -75,7 +75,7 @@ config_value_dup (mu_config_value_t *src)
static mu_cfg_node_t *
mu_cfg_alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc,
const char *tag, mu_config_value_t *label,
mu_cfg_node_t *node)
mu_list_t nodelist)
{
char *p;
mu_cfg_node_t *np;
......@@ -87,8 +87,7 @@ mu_cfg_alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc,
np->tag = p;
strcpy (p, tag);
np->label = label;
np->node = node;
np->next = NULL;
np->nodes = nodelist;
return np;
}
......@@ -179,12 +178,44 @@ debug_print_node (mu_cfg_node_t *node)
}
}
static void
free_node_item (void *item)
{
mu_cfg_node_t *node = item;
switch (node->type)
{
case mu_cfg_node_statement:
mu_list_destroy (&node->nodes);
break;
case mu_cfg_node_undefined: /* hmm... */
case mu_cfg_node_param:
break;
}
mu_cfg_free_node (node);
}
int
mu_cfg_create_node_list (mu_list_t *plist)
{
int rc;
mu_list_t list;
rc = mu_list_create (&list);
if (rc)
return rc;
mu_list_set_destroy_item (list, free_node_item);
*plist = list;
return 0;
}
%}
%union {
mu_cfg_node_t node;
mu_cfg_node_t *pnode;
struct { mu_cfg_node_t *head, *tail; } nodelist;
mu_list_t /* of mu_cfg_node_t */ nodelist;
char *string;
mu_config_value_t value, *pvalue;
mu_list_t list;
......@@ -205,21 +236,19 @@ debug_print_node (mu_cfg_node_t *node)
input : stmtlist
{
parse_head = $1.head;
parse_tail = $1.tail;
parse_node_list = $1;
}
;
stmtlist: stmt
{
$$.head = $$.tail = $1;
debug_print_node ($1);
mu_cfg_create_node_list (&$$);
mu_list_append ($$, $1);
}
| stmtlist stmt
{
mu_list_append ($1, $2);
$$ = $1;
$$.tail->next = $2;
$$.tail = $2;
debug_print_node ($2);
}
;
......@@ -246,8 +275,7 @@ block : ident tag '{' '}' opt_sc
| ident tag '{' stmtlist '}' opt_sc
{
$$ = mu_cfg_alloc_node (mu_cfg_node_statement, &$1.locus,
$1.name, $2,
$4.head);
$1.name, $2, $4);
}
;
......@@ -443,10 +471,9 @@ mu_cfg_parse (mu_cfg_tree_t **ptree)
tree = mu_alloc (sizeof (*tree));
tree->debug = _mu_cfg_debug;
_mu_cfg_debug = NULL;
tree->head = parse_head;
tree->tail = parse_tail;
tree->nodes = parse_node_list;
tree->pool = mu_cfg_lexer_pool ();
parse_head = parse_tail = NULL;
parse_node_list = NULL;
*ptree = tree;
return rc;
}
......@@ -479,12 +506,9 @@ mu_cfg_tree_union (mu_cfg_tree_t **pa, mu_cfg_tree_t **pb)
return rc;
/* Link node lists */
if (a->tail)
a->tail->next = b->head;
else
a->head = b->head;
a->tail = b->tail;
mu_list_append_list (a->nodes, b->nodes);
mu_list_destroy (&b->nodes);
mu_debug_destroy (&b->debug, mu_debug_get_owner (b->debug));
free (b);
*pb = NULL;
......@@ -539,11 +563,20 @@ do_include (const char *name, int flags, mu_cfg_locus_t *loc)
int
mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags)
{
mu_cfg_node_t *prev, *node;
int rc;
mu_iterator_t itr;
for (prev = NULL, node = tree->head; node; )
if (!tree->nodes)
return 0;
rc = mu_list_get_iterator (tree->nodes, &itr);
if (rc)
return rc;
for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
mu_iterator_next (itr))
{
mu_cfg_node_t *next = node->next;
mu_cfg_node_t *node;
mu_iterator_current (itr, (void**) &node);
if (node->type == mu_cfg_node_statement)
{
......@@ -554,180 +587,90 @@ mu_cfg_tree_postprocess (mu_cfg_tree_t *tree, int flags)
{
if (strcmp (node->label->v.string, mu_program_name) == 0)
{
mu_cfg_node_t *p;
/* Move all nodes from this block to the topmost
level */
if (prev)
prev->next = node->node;
else
tree->head = node->node;
p = node->node;
mu_cfg_free_node (node);
for (node = prev->next; node->next; node = node->next)
;
node->next = next;
mu_iterator_ctl (itr, mu_itrctl_insert_list,
node->nodes);
mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
/*FIXME:mu_cfg_free_node (node);*/
}
}
else
{
mu_cfg_perror (tree->debug, &node->locus,
_("argument to `program' is not a string"));
if (prev)
prev->next = next;
else
tree->head = next;
mu_cfg_free_node (node);
mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
}
}
}
else if (node->type == mu_cfg_node_param &&
strcmp (node->tag, "include") == 0)
{
/* Remove node from the list */
if (prev)
prev->next = next;
else
tree->head = next;
if (node->label->type == MU_CFG_STRING)
{
mu_cfg_tree_t *t = do_include (node->label->v.string, flags,
&node->locus);
if (t)
{
if (prev)
prev->next = t->head;
else
tree->head = t->head;
t->tail->next = next;
/* FIXME: check return value */
/* Merge the new tree into the current point and
destroy the rest of it */
mu_iterator_ctl (itr, mu_itrctl_insert_list, t->nodes);
mu_opool_union (&tree->pool, &t->pool);
mu_debug_destroy (&t->debug, NULL);
free (t);
mu_cfg_destroy_tree (&t);
}
}
else
mu_cfg_perror (tree->debug, &node->locus,
_("argument to `include' is not a string"));
mu_cfg_free_node (node);
/* Remove node from the list */
mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
}
prev = node;
node = next;
}
return 0;
}
static int
_mu_cfg_preorder_recursive (mu_cfg_node_t *node,
mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end,
void *data)
{
switch (node->type)
{
case mu_cfg_node_undefined:
abort ();
case mu_cfg_node_statement:
switch (beg (node, data))
{
case MU_CFG_ITER_OK:
if (mu_cfg_preorder (node->node, beg, end, data))
return MU_CFG_ITER_STOP;
if (end && end (node, data) == MU_CFG_ITER_STOP)
return MU_CFG_ITER_STOP;
break;
case MU_CFG_ITER_SKIP:
break;
case MU_CFG_ITER_STOP:
return MU_CFG_ITER_STOP;
}
break;
case mu_cfg_node_param:
return beg (node, data);
}
return MU_CFG_ITER_OK;
}
int
mu_cfg_preorder(mu_cfg_node_t *node,
mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, void *data)
_mu_cfg_preorder_recursive (void *item, void *cbdata)
{
for (; node; node = node->next)
if (_mu_cfg_preorder_recursive(node, beg, end, data) == MU_CFG_ITER_STOP)
return 1;
return 0;
}
mu_cfg_node_t *node = item;
struct mu_cfg_iter_closure *clos = cbdata;
static int
_mu_cfg_postorder_recursive(mu_cfg_node_t *node,
mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end,
void *data)
{
switch (node->type)
{
case mu_cfg_node_undefined:
abort ();
case mu_cfg_node_statement:
switch (beg (node, data))
switch (clos->beg (node, clos->data))
{
case MU_CFG_ITER_OK:
if (mu_cfg_postorder (node->node, beg, end, data))
return MU_CFG_ITER_STOP;
if (end && end (node, data) == MU_CFG_ITER_STOP)
return MU_CFG_ITER_STOP;
if (mu_cfg_preorder (node->nodes, clos))
return 1;
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 MU_CFG_ITER_STOP;
return 1;
}
break;
case mu_cfg_node_param:
return beg (node, data);
return clos->beg (node, clos->data) == MU_CFG_ITER_STOP;
}
return 0;
}
int
mu_cfg_postorder (mu_cfg_node_t *node,
mu_cfg_iter_func_t beg, mu_cfg_iter_func_t end, void *data)
mu_cfg_preorder (mu_list_t nodelist, struct mu_cfg_iter_closure *clos)
{
if (!node)
return 1;
if (node->next
&& mu_cfg_postorder (node->next, beg, end, data) == MU_CFG_ITER_STOP)
return 1;
return _mu_cfg_postorder_recursive (node, beg, end, data)
== MU_CFG_ITER_STOP;
return mu_list_do (nodelist, _mu_cfg_preorder_recursive, clos);
}
static int
free_section (const mu_cfg_node_t *node, void *data)
{
if (node->type == mu_cfg_node_statement)
free ((void *) node);
return MU_CFG_ITER_OK;
}
static int
free_param (const mu_cfg_node_t *node, void *data)
{
if (node->type == mu_cfg_node_param)
free ((void*) node);
return MU_CFG_ITER_OK;
}
void
mu_cfg_destroy_tree (mu_cfg_tree_t **ptree)
......@@ -735,7 +678,7 @@ mu_cfg_destroy_tree (mu_cfg_tree_t **ptree)
if (ptree && *ptree)
{
mu_cfg_tree_t *tree = *ptree;
mu_cfg_postorder (tree->head, free_param, free_section, NULL);
mu_list_destroy (&tree->nodes);
mu_opool_destroy (&tree->pool);
*ptree = NULL;
}
......@@ -1423,11 +1366,14 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
{
mu_debug_t debug = NULL;
struct scan_tree_data dat;
struct mu_cfg_iter_closure clos;
dat.tree = tree;
dat.list = NULL;
dat.error = 0;
dat.call_data = data;
dat.target = target;
if (!tree->debug)
{
mu_diag_get_debug (&debug);
......@@ -1435,7 +1381,10 @@ mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
}
if (push_section (&dat, sections))
return 1;
mu_cfg_preorder (tree->head, _scan_tree_helper, _scan_tree_end_helper, &dat);
clos.beg = _scan_tree_helper;
clos.end = _scan_tree_end_helper;
clos.data = &dat;
mu_cfg_preorder (tree->nodes, &clos);
if (debug)
{
mu_debug_set_locus (debug, NULL, 0);
......@@ -1501,7 +1450,7 @@ mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
enum mu_cfg_node_type type,
const mu_cfg_locus_t *loc,
const char *tag, const char *label,
mu_cfg_node_t *node)
mu_list_t nodelist)
{
char *p;
mu_cfg_node_t *np;
......@@ -1528,24 +1477,32 @@ mu_cfg_tree_create_node (struct mu_cfg_tree *tree,
}
else
np->label = NULL;
np->node = node;
np->next = NULL;
np->nodes = nodelist;
return np;
}
void
mu_cfg_tree_add_node (mu_cfg_tree_t *tree, mu_cfg_node_t *node)
{
if (!tree->head)
tree->head = node;
else
{
mu_cfg_node_t *p;
for (p = tree->head; p->next; p = p->next)
;
p->next = node;
}
if (!node)
return;
if (!tree->nodes)
/* FIXME: return code? */
mu_cfg_create_node_list (&tree->nodes);
mu_list_append (tree->nodes, node);
}
void
mu_cfg_tree_add_nodelist (mu_cfg_tree_t *tree, mu_list_t nodelist)
{
if (!nodelist)
return;
if (!tree->nodes)
/* FIXME: return code? */
mu_cfg_create_node_list (&tree->nodes);
mu_list_append_list (tree->nodes, nodelist);
}
/* Return 1 if configuration value A equals B */
int
......@@ -1740,10 +1697,11 @@ node_finder (const mu_cfg_node_t *node, void *data)
}
int
mu_cfg_find_node (mu_cfg_node_t *tree, const char *path, mu_cfg_node_t **pval)
mu_cfg_find_node (mu_cfg_tree_t *tree, const char *path, mu_cfg_node_t **pval)
{
int rc;
struct find_data data;
struct mu_cfg_iter_closure clos;
rc = mu_argcv_get_np (path, strlen (path),
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)
return rc;
data.tag = 0;
parse_tag (&data);
rc = mu_cfg_preorder (tree, node_finder, NULL, &data);
clos.beg = node_finder;
clos.end = NULL;
clos.data = &data;
rc = mu_cfg_preorder (tree->nodes, &clos);
destroy_value (data.label);
if (rc)
{
......@@ -1784,6 +1746,7 @@ mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode)
for (i = argc - 1; i >= 0; i--)
{
mu_list_t nodelist = NULL;
char *p = strrchr (argv[i], '=');
mu_config_value_t *label = NULL;
......@@ -1795,8 +1758,13 @@ mu_cfg_create_subtree (const char *path, mu_cfg_node_t **pnode)
if (i == argc - 1)
type = mu_cfg_node_param;
}
node = mu_cfg_alloc_node (type, &locus, argv[i], label, node);
if (node)
{
mu_cfg_create_node_list (&nodelist);
mu_list_append (nodelist, node);
}
node = mu_cfg_alloc_node (type, &locus, argv[i], label, nodelist);
}
mu_argcv_free (argc, argv);
......
......@@ -93,7 +93,7 @@ set_debug_flags (mu_debug_t debug, const char *arg)
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
......@@ -108,7 +108,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
case ARGP_KEY_FINI:
if (dry_run && !debug_level)
debug_level = 1;
mu_argp_node_list_finish (&lst, NULL, NULL);
mu_argp_node_list_finish (lst, NULL, NULL);
break;
case 'a':
......@@ -117,7 +117,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'd':
mu_argp_node_list_new (&lst, "debug", arg ? arg : "9");
mu_argp_node_list_new (lst, "debug", arg ? arg : "9");
break;
case 'h':
......@@ -129,11 +129,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 't':
mu_argp_node_list_new (&lst, "mimetypes", arg);
mu_argp_node_list_new (lst, "mimetypes", arg);
break;
case OPT_METAMAIL:
mu_argp_node_list_new (&lst, "metamail", arg ? arg : "metamail");
mu_argp_node_list_new (lst, "metamail", arg ? arg : "metamail");
break;
default:
......
......@@ -111,24 +111,24 @@ mu_kwd_t method_kwd[] = {
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
case 'r':
mu_argp_node_list_new (&lst, "reverse", "yes");
mu_argp_node_list_new (lst, "reverse", "yes");
break;
case 'p':
mu_argp_node_list_new (&lst, "preserve", "yes");
mu_argp_node_list_new (lst, "preserve", "yes");
break;
case 'P':
mu_argp_node_list_new (&lst, "mailbox-ownership", arg);
mu_argp_node_list_new (lst, "mailbox-ownership", arg);
break;
case 'u':
mu_argp_node_list_new (&lst, "uidl", "yes");
mu_argp_node_list_new (lst, "uidl", "yes");
break;
case 'v':
......@@ -136,7 +136,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case OPT_EMACS:
mu_argp_node_list_new (&lst, "emacs", "yes");
mu_argp_node_list_new (lst, "emacs", "yes");
break;
case ARGP_KEY_INIT:
......@@ -144,7 +144,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
mu_argp_node_list_finish (lst, NULL, NULL);
break;
default:
......
......@@ -146,22 +146,22 @@ static const char *pop3d_argp_capa[] = {
static error_t
pop3d_parse_opt (int key, char *arg, struct argp_state *astate)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
case 'd':
mu_argp_node_list_new (&lst, "mode", "daemon");
mu_argp_node_list_new (lst, "mode", "daemon");
if (arg)
mu_argp_node_list_new (&lst, "max-children", arg);
mu_argp_node_list_new (lst, "max-children", arg);
break;
case 'i':
mu_argp_node_list_new (&lst, "mode", "inetd");
mu_argp_node_list_new (lst, "mode", "inetd");
break;
case OPT_FOREGROUND:
mu_argp_node_list_new (&lst, "foreground", "yes");
mu_argp_node_list_new (lst, "foreground", "yes");
break;
case ARGP_KEY_INIT:
......@@ -169,7 +169,7 @@ pop3d_parse_opt (int key, char *arg, struct argp_state *astate)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
mu_argp_node_list_finish (lst, NULL, NULL);
break;
default:
......
......@@ -79,7 +79,7 @@ int show_all = 0;
static error_t
readmsg_parse_opt (int key, char *arg, struct argp_state *astate)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
......@@ -88,27 +88,27 @@ readmsg_parse_opt (int key, char *arg, struct argp_state *astate)
break;
case 'h':
mu_argp_node_list_new (&lst, "header", "yes");
mu_argp_node_list_new (lst, "header", "yes");
break;
case 'f':
mu_argp_node_list_new (&lst, "folder", arg);
mu_argp_node_list_new (lst, "folder", arg);
break;
case 'w':
mu_argp_node_list_new (&lst, "weedlist", arg);
mu_argp_node_list_new (lst, "weedlist", arg);
break;
case 'n':
mu_argp_node_list_new (&lst, "no-header", "yes");
mu_argp_node_list_new (lst, "no-header", "yes");
break;
case 'p':
mu_argp_node_list_new (&lst, "form-feeds", "yes");
mu_argp_node_list_new (lst, "form-feeds", "yes");
break;
case 'a':
mu_argp_node_list_new (&lst, "show-all-match", "yes");
mu_argp_node_list_new (lst, "show-all-match", "yes");
break;
case ARGP_KEY_INIT:
......@@ -117,8 +117,8 @@ readmsg_parse_opt (int key, char *arg, struct argp_state *astate)
case ARGP_KEY_FINI:
if (dbug)
mu_argp_node_list_new (&lst, "debug", mu_umaxtostr (0, dbug));
mu_argp_node_list_finish (&lst, NULL, NULL);
mu_argp_node_list_new (lst, "debug", mu_umaxtostr (0, dbug));
mu_argp_node_list_finish (lst, NULL, NULL);
break;
default:
......
......@@ -172,12 +172,12 @@ mu_compat_printer (void *data, mu_log_level_t level, const char *buf)
static error_t
parser (int key, char *arg, struct argp_state *state)
{
static struct mu_argp_node_list lst;
static mu_list_t lst;
switch (key)
{
case 'e':
mu_argp_node_list_new (&lst, "email", arg);
mu_argp_node_list_new (lst, "email", arg);
break;
case 'n':
......@@ -185,7 +185,7 @@ parser (int key, char *arg, struct argp_state *state)
break;
case 'k':
mu_argp_node_list_new (&lst, "keep-going", "yes");
mu_argp_node_list_new (lst, "keep-going", "yes");
break;
case 'c':
......@@ -197,23 +197,23 @@ parser (int key, char *arg, struct argp_state *state)
break;
case 'f':
mu_argp_node_list_new (&lst, "mbox-url", arg);
mu_argp_node_list_new (lst, "mbox-url", arg);
break;
case 't':
mu_argp_node_list_new (&lst, "ticket", arg);
mu_argp_node_list_new (lst, "ticket", arg);
break;
case 'd':
mu_argp_node_list_new (&lst, "debug", arg ? arg : D_DEFAULT);
mu_argp_node_list_new (lst, "debug", arg ? arg : D_DEFAULT);
break;
case 'v':
mu_argp_node_list_new (&lst, "verbose", "yes");
mu_argp_node_list_new (lst, "verbose", "yes");
break;
case ARG_LINE_INFO:
mu_argp_node_list_new (&lst, "line-info",
mu_argp_node_list_new (lst, "line-info",
is_true_p (arg) ? "yes" : "no");
break;
......@@ -236,7 +236,7 @@ parser (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_FINI:
mu_argp_node_list_finish (&lst, NULL, NULL);
mu_argp_node_list_finish (lst, NULL, NULL);
break;
default:
......