summaryrefslogtreecommitdiffabout
path: root/lib
authorSergey Poznyakoff <gray@gnu.org.ua>2012-10-12 14:29:14 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2012-10-12 14:29:14 (GMT)
commit75f2669bf1b62b441002ac361e245254e9ad7330 (patch) (side-by-side diff)
tree16e6af51b24d9a86d5cdefcc58723582c404d22c /lib
parentdfa58f8b8ebf024c2ec678a836adcd055e4bc052 (diff)
downloadeclat-75f2669bf1b62b441002ac361e245254e9ad7330.tar.gz
eclat-75f2669bf1b62b441002ac361e245254e9ad7330.tar.bz2
Implement sequence map.
* doc/eclat.conf.5: Document sequence maps. * lib/Makefile.am: Add new files. * lib/libeclat.h (eclat_map_drv_seq): New extern. * lib/seqmap.c: New file. * src/eclat.c: Minor fixes. * tests/Makefile.am: Add new testcase. * tests/testsuite.at: Likewise. * tests/seqmap.at: New file.
Diffstat (limited to 'lib') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/libeclat.h2
-rw-r--r--lib/seqmap.c161
3 files changed, 163 insertions, 1 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index ede2b7b..7b2cb11 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -49,6 +49,7 @@ libeclat_a_SOURCES=\
qencode.c\
qfree.c\
reqsign.c\
+ seqmap.c\
sha1.c\
sha1.h\
urlencode.c\
diff --git a/lib/libeclat.h b/lib/libeclat.h
index 0843fb1..ee94345 100644
--- a/lib/libeclat.h
+++ b/lib/libeclat.h
@@ -155,4 +155,4 @@ extern struct eclat_map_drv eclat_map_drv_file;
extern struct eclat_map_drv eclat_map_drv_gdbm;
extern struct eclat_map_drv eclat_map_drv_ldap;
extern struct eclat_map_drv eclat_map_drv_null;
-
+extern struct eclat_map_drv eclat_map_drv_seq;
diff --git a/lib/seqmap.c b/lib/seqmap.c
new file mode 100644
index 0000000..777bbd7
--- a/dev/null
+++ b/lib/seqmap.c
@@ -0,0 +1,161 @@
+/* This file is part of Eclat.
+ Copyright (C) 2012 Sergey Poznyakoff.
+
+ Eclat 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.
+
+ Eclat 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 Eclat. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "libeclat.h"
+#include <errno.h>
+
+struct seqmap {
+ struct grecs_list *namelist;
+ size_t nmaps;
+ struct eclat_map **maps;
+};
+
+static struct grecs_keyword seqmap_kw[] = {
+ { "type", "'sequence", "Set sequence map type", grecs_type_null },
+ { "key", "<arg: string>", "key expression", grecs_type_null },
+ { "sequence", "arg", "list of maps to use",
+ grecs_type_string, GRECS_LIST,
+ NULL, offsetof(struct seqmap, namelist) },
+ { NULL }
+};
+
+static void
+seqmap_confhelp()
+{
+ static struct grecs_keyword seqmap_top[] = {
+ { "map", "name: string",
+ "Configuration for a sequence map",
+ grecs_type_section, GRECS_INAC, NULL, 0, NULL, NULL,
+ seqmap_kw },
+ { NULL }
+ };
+ grecs_print_statement_array(seqmap_top, 1, 0, stdout);
+}
+
+static void
+seqmap_free(int dbg, void *data)
+{
+ struct seqmap *seqmap = data;
+
+ grecs_list_free(seqmap->namelist);
+ if (seqmap->maps) {
+#if 0
+ size_t i;
+ /* FIXME: Uncomment this when reference
+ counters are implemented */
+ for (i = 0; i < seqmap->nmaps; i++)
+ if (seqmap->maps[i])
+ eclat_map_free(seqmap->maps[i]);
+#endif
+ free(seqmap->maps);
+ }
+ free(seqmap);
+}
+
+static int
+seqmap_config(int dbg, struct grecs_node *node, void *data)
+{
+ struct seqmap *seqmap, **return_seqmap = data;
+ int i;
+
+ seqmap = grecs_malloc(sizeof(*seqmap));
+ for (i = 0; seqmap_kw[i].ident; i++)
+ seqmap_kw[i].varptr = seqmap;
+ if (grecs_tree_process(node->down, seqmap_kw)) {
+ seqmap_free(dbg, seqmap);
+ return eclat_map_failure;
+ }
+ if (!seqmap->namelist ||
+ (seqmap->nmaps = grecs_list_size(seqmap->namelist)) == 0) {
+ grecs_error(&node->locus, 0, "sequence empty");
+ seqmap_free(dbg, seqmap);
+ return eclat_map_failure;
+ }
+ seqmap->maps = grecs_calloc(seqmap->nmaps, sizeof(seqmap->maps[0]));
+ *return_seqmap = seqmap;
+ return eclat_map_ok;
+}
+
+static int
+seqmap_open(int dbg, void *data)
+{
+ struct seqmap *seqmap = data;
+ struct grecs_list_entry *ep;
+ size_t i;
+ int rc;
+
+ for (ep = seqmap->namelist->head, i = 0; ep; ep = ep->next, i++) {
+ struct eclat_map *map;
+
+ map = eclat_map_lookup(ep->data);
+ if (!map) {
+ err("no such map: %s", ep->data);
+ return eclat_map_failure;
+ }
+ if ((rc = eclat_map_open(map)) != eclat_map_ok)
+ return rc;
+ seqmap->maps[i] = map;
+ }
+ return eclat_map_ok;
+}
+
+static int
+seqmap_close(int dbg, void *data)
+{
+ struct seqmap *seqmap = data;
+ size_t i;
+
+ for (i = 0; i < seqmap->nmaps; i++) {
+ if (seqmap->maps[i])
+ eclat_map_close(seqmap->maps[i]);
+ }
+ return eclat_map_ok;
+}
+
+static int
+seqmap_get(int dbg, void *data, const char *key, char **return_value)
+{
+ struct seqmap *seqmap = data;
+ size_t i;
+ char *p = grecs_strdup(key);
+ char *v;
+
+ for (i = 0; i < seqmap->nmaps; i++) {
+ int rc = eclat_map_get(seqmap->maps[i], p, &v);
+ free(p);
+ if (rc != eclat_map_ok) {
+ debug(dbg, 1, ("map %s returned %s",
+ seqmap->maps[i]->name,
+ eclat_map_strerror(rc)));
+ return rc;
+ }
+ p = v;
+ }
+
+ *return_value = v;
+ return eclat_map_ok;
+}
+
+struct eclat_map_drv eclat_map_drv_seq = {
+ "sequence",
+ seqmap_config,
+ seqmap_open,
+ seqmap_close,
+ seqmap_get,
+ seqmap_free,
+ seqmap_confhelp
+};
+

Return to:

Send suggestions and report system problems to the System administrator.