diff options
-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 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/gcffmt.c | 25 | ||||
-rw-r--r-- | tests/join.at | 48 | ||||
-rw-r--r-- | tests/testsuite.at | 2 |
8 files changed, 141 insertions, 6 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; } - diff --git a/tests/Makefile.am b/tests/Makefile.am index b4b0dce..e88b689 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -45,6 +45,7 @@ TESTSUITE_AT = \ format01.at\ format02.at\ cfhelp.at\ + join.at\ peek00.at\ peek01.at\ peek02.at\ diff --git a/tests/gcffmt.c b/tests/gcffmt.c index 64a4f63..2097c02 100644 --- a/tests/gcffmt.c +++ b/tests/gcffmt.c @@ -25,7 +25,8 @@ static void usage(const char *arg, FILE *fp, int code) { fprintf(fp, - "usage: %s [-h] [-locus] [-delim=char] [-reduce] [-sort] file\n", + "usage: %s [-h] [-locus] [-delim=char] [-reduce] [-sort] " + "file [file...]\n", arg); exit(code); } @@ -60,18 +61,32 @@ main(int argc, char **argv) usage(progname, stdout, 0); else if (arg[0] == '-') usage(progname, stderr, 1); - else if (file) - usage(progname, stderr, 1); - else + else { file = arg; + --argc; + break; + } } - if (!file || argc) + if (!file) usage(progname, stderr, 1); tree = grecs_parse(file); if (!tree) exit(1); + + for (; argc; argc--) { + char *arg = *++argv; + node = grecs_parse(arg); + if (!node) + exit(1); + if (grecs_tree_join(tree, node)) { + fprintf(stderr, "join failed\n"); + exit(1); + } + grecs_tree_free(node); + } + if (reduce) grecs_tree_reduce(tree, NULL); if (sort) diff --git a/tests/join.at b/tests/join.at new file mode 100644 index 0000000..5eb177d --- /dev/null +++ b/tests/join.at @@ -0,0 +1,48 @@ +# This file is part of grecs -*- Autotest -*- +# Copyright (C) 2007, 2009-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, 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/>. + +AT_SETUP(Join) +AT_KEYWORDS([join]) + +AT_DATA([1.cf],[a 1; +b 2; +c { + a x; + b y; +} +]) + +AT_DATA([2.cf],[x 1; +y 2; +z { + x 3; + y 4; +} +]) + +AT_CHECK([gcffmt -locus 1.cf 2.cf], +[0], +[1.cf:1: .a: "1" +1.cf:2: .b: "2" +1.cf:4: .c.a: "x" +1.cf:5: .c.b: "y" +2.cf:1: .x: "1" +2.cf:2: .y: "2" +2.cf:4: .z.x: "3" +2.cf:5: .z.y: "4" +]) + +AT_CLEANUP diff --git a/tests/testsuite.at b/tests/testsuite.at index 184108c..b31eeef 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -61,6 +61,8 @@ m4_include([reduce00.at]) m4_include([reduce01.at]) m4_include([reduce02.at]) +m4_include([join.at]) + m4_if(GRECS_VERCMP_AT,,,[m4_include(GRECS_VERCMP_AT)]) # End of testsuite.at |