summaryrefslogtreecommitdiff
path: root/Src/params.c
diff options
context:
space:
mode:
authorAxel Beckert <abe@deuxchevaux.org>2020-02-14 01:58:20 +0100
committerAxel Beckert <abe@deuxchevaux.org>2020-02-14 01:58:20 +0100
commitbfc5d42735c1660263904ec5254cccf539a0a458 (patch)
tree9bbb81b4a53941427e6f9e65ae55027d9108df8c /Src/params.c
parent74561cc51b8867e43cb2937ab2edfb36e2a829bf (diff)
parent643de931640e01aa246723d2038328ef33737965 (diff)
downloadzsh-bfc5d42735c1660263904ec5254cccf539a0a458.tar.gz
zsh-bfc5d42735c1660263904ec5254cccf539a0a458.zip
Merge tag 'zsh-5.7.1-test-3' into debian
Test release: 5.7.1-test-3
Diffstat (limited to 'Src/params.c')
-rw-r--r--Src/params.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/Src/params.c b/Src/params.c
index 089a958ae..863b32600 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -44,7 +44,11 @@
#endif
#endif
-/* what level of localness we are at */
+/* What level of localness we are at.
+ *
+ * Hand-wavingly, this is incremented at every function call and decremented
+ * at every function return. See startparamscope().
+ */
/**/
mod_export int locallevel;
@@ -474,7 +478,13 @@ static initparam argvparam_pm = IPDEF9("", &pparams, NULL, \
static Param argvparam;
-/* hash table containing the parameters */
+/* "parameter table" - hash table containing the parameters
+ *
+ * realparamtab always points to the shell's global table. paramtab is sometimes
+ * temporarily changed to point at another table, while dealing with the keys
+ * of an associative array (for example, see makecompparams() which initializes
+ * the associative array ${compstate}).
+ */
/**/
mod_export HashTable paramtab, realparamtab;
@@ -1124,8 +1134,10 @@ copyparam(Param tpm, Param pm, int fakecopy)
tpm->base = pm->base;
tpm->width = pm->width;
tpm->level = pm->level;
- if (!fakecopy)
+ if (!fakecopy) {
+ tpm->old = pm->old;
tpm->node.flags &= ~PM_SPECIAL;
+ }
switch (PM_TYPE(pm->node.flags)) {
case PM_SCALAR:
tpm->u.str = ztrdup(pm->gsu.s->getfn(pm));
@@ -2201,10 +2213,10 @@ getstrvalue(Value v)
if (v->flags & VALFLAG_SUBST) {
if (v->pm->node.flags & (PM_LEFT|PM_RIGHT_B|PM_RIGHT_Z)) {
- unsigned int fwidth = v->pm->width ? v->pm->width : MB_METASTRLEN(s);
+ size_t fwidth = v->pm->width ? (unsigned int)v->pm->width : MB_METASTRLEN(s);
switch (v->pm->node.flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) {
char *t, *tend;
- unsigned int t0;
+ size_t t0;
case PM_LEFT:
case PM_LEFT | PM_RIGHT_Z:
@@ -2585,7 +2597,7 @@ assignstrvalue(Value v, char *val, int flags)
Param pm = v->pm;
/* Size doesn't change, can limit actions to only
* overwriting bytes in already allocated string */
- strncpy(z + v->start, val, vlen);
+ memcpy(z + v->start, val, vlen);
/* Implement remainder of strsetfn */
if (!(pm->node.flags & PM_HASHELEM) &&
((pm->node.flags & PM_NAMEDDIR) ||
@@ -3546,7 +3558,7 @@ setiparam(char *s, zlong val)
/*
* Set an integer parameter without forcing creation of an integer type.
- * This is useful if the integer is going to be set to a parmaeter which
+ * This is useful if the integer is going to be set to a parameter which
* would usually be scalar but may not exist.
*/
@@ -3617,10 +3629,18 @@ unsetparam_pm(Param pm, int altflag, int exp)
altpm = (Param) paramtab->getnode(paramtab, altremove);
/* tied parameters are at the same local level as each other */
oldpm = NULL;
- while (altpm && altpm->level > pm->level) {
- /* param under alternate name hidden by a local */
- oldpm = altpm;
- altpm = altpm->old;
+ /*
+ * Look for param under alternate name hidden by a local.
+ * If this parameter is special, however, the visible
+ * parameter is the special and the hidden one is keeping
+ * an old value --- we just mark the visible one as unset.
+ */
+ if (altpm && !(altpm->node.flags & PM_SPECIAL))
+ {
+ while (altpm && altpm->level > pm->level) {
+ oldpm = altpm;
+ altpm = altpm->old;
+ }
}
if (altpm) {
if (oldpm && !altpm->level) {
@@ -5858,7 +5878,7 @@ printparamnode(HashNode hn, int printflags)
doneminus = 0;
}
if ((pmptr->flags & PMTF_USE_WIDTH) && p->width) {
- printf("%d ", p->width);
+ printf("%u ", p->width);
doneminus = 0;
}
}