Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Anyone want to help make zsh/db/gdbm work?
On 23 January 2015 at 05:19, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
wrote:
> However, there's still this:
>
> schaefer<518> typeset GDBMDB
> schaefer<519> (){ local GDBMDB; unset GDBMDB; ztie -d db/gdbm -f gdbmdb
GDBMDB }
> ../../zsh-5.0/Src/params.c:4914: BUG: in restoring scope of special
parameter
> zsh: segmentation fault (core dumped) Src/zsh
I think this is better, but you may still be able to find ways it
fails. It's possibly a bit more paranoid than it needs to be;
the PM_REMOVABLE flag is probably the key.
However, in any case I think the way ztie and zuntie work play
fast and loose with parameters. Try
typeset GDBMB-foo
(){
local GDBMDB
unset GDBMDB
ztie -d db/gdbm -f gdbmdb GDBMDB
zuntie GDBMDB
}
print $GDBMB
Note there's now a zuntie there. This still doesn't appear to work.
It now does without the zuntie, though, at least for the most obvious
limited value of "work".
diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c
index f079094..d75af98 100644
--- a/Src/Modules/db_gdbm.c
+++ b/Src/Modules/db_gdbm.c
@@ -43,6 +43,9 @@ static char *backtype = "db/gdbm";
static const struct gsu_scalar gdbm_gsu =
{ gdbmgetfn, gdbmsetfn, gdbmunsetfn };
+/**/
+static const struct gsu_hash gdbm_hash_gsu =
+{ hashgetfn, hashsetfn, gdbmhashunsetfn };
static struct builtin bintab[] = {
BUILTIN("ztie", 0, bin_ztie, 1, -1, 0, "d:f:", NULL),
@@ -84,12 +87,14 @@ bin_ztie(char *nam, char **args, Options ops,
UNUSED(int func))
return 1;
}
- if (!(tied_param = createspecialhash(pmname, &getgdbmnode,
&scangdbmkeys, 0))) {
+ if (!(tied_param = createspecialhash(pmname, &getgdbmnode,
&scangdbmkeys,
+ PM_REMOVABLE))) {
zwarnnam(nam, "cannot create the requested parameter %s", pmname);
gdbm_close(dbf);
return 1;
}
+ tied_param->gsu.h = &gdbm_hash_gsu;
tied_param->u.hash->tmpdata = (void *)dbf;
return 0;
@@ -225,6 +230,25 @@ scangdbmkeys(HashTable ht, ScanFunc func, int flags)
}
+/**/
+static void
+gdbmhashunsetfn(Param pm, UNUSED(int exp))
+{
+ GDBM_FILE dbf = (GDBM_FILE)(pm->u.hash->tmpdata);
+
+ if (!dbf) /* paranoia */
+ return;
+
+ gdbm_close(dbf);
+ pm->u.hash->tmpdata = NULL;
+
+ /* hash table is now normal, so proceed normally... */
+ pm->node.flags &= ~PM_SPECIAL;
+ pm->gsu.h = &stdhash_gsu;
+ pm->gsu.h->setfn(pm, NULL);
+ pm->node.flags |= PM_UNSET;
+}
+
#else
# error no gdbm
#endif /* have gdbm */
Messages sorted by:
Reverse Date,
Date,
Thread,
Author