diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Modules/db_gdbm.c | 240 | ||||
-rw-r--r-- | Src/Modules/db_gdbm.mdd | 12 |
2 files changed, 252 insertions, 0 deletions
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" |