aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-10-07 21:17:16 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2012-10-07 21:20:00 +0300
commit3f1639c2112f8242a542ca0a1b959f657d012cc9 (patch)
tree6951514621c1ac6cde192dbed7cdf736fb6bc39a
parent1fbcbdb432e945aa3f63be5b9170e94a0c9ef6c3 (diff)
downloadeclat-3f1639c2112f8242a542ca0a1b959f657d012cc9.tar.gz
eclat-3f1639c2112f8242a542ca0a1b959f657d012cc9.tar.bz2
Implement GDBM map backend.
* README: Document --with-gdbm * configure.ac: Detect libgdbm. New option --with-gdbm. * lib/gdbmmap.c * lib/Makefile.am (maps) [COND_GDBM]: Add new file. * lib/libeclat.h (eclat_map_drv_gdbm): New extern. * src/Makefile.am (LDADD): Add MAPLIBS. * src/eclat.c (mail) [WITH_GDBM]: Register eclat_map_drv_gdbm.
-rw-r--r--README11
-rw-r--r--configure.ac27
-rw-r--r--lib/Makefile.am5
-rw-r--r--lib/gdbmmap.c116
-rw-r--r--lib/libeclat.h1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/eclat.c3
7 files changed, 163 insertions, 2 deletions
diff --git a/README b/README
index 01696a8..c1cd00d 100644
--- a/README
+++ b/README
@@ -41,7 +41,7 @@ To compile, run the usual encantation:
For information about the configure script and its generic options, refer to
the file INSTALL included in the distribution.
-The following option is specific to this package:
+The following options are specific to this package:
--enable-split-format
@@ -50,6 +50,15 @@ The following option is specific to this package:
instructions for each command supported by eclat. Use this option if
you wish to use separate files instead.
+ --with-gdbm
+ --without-gdbm
+
+ Build (don't build) GDBM translation map. By default it is built
+ if GNU DBM library and header file are present on the system.
+ Specifying --without-gdbm instructs configure not to build GDBM
+ translation map. The --with-gdbm option forces configure to abort
+ if GDBM is not present.
+
** Shell completion
To facilitate the use of the tool, the package includes a Bash script
diff --git a/configure.ac b/configure.ac
index e878bca..fbb53ea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -59,6 +59,33 @@ AC_CHECK_HEADER([expat.h], [],
AC_CHECK_LIB([expat], [XML_Parse],[],
[AC_MSG_ERROR([required library libexpat is not found])])
+# MAPS
+AC_SUBST([MAPLIBS])
+
+AC_ARG_WITH([gdbm],
+ [AC_HELP_STRING([--with-gdbm],
+ [use GNU DBM])],
+ [case "${withval}" in
+ yes|no) status_gdbm=${withval};;
+ *) AC_MSG_ERROR(bad value ${withval} for --with-gdbm) ;;
+ esac],
+ [status_gdbm=auto])
+
+if test $status_gdbm != "no"; then
+ AC_CHECK_HEADERS(gdbm.h)
+ AC_CHECK_LIB(gdbm, gdbm_open, [dbmlib=-lgdbm], [dbmlib=])
+ if test "$ac_cv_header_getopt_h" = yes && test -n "$dbmlib"; then
+ MAPLIBS="$MAPLIBS $dbmlib"
+ status_gdbm=yes
+ AC_DEFINE(WITH_GDBM,1,[Use GDB GDBM])
+ elif test $status_gdbm = yes; then
+ AC_MSG_ERROR([required library libgdbm (or its header) is not found])
+ else
+ status_gdbm=no
+ fi
+fi
+AM_CONDITIONAL([COND_GDBM],[test $status_gdbm = yes])
+
# Grecs subsystem
GRECS_SETUP([grecs],[tests getopt git2chg])
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e7b9d20..829ef1b 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -16,7 +16,12 @@
noinst_LIBRARIES=libeclat.a
+if COND_GDBM
+ GDBMMAP=gdbmmap.c
+endif
+
maps = \
+ $(GDBMMAP)\
filemap.c
libeclat_a_SOURCES=\
diff --git a/lib/gdbmmap.c b/lib/gdbmmap.c
new file mode 100644
index 0000000..4fdaa33
--- /dev/null
+++ b/lib/gdbmmap.c
@@ -0,0 +1,116 @@
+/* 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 <gdbm.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+struct gdbm_map {
+ char *name;
+ GDBM_FILE file;
+ struct grecs_locus locus;
+ int nullflag;
+};
+
+static int
+gdbm_map_config(int dbg, struct grecs_node *node, void *data)
+{
+ struct gdbm_map *gdbm_map, **return_gdbm_map = data;
+ const char *filename;
+ struct grecs_node *p;
+
+ if (eclat_get_string_node(node, "file", 0, &p))
+ return eclat_map_failure;
+ gdbm_map = grecs_malloc(sizeof(*gdbm_map));
+ gdbm_map->name = grecs_strdup(p->v.value->v.string);
+ gdbm_map->locus = p->locus;
+ switch (eclat_get_string_node(node, "null", 1, &p)) {
+ case eclat_map_failure:
+ return eclat_map_failure;
+ case eclat_map_not_found:
+ break;
+ case eclat_map_ok:
+ if (grecs_string_convert(&gdbm_map->nullflag, grecs_type_bool,
+ p->v.value->v.string,
+ &p->locus))
+ return eclat_map_failure;
+ }
+
+ *return_gdbm_map = gdbm_map;
+ return eclat_map_ok;
+}
+
+static void
+gdbm_map_free(int dbg, void *data)
+{
+ struct gdbm_map *gdbm_map = data;
+ free(gdbm_map->name);
+ free(gdbm_map);
+}
+
+static int
+gdbm_map_open(int dbg, void *data)
+{
+ struct gdbm_map *gdbm_map = data;
+
+ gdbm_map->file = gdbm_open(gdbm_map->name, 512, GDBM_READER, O_RDONLY,
+ NULL);
+ if (gdbm_map->file == NULL)
+ return eclat_map_failure;
+ return eclat_map_ok;
+}
+
+static int
+gdbm_map_close(int dbg, void *data)
+{
+ struct gdbm_map *gdbm_map = data;
+ gdbm_close(gdbm_map->file);
+ return eclat_map_ok;
+}
+
+static int
+gdbm_map_get(int dbg, void *data, const char *key, char **return_value)
+{
+ struct gdbm_map *gdbm_map = data;
+ datum keydat, content;
+
+ keydat.dptr = (char*)key;
+ keydat.dsize = strlen(key) + (gdbm_map->nullflag ? 1 : 0);
+ gdbm_errno = 0;
+ content = gdbm_fetch(gdbm_map->file, keydat);
+ if (content.dptr == NULL) {
+ if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
+ return eclat_map_not_found;
+ err("%s: %s", gdbm_map->name, gdbm_strerror(gdbm_errno));
+ return eclat_map_failure;
+ }
+ *return_value = grecs_malloc(content.dsize + 1);
+ memcpy(*return_value, content.dptr, content.dsize);
+ (*return_value)[content.dsize] = 0;
+ free (content.dptr);
+ return eclat_map_ok;
+}
+
+struct eclat_map_drv eclat_map_drv_gdbm = {
+ "gdbm",
+ gdbm_map_config,
+ gdbm_map_open,
+ gdbm_map_close,
+ gdbm_map_get,
+ gdbm_map_free
+};
diff --git a/lib/libeclat.h b/lib/libeclat.h
index 1f16d5d..ddf4db9 100644
--- a/lib/libeclat.h
+++ b/lib/libeclat.h
@@ -144,5 +144,6 @@ int eclat_get_string_node(struct grecs_node *node, const char *name,
struct grecs_node **pret);
extern struct eclat_map_drv eclat_map_drv_file;
+extern struct eclat_map_drv eclat_map_drv_gdbm;
diff --git a/src/Makefile.am b/src/Makefile.am
index 1f533ef..7b9b7f0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,7 +38,7 @@ eclat_SOURCES=\
startinst.c\
util.c
-LDADD=../lib/libeclat.a @LIBOBJS@ ../grecs/src/libgrecs.a $(CURL_LIBS)
+LDADD=../lib/libeclat.a @LIBOBJS@ ../grecs/src/libgrecs.a $(CURL_LIBS) @MAPLIBS@
INCLUDES = -I$(top_srcdir)/grecs/src/ -I$(top_srcdir)/lib $(CURL_CFLAGS)
AM_CPPFLAGS= \
-DSYSCONFDIR=\"$(sysconfdir)\"\
diff --git a/src/eclat.c b/src/eclat.c
index 704ac56..f8bbaa5 100644
--- a/src/eclat.c
+++ b/src/eclat.c
@@ -594,6 +594,9 @@ main(int argc, char **argv)
forlan_init();
eclat_map_init();
eclat_map_drv_register(&eclat_map_drv_file);
+#ifdef WITH_GDBM
+ eclat_map_drv_register(&eclat_map_drv_gdbm);
+#endif
config_init();
parse_options(argc, argv, &index);

Return to:

Send suggestions and report system problems to the System administrator.