diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-07 01:47:16 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-07 01:49:38 +0300 |
commit | 72b77743f20f909e83eacca3b47558d943ac2fcb (patch) | |
tree | 51cb9c4a5ba7324fa8525fb04cda9603c21897e1 /src | |
parent | ed39daa568d162617a183497010d70a55a38ae73 (diff) | |
download | grecs-72b77743f20f909e83eacca3b47558d943ac2fcb.tar.gz grecs-72b77743f20f909e83eacca3b47558d943ac2fcb.tar.bz2 |
Implement tree join.
* src/join.c: New file.
* src/Make.am: Add join.c
* src/grecs.h (grecs_tree_join): New function.
* tests/gcffmt.c (main): If several files are given, process
them all and join the resulting trees.
* tests/join.at: New testcase.
* tests/testsuite.at: Include join.at.
* tests/Makefile.am: Add join.at.
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 @@ -16,12 +16,13 @@ GRECS_SRC = \ diag.c\ format.c\ grecs-gram.y\ grecs-lex.l\ + join.c\ list.c\ lookup.c\ mem.c\ preproc.c\ sort.c\ symtab.c\ diff --git a/src/grecs.h b/src/grecs.h index dabcf7c..f32fc1f 100644 --- a/src/grecs.h +++ b/src/grecs.h @@ -327,12 +327,13 @@ enum grecs_tree_recurse_res { typedef enum grecs_tree_recurse_res (*grecs_tree_recursor_t)(enum grecs_tree_recurse_op, struct grecs_node *, void *); 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); int grecs_value_eq(struct grecs_value *a, struct grecs_value *b); struct grecs_node *grecs_find_node(struct grecs_node *node, const char *path); 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; +} @@ -1021,7 +1021,6 @@ grecs_tree_reduce(struct grecs_node *node, struct grecs_keyword *kwd) clos.sections = NULL; } rc = grecs_tree_recurse(node->down, reduceproc, &clos); grecs_list_free(clos.sections); return rc; } - |