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

Re: destructive list-expand

I wrote:

> ...
> Yes, I pointed that out and the reason for it: _expand uses
>       eval 'exp=( ${${(e)exp//\\[ 	
>     ]/ }//(#b)([ 	
>     ])/\\$match[1]} )' 2>/dev/null
> But that doesn't work here:
>     beta% echo ${(M)${(f)"$(<=(print -l *))"}:#*conf*}
>     acconfig.h conf config.cache config.guess config.h config.h.in config.log config.moduls config.status config.sub configure configure.in sconf
>     beta% foo='${(M)${(f)"$(<=(print -l *))"}:#*conf*}'
>     beta% echo ${(e)foo}
>     beta% echo ${(e)~foo}
>     CVS ChangeLog ChangeLog-Release ChangeLog.3.0 ChangeLog~ Completion Config Doc Etc Functions INSTALL LICENCE META-FAQ Makefile Makefile.in Misc README Src StartupFiles Test Util a acconfig.h aclocal.m4 aczsh.m4 conf config.cache config.guess config.h config.h.in config.log config.modules config.status config.sub configure configure.in core install-sh mkinstalldirs sconf so_locations stamp-h stamp-h.in

Part of the reason may probably be fixed by this (not to be committed
until some knowledgeable person comments):

Index: Src/subst.c
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.17
diff -u -r1.17 subst.c
--- Src/subst.c	2001/04/28 17:38:01	1.17
+++ Src/subst.c	2001/05/16 12:39:51
@@ -720,9 +720,13 @@
     if (!(err ? parsestr(s) : parsestrnoerr(s))) {
 	if (!single) {
+            int qt = 0;
 	    for (; *s; s++)
-		if (*s == Qstring)
+		if (!qt && *s == Qstring)
 		    *s = String;
+                else if (*s == Dnull)
+                    qt = !qt;
 	return 0;

That loop is in subst_parse_str() and turns all Qstring tokens into
String, even the one inside those double quotes in the parameter
expression. That makes the inner substitution return a string instead
of an array.

The patch leaves all Qstring's inside Dnull's unchanged.

The other part of the problem (not tackled by the patch) is that the
pattern after `:#...' is not tokenized. In paramsubst() is some code
that tokenizes the pattern, but only if it things the whole parameter
expansion is inside quotes. But the result of a ${(e)...} is not
considered to be in double quotes exactly because of the loop above.
There must be some reason for this because, of course, we never ever
even think about doing things that are not needed. Ahem.

I'm not sure how to fix this. We don't want the string from a ${(e)...}
being completely tokenized (that's the ~-modifier's job), but having the
patterns used inside parameter expansions be tokenized would be the
right thing, I think, wouldn't it? But where and when exactly would that
have to happen? So that it doesn't interfere with whatever made us add
that loop above?


Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx

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