Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH zsh/param/private and related stuff
- X-seq: zsh-workers 37208
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: PATCH zsh/param/private and related stuff
- Date: Mon, 23 Nov 2015 21:37:56 -0800
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brasslantern-com.20150623.gappssmtp.com; s=20150623; h=from:message-id:date:to:subject:mime-version:content-type; bh=JuAOXumK8cM7aaQiSeVyL6V12wzk2WolcWB7YUtmJSY=; b=wHSXmCEMwotZ27oLJrt2j3c+JbYXah+52fl/ZakyYPtcirgh9XBT9zvGYTQph1rjhF spNETW1JW8dBQzo3Q+B3coCviggBJEOXIJQwrbQ54ceiEAXIkOne2Cz5ya2OruTNfa6d NuGwvQB5umNyZmZvvPIREMLeJh7/YpR48fBgcmVxoi7lzq5ggFJDCncquljGMD9V1x2l UC44RG3lmgp8vmXUddiiPJh4ewr7wknv77L6pWt8CJE3lohVSbpjpNS+viKkU1r1V5e6 a9fy2UKARj+kbMmN4xNW0RZ+zP6/TMETC2CgiVzqZAvLPv6l+g7pWKOWRLl1Ml2kbFlD guFw==
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
I'm not sure whether one of the recent changes for warn_create_global
caused the problems noted in 37196 - 37198 or whether they were there
before and the [lack of] warnings just made it more obvious. However,
there's an error routine in param_private.c that was supposed to be
called if a private was assigned at a nested scope, and that routine
never gets called now. (At some point I may try git-bisect if I can
come up with a sufficient test case.)
In any event as you can see from the source comments I added, I finally
figured out that "exp" is Wischnowskese for "explicit" as the second
argument of the unset callbacks, so I was able to partially fix things
by referencing that. Some work still needed RE the lack of call to the
aforementioned error routine.
There's some commented-out code in here that will probably turn into
warning messages in a subsequent patch. I think we could safely put
this out as 5.2 with a mention in the BUGS file of the 37196 problem.
diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c
index 7f9aa79..7d1ba9c 100644
--- a/Src/Modules/param_private.c
+++ b/Src/Modules/param_private.c
@@ -218,8 +218,10 @@ setfn_error(Param pm)
* The unsetfn family compare locallevel and restore the old GSU before
* calling the original unsetfn. This assures that if the old unsetfn
* wants to use its getfn or setfn, they're unconditionally present.
+ * The "explicit" flag indicates that "unset" was called, if zero the
+ * parameter is going out of scope (see params.c).
*
- */
+ */
/**/
static char *
@@ -248,13 +250,15 @@ pps_setfn(Param pm, char *x)
/**/
static void
-pps_unsetfn(Param pm, int x)
+pps_unsetfn(Param pm, int explicit)
{
struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.s);
GsuScalar gsu = (GsuScalar)(c->g);
pm->gsu.s = gsu;
if (locallevel <= pm->level)
- gsu->unsetfn(pm, x);
+ gsu->unsetfn(pm, explicit);
+ if (explicit)
+ pm->gsu.s = (GsuScalar)c;
}
/**/
@@ -283,13 +287,15 @@ ppi_setfn(Param pm, zlong x)
/**/
static void
-ppi_unsetfn(Param pm, int x)
+ppi_unsetfn(Param pm, int explicit)
{
struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.i);
GsuInteger gsu = (GsuInteger)(c->g);
pm->gsu.i = gsu;
if (locallevel <= pm->level)
- gsu->unsetfn(pm, x);
+ gsu->unsetfn(pm, explicit);
+ if (explicit)
+ pm->gsu.i = (GsuInteger)c;
}
/**/
@@ -318,13 +324,15 @@ ppf_setfn(Param pm, double x)
/**/
static void
-ppf_unsetfn(Param pm, int x)
+ppf_unsetfn(Param pm, int explicit)
{
struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.f);
GsuFloat gsu = (GsuFloat)(c->g);
pm->gsu.f = gsu;
if (locallevel <= pm->level)
- gsu->unsetfn(pm, x);
+ gsu->unsetfn(pm, explicit);
+ if (explicit)
+ pm->gsu.f = (GsuFloat)c;
}
/**/
@@ -354,13 +362,15 @@ ppa_setfn(Param pm, char **x)
/**/
static void
-ppa_unsetfn(Param pm, int x)
+ppa_unsetfn(Param pm, int explicit)
{
struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.a);
GsuArray gsu = (GsuArray)(c->g);
pm->gsu.a = gsu;
if (locallevel <= pm->level)
- gsu->unsetfn(pm, x);
+ gsu->unsetfn(pm, explicit);
+ if (explicit)
+ pm->gsu.a = (GsuArray)c;
}
static HashTable emptytable;
@@ -391,13 +401,15 @@ pph_setfn(Param pm, HashTable x)
/**/
static void
-pph_unsetfn(Param pm, int x)
+pph_unsetfn(Param pm, int explicit)
{
struct gsu_closure *c = (struct gsu_closure *)(pm->gsu.h);
GsuHash gsu = (GsuHash)(c->g);
pm->gsu.h = gsu;
if (locallevel <= pm->level)
- gsu->unsetfn(pm, x);
+ gsu->unsetfn(pm, explicit);
+ if (explicit)
+ pm->gsu.h = (GsuHash)c;
}
/*
@@ -425,9 +437,13 @@ scopeprivate(HashNode hn, int onoff)
pm->node.flags |= PM_NORESTORE;
else
pm->node.flags |= PM_UNSET;
- else if (!(pm->node.flags & PM_NORESTORE))
- pm->node.flags &= ~PM_UNSET;
- pm->node.flags &= ~PM_NORESTORE;
+ else {
+ if (pm->node.flags & PM_NORESTORE)
+ pm->node.flags |= PM_UNSET; /* createparam() may frob */
+ else
+ pm->node.flags &= ~PM_UNSET;
+ pm->node.flags &= ~PM_NORESTORE;
+ }
}
}
diff --git a/Src/params.c b/Src/params.c
index 602f69f..4600284 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -880,6 +880,10 @@ createparam(char *name, int flags)
zerr("read-only variable: %s", name);
return NULL;
}
+ if ((oldpm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
+ zerr("%s: restricted", name);
+ return NULL;
+ }
if (!(oldpm->node.flags & PM_UNSET) || (oldpm->node.flags & PM_SPECIAL)) {
oldpm->node.flags &= ~PM_UNSET;
if ((oldpm->node.flags & PM_SPECIAL) && oldpm->ename) {
@@ -890,10 +894,6 @@ createparam(char *name, int flags)
}
return NULL;
}
- if ((oldpm->node.flags & PM_RESTRICTED) && isset(RESTRICTED)) {
- zerr("%s: restricted", name);
- return NULL;
- }
pm = oldpm;
pm->base = pm->width = 0;
@@ -2777,6 +2777,7 @@ assignsparam(char *s, char *val, int flags)
if (!v && !(v = getvalue(&vbuf, &t, 1))) {
unqueue_signals();
zsfree(val);
+ /* errflag |= ERRFLAG_ERROR; */
return NULL;
}
if (flags & ASSPM_WARN_CREATE)
@@ -2926,6 +2927,7 @@ assignaparam(char *s, char **val, int flags)
if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING))) {
unqueue_signals();
freearray(val);
+ /* errflag |= ERRFLAG_ERROR; */
return NULL;
}
@@ -2988,6 +2990,7 @@ sethparam(char *s, char **val)
return NULL;
queue_signals();
if (!(v = fetchvalue(&vbuf, &s, 1, SCANPM_ASSIGNING))) {
+ DPUTS(!v, "BUG: assigning to undeclared associative array");
createparam(t, PM_HASHED);
checkcreate = isset(WARNCREATEGLOBAL) && locallevel > 0;
} else if (!(PM_TYPE(v->pm->node.flags) & PM_HASHED) &&
@@ -3000,6 +3003,7 @@ sethparam(char *s, char **val)
if (!v)
if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING))) {
unqueue_signals();
+ /* errflag |= ERRFLAG_ERROR; */
return NULL;
}
if (checkcreate)
@@ -3061,8 +3065,11 @@ setnparam(char *s, mnumber val)
} else if (val.type & MN_INTEGER) {
pm->base = outputradix;
}
- v = getvalue(&vbuf, &t, 1);
- DPUTS(!v, "BUG: value not found for new parameter");
+ if (!(v = getvalue(&vbuf, &t, 1))) {
+ DPUTS(!v, "BUG: value not found for new parameter");
+ /* errflag |= ERRFLAG_ERROR; */
+ return NULL;
+ }
if (!was_unset && isset(WARNCREATEGLOBAL) && locallevel > 0)
check_warn_create(v->pm, "numeric");
}
@@ -3219,6 +3226,10 @@ unsetparam_pm(Param pm, int altflag, int exp)
*
* This could usefully be made type-specific, but then we need
* to be more careful when calling the unset method directly.
+ *
+ * The "exp"licit parameter should be nonzero for assignments and the
+ * unset command, and zero for implicit unset (e.g., end of scope).
+ * Currently this is used only by some modules.
*/
/**/
@@ -5105,8 +5116,11 @@ freeparamnode(HashNode hn)
{
Param pm = (Param) hn;
- /* Since the second flag to unsetfn isn't used, I don't *
- * know what its value should be. */
+ /* The second argument of unsetfn() is used by modules to
+ * differentiate "exp"licit unset from implicit unset, as when
+ * a parameter is going out of scope. It's not clear which
+ * of these applies here, but passing 1 has always worked.
+ */
if (delunset)
pm->gsu.s->unsetfn(pm, 1);
zsfree(pm->node.nam);
diff --git a/Test/V10private.ztst b/Test/V10private.ztst
index c66f175..f877455 100644
--- a/Test/V10private.ztst
+++ b/Test/V10private.ztst
@@ -11,6 +11,11 @@
(zmodload -u zsh/param/private && zmodload zsh/param/private)
0:unload and reload the module without crashing
+ $ZTST_exe +Z -f $ZTST_srcdir/ztst.zsh $ZTST_srcdir/B02typeset.ztst
+0:typeset still works with zsh/param/private module loaded
+*>*
+*>*
+
typeset scalar_test=toplevel
() {
print $scalar_test
@@ -237,7 +242,7 @@ F:note "typeset" rather than "private" in output from outer
}
print Y ${(kv)hash_test} Z $array_test
}
- print ${(kv)hash_test}
+ print ${(kv)hash_test} ${(t)array_test}
0:privates are not visible in anonymous functions, part 3
>X top level
>Y in function Z in function
--
Barton E. Schaefer
Messages sorted by:
Reverse Date,
Date,
Thread,
Author