From 82ff9f24f170eea7daa935fdaa09ab75a2f277ff Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sun, 18 Apr 2021 13:58:09 -0700 Subject: 48560: add TYPESET_TO_UNSET option to remove initialization of parameters Changes typeset such that ${newparam-notset} yields "notset" and "typeset -p newparam" does not show an assignment to the parameter. This is similar to the default behavior of bash and ksh, with minor differences in typeset output. Also add tests for some POSIX incompatibilities plus minor changes for test harness robustness. --- Src/params.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'Src/params.c') diff --git a/Src/params.c b/Src/params.c index 122f5da7d..33bbc54f6 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2093,7 +2093,8 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) if (sav) *s = sav; *pptr = s; - if (!pm || (pm->node.flags & PM_UNSET)) + if (!pm || ((pm->node.flags & PM_UNSET) && + !(pm->node.flags & PM_DECLARED))) return NULL; if (v) memset(v, 0, sizeof(*v)); @@ -3055,6 +3056,7 @@ assignsparam(char *s, char *val, int flags) * Don't warn about anything. */ flags &= ~ASSPM_WARN; + v->pm->node.flags &= ~PM_DEFAULTED; } *ss = '['; v = NULL; @@ -3080,6 +3082,7 @@ assignsparam(char *s, char *val, int flags) } if (flags & ASSPM_WARN) check_warn_pm(v->pm, "scalar", created, 1); + v->pm->node.flags &= ~PM_DEFAULTED; if (flags & ASSPM_AUGMENT) { if (v->start == 0 && v->end == -1) { switch (PM_TYPE(v->pm->node.flags)) { @@ -3232,6 +3235,7 @@ assignaparam(char *s, char **val, int flags) if (flags & ASSPM_WARN) check_warn_pm(v->pm, "array", created, may_warn_about_nested_vars); + v->pm->node.flags &= ~PM_DEFAULTED; /* * At this point, we may have array entries consisting of @@ -3444,6 +3448,7 @@ sethparam(char *s, char **val) return NULL; } check_warn_pm(v->pm, "associative array", checkcreate, 1); + v->pm->node.flags &= ~PM_DEFAULTED; setarrvalue(v, val); unqueue_signals(); return v->pm; @@ -3515,6 +3520,7 @@ assignnparam(char *s, mnumber val, int flags) if (flags & ASSPM_WARN) check_warn_pm(v->pm, "numeric", 0, 1); } + v->pm->node.flags &= ~PM_DEFAULTED; setnumvalue(v, val); unqueue_signals(); return v->pm; @@ -3619,6 +3625,7 @@ unsetparam_pm(Param pm, int altflag, int exp) else altremove = NULL; + pm->node.flags &= ~PM_DECLARED; /* like ksh, not like bash */ if (!(pm->node.flags & PM_UNSET)) pm->gsu.s->unsetfn(pm, exp); if (pm->env) @@ -3652,6 +3659,8 @@ unsetparam_pm(Param pm, int altflag, int exp) } zsfree(altremove); + if (!(pm->node.flags & PM_SPECIAL)) + pm->gsu.s = &stdscalar_gsu; } /* @@ -4116,6 +4125,11 @@ tiedarrsetfn(Param pm, char *x) if (*dptr->arrptr) freearray(*dptr->arrptr); + else if (pm->ename) { + Param altpm = (Param) paramtab->getnode(paramtab, pm->ename); + if (altpm) + altpm->node.flags &= ~PM_DEFAULTED; + } if (x) { char sepbuf[3]; if (imeta(dptr->joinchar)) @@ -5035,6 +5049,7 @@ arrfixenv(char *s, char **t) if (isset(ALLEXPORT)) pm->node.flags |= PM_EXPORTED; + pm->node.flags &= ~PM_DEFAULTED; /* * Do not "fix" parameters that were not exported @@ -5839,8 +5854,9 @@ printparamnode(HashNode hn, int printflags) Param peer = NULL; if (p->node.flags & PM_UNSET) { - if (printflags & (PRINT_POSIX_READONLY|PRINT_POSIX_EXPORT) && - p->node.flags & (PM_READONLY|PM_EXPORTED)) { + if ((printflags & (PRINT_POSIX_READONLY|PRINT_POSIX_EXPORT) && + p->node.flags & (PM_READONLY|PM_EXPORTED)) || + (p->node.flags & PM_DEFAULTED) == PM_DEFAULTED) { /* * Special POSIX rules: show the parameter as readonly/exported * even though it's unset, but with no value. -- cgit 1.4.1