summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Src/Modules/db_gdbm.c240
-rw-r--r--Src/Modules/db_gdbm.mdd12
3 files changed, 257 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 7a1f8b7ce..5000a601e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-07-21 Clint Adams <clint@zsh.org>
+
+ * 25319: Src/Modules/db_gdbm.c: fix zuntie, add -f option
+ to ztie.
+
2008-07-20 Clint Adams <clint@zsh.org>
* 25318: Src/Modules/db_gdbm.c, Src/Modules/db_gdbm.mdd,
diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c
new file mode 100644
index 000000000..f0915e0a8
--- /dev/null
+++ b/Src/Modules/db_gdbm.c
@@ -0,0 +1,240 @@
+/*
+ * db_gdbm.c - bindings for gdbm
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 2008 Clint Adams
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Clint Adams or the Zsh Development
+ * Group be liable to any party for direct, indirect, special, incidental, or
+ * consequential damages arising out of the use of this software and its
+ * documentation, even if Peter Stephenson, Sven Wischnowsky and the Zsh
+ * Development Group have been advised of the possibility of such damage.
+ *
+ * Clint Adams and the Zsh Development Group
+ * specifically disclaim any warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose.
+ * The software provided hereunder is on an "as is" basis, and Peter
+ * Stephenson, Sven Wischnowsky and the Zsh Development Group have no
+ * obligation to provide maintenance, support, updates, enhancements, or
+ * modifications.
+ *
+ */
+
+#include "db_gdbm.mdh"
+#include "db_gdbm.pro"
+
+/*
+ * Make sure we have all the bits I'm using for memory mapping, otherwise
+ * I don't know what I'm doing.
+ */
+#if defined(HAVE_GDBM_H) && defined(HAVE_GDBM_OPEN)
+
+#include <gdbm.h>
+
+static const struct gsu_hash gdbm_gsu =
+{ gdbmgetfn, gdbmsetfn, gdbmunsetfn };
+
+static struct builtin bintab[] = {
+ BUILTIN("ztie", 0, bin_ztie, 1, -1, 0, "d:f:", NULL),
+ BUILTIN("zuntie", 0, bin_zuntie, 1, -1, 0, NULL, NULL),
+};
+
+GDBM_FILE dbf = NULL;
+Param tied_param;
+
+/**/
+static int
+bin_ztie(char *nam, char **args, Options ops, UNUSED(int func))
+{
+ char *resource_name, *pmname;
+
+ if(!OPT_ISSET(ops,'d')) {
+ zwarnnam(nam, "you must pass `-d db/gdbm' to ztie", NULL);
+ return 1;
+ }
+ if(!OPT_ISSET(ops,'f')) {
+ zwarnnam(nam, "you must pass `-f' with a filename to ztie", NULL);
+ return 1;
+ }
+
+ /* Here should be a lookup of the backend type against
+ * a registry.
+ */
+
+ if(dbf) {
+ zwarnnam(nam, "something is already ztied and this implementation is flawed", NULL);
+ return 1;
+ }
+
+ pmname = ztrdup(*args);
+
+ resource_name = OPT_ARG(ops, 'f');
+
+ if (!(tied_param = createspecialhash(pmname, &getgdbmnode, &scangdbmkeys, PM_SPECIAL | PM_HASHED))) {
+ zwarnnam(nam, "cannot create the requested parameter name", NULL);
+ return 1;
+ }
+
+ dbf = gdbm_open(resource_name, 0, GDBM_WRCREAT | GDBM_SYNC, 0666, 0);
+ if(!dbf) {
+ zwarnnam(nam, "error opening database file %s", resource_name);
+ return 1;
+ }
+
+ return 0;
+}
+
+/**/
+static int
+bin_zuntie(char *nam, char **args, Options ops, UNUSED(int func))
+{
+ paramtab->removenode(paramtab, tied_param->node.nam);
+ free(tied_param);
+ tied_param = NULL;
+ gdbm_close(dbf);
+ dbf = NULL;
+
+ return 0;
+}
+
+
+/**/
+static char *
+gdbmgetfn(Param pm)
+{
+return;
+}
+
+/**/
+static void
+gdbmsetfn(Param pm, char **key)
+{
+return;
+}
+
+/**/
+static void
+gdbmunsetfn(Param pm, int um)
+{
+return;
+}
+
+/**/
+static HashNode
+getgdbmnode(UNUSED(HashTable ht), const char *name)
+{
+ int len, ret;
+ char *nameu;
+ datum content, key;
+ Param pm = NULL;
+
+ nameu = dupstring(name);
+ unmetafy(nameu, &len);
+ key.dptr = nameu;
+
+ pm = (Param) hcalloc(sizeof(struct param));
+ pm->node.nam = nameu;
+ pm->node.flags = PM_SCALAR;
+
+ ret = gdbm_exists(dbf, key);
+ if(!ret) {
+ pm->u.str = dupstring("");
+ pm->node.flags |= PM_UNSET;
+ } else {
+ content = gdbm_fetch(dbf, key);
+
+ pm->u.str = content.dptr;
+ pm->gsu.s = &nullsetscalar_gsu;
+ }
+ return &pm->node;
+}
+
+/**/
+static void
+scangdbmkeys(UNUSED(HashTable ht), ScanFunc func, int flags)
+{
+ Param pm = NULL;
+ datum key, content;
+
+ pm = (Param) hcalloc(sizeof(struct param));
+
+ pm->node.flags = PM_SCALAR;
+ pm->gsu.s = &nullsetscalar_gsu;
+
+ key = gdbm_firstkey(dbf);
+
+ while(key.dptr) {
+ content = gdbm_fetch(dbf, key);
+
+ pm->u.str = content.dptr;
+ pm->gsu.s = &nullsetscalar_gsu;
+
+ func(&pm->node, flags);
+
+ key = gdbm_nextkey(dbf, key);
+ }
+
+}
+
+#else
+# error no gdbm
+#endif /* have gdbm */
+
+static struct features module_features = {
+ bintab, sizeof(bintab)/sizeof(*bintab),
+ NULL, 0,
+ NULL, 0,
+ NULL, 0,
+ 0
+};
+
+/**/
+int
+setup_(UNUSED(Module m))
+{
+ return 0;
+}
+
+/**/
+int
+features_(Module m, char ***features)
+{
+ *features = featuresarray(m, &module_features);
+ return 0;
+}
+
+/**/
+int
+enables_(Module m, int **enables)
+{
+ return handlefeatures(m, &module_features, enables);
+}
+
+/**/
+int
+boot_(UNUSED(Module m))
+{
+ return 0;
+}
+
+/**/
+int
+cleanup_(UNUSED(Module m))
+{
+ return setfeatureenables(m, &module_features, NULL);
+}
+
+/**/
+int
+finish_(UNUSED(Module m))
+{
+ return 0;
+}
diff --git a/Src/Modules/db_gdbm.mdd b/Src/Modules/db_gdbm.mdd
new file mode 100644
index 000000000..ce7926bd9
--- /dev/null
+++ b/Src/Modules/db_gdbm.mdd
@@ -0,0 +1,12 @@
+name=zsh/db/gdbm
+link='if test "x$ac_cv_lib_gdbm_gdbm_open" = xyes && test "x$ac_cv_header_gdbm_h" = xyes; then
+ echo dynamic
+else
+ echo no
+fi
+'
+load=no
+
+autofeatures="b:ztie b:zuntie"
+
+objects="db_gdbm.o"