From mboxrd@z Thu Jan 1 00:00:00 1970 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes Date: Tue, 2 Feb 1999 17:58:49 +0100 (MET) Message-Id: <199902021658.RAA09882@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: Sven Wischnowsky's message of Tue, 2 Feb 1999 08:52:20 +0100 (MET) Subject: Re: Associative array ordering and selective unset (Re: Example function) X-Mailing-List: 5183 I wrote: > Maybe yet another flag? E.g.: `P' makes the thing after the > flags be used as the name of a parameter. So `${(P)foo}' is the same > as `$foo', but `${(P)${foo}}' will take the value of `foo' as the name > of a parameter and work on it. So your example would become: > > if [[ $#arg > 1 && ${(Pt)${argv[1]}} == association ]] ... The patch below does this (it was quite easy). With it you can do things like the above or `${(P)+${foo}}' to see if the parameter whose name is stored in `foo' is set. If the inner `${...}' produces multiple words they are joind using IFS which will result in an invalid parameter name (which is reported as being unset). Maybe we should make the code test if it is a valid name and barf otherwise. Or we could use only the first word. Any other suggestions? But I don't know if you like this anyway... The patch also changes the docs and the new-completion-examples. Bye Sven --- os/subst.c Mon Feb 1 10:53:56 1999 +++ Src/subst.c Tue Feb 2 17:27:50 1999 @@ -718,10 +718,12 @@ int copied = 0; int arrasg = 0; int eval = 0; + int aspar = 0; int nojoin = 0; char inbrace = 0; /* != 0 means ${...}, otherwise $... */ char hkeys = 0; char hvals = 0; + int subexp; *s++ = '\0'; if (!ialnum(*s) && *s != '#' && *s != Pound && *s != '-' && @@ -813,6 +815,9 @@ case 'e': eval = 1; break; + case 'P': + aspar = 1; + break; case 'c': whichlen = 1; @@ -949,7 +954,8 @@ } else globsubst = 1; } else if (*s == '+') { - if (iident(s[1])) + if (iident(s[1]) || (aspar && isstring(s[1]) && + (s[2] == Inbrace || s[2] == Inpar))) chkset = 1, s++; else if (!inbrace) { *aptr = '$'; @@ -965,7 +971,8 @@ globsubst = globsubst && !qt; idbeg = s; - if (s[-1] && isstring(*s) && (s[1] == Inbrace || s[1] == Inpar)) { + if ((subexp = (s[-1] && isstring(*s) && + (s[1] == Inbrace || s[1] == Inpar)))) { int sav; int quoted = *s == Qstring; @@ -973,17 +980,22 @@ skipparens(*s, *s == Inpar ? Outpar : Outbrace, &s); sav = *s; *s = 0; - if (multsub(&val, &aval, &isarr, NULL) && quoted) { + if (multsub(&val, (aspar ? NULL : &aval), &isarr, NULL) && quoted) { isarr = -1; aval = alloc(sizeof(char *)); - } + aspar = 0; + } else if (aspar) + idbeg = val; if (isarr) isarr = -1; copied = 1; *s = sav; v = (Value) NULL; - } else { - if (!(v = fetchvalue(&s, (wantt ? -1 : + } + if (!subexp || aspar) { + char *ov = val; + + if (!(v = fetchvalue((subexp ? &ov : &s), (wantt ? -1 : ((unset(KSHARRAYS) || inbrace) ? 1 : -1)), hkeys|hvals))) vunset = 1; --- od/Zsh/expn.yo Mon Feb 1 10:53:36 1999 +++ Doc/Zsh/expn.yo Tue Feb 2 17:51:35 1999 @@ -477,9 +477,10 @@ pindex(GLOB_SUBST) Turn on the tt(GLOB_SUBST) option for the evaluation of var(spec); if the `tt(~)' is doubled, turn it off. When this option is -set, any pattern characters resulting -from parameter expansion are eligible for filename expansion and filename -generation. +set, the string resulting from the expansion will be interpreted as a +pattern thus becoming eligible for filename expansion and filename +generation and usable as a pattern in pattern-matching contexts like +the `tt(=)' and `tt(!=)' operators in conditions. ) enditem() @@ -522,6 +523,15 @@ Perform em(parameter expansion), em(command substitution) and em(arithmetic expansion) on the result. Such expansions can be nested but too deep recursion may have unpredictable effects. +) +item(tt(P))( +If used with a parameter name, this flag has no effect. But if it is +used with a tt(${)...tt(}) type parameter expression or a +tt($LPAR())...tt(RPAR()) type command substitution in place of +the parameter name this flag makes the result of the expansion be +taken as a parameter name which is then used. E.g. if you have +`tt(foo=bar)' and `tt(bar=baz)', the string `tt(${(P)${foo}})' will be +expanded to `tt(baz)'. ) item(tt(o))( Sort the resulting words in ascending order. diff -u om/new-completion-examples Misc/new-completion-examples --- om/new-completion-examples Mon Feb 1 10:53:27 1999 +++ Misc/new-completion-examples Tue Feb 2 17:43:34 1999 @@ -75,11 +75,8 @@ # the arguments from the command line as its arguments. call-complete() { - local var - - eval var\=\$\{\+$1\} - if (( var )); then - eval complist \$\{${1}\[\@\]\} + if [[ ${(P)+${1}} -eq 1 ]] then + complist ${(@P)${1}} else "$@" fi @@ -96,15 +93,6 @@ setopt localoptions nullglob rcexpandparam globdots unsetopt markdirs globsubst shwordsplit nounset - # We first try the `compctl's. This is without first (-T) and default (-D) - # completion. If you want them add `-T' and/or `-D' to this command. - # If this produces any matches, we don't try new style completion. If you - # want to have that tried anyway, remove the `[[ -nmatches ... ]] ...' - # below. - - compcall - [[ -nmatches 0 ]] || return - # An entry for `--first--' is the replacement for `compctl -T' # The `|| return 1' is used throughout: if a function producing matches # returns non-zero this is interpreted as `do not try to produce more matches' @@ -117,6 +105,15 @@ # convenience alias `compsub'. if [[ $CONTEXT == argument || $CONTEXT == command ]] then + # We first try the `compctl's. This is without first (-T) and default (-D) + # completion. If you want them add `-T' and/or `-D' to this command. + # If this produces any matches, we don't try new style completion. If you + # want to have that tried anyway, remove the `[[ -nmatches ... ]] ...' + # below. + + compcall + [[ -nmatches 0 ]] || return + compsub else # Let's see if we have a special completion definition for the other @@ -205,7 +202,7 @@ if [[ "$a[1]" = '(' ]] then ppres=( $a[2,-2]/ ) else - eval ppres\=\( \$$a/ \) + ppres=( ${(P)${a}} ) [[ $#ppres -eq 0 ]] && ppres=( $a/ ) fi [[ $#ppres -eq 0 ]] && ppres=( '' ) @@ -329,11 +326,8 @@ defcomp __subscr --subscr-- __subscr() { - local t - - eval t\=\$\{\(t\)$COMMAND\} compalso --math-- "$@" - [[ $t = assoc* ]] && eval complist -k \"\(\$\{\(k\)$COMMAND\}\)\" + [[ ${(Pt)${COMMAND}} = assoc* ]] && complist -k "( ${(kP)${COMMAND}} )" } # Do sub-completion for pre-command modifiers. -- Sven Wischnowsky wischnow@informatik.hu-berlin.de