summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2012-12-15 18:57:55 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2012-12-15 18:57:55 (GMT)
commite60288d595ec405c5d416e5da54b516e65f8a8c5 (patch) (side-by-side diff)
treed88aaa4352658be717b463ca60c05d85b41d1cd0
parent00110918072f77e0e5705e93ad91207f1bd0d873 (diff)
downloadeclat-e60288d595ec405c5d416e5da54b516e65f8a8c5.tar.gz
eclat-e60288d595ec405c5d416e5da54b516e65f8a8c5.tar.bz2
Implement direct and reverse map lookups.
Not all maps support reverse lookups generically (for example, gdbm does not), therefore introduce a new "bidi" (bi-directional) map, which is a compound of two maps, each one used for a particular lookup direction. * lib/Makefile.am (maps): List all maps here. * lib/bidimap.c: New file. Implementation of a bi-directional map. * lib/filemap.c: Update to the changes in API. Implement reverse lookup. * lib/gdbmmap.c: Update to the changes in API. * lib/nullmap.c: Likewise. * lib/seqmap.c: Likewise. * lib/ldapmap.c: Update to the changes in API. Implement reverse lookup. New configuration keywords: reverse-filter, reverse-attr. * lib/libeclat.h (eclat_map_drv) <map_get>: Change signature, take search direction as a new argument. (eclat_map_get): Likewise. (eclat_map) <eclat_map_bad_dir>: New status code. (MAP_DIR, MAP_REV): New macros. (eclat_map_name_split): New function. (eclat_map_drv_bidi): New extern. * lib/map.c (eclat_map_get): Change signature, take search direction as a new argument. Pass new keyword to the "key" translation: "dir". (eclat_map_strerror): Handle new status code. (eclat_map_name_split): New function. * src/eclat.c (main): Register eclat_map_drv_bidi. * src/util.c (translate_ids): Use eclat_map_name_split to obtain direction code from the map name. (translate_resource_ids): Use direct lookups. * tests/Makefile.am: Add new testcases. * tests/testsuite.at: Likewise. * tests/bidimap.at: New testcase. * tests/filemap.at: Test reverse lookups.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--lib/Makefile.am7
-rw-r--r--lib/bidimap.c175
-rw-r--r--lib/filemap.c66
-rw-r--r--lib/gdbmmap.c6
-rw-r--r--lib/ldapmap.c46
-rw-r--r--lib/libeclat.h12
-rw-r--r--lib/map.c44
-rw-r--r--lib/nullmap.c2
-rw-r--r--lib/seqmap.c4
-rw-r--r--src/eclat.c3
-rw-r--r--src/util.c18
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/bidimap.at58
-rw-r--r--tests/filemap.at15
-rw-r--r--tests/testsuite.at1
15 files changed, 423 insertions, 35 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e418134..8bd147c 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -25,9 +25,12 @@ if COND_LDAP
endif
maps = \
+ bidimap.c\
$(GDBMMAP)\
filemap.c\
- $(LDAPMAP)
+ nullmap.c\
+ $(LDAPMAP)\
+ seqmap.c
libeclat_a_SOURCES=\
base64.c\
@@ -44,14 +47,12 @@ libeclat_a_SOURCES=\
hmac_sha1.c\
libeclat.h\
map.c\
- nullmap.c\
q2url.c\
qaddparm.c\
qcreat.c\
qencode.c\
qfree.c\
reqsign.c\
- seqmap.c\
sha1.c\
sha1.h\
urlencode.c\
diff --git a/lib/bidimap.c b/lib/bidimap.c
new file mode 100644
index 0000000..022e821
--- a/dev/null
+++ b/lib/bidimap.c
@@ -0,0 +1,175 @@
+/* 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 bidimap {
+ struct submap {
+ char *name;
+ struct eclat_map *map;
+ int dir;
+ } submap[2];
+};
+
+static int
+cb_submap(enum grecs_callback_command cmd,
+ grecs_locus_t *locus,
+ void *varptr,
+ grecs_value_t *value,
+ void *cb_data)
+{
+ struct submap *submap = varptr;
+ char *name, *q;
+ int dir;
+
+ if (cmd != grecs_callback_set_value) {
+ grecs_error(locus, 0, "Unexpected block statement");
+ return 1;
+ }
+ if (!value || value->type != GRECS_TYPE_STRING) {
+ grecs_error(locus, 0, "expected a string");
+ return 1;
+ }
+
+ dir = eclat_map_name_split(value->v.string, &submap->name, &q);
+ if (dir == -1) {
+ grecs_error(locus, 0, "bad qualifier: %s", q);
+ return 1;
+ }
+
+ submap->dir = dir;
+ return 0;
+}
+
+static struct grecs_keyword bidimap_kw[] = {
+ { "type", "'bidi", "Set bi-directional map type", grecs_type_null },
+ { "key", "<arg: string>", "key expression", grecs_type_null },
+ { "direct-map", "arg", "map for direct lookups",
+ grecs_type_string, GRECS_DFLT,
+ NULL, offsetof(struct bidimap, submap[MAP_DIR]), cb_submap },
+ { "reverse-map", "arg", "map for reverse lookups",
+ grecs_type_string, GRECS_DFLT,
+ NULL, offsetof(struct bidimap, submap[MAP_REV]), cb_submap },
+ { NULL }
+};
+
+static void
+bidimap_confhelp()
+{
+ static struct grecs_keyword bidimap_top[] = {
+ { "map", "name: string",
+ "Configuration for a generic bi-directional map",
+ grecs_type_section, GRECS_INAC, NULL, 0, NULL, NULL,
+ bidimap_kw },
+ { NULL }
+ };
+ grecs_print_statement_array(bidimap_top, 1, 0, stdout);
+}
+
+static void
+bidimap_free(int dbg, void *data)
+{
+ struct bidimap *bidimap = data;
+
+#if 0
+ /* FIXME: Uncomment this when reference
+ counters are implemented */
+ eclat_map_free(bidimap->submap[MAP_DIR].map);
+ eclat_map_free(bidimap->submap[MAP_REV].map);
+#endif
+ free(bidimap);
+}
+
+static int
+bidimap_config(int dbg, struct grecs_node *node, void *data)
+{
+ struct bidimap *map, **return_map = data;
+ int i;
+
+ map = grecs_malloc(sizeof(*map));
+ for (i = 0; bidimap_kw[i].ident; i++)
+ bidimap_kw[i].varptr = map;
+ if (grecs_tree_process(node->down, bidimap_kw)) {
+ bidimap_free(dbg, map);
+ return eclat_map_failure;
+ }
+
+ if (!map->submap[MAP_DIR].name && !map->submap[MAP_REV].name) {
+ grecs_error(&node->locus, 0, "no maps declared");
+ bidimap_free(dbg, map);
+ return eclat_map_failure;
+ }
+
+ *return_map = map;
+ return eclat_map_ok;
+}
+
+static int
+bidimap_open(int dbg, void *data)
+{
+ struct bidimap *bidimap = data;
+ struct eclat_map *map;
+ int i;
+ int rc;
+
+ for (i = 0; i < 2; i++) {
+ map = eclat_map_lookup(bidimap->submap[i].name);
+ if (!map)
+ continue;
+ if ((rc = eclat_map_open(map)) != eclat_map_ok)
+ return rc;
+ bidimap->submap[i].map = map;
+ }
+ return eclat_map_ok;
+}
+
+static int
+bidimap_close(int dbg, void *data)
+{
+ struct bidimap *map = data;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if (map->submap[i].map)
+ eclat_map_close(map->submap[i].map);
+ }
+ return eclat_map_ok;
+}
+
+static int
+bidimap_get(int dbg, int dir, void *data, const char *key, char **return_value)
+{
+ struct bidimap *map = data;
+
+ if (!map->submap[dir].map)
+ return eclat_map_bad_dir;
+
+ return eclat_map_get(map->submap[dir].map, map->submap[dir].dir,
+ key, return_value);
+}
+
+struct eclat_map_drv eclat_map_drv_bidi = {
+ "bidi",
+ bidimap_config,
+ bidimap_open,
+ bidimap_close,
+ bidimap_get,
+ bidimap_free,
+ bidimap_confhelp
+};
+
+
diff --git a/lib/filemap.c b/lib/filemap.c
index c43ba35..e797169 100644
--- a/lib/filemap.c
+++ b/lib/filemap.c
@@ -111,7 +111,7 @@ skipline(FILE *fp)
}
static int
-filemap_get(int dbg, void *data, const char *key, char **return_value)
+filemap_get_0(int dbg, void *data, const char *key, char **return_value)
{
struct filemap *filemap = data;
FILE *fp = filemap->fp;
@@ -161,6 +161,70 @@ filemap_get(int dbg, void *data, const char *key, char **return_value)
return rc;
}
+static int
+filemap_get_1(int dbg, void *data, const char *key, char **return_value)
+{
+ struct filemap *filemap = data;
+ FILE *fp = filemap->fp;
+ int line = 0;
+ int rc, c;
+ const char *p;
+ size_t len;
+
+ rewind(fp);
+ while ((c = getc(fp)) != EOF) {
+ line++;
+ while (c != EOF && (c == ' ' || c == '\t'))
+ c = getc(fp);
+ if (c == '\n')
+ continue;
+ if (c == '#') {
+ skipline(fp);
+ continue;
+ }
+ if (c == EOF)
+ break;
+ for (len = 0; c != EOF && c != ':'; len++)
+ c = getc(fp);
+ if (c == EOF)
+ break;
+ if (c == '\n')
+ continue;
+ if (c == ':') {
+ for (p = key, c = getc(fp), len++;
+ c != EOF && c != '\n' && *p == c;
+ p++, len++, c = getc(fp));
+ if (c == EOF || c == '\n')
+ break;
+ skipline(fp);
+ }
+ }
+
+ if (c == '\n') {
+ struct grecs_txtacc *acc;
+
+ debug(dbg, 2, ("%s:%d: found key", filemap->name, line));
+ fseek(fp, - (len + 1), SEEK_CUR);
+ acc = grecs_txtacc_create();
+ while ((c = getc(fp)) != EOF && c != ':')
+ grecs_txtacc_grow_char(acc, c);
+ grecs_txtacc_grow_char(acc, 0);
+ *return_value = grecs_txtacc_finish(acc, 1);
+ grecs_txtacc_free(acc);
+ rc = eclat_map_ok;
+ } else
+ rc = eclat_map_not_found;
+
+ return rc;
+}
+
+static int
+filemap_get(int dbg, int dir, void *data, const char *key, char **return_value)
+{
+ return (dir ? filemap_get_1 : filemap_get_0)(dbg, data, key,
+ return_value);
+}
+
struct eclat_map_drv eclat_map_drv_file = {
"file",
filemap_config,
diff --git a/lib/gdbmmap.c b/lib/gdbmmap.c
index 8433923..aa87a8e 100644
--- a/lib/gdbmmap.c
+++ b/lib/gdbmmap.c
@@ -111,11 +111,15 @@ gdbm_map_close(int dbg, void *data)
}
static int
-gdbm_map_get(int dbg, void *data, const char *key, char **return_value)
+gdbm_map_get(int dbg, int dir, void *data, const char *key,
+ char **return_value)
{
struct gdbm_map *gdbm_map = data;
datum keydat, content;
+ if (dir == MAP_REV)
+ return eclat_map_bad_dir;
+
keydat.dptr = (char*)key;
keydat.dsize = strlen(key) + (gdbm_map->nullflag ? 1 : 0);
gdbm_errno = 0;
diff --git a/lib/ldapmap.c b/lib/ldapmap.c
index 4e780af..092daa2 100644
--- a/lib/ldapmap.c
+++ b/lib/ldapmap.c
@@ -33,8 +33,8 @@ struct ldap_map {
char *passfile;
int tls;
int prompt;
- char *filter;
- char *attr;
+ char *filter[2];
+ char *attr[2];
int dbg;
LDAP *ld;
};
@@ -99,11 +99,19 @@ static struct grecs_keyword ldapmap_kw[] = {
{ "filter", "arg",
"Filter expression",
grecs_type_string, GRECS_DFLT,
- NULL, offsetof(struct ldap_map, filter) },
+ NULL, offsetof(struct ldap_map, filter[0]) },
+ { "reverse-filter", "arg",
+ "Reverse filter expression",
+ grecs_type_string, GRECS_DFLT,
+ NULL, offsetof(struct ldap_map, filter[1]) },
{ "attr", "arg",
"Attribute to return",
grecs_type_string, GRECS_DFLT,
- NULL, offsetof(struct ldap_map, attr) },
+ NULL, offsetof(struct ldap_map, attr[0]) },
+ { "reverse-attr", "arg",
+ "Attribute to return from reverse lookup",
+ grecs_type_string, GRECS_DFLT,
+ NULL, offsetof(struct ldap_map, attr[1]) },
{ "debug", "n",
"Set LDAP debug level",
grecs_type_int, GRECS_DFLT,
@@ -137,14 +145,18 @@ ldap_map_config(int dbg, struct grecs_node *node, void *data)
grecs_error(&node->locus, 0, "LDAP URI not supplied");
rc = 1;
}
- if (!ldap_map->filter) {
+ if (!ldap_map->filter[0] && !ldap_map->filter[1]) {
grecs_error(&node->locus, 0, "LDAP filter not supplied");
rc = 1;
}
- if (!ldap_map->attr) {
+ if (ldap_map->filter[0] && !ldap_map->attr[0]) {
grecs_error(&node->locus, 0, "LDAP attr not supplied");
rc = 1;
}
+ if (ldap_map->filter[1] && !ldap_map->attr[1]) {
+ grecs_error(&node->locus, 0, "LDAP reverse-attr not supplied");
+ rc = 1;
+ }
if (rc) {
ldap_map_free(dbg, ldap_map);
@@ -179,8 +191,10 @@ ldap_map_free(int dbg, void *data)
free(map->base);
free(map->binddn);
free(map->bindpw);
- free(map->filter);
- free(map->attr);
+ free(map->filter[0]);
+ free(map->filter[1]);
+ free(map->attr[0]);
+ free(map->attr[1]);
free(data);
}
@@ -558,7 +572,8 @@ get_ldap_attrs(LDAP *ld, LDAPMessage *msg, const char *attr)
}
static int
-ldap_map_get(int dbg, void *data, const char *key, char **return_value)
+ldap_map_get(int dbg, int dir, void *data, const char *key,
+ char **return_value)
{
struct ldap_map *map = data;
int rc, i;
@@ -568,13 +583,16 @@ ldap_map_get(int dbg, void *data, const char *key, char **return_value)
char **ret;
const char *kwe[3];
char *filter;
-
+
+ if (!map->filter[dir])
+ return eclat_map_bad_dir;
+
kwe[0] = "key";
kwe[1] = key;
kwe[2] = NULL;
- filter = eclat_expand_kw(map->filter, kwe);
+ filter = eclat_expand_kw(map->filter[dir], kwe);
- attrs[0] = (char*) map->attr;
+ attrs[0] = (char*) map->attr[dir];
attrs[1] = NULL;
rc = ldap_search_ext(map->ld, map->base, LDAP_SCOPE_SUBTREE,
filter, attrs, 0,
@@ -595,10 +613,10 @@ ldap_map_get(int dbg, void *data, const char *key, char **return_value)
msg = ldap_first_entry(map->ld, res);
if (!msg) {
ldap_msgfree(res);
- return eclat_map_failure;
+ return eclat_map_not_found;
}
- ret = get_ldap_attrs(map->ld, msg, map->attr);
+ ret = get_ldap_attrs(map->ld, msg, map->attr[dir]);
ldap_msgfree(res);
diff --git a/lib/libeclat.h b/lib/libeclat.h
index a558dae..a0ae6d7 100644
--- a/lib/libeclat.h
+++ b/lib/libeclat.h
@@ -129,7 +129,7 @@ struct eclat_map_drv {
int (*map_config)(int, struct grecs_node *, void *);
int (*map_open)(int, void *);
int (*map_close)(int, void *);
- int (*map_get)(int, void *, const char *, char **);
+ int (*map_get)(int, int, void *, const char *, char **);
void (*map_free)(int, void *);
void (*map_confhelp)(void);
};
@@ -145,22 +145,29 @@ struct eclat_map {
enum eclat_map_status {
eclat_map_ok,
eclat_map_failure,
+ eclat_map_bad_dir,
eclat_map_not_found
};
+#define MAP_DIR 0
+#define MAP_REV 1
+
void eclat_map_init(void);
struct eclat_map *eclat_map_lookup(const char *name);
int eclat_map_config(struct grecs_node *node, struct eclat_map **return_map);
void eclat_map_free(struct eclat_map *map);
int eclat_map_open(struct eclat_map *map);
int eclat_map_close(struct eclat_map *map);
-int eclat_map_get(struct eclat_map *map, const char *key, char **value);
+int eclat_map_get(struct eclat_map *map, int dir, const char *key,
+ char **value);
const char *eclat_map_strerror(int rc);
int eclat_map_drv_register(struct eclat_map_drv *drv);
void eclat_map_foreach(int (*fun)(struct eclat_map *, void *), void *data);
void eclat_map_free_all(void);
void eclat_map_confhelp(void);
+int eclat_map_name_split(const char *mapname, char **name, char **endp);
+
int eclat_get_string_node(struct grecs_node *node, const char *name,
int optional,
struct grecs_node **pret);
@@ -170,3 +177,4 @@ 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;
+extern struct eclat_map_drv eclat_map_drv_bidi;
diff --git a/lib/map.c b/lib/map.c
index 461ead0..42b26cb 100644
--- a/lib/map.c
+++ b/lib/map.c
@@ -18,6 +18,7 @@
#include "wordsplit.h"
#include <sysexits.h>
#include <string.h>
+#include <assert.h>
static int map_dbg = -1;
static struct grecs_symtab *openmap_symtab, *mapdrv_symtab;
@@ -238,25 +239,28 @@ eclat_map_close(struct eclat_map *map)
}
int
-eclat_map_get(struct eclat_map *map, const char *key, char **value)
+eclat_map_get(struct eclat_map *map, int dir, const char *key, char **value)
{
int rc;
char *p = NULL;
debug(map_dbg, 1,
- ("looking up \"%s\" in map \"%s\"", key, map->name));
+ ("looking up \"%s\" in map \"%s\", dir=%d", key, map->name,
+ dir));
if (!(map->flags & ECLAT_MAP_OPEN)) {
debug(map_dbg, 1, ("map \"%s\" not open", map->name));
return eclat_map_failure;
}
if (map->keytrans) {
- const char *kwe[5];
+ const char *kwe[7];
kwe[0] = "key";
kwe[1] = key;
kwe[2] = "map";
kwe[3] = map->name;
- kwe[4] = NULL;
+ kwe[4] = "dir";
+ kwe[5] = dir ? "1" : "0";
+ kwe[6] = NULL;
p = eclat_expand_kw(map->keytrans, kwe);
debug(map_dbg, 1,
@@ -265,7 +269,7 @@ eclat_map_get(struct eclat_map *map, const char *key, char **value)
key = p;
}
- rc = map->drv->map_get(map_dbg, map->data, key, value);
+ rc = map->drv->map_get(map_dbg, dir, map->data, key, value);
free(p);
@@ -285,6 +289,8 @@ eclat_map_strerror(int rc)
return "failure";
case eclat_map_not_found:
return "not found";
+ case eclat_map_bad_dir:
+ return "wrond lookup direction";
}
return "unknown error";
}
@@ -340,3 +346,31 @@ eclat_map_confhelp()
{
grecs_symtab_enumerate(mapdrv_symtab, drv_help, NULL);
}
+
+int
+eclat_map_name_split(const char *mapname, char **name, char **endp)
+{
+ size_t len = strcspn(mapname, ":");
+ int dir;
+
+ if (endp)
+ *endp = (char*) mapname + len;
+ if (!mapname[len]) {
+ *name = grecs_strdup(mapname);
+ dir = MAP_DIR;
+ } else {
+ const char *q = mapname + len + 1;
+
+ if (strcmp(q, "0") == 0 || strcmp(q, "dir") == 0)
+ dir = MAP_DIR;
+ else if (strcmp(q, "1") == 0 || strcmp(q, "rev") == 0)
+ dir = MAP_REV;
+ else
+ return -1;
+
+ *name = grecs_malloc(len + 1);
+ memcpy(*name, mapname, len);
+ (*name)[len] = 0;
+ }
+ return dir;
+}
diff --git a/lib/nullmap.c b/lib/nullmap.c
index 7d29191..ff446d9 100644
--- a/lib/nullmap.c
+++ b/lib/nullmap.c
@@ -63,7 +63,7 @@ nullmap_close(int dbg, void *data)
}
static int
-nullmap_get(int dbg, void *data, const char *key, char **return_value)
+nullmap_get(int dbg, int dir, void *data, const char *key, char **return_value)
{
*return_value = grecs_strdup(key);
return eclat_map_ok;
diff --git a/lib/seqmap.c b/lib/seqmap.c
index 777bbd7..fe0aeba 100644
--- a/lib/seqmap.c
+++ b/lib/seqmap.c
@@ -126,7 +126,7 @@ seqmap_close(int dbg, void *data)
}
static int
-seqmap_get(int dbg, void *data, const char *key, char **return_value)
+seqmap_get(int dbg, int dir, void *data, const char *key, char **return_value)
{
struct seqmap *seqmap = data;
size_t i;
@@ -134,7 +134,7 @@ seqmap_get(int dbg, void *data, const char *key, char **return_value)
char *v;
for (i = 0; i < seqmap->nmaps; i++) {
- int rc = eclat_map_get(seqmap->maps[i], p, &v);
+ int rc = eclat_map_get(seqmap->maps[i], dir, p, &v);
free(p);
if (rc != eclat_map_ok) {
debug(dbg, 1, ("map %s returned %s",
diff --git a/src/eclat.c b/src/eclat.c
index 75e7c7d..0bc79ae 100644
--- a/src/eclat.c
+++ b/src/eclat.c
@@ -642,6 +642,7 @@ main(int argc, char **argv)
eclat_map_drv_register(&eclat_map_drv_null);
eclat_map_drv_register(&eclat_map_drv_file);
eclat_map_drv_register(&eclat_map_drv_seq);
+ eclat_map_drv_register(&eclat_map_drv_bidi);
#ifdef WITH_GDBM
eclat_map_drv_register(&eclat_map_drv_gdbm);
#endif
@@ -696,7 +697,7 @@ main(int argc, char **argv)
if (test_map_name) {
int i;
-
+
if (argc < 1)
die(EX_USAGE, "wrong number of arguments");
translate_ids(argc, argv, test_map_name);
diff --git a/src/util.c b/src/util.c
index e682c31..9e90ca5 100644
--- a/src/util.c
+++ b/src/util.c
@@ -27,21 +27,29 @@ translate_ids(int argc, char **argv, const char *mapname)
int i;
struct eclat_map *map;
char *val;
+ char *p, *q, *realname;
+ int dir;
if (!translate_option || argc == 0)
return;
if (custom_map)
mapname = custom_map;
- map = eclat_map_lookup(mapname);
- if (!map)
- die(EX_UNAVAILABLE, "no such map: %s", mapname);
+ dir = eclat_map_name_split(mapname, &realname, &q);
+ if (dir == -1)
+ die(EX_USAGE, "bad qualifier: %s", q);
+
+ map = eclat_map_lookup(realname);
+ if (!map)
+ die(EX_UNAVAILABLE, "no such map: %s", realname);
+ free(realname);
+
if (eclat_map_open(map) != eclat_map_ok)
exit(EX_UNAVAILABLE);
for (i = 0; i < argc; i++) {
if (!strchr(argv[i], '=')) {
- int rc = eclat_map_get(map, argv[i], &val);
+ int rc = eclat_map_get(map, dir, argv[i], &val);
if (rc != eclat_map_ok) {
die(EX_UNAVAILABLE, "cannot translate %s: %s",
argv[i], eclat_map_strerror(rc));
@@ -94,7 +102,7 @@ translate_resource_ids(int argc, char **argv)
ws.ws_wordv[j]);
if (eclat_map_open(map) != eclat_map_ok)
exit(EX_UNAVAILABLE);
- rc = eclat_map_get(map, p, &val);
+ rc = eclat_map_get(map, MAP_DIR, p, &val);
if (rc != eclat_map_ok) {
die(EX_UNAVAILABLE,
"cannot translate %s using map %s: %s",
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8d12342..0a302a6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -42,6 +42,7 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
TESTSUITE_AT = \
allocate-address.at\
associate-address.at\
+ bidimap.at\
create-snapshot.at\
decode.at\
delete-snapshot.at\
diff --git a/tests/bidimap.at b/tests/bidimap.at
new file mode 100644
index 0000000..ed3b6b9
--- a/dev/null
+++ b/tests/bidimap.at
@@ -0,0 +1,58 @@
+# This file is part of Eclat -*- Autotest -*-
+# 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/>.
+
+AT_SETUP([bidi])
+AT_KEYWORDS([map bidimap])
+
+AT_DATA([test.conf],
+[map dir {
+ type file;
+ file "dir.txt";
+}
+
+map rev {
+ type file;
+ file "rev.txt";
+};
+
+map inst {
+ type bidi;
+ direct-map dir;
+ reverse-map rev;
+}
+])
+
+AT_DATA([dir.txt],
+[db:i-feed1234
+web:i-deadbeef
+])
+
+AT_DATA([rev.txt],
+[i-deadbeef:web
+i-feed1234:db
+])
+
+AT_CHECK([eclat --config-file test.conf --test-map inst:0 db],
+[0],
+[i-feed1234
+])
+
+AT_CHECK([eclat --config-file test.conf --test-map inst:1 i-feed1234],
+[0],
+[db
+])
+
+AT_CLEANUP
diff --git a/tests/filemap.at b/tests/filemap.at
index b84da7c..52c5e83 100644
--- a/tests/filemap.at
+++ b/tests/filemap.at
@@ -35,4 +35,19 @@ AT_CHECK([eclat --config-file test.conf --test-map file dbserv],
[i-deadbeef
])
+AT_CHECK([eclat --config-file test.conf --test-map file:rev i-feed1234],
+[0],
+[web
+])
+
+AT_CHECK([eclat --config-file test.conf --test-map file:rev i-12345678],
+[0],
+[dbserver
+])
+
+AT_CHECK([eclat --config-file test.conf --test-map file:rev i-deadbeef],
+[0],
+[dbserv
+])
+
AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 65e1d99..35640e8 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -83,5 +83,6 @@ m4_include([nullmap.at])
m4_include([filemap.at])
m4_include([gdbmmap.at])
m4_include([seqmap.at])
+m4_include([bidimap.at])
# End of testsuite.at

Return to:

Send suggestions and report system problems to the System administrator.