summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Modules/param_private.c44
-rw-r--r--Src/Zle/zle_main.c3
-rw-r--r--Src/builtin.c1
-rw-r--r--Src/params.c36
-rw-r--r--Src/subst.c2
-rw-r--r--Src/utils.c15
6 files changed, 71 insertions, 30 deletions
diff --git a/Src/Modules/param_private.c b/Src/Modules/param_private.c
index 7f9aa7921..7d1ba9c87 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/Zle/zle_main.c b/Src/Zle/zle_main.c
index 593d636cc..38427e8e3 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -2045,7 +2045,8 @@ setup_(UNUSED(Module m))
bpaste = zshcalloc(3*sizeof(char *));
bpaste[0] = ztrdup("\033[?2004h");
bpaste[1] = ztrdup("\033[?2004l");
- setaparam("zle_bracketed_paste", bpaste);
+ /* Intended to be global, no WARNCREATEGLOBAL check. */
+ assignaparam("zle_bracketed_paste", bpaste, 0);
return 0;
}
diff --git a/Src/builtin.c b/Src/builtin.c
index 01eb5b84c..cac4f42f9 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -3712,6 +3712,7 @@ bin_hash(char *name, char **argv, Options ops, UNUSED(int func))
zwarnnam(name, "bad pattern : %s", *argv);
returnval = 1;
}
+ argv++;
continue;
}
if (!(asg = getasg(&argv, NULL))) {
diff --git a/Src/params.c b/Src/params.c
index b121bd6ad..4600284f0 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;
}
@@ -2970,6 +2972,7 @@ sethparam(char *s, char **val)
struct value vbuf;
Value v;
char *t = s;
+ int checkcreate = 0;
if (!isident(s)) {
zerr("not an identifier: %s", s);
@@ -2987,9 +2990,9 @@ 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);
- if (isset(WARNCREATEGLOBAL) && locallevel > 0)
- check_warn_create(v->pm, "associative array");
+ checkcreate = isset(WARNCREATEGLOBAL) && locallevel > 0;
} else if (!(PM_TYPE(v->pm->node.flags) & PM_HASHED) &&
!(v->pm->node.flags & PM_SPECIAL)) {
unsetparam(t);
@@ -3000,8 +3003,11 @@ sethparam(char *s, char **val)
if (!v)
if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING))) {
unqueue_signals();
+ /* errflag |= ERRFLAG_ERROR; */
return NULL;
}
+ if (checkcreate)
+ check_warn_create(v->pm, "associative array");
setarrvalue(v, val);
unqueue_signals();
return v->pm;
@@ -3059,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");
}
@@ -3217,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.
*/
/**/
@@ -5103,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/Src/subst.c b/Src/subst.c
index b7f8338c7..d9c9d24aa 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -2454,7 +2454,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
val = dyncat(val, "-unique");
if (f & PM_HIDE)
val = dyncat(val, "-hide");
- if (f & PM_HIDE)
+ if (f & PM_HIDEVAL)
val = dyncat(val, "-hideval");
if (f & PM_SPECIAL)
val = dyncat(val, "-special");
diff --git a/Src/utils.c b/Src/utils.c
index 0afa8c908..464097034 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -3143,6 +3143,7 @@ strftimehandling:
* in the accounting in bufsize (but nowhere else).
*/
{
+ char origchar = fmt[-1];
int size = fmt - fmtstart;
char *tmp, *last;
tmp = zhalloc(size + 1);
@@ -3163,11 +3164,17 @@ strftimehandling:
*buf = '\1';
if (!strftime(buf, bufsize + 2, tmp, tm))
{
- if (*buf) {
- buf[0] = '\0';
- return -1;
+ /*
+ * Some locales don't have strings for
+ * AM/PM, so empty output is valid.
+ */
+ if (*buf || (origchar != 'p' && origchar != 'P')) {
+ if (*buf) {
+ buf[0] = '\0';
+ return -1;
+ }
+ return 0;
}
- return 0;
}
decr = strlen(buf);
buf += decr;