diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Make.am | 1 | ||||
-rw-r--r-- | src/grecs.h | 1 | ||||
-rw-r--r-- | src/join.c | 68 | ||||
-rw-r--r-- | src/tree.c | 1 |
4 files changed, 70 insertions, 1 deletions
diff --git a/src/Make.am b/src/Make.am index 531e2ef..27f8010 100644 --- a/src/Make.am +++ b/src/Make.am @@ -19,6 +19,7 @@ GRECS_SRC = \ format.c\ grecs-gram.y\ grecs-lex.l\ + join.c\ list.c\ lookup.c\ mem.c\ diff --git a/src/grecs.h b/src/grecs.h index dabcf7c..f32fc1f 100644 --- a/src/grecs.h +++ b/src/grecs.h @@ -330,6 +330,7 @@ typedef enum grecs_tree_recurse_res int grecs_tree_recurse(struct grecs_node *node, grecs_tree_recursor_t recfun, void *data); +int grecs_tree_join(struct grecs_node *dst, struct grecs_node *src); int grecs_tree_process(struct grecs_node *node, struct grecs_keyword *kwd); diff --git a/src/join.c b/src/join.c new file mode 100644 index 0000000..fd7c3ad --- /dev/null +++ b/src/join.c @@ -0,0 +1,68 @@ +/* grecs - Gray's Extensible Configuration System + Copyright (C) 2007-2011 Sergey Poznyakoff + + Grecs is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + + Grecs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Grecs. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdlib.h> +#include <errno.h> +#include "grecs.h" + +static enum grecs_tree_recurse_res +reset_locus(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data) +{ + struct grecs_symtab *st = data; + switch (op) { + case grecs_tree_recurse_set: + case grecs_tree_recurse_pre: + if (node->locus.file) { + struct grecs_syment *ent, key; + int install = 1; + key.name = (char*) node->locus.file; + ent = grecs_symtab_lookup_or_install(st, &key, + &install); + if (!ent) + grecs_alloc_die(); + node->locus.file = ent->name; + } + break; + default: + break; + } + return grecs_tree_recurse_ok; + +} + +int +grecs_tree_join(struct grecs_node *dst, struct grecs_node *src) +{ + struct grecs_node *p; + + if (dst->type != grecs_node_root || src->type != grecs_node_root) + return 1; + grecs_node_bind(dst, src->down, 1); + for (p = src->down; p; p = p->next) + p->up = dst; + if (!src->v.texttab) { + dst->v.texttab = src->v.texttab; + } else { + grecs_tree_recurse(src->down, reset_locus, dst->v.texttab); + grecs_symtab_free(src->v.texttab); + } + src->v.texttab = NULL; + src->down = NULL; + return 0; +} @@ -1024,4 +1024,3 @@ grecs_tree_reduce(struct grecs_node *node, struct grecs_keyword *kwd) grecs_list_free(clos.sections); return rc; } - |