diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c index 5bf675e2a..a659300fd 100644 --- a/Src/Modules/parameter.c +++ b/Src/Modules/parameter.c @@ -105,10 +105,15 @@ getpmparameter(UNUSED(HashTable ht), const char *name) pm->node.nam = dupstring(name); pm->node.flags = PM_SCALAR | PM_READONLY; pm->gsu.s = &nullsetscalar_gsu; - if ((rpm = (Param) realparamtab->getnode(realparamtab, name)) && - !(rpm->node.flags & PM_UNSET)) + if ((rpm = (Param) realparamtab->getnode2(realparamtab, name)) && + !(rpm->node.flags & PM_UNSET)) { pm->u.str = paramtypestr(rpm); - else { + if ((rpm->node.flags & PM_NAMEREF) && + (rpm = (Param) realparamtab->getnode(realparamtab, name)) && + !(rpm->node.flags & PM_UNSET)) { + pm->u.str = zhtricat(pm->u.str, "-", paramtypestr(rpm)); + } + } else { pm->u.str = dupstring(""); pm->node.flags |= (PM_UNSET|PM_SPECIAL); } diff --git a/Src/params.c b/Src/params.c index 69b7f484f..98950d88f 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2155,7 +2155,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) return NULL; if (ss) *ss = sav; - s = ss; + s = dyncat(ss,*pptr); } if (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) { /* Overload v->isarr as the flag bits for hashed arrays. */ @@ -6170,6 +6170,7 @@ setscope(Param pm) { if (pm->node.flags & PM_NAMEREF) { Param basepm; + struct asgment stop; char *t = pm->u.str ? itype_end(pm->u.str, IIDENT, 0) : NULL; /* Temporarily change nameref to array parameter itself */ @@ -6177,7 +6178,12 @@ setscope(Param pm) *t = 0; else t = 0; - basepm = (Param)resolve_nameref(pm, NULL); + stop.name = ""; + stop.value.scalar = NULL; + stop.flags = PM_NAMEREF; + if (locallevel) + stop.flags |= PM_LOCAL; + basepm = (Param)resolve_nameref(pm, &stop); if (t) { pm->width = t - pm->u.str; *t = '['; diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst index b38831100..a663194a7 100644 --- a/Test/K01nameref.ztst +++ b/Test/K01nameref.ztst @@ -1,11 +1,11 @@ -# Tests for the zsh/param/private module +# Tests for named references %prep # Required in order to declare an unset hash for substitution test setopt TYPESET_TO_UNSET - : ${ZTST_continue:=1} + : ${ZTST_continue::=1} %test @@ -53,7 +53,13 @@ F:Other type changes are fatal errors, should this also be? typeset var=value typeset -n ptr=var print $ptr -0:basic nameref expansion +0:basic nameref expansion, no braces +>value + + typeset var=value + typeset -n ptr=var + print ${ptr} +0:basic nameref expansion, braces >value typeset var=(val1 val2) @@ -115,9 +121,10 @@ F:Other type changes are fatal errors, should this also be? >typeset -n ptr=var >typeset -a var=( new1 new2 ) - typeset -p ptr1 ptr2 var + typeset -p ptr ptr1 ptr2 var 1:check state of paramtab ONE F:unexpected side-effects of previous tests +*?*no such variable: ptr *?*no such variable: ptr1 *?*no such variable: ptr2 *?*no such variable: var @@ -247,13 +254,24 @@ F:unexpected side-effects of previous tests typeset -n ptr2='path[2]' print -r -- $ptr2 -0d:nameref to array element +0q:nameref to array element, no braces +>${path[2]} + + typeset -n ptr2='path[2]' + print -r -- ${ptr2} +0q:nameref to array element, with braces >${path[2]} typeset -A hash=(x MISS y HIT) typeset -n ptr1='hash[y]' print -r -- $ptr1 -0:nameref to hash element +0:nameref to hash element, no braces +>HIT + + typeset -A hash=(x MISS y HIT) + typeset -n ptr1='hash[y]' + print -r -- ${ptr1} +0:nameref to hash element, with braces >HIT typeset -a ary=(1 2) @@ -362,16 +380,16 @@ F:unexpected side-effects of previous tests >typeset -n ptr=lval >typeset -n ptr=gval + typeset -A var=(myself outside) () { - zmodload -u zsh/parameter - typeset -n myself=parameters[myself] - local -h parameters + typeset -n myself=var[myself] + local -h var print -r -- $myself - typeset -p parameters + typeset -p var } -0:up-reference part 3, autoloading with hidden special ->nameref-local ->typeset parameters +0:up-reference part 3, hidden global +>outside +>typeset var () { typeset notdef @@ -401,7 +419,7 @@ F:unexpected side-effects of previous tests 1:up-reference part 5, stacked namerefs, end not in scope F:What is the correct behavior for the scope of ptr1? >typeset -n ptr1=ptr2 ->typeset -n ptr2='' +>typeset -n ptr2 >ptr1=ptr2 >ptr2=val >ptr1=LOCAL @@ -427,13 +445,68 @@ F:What is the correct behavior for the scope of ptr1? 0:up-reference part 6, stacked namerefs, end is in scope F:Same test, should part 5 output look like this? >typeset -n ptr1=ptr2 ->typeset -n ptr2='' +>typeset -n ptr2 >ptr1=ptr2 ->ptr2='' +>ptr2 >ptr1=val >ptr2= >typeset -n ptr1=ptr2 >typeset -n ptr2='' >typeset ptr2=val + if zmodload zsh/parameter; then + () { + zmodload -u zsh/parameter + typeset -n myself=parameters[myself] + local -h parameters + print -r -- $myself + typeset -p parameters + } + else ZTST_skip='Cannot zmodload zsh/parameter, skipping autoload test' + fi +0:up-reference part 3, autoloading with hidden special +>nameref-local-nameref-local +>typeset parameters + + typeset ptr2=var2 + typeset var2=GLOBAL + () { + typeset -n ptr1=ptr2 + typeset ptr2=var1 + typeset var1=VAR1 + typeset var2=VAR2 + print -r -- ${(P)ptr1} + } +0: +>VAR2 + + ary=(one two three four) + typeset -n ptr=ary + print -r ${(j.:.)ptr//o/0} +0:expansion flags and string replacement +>0ne:tw0:three:f0ur + + var=value + typeset -n ptr=var + myscalar=ptr + echo ${(P)myscalar} +0:named references with (P), as ${(P)name_of_nameref} +>value + + var=value + myscalar=var + typeset -n ptr=myscalar + echo ${(P)ptr} +0:named references with (P), as ${(P)nameref} +>value + + ary=( 'bry[1]' 'bry[2]' ) + bry=( lorem ipsum ) + typeset -n ptr='ary[2]' + print -r -- ${ptr} + print -r -- ${(P)ptr} +0:named references with (P), array element to array element +>bry[2] +>ipsum + %clean diff --git a/Test/README b/Test/README index 670434ac3..b9d393d7c 100644 --- a/Test/README +++ b/Test/README @@ -6,6 +6,7 @@ scripts names: C: shell commands with special syntax D: substititution E: options + K: features adopted from ksh P: privileged (needs super-user privileges) V: modules W: builtin interactive commands and constructs