[PATCH] Adapt gdbm code to named references
Philippe Altherr <[email protected]>
| Newsgroups | gmane.comp.shells.zsh.devel |
|---|---|
| Message-ID | <CAGdYchtWFD+j+NkaUSoBKsoo8N3Oyatk1P_NceRGakLpSAGb+Q@mail.gmail.com> |
The patch below makes the gdbm code compatible with named references. If a
named reference is given to ztie, it will tie the DB to the referred
variable. This is similar to what typeset does (when invoked without -n).
An alternative would be to ignore named references and always tie the DB to
the given variable. I chose the current approach because of its similarity
with what typeset does but I don't have a strong preference.
The patch slightly changes the scope of DBs tied to local parameters. The
scope of such DBs used to be the scope in which ztie was invoked. The way
this was implemented is not compatible with named references (when they
refer to a hidden variable). With the patch, the scope of the DB becomes
the scope of the local parameter, which arguably is also what the current
documentation suggests
<https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#The-zsh_002fdb_002fgdbm-Module:~:text=This%20happens%20automatically%20if%20the%20parameter%20is%20explicitly%20unset%20or%20its%20local%20scope%20(function)%20ends.>
.
() {
local dbase
() {
ztie -d db/gdbm -f sample.gdbm dbase
# …
# The DB used to be untied here, at the end of the scope in which ztie
was called.
}
# …
# The DB is now untied here, at the end of the scope in which its
variable was declared.
}
- Adapt gdbm code to named references
<https://github.com/paltherr/zsh/compare/adapt-gdbm-to-namerefs-start...paltherr:zsh:adapt-gdbm-to-namerefs>
The patch also contains a few code cleanups. See the GitHub commits for
more details.
Philippe
adapt-gdbm-to-namerefs.txt
(text/plain, 6.2 KB)
diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c
index 34f577e30..2625469e4 100644
--- a/Src/Modules/db_gdbm.c
+++ b/Src/Modules/db_gdbm.c
@@ -38,12 +38,6 @@
#define PM_UPTODATE PM_DONTIMPORT_SUID /* Safe PM_ bit to re-use */
#endif
-static Param createhash( char *name, int flags );
-static int append_tied_name( const char *name );
-static int remove_tied_name( const char *name );
-static char *unmetafy_zalloc(const char *to_copy, int *new_len);
-static void myfreeparamnode(HashNode hn);
-
static int no_database_action = 0;
/*
@@ -139,7 +133,7 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func))
resource_name = OPT_ARG(ops, 'f');
pmname = *args;
- if ((tied_param = (Param)paramtab->getnode(paramtab, pmname)) &&
+ if ((tied_param = (Param)realparamtab->getnode(realparamtab, pmname)) &&
!(tied_param->node.flags & PM_UNSET)) {
/*
* Unset any existing parameter. Note there's no implicit
@@ -165,7 +159,7 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func))
return 1;
}
- if (!(tied_param = createhash(pmname, pmflags))) {
+ if (!(tied_param = creategdbmhash(pmname, pmflags))) {
zwarnnam(nam, "cannot create the requested parameter %s", pmname);
gdbm_close(dbf);
return 1;
@@ -191,7 +185,7 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func))
dbf_carrier->dbfile_path = ztrdup(resource_name);
addmodulefd(gdbm_fdesc(dbf), FDT_INTERNAL);
- append_tied_name(pmname);
+ append_tied_name(tied_param->node.nam);
return 0;
}
@@ -205,7 +199,7 @@ bin_zuntie(char *nam, char **args, Options ops, UNUSED(int func))
int ret = 0;
for (pmname = *args; *args++; pmname = *args) {
- pm = (Param) paramtab->getnode(paramtab, pmname);
+ pm = (Param) realparamtab->getnode(realparamtab, pmname);
if(!pm) {
zwarnnam(nam, "cannot untie %s", pmname);
ret = 1;
@@ -245,7 +239,7 @@ bin_zgdbmpath(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
return 1;
}
- pm = (Param) paramtab->getnode(paramtab, pmname);
+ pm = (Param) realparamtab->getnode(realparamtab, pmname);
if(!pm) {
zwarnnam(nam, "no such parameter: %s", pmname);
return 1;
@@ -657,7 +651,8 @@ finish_(UNUSED(Module m))
* Utility functions *
*********************/
-static Param createhash( char *name, int flags ) {
+/**/
+static Param creategdbmhash( char *name, int flags ) {
Param pm;
HashTable ht;
@@ -666,20 +661,11 @@ static Param createhash( char *name, int flags ) {
return NULL;
}
- if (pm->old)
- pm->level = locallevel;
-
/* This creates standard hash. */
ht = pm->u.hash = newparamtable(17, name);
- if (!pm->u.hash) {
- paramtab->removenode(paramtab, name);
- paramtab->freenode(&pm->node);
- zwarnnam(name, "out of memory when allocating hash");
- return NULL;
- }
/* Does free Param (unsetfn is called) */
- ht->freenode = myfreeparamnode;
+ ht->freenode = freegdbmnode;
/* These provide special features */
ht->getnode = ht->getnode2 = getgdbmnode;
@@ -692,6 +678,7 @@ static Param createhash( char *name, int flags ) {
* Adds parameter name to `zgdbm_tied`
*/
+/**/
static int append_tied_name( const char *name ) {
int old_len = arrlen(zgdbm_tied);
char **new_zgdbm_tied = zshcalloc( (old_len+2) * sizeof(char *));
@@ -717,6 +704,7 @@ static int append_tied_name( const char *name ) {
* Removes parameter name from `zgdbm_tied`
*/
+/**/
static int remove_tied_name( const char *name ) {
int old_len = arrlen(zgdbm_tied);
int new_len;
@@ -772,6 +760,8 @@ static int remove_tied_name( const char *name ) {
* - does zalloc of exact size for the new string,
* - restores work buffer to original content, to restore strlen
*/
+
+/**/
static char *
unmetafy_zalloc(const char *to_copy, int *new_len) {
char *work, *to_return;
@@ -795,8 +785,9 @@ unmetafy_zalloc(const char *to_copy, int *new_len) {
return to_return;
}
+/**/
static void
-myfreeparamnode(HashNode hn)
+freegdbmnode(HashNode hn)
{
Param pm = (Param) hn;
diff --git a/Test/V11db_gdbm.ztst b/Test/V11db_gdbm.ztst
index 6d74cef2c..1ac9fc0c2 100644
--- a/Test/V11db_gdbm.ztst
+++ b/Test/V11db_gdbm.ztst
@@ -204,34 +204,67 @@
local -a dbase
dbase=( fromarray )
() {
- local -a dbase
+ local dbase
+ () {
ztie -d db/gdbm -f $dbfile dbase
- echo ${(t)dbase}
- zuntie dbase
+ echo "Connected:" $dbase[a]
+ }
+ echo "Still connected:" $dbase[a]
}
echo $dbase[1]
ztie -d db/gdbm -f $dbfile dbase2
echo "Can connect, so untie happened:" $dbase2[a]
zuntie dbase2
0:Test of automatic untie (use of local scope) and of scoping
->association-local-special
+>Connected: b
+>Still connected: b
>fromarray
>Can connect, so untie happened: b
+ local dbase
+ () {
+ local -n rbase=dbase
+ local dbase=not-a-dbase
+ ztie -d db/gdbm -f $dbfile rbase
+ echo $dbase
+ echo "Connected:" $rbase[a]
+ zuntie rbase
+ echo "Disconnected:" $rbase[a]
+ ztie -d db/gdbm -f $dbfile rbase
+ echo "Reconnected:" $rbase[a]
+ echo $dbase
+ }
+ echo "Still connected:" $dbase[a]
+ zuntie dbase
+0:Test of tie to hidden local via named reference
+>not-a-dbase
+>Connected: b
+>Disconnected:
+>Reconnected: b
+>not-a-dbase
+>Still connected: b
+
echo $zgdbm_tied ${#zgdbm_tied}
ztie -r -d db/gdbm -f $dbfile dbase
echo $zgdbm_tied ${#zgdbm_tied}
ztie -d db/gdbm -f ${dbfile}2 dbase2
echo $zgdbm_tied ${#zgdbm_tied}
+ local -n rbase3=dbase3
+ ztie -d db/gdbm -f ${dbfile}3 rbase3
+ echo $zgdbm_tied ${#zgdbm_tied}
zuntie -u dbase
echo $zgdbm_tied ${#zgdbm_tied}
zuntie dbase2
echo $zgdbm_tied ${#zgdbm_tied}
+ zuntie rbase3
+ echo $zgdbm_tied ${#zgdbm_tied}
0:zgdbm_tied parameter
>0
>dbase 1
>dbase dbase2 2
->dbase2 1
+>dbase dbase2 dbase3 3
+>dbase2 dbase3 2
+>dbase3 1
>0
unset zgdbm_tied 2>/dev/null
@@ -311,8 +344,14 @@
zgdbmpath dbase
[[ $REPLY = */Test/db.gdbm ]] && echo correct
zuntie -u dbase
+ local -n rbase=dbase
+ ztie -r -d db/gdbm -f $dbfile rbase
+ zgdbmpath rbase
+ [[ $REPLY = */Test/db.gdbm ]] && echo correct
+ zuntie -u rbase
0:zgdbmpath builtin
>correct
+>correct
>correct
ztie -d db/gdbm -f $dbfile dbase