aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Make.am1
-rw-r--r--src/grecs.h1
-rw-r--r--src/join.c68
-rw-r--r--src/tree.c1
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/gcffmt.c25
-rw-r--r--tests/join.at48
-rw-r--r--tests/testsuite.at2
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;
+}
diff --git a/src/tree.c b/src/tree.c
index 22a169a..955fc52 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -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

Return to:

Send suggestions and report system problems to the System administrator.