* Re: Associative array ordering and selective unset (Re: Example function)
@ 1999-02-02 16:58 Sven Wischnowsky
1999-02-02 17:41 ` ${(P)${foo}} (Re: Associative array ordering) Bart Schaefer
0 siblings, 1 reply; 7+ messages in thread
From: Sven Wischnowsky @ 1999-02-02 16:58 UTC (permalink / raw)
To: zsh-workers
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
^ permalink raw reply [flat|nested] 7+ messages in thread
* ${(P)${foo}} (Re: Associative array ordering)
1999-02-02 16:58 Associative array ordering and selective unset (Re: Example function) Sven Wischnowsky
@ 1999-02-02 17:41 ` Bart Schaefer
0 siblings, 0 replies; 7+ messages in thread
From: Bart Schaefer @ 1999-02-02 17:41 UTC (permalink / raw)
To: zsh-workers
On Feb 2, 5:58pm, Sven Wischnowsky wrote:
} Subject: Re: Associative array ordering and selective unset (Re: Example
}
} 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.
}
} The patch below does this (it was quite easy).
Well, you got to that before I got around to responding to that particular
tidbit.
The other day someone asked about ksh namerefs in zsh, and I said that with
${(e)...} you didn't really need them. Here's a case where they would have
been exactly what the doctor ordered; in an appropriate muddle of ksh and
zsh syntax,
nameref ref=$arg[1]
echo ${(t)!ref}
which is a whole lot easier on the eyes, it must be admitted.
} 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.
There are actually several ways we can go from here.
We can keep Sven's syntax as is.
We can modify Sven's syntax so that ${(P)foo} is the same as ${(P)${foo}},
and make ${!foo} a synonym for it in ksh compatibility mode. This is
almost like ksh namerefs except that they don't get their own namespace.
We can make ${!foo} a synonym for ${(P)${foo}} (either in ksh mode or all
the time), leaving ${(P)foo} alone. I'm not too thrilled about this one.
We can add another hash table to be the nameref namespace, implement the
nameref and `typeset -n' builtins, and make ${(P)foo} [or another letter]
and ${!foo} synonyms where `foo' must be a nameref. That would deprecate
${(P)${foo}}.
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: ${(P)${foo}} (Re: Associative array ordering)
1999-02-03 10:06 Sven Wischnowsky
@ 1999-02-03 10:42 ` Peter Stephenson
0 siblings, 0 replies; 7+ messages in thread
From: Peter Stephenson @ 1999-02-03 10:42 UTC (permalink / raw)
To: zsh-workers
Sven Wischnowsky wrote:
> I forgot to append the patch for the docs, sorry.
Needs a slight addition.
--- Doc/Zsh/expn.yo.par Wed Feb 3 11:33:50 1999
+++ Doc/Zsh/expn.yo Wed Feb 3 11:39:43 1999
@@ -531,7 +531,7 @@
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 strings
-`tt(${(P)foo}' and `tt(${(P)${foo}})' will be expanded to `tt(baz)'.
+`tt(${(P)foo})' and `tt(${(P)${foo}})' will be expanded to `tt(baz)'.
)
item(tt(o))(
Sort the resulting words in ascending order.
--
Peter Stephenson <pws@ibmth.df.unipi.it> Tel: +39 050 844536
WWW: http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: ${(P)${foo}} (Re: Associative array ordering)
@ 1999-02-03 10:06 Sven Wischnowsky
1999-02-03 10:42 ` Peter Stephenson
0 siblings, 1 reply; 7+ messages in thread
From: Sven Wischnowsky @ 1999-02-03 10:06 UTC (permalink / raw)
To: zsh-workers
I wrote:
> Bart Schaefer wrote:
>
> > Let's go this way: Implement ${(P)foo}, the same as ${(P)${foo}} where
> > the inner ${...} has no flags or modifiers, and leave ${!foo} undefined
> > until we do real namerefs (if we ever do).
>
> Yep.
I forgot to append the patch for the docs, sorry.
Bye
Sven
--- od/Zsh/expn.yo Wed Feb 3 08:46:59 1999
+++ Doc/Zsh/expn.yo Wed Feb 3 11:06:10 1999
@@ -525,13 +525,13 @@
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)'.
+This makes the value of the parameter var(name) be taken as a
+parameter name on which to work. 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 strings
+`tt(${(P)foo}' and `tt(${(P)${foo}})' will be expanded to `tt(baz)'.
)
item(tt(o))(
Sort the resulting words in ascending order.
--
Sven Wischnowsky wischnow@informatik.hu-berlin.de
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: ${(P)${foo}} (Re: Associative array ordering)
@ 1999-02-03 9:55 Sven Wischnowsky
0 siblings, 0 replies; 7+ messages in thread
From: Sven Wischnowsky @ 1999-02-03 9:55 UTC (permalink / raw)
To: zsh-workers
Bart Schaefer wrote:
> Let's go this way: Implement ${(P)foo}, the same as ${(P)${foo}} where
> the inner ${...} has no flags or modifiers, and leave ${!foo} undefined
> until we do real namerefs (if we ever do).
Yep.
Bye
Sven
--- os/subst.c Wed Feb 3 10:55:01 1999
+++ Src/subst.c Wed Feb 3 10:48:21 1999
@@ -991,6 +991,12 @@
copied = 1;
*s = sav;
v = (Value) NULL;
+ } else if (aspar) {
+ if ((v = getvalue(&s, 1))) {
+ val = idbeg = getstrvalue(v);
+ subexp = 1;
+ } else
+ vunset = 1;
}
if (!subexp || aspar) {
char *ov = val;
--
Sven Wischnowsky wischnow@informatik.hu-berlin.de
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: ${(P)${foo}} (Re: Associative array ordering)
1999-02-03 8:02 Sven Wischnowsky
@ 1999-02-03 8:39 ` Bart Schaefer
0 siblings, 0 replies; 7+ messages in thread
From: Bart Schaefer @ 1999-02-03 8:39 UTC (permalink / raw)
To: Sven Wischnowsky, zsh-workers
On Feb 3, 9:02am, Sven Wischnowsky wrote:
} Subject: Re: ${(P)${foo}} (Re: Associative array ordering)
}
} Bart Schaefer wrote:
}
} > There are actually several ways we can go from here.
} >
} > We can keep Sven's syntax as is.
} >
} > We can modify Sven's syntax so that ${(P)foo} is the same as ${(P)${foo}},
} > and make ${!foo} a synonym for it in ksh compatibility mode. This is
} > almost like ksh namerefs except that they don't get their own namespace.
}
} I first thought about implementing ${(P)foo}, but implementing only the one
} I did, seemed easier.
I suspect that's at least in part how we ended up with ${${param}} instead
of simply ${{param}} in the first place, but ....
} Now that I had a deeper look into the substitution
} code again, making ${(P)foo} work doesn't look that complicated, too.
} Although that would be less powerful, so keeping the thing I
} implemented may still be useful.
Yes, particularly ${(P)$(...)} is probably useful, even if ${(P)${...}}
was not.
} Making ${!foo} a synonym may be useful, and as far as I can this we
} wouldn't have to restrict this to ksh compatibility mode (am I missing
} something?).
You're missing `setopt banghist`, which is unsetopt in ksh mode. ${!foo}
will have substituted the history item beginning with "foo" long before
it makes it to the parameter code. That's why the ${!assoc[@]} syntax
is accepted only in ksh mode, too.
Let's go this way: Implement ${(P)foo}, the same as ${(P)${foo}} where
the inner ${...} has no flags or modifiers, and leave ${!foo} undefined
until we do real namerefs (if we ever do).
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: ${(P)${foo}} (Re: Associative array ordering)
@ 1999-02-03 8:02 Sven Wischnowsky
1999-02-03 8:39 ` Bart Schaefer
0 siblings, 1 reply; 7+ messages in thread
From: Sven Wischnowsky @ 1999-02-03 8:02 UTC (permalink / raw)
To: zsh-workers
Bart Schaefer wrote:
> On Feb 2, 5:58pm, Sven Wischnowsky wrote:
> } Subject: Re: Associative array ordering and selective unset (Re: Example
> }
> } 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.
> }
> } The patch below does this (it was quite easy).
>
> Well, you got to that before I got around to responding to that particular
> tidbit.
>
> The other day someone asked about ksh namerefs in zsh, and I said that with
> ${(e)...} you didn't really need them. Here's a case where they would have
> been exactly what the doctor ordered; in an appropriate muddle of ksh and
> zsh syntax,
>
> nameref ref=$arg[1]
> echo ${(t)!ref}
>
> which is a whole lot easier on the eyes, it must be admitted.
Yes, but in cases where you need it only once, this is a bit verbose,
don't you think?
> } 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.
>
> There are actually several ways we can go from here.
>
> We can keep Sven's syntax as is.
>
> We can modify Sven's syntax so that ${(P)foo} is the same as ${(P)${foo}},
> and make ${!foo} a synonym for it in ksh compatibility mode. This is
> almost like ksh namerefs except that they don't get their own namespace.
I first thought about implementing ${(P)foo}, but implementing only the one
I did, seemed easier. Now that I had a deeper look into the substitution
code again, making ${(P)foo} work doesn't look that complicated, too.
Although that would be less powerful, so keeping the thing I
implemented may still be useful.
Making ${!foo} a synonym may be useful, and as far as I can this we
wouldn't have to restrict this to ksh compatibility mode (am I missing
something?).
> We can make ${!foo} a synonym for ${(P)${foo}} (either in ksh mode or all
> the time), leaving ${(P)foo} alone. I'm not too thrilled about this one.
Neither am I.
> We can add another hash table to be the nameref namespace, implement the
> nameref and `typeset -n' builtins, and make ${(P)foo} [or another letter]
> and ${!foo} synonyms where `foo' must be a nameref. That would deprecate
> ${(P)${foo}}.
Namerefs may be useful anyway. But, as I said above I wouldn't like to
have to invent a nameref just to use this double-lookup once.
So, I'd vote for the ${!foo}=${(P)foo}=${(P)${foo}}-but-${(P)${foo#*=}}-
still-works suggestion, or for the last one (without the deprecation
bit). Those two can be combined anyway.
Bye
Sven
--
Sven Wischnowsky wischnow@informatik.hu-berlin.de
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~1999-02-03 10:42 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-02-02 16:58 Associative array ordering and selective unset (Re: Example function) Sven Wischnowsky
1999-02-02 17:41 ` ${(P)${foo}} (Re: Associative array ordering) Bart Schaefer
1999-02-03 8:02 Sven Wischnowsky
1999-02-03 8:39 ` Bart Schaefer
1999-02-03 9:55 Sven Wischnowsky
1999-02-03 10:06 Sven Wischnowsky
1999-02-03 10:42 ` Peter Stephenson
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).