Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Associative array ordering and selective unset (Re: Example function)



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@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author