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

Re: parse error in process substitution



On Sun, 16 Nov 2008 13:51:27 -0800
Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> schaefer[507] echo ${~:-(<(echo|cat)|>(echo|cat))}
> zsh: bad pattern: (<(echo|cat)|/proc/self/fd/12)
> zsh: command not found: echocat
> 
> Something still seems a bit odd there.  Where did "echocat" come from?

OK, I now understand this one.  My change mixed up handling of process and
parameter substitution, so that after a GLOB_SUBST you could get back to
process substitution, and because it hadn't been parsed properly in the
first instance you were in a fairly confused state.

It's clearly documented and has been for a long time that process
substitution comes before parameter and command substitution, so the fix is
straightforward and doesn't need specially documenting.

I've changed the text about when process subsitutions happens.  Further
improvements with explicit text are welcome.

I think that's the end of actual bugs I know about, the rest are disputable
changes of behaviour which I'll think some more about.

Index: README
===================================================================
RCS file: /cvsroot/zsh/zsh/README,v
retrieving revision 1.60
diff -u -r1.60 README
--- README	15 Nov 2008 16:30:31 -0000	1.60
+++ README	17 Nov 2008 16:01:09 -0000
@@ -74,11 +74,9 @@
 (However, the latter two forms caused the current argument to be
 terminated and a new one started even if they occurred in the middle of
 a string.)  Now all three may be followed by other strings, and the
-latter two may also be preceeded by other strings.  None may occur inside
-parameter substitutions, or inside parentheses used for grouping of
-patterns, in order to avoid clashes with cases where
-tt(<) or tt(>) were not treated specially in previous versions of the
-shell.
+latter two may also be preceeded by other strings.  Remaining
+limitations on their use (to reduce incompatibilities to a minimum)
+are documented in the zshexpn.1 manual.
 
 In previous versions of the shell it was possible to use index 0 in an
 array or string subscript to refer to the same element as index 1 if the
Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.98
diff -u -r1.98 expn.yo
--- Doc/Zsh/expn.yo	13 Nov 2008 21:18:14 -0000	1.98
+++ Doc/Zsh/expn.yo	17 Nov 2008 16:01:09 -0000
@@ -360,9 +360,8 @@
 is subject to process substitution.  The expression may be preceeded
 or followed by other strings except that, to prevent clashes with
 commonly occurring strings and patterns, the last
-form must occur at the start of a command argument, and none of
-the forms may occur inside parentheses used for grouping of patterns or
-inside parameter substitutions.
+form must occur at the start of a command argument, and the forms
+are only expanded when first parsing command or assignment arguments.
 
 In the case of the tt(<) or tt(>) forms, the shell runs the commands in
 var(list) asynchronously.  If the system supports the tt(/dev/fd)
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.91
diff -u -r1.91 subst.c
--- Src/subst.c	13 Nov 2008 21:18:14 -0000	1.91
+++ Src/subst.c	17 Nov 2008 16:01:09 -0000
@@ -152,8 +152,8 @@
     char *str  = str3, c;
 
     while (!errflag && (c = *str)) {
-	if ((c == Inang || c == Outang || (str == str3 && c == Equals)) &&
-	    str[1] == Inpar) {
+	if (((c = *str) == Inang || c == Outang || (str == str3 && c == Equals))
+	    && str[1] == Inpar) {
 	    char *subst, *rest, *snew, *sptr;
 	    int str3len = str - str3, sublen, restlen;
 
@@ -181,8 +181,13 @@
 	    str3 = snew;
 	    str = snew + str3len + sublen;
 	    setdata(node, str3);
-	    continue;
-	} else if ((qt = c == Qstring) || c == String) {
+	} else
+	    str++;
+    }
+    str = str3;
+
+    while (!errflag && (c = *str)) {
+	if ((qt = c == Qstring) || c == String) {
 	    if ((c = str[1]) == Inpar) {
 		if (!qt)
 		    list->list.flags |= LF_ARRAY;

-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070



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