diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Modules/param_private.c | 44 | ||||
-rw-r--r-- | Src/Zle/zle_main.c | 3 | ||||
-rw-r--r-- | Src/builtin.c | 1 | ||||
-rw-r--r-- | Src/params.c | 36 | ||||
-rw-r--r-- | Src/subst.c | 2 | ||||
-rw-r--r-- | Src/utils.c | 15 |
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; |