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

Re: More crash Re: More incmdpos stuff Re: Crash Re: Trial for 5.0.7



On Fri, 03 Oct 2014 07:50:22 -0700
Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:

> On Oct 3,  1:27pm, Peter Stephenson wrote:
> } Subject: Re: More incmdpos stuff Re: Crash Re: Trial for 5.0.7
> }
> } On Fri, 03 Oct 2014 13:47:25 +0200
> } Mikael Magnusson <mikachu@xxxxxxxxx> wrote:
> } > % () ( echo hi; echo $@ ) ls
> } > hi
> } > ls --color=auto -T 0 -A -v --quoting-style=shell
> } 
> } I think the right answer is along the lines of "WHY THE **@*@*@ WOULD
> } ANYBODY USE SYNTAX LIKE THAT SHELL SYNTAX IS UNREADABLE ENOUGH AS IT IS
> } WITHOUT (FROTH, GIBBER, ...)", but instead here's a minimal change until
> } I get around to investigating why I thought I needed to leave incmdpos
> } = 1 for non-anymous functions.
> 
> Well, here's a clue:  With the patch from 33343 applied, it now makes no
> difference whether I do or do not back out the parse.c hunks from 32552.
> Either way, 'print foo | () cat' crashes.

The explanation is I screwed up.  *complex should never be set to 0
except where the variable pointed to is created --- it should only be
conditionally set to 1.  (For zsh-shaped values of "never".)

My version of gdb wouldn't let me examine complex because "everybody
knows" it's a keyword.  I've changed it globally to cmplx because there
seemed no good reason to run into the problem next time I debug this
(even if there are workarounds).  The actual fix is a single change in
the last hunk in Src/parse.c.

diff --git a/Src/parse.c b/Src/parse.c
index ad1ba89..f4ea639 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -202,7 +202,7 @@ struct heredocs *hdocs;
  * sublists is that they can be executed faster, see exec.c. In the
  * parser, the test if a list can be simplified is done quite simply
  * by passing a int* around which gets set to non-zero if the thing
- * just parsed is `complex', i.e. may need to be run by forking or 
+ * just parsed is `cmplx', i.e. may need to be run by forking or 
  * some such.
  *
  * In each of the above, strings are encoded as one word code. For empty
@@ -564,9 +564,9 @@ parse_cond(void)
 
 /**/
 static void
-set_list_code(int p, int type, int complex)
+set_list_code(int p, int type, int cmplx)
 {
-    if (!complex && (type == Z_SYNC || type == (Z_SYNC | Z_END)) &&
+    if (!cmplx && (type == Z_SYNC || type == (Z_SYNC | Z_END)) &&
 	WC_SUBLIST_TYPE(ecbuf[p + 1]) == WC_SUBLIST_END) {
 	int ispipe = !(WC_SUBLIST_FLAGS(ecbuf[p + 1]) & WC_SUBLIST_SIMPLE);
 	ecbuf[p] = WCB_LIST((type | Z_SIMPLE), ecused - 2 - p);
@@ -581,9 +581,9 @@ set_list_code(int p, int type, int complex)
 
 /**/
 static void
-set_sublist_code(int p, int type, int flags, int skip, int complex)
+set_sublist_code(int p, int type, int flags, int skip, int cmplx)
 {
-    if (complex)
+    if (cmplx)
 	ecbuf[p] = WCB_SUBLIST(type, flags, skip);
     else {
 	ecbuf[p] = WCB_SUBLIST(type, (flags | WC_SUBLIST_SIMPLE), skip);
@@ -597,7 +597,7 @@ set_sublist_code(int p, int type, int flags, int skip, int complex)
 
 /**/
 static int
-par_list(int *complex)
+par_list(int *cmplx)
 {
     int p, lp = -1, c;
 
@@ -610,10 +610,10 @@ par_list(int *complex)
     c = 0;
 
     if (par_sublist(&c)) {
-	*complex |= c;
+	*cmplx |= c;
 	if (tok == SEPER || tok == AMPER || tok == AMPERBANG) {
 	    if (tok != SEPER)
-		*complex = 1;
+		*cmplx = 1;
 	    set_list_code(p, ((tok == SEPER) ? Z_SYNC :
 			      (tok == AMPER) ? Z_ASYNC :
 			      (Z_ASYNC | Z_DISOWN)), c);
@@ -638,13 +638,13 @@ par_list(int *complex)
 
 /**/
 static int
-par_list1(int *complex)
+par_list1(int *cmplx)
 {
     int p = ecadd(0), c = 0;
 
     if (par_sublist(&c)) {
 	set_list_code(p, (Z_SYNC | Z_END), c);
-	*complex |= c;
+	*cmplx |= c;
 	return 1;
     } else {
 	ecused--;
@@ -658,7 +658,7 @@ par_list1(int *complex)
 
 /**/
 static int
-par_sublist(int *complex)
+par_sublist(int *cmplx)
 {
     int f, p, c = 0;
 
@@ -667,7 +667,7 @@ par_sublist(int *complex)
     if ((f = par_sublist2(&c)) != -1) {
 	int e = ecused;
 
-	*complex |= c;
+	*cmplx |= c;
 	if (tok == DBAR || tok == DAMPER) {
 	    enum lextok qtok = tok;
 	    int sl;
@@ -676,7 +676,7 @@ par_sublist(int *complex)
 	    zshlex();
 	    while (tok == SEPER)
 		zshlex();
-	    sl = par_sublist(complex);
+	    sl = par_sublist(cmplx);
 	    set_sublist_code(p, (sl ? (qtok == DBAR ?
 				       WC_SUBLIST_OR : WC_SUBLIST_AND) :
 				 WC_SUBLIST_END),
@@ -697,20 +697,20 @@ par_sublist(int *complex)
 
 /**/
 static int
-par_sublist2(int *complex)
+par_sublist2(int *cmplx)
 {
     int f = 0;
 
     if (tok == COPROC) {
-	*complex = 1;
+	*cmplx = 1;
 	f |= WC_SUBLIST_COPROC;
 	zshlex();
     } else if (tok == BANG) {
-	*complex = 1;
+	*cmplx = 1;
 	f |= WC_SUBLIST_NOT;
 	zshlex();
     }
-    if (!par_pline(complex) && !f)
+    if (!par_pline(cmplx) && !f)
 	return -1;
 
     return f;
@@ -722,19 +722,19 @@ par_sublist2(int *complex)
 
 /**/
 static int
-par_pline(int *complex)
+par_pline(int *cmplx)
 {
     int p;
     zlong line = toklineno;
 
     p = ecadd(0);
 
-    if (!par_cmd(complex, 0)) {
+    if (!par_cmd(cmplx, 0)) {
 	ecused--;
 	return 0;
     }
     if (tok == BAR) {
-	*complex = 1;
+	*cmplx = 1;
 	cmdpush(CS_PIPE);
 	zshlex();
 	while (tok == SEPER)
@@ -742,7 +742,7 @@ par_pline(int *complex)
 	ecbuf[p] = WCB_PIPE(WC_PIPE_MID, (line >= 0 ? line + 1 : 0));
 	ecispace(p + 1, 1);
 	ecbuf[p + 1] = ecused - 1 - p;
-	if (!par_pline(complex)) {
+	if (!par_pline(cmplx)) {
 	    tok = LEXERR;
 	}
 	cmdpop();
@@ -758,7 +758,7 @@ par_pline(int *complex)
 	ecbuf[r + 1] = 2;
 	ecbuf[r + 2] = ecstrcode("1");
 
-	*complex = 1;
+	*cmplx = 1;
 	cmdpush(CS_ERRPIPE);
 	zshlex();
 	while (tok == SEPER)
@@ -766,7 +766,7 @@ par_pline(int *complex)
 	ecbuf[p] = WCB_PIPE(WC_PIPE_MID, (line >= 0 ? line + 1 : 0));
 	ecispace(p + 1, 1);
 	ecbuf[p + 1] = ecused - 1 - p;
-	if (!par_pline(complex)) {
+	if (!par_pline(cmplx)) {
 	    tok = LEXERR;
 	}
 	cmdpop();
@@ -786,14 +786,14 @@ par_pline(int *complex)
 
 /**/
 static int
-par_cmd(int *complex, int zsh_construct)
+par_cmd(int *cmplx, int zsh_construct)
 {
     int r, nr = 0;
 
     r = ecused;
 
     if (IS_REDIROP(tok)) {
-	*complex = 1;
+	*cmplx = 1;
 	while (IS_REDIROP(tok)) {
 	    nr += par_redir(&r, NULL);
 	}
@@ -801,57 +801,57 @@ par_cmd(int *complex, int zsh_construct)
     switch (tok) {
     case FOR:
 	cmdpush(CS_FOR);
-	par_for(complex);
+	par_for(cmplx);
 	cmdpop();
 	break;
     case FOREACH:
 	cmdpush(CS_FOREACH);
-	par_for(complex);
+	par_for(cmplx);
 	cmdpop();
 	break;
     case SELECT:
-	*complex = 1;
+	*cmplx = 1;
 	cmdpush(CS_SELECT);
-	par_for(complex);
+	par_for(cmplx);
 	cmdpop();
 	break;
     case CASE:
 	cmdpush(CS_CASE);
-	par_case(complex);
+	par_case(cmplx);
 	cmdpop();
 	break;
     case IF:
-	par_if(complex);
+	par_if(cmplx);
 	break;
     case WHILE:
 	cmdpush(CS_WHILE);
-	par_while(complex);
+	par_while(cmplx);
 	cmdpop();
 	break;
     case UNTIL:
 	cmdpush(CS_UNTIL);
-	par_while(complex);
+	par_while(cmplx);
 	cmdpop();
 	break;
     case REPEAT:
 	cmdpush(CS_REPEAT);
-	par_repeat(complex);
+	par_repeat(cmplx);
 	cmdpop();
 	break;
     case INPAR:
-	*complex = 1;
+	*cmplx = 1;
 	cmdpush(CS_SUBSH);
-	par_subsh(complex, zsh_construct);
+	par_subsh(cmplx, zsh_construct);
 	cmdpop();
 	break;
     case INBRACE:
 	cmdpush(CS_CURSH);
-	par_subsh(complex, zsh_construct);
+	par_subsh(cmplx, zsh_construct);
 	cmdpop();
 	break;
     case FUNC:
 	cmdpush(CS_FUNCDEF);
-	par_funcdef(complex);
+	par_funcdef(cmplx);
 	cmdpop();
 	break;
     case DINBRACK:
@@ -869,7 +869,7 @@ par_cmd(int *complex, int zsh_construct)
 	    static int inpartime = 0;
 
 	    if (!inpartime) {
-		*complex = 1;
+		*cmplx = 1;
 		inpartime = 1;
 		par_time();
 		inpartime = 0;
@@ -882,13 +882,13 @@ par_cmd(int *complex, int zsh_construct)
 	{
 	    int sr;
 
-	    if (!(sr = par_simple(complex, nr))) {
+	    if (!(sr = par_simple(cmplx, nr))) {
 		if (!nr)
 		    return 0;
 	    } else {
 		/* Take account of redirections */
 		if (sr > 1) {
-		    *complex = 1;
+		    *cmplx = 1;
 		    r += sr - 1;
 		}
 	    }
@@ -896,7 +896,7 @@ par_cmd(int *complex, int zsh_construct)
 	break;
     }
     if (IS_REDIROP(tok)) {
-	*complex = 1;
+	*cmplx = 1;
 	while (IS_REDIROP(tok))
 	    (void)par_redir(&r, NULL);
     }
@@ -914,7 +914,7 @@ par_cmd(int *complex, int zsh_construct)
 
 /**/
 static void
-par_for(int *complex)
+par_for(int *cmplx)
 {
     int oecused = ecused, csh = (tok == FOREACH), p, sel = (tok == SELECT);
     int type;
@@ -999,20 +999,20 @@ par_for(int *complex)
 	zshlex();
     if (tok == DOLOOP) {
 	zshlex();
-	par_save_list(complex);
+	par_save_list(cmplx);
 	if (tok != DONE)
 	    YYERRORV(oecused);
 	incmdpos = 0;
 	zshlex();
     } else if (tok == INBRACE) {
 	zshlex();
-	par_save_list(complex);
+	par_save_list(cmplx);
 	if (tok != OUTBRACE)
 	    YYERRORV(oecused);
 	incmdpos = 0;
 	zshlex();
     } else if (csh || isset(CSHJUNKIELOOPS)) {
-	par_save_list(complex);
+	par_save_list(cmplx);
 	if (tok != ZEND)
 	    YYERRORV(oecused);
 	incmdpos = 0;
@@ -1020,7 +1020,7 @@ par_for(int *complex)
     } else if (unset(SHORTLOOPS)) {
 	YYERRORV(oecused);
     } else
-	par_save_list1(complex);
+	par_save_list1(cmplx);
 
     ecbuf[p] = (sel ?
 		WCB_SELECT(type, ecused - 1 - p) :
@@ -1036,7 +1036,7 @@ par_for(int *complex)
 
 /**/
 static void
-par_case(int *complex)
+par_case(int *cmplx)
 {
     int oecused = ecused, brflag, p, pp, n = 1, type;
     int ona, onc;
@@ -1153,7 +1153,7 @@ par_case(int *complex)
 	pp = ecadd(0);
 	ecstr(str);
 	ecadd(ecnpats++);
-	par_save_list(complex);
+	par_save_list(cmplx);
 	n++;
 	if (tok == SEMIAMP)
 	    type = WC_CASE_AND;
@@ -1183,7 +1183,7 @@ par_case(int *complex)
 
 /**/
 static void
-par_if(int *complex)
+par_if(int *cmplx)
 {
     int oecused = ecused, p, pp, type, usebrace = 0;
     enum lextok xtok;
@@ -1210,7 +1210,7 @@ par_if(int *complex)
 	}
 	pp = ecadd(0);
 	type = (xtok == IF ? WC_IF_IF : WC_IF_ELIF);
-	par_save_list(complex);
+	par_save_list(cmplx);
 	incmdpos = 1;
 	if (tok == ENDINPUT) {
 	    cmdpop();
@@ -1225,7 +1225,7 @@ par_if(int *complex)
 	    cmdpop();
 	    cmdpush(nc);
 	    zshlex();
-	    par_save_list(complex);
+	    par_save_list(cmplx);
 	    ecbuf[pp] = WCB_IF(type, ecused - 1 - pp);
 	    incmdpos = 1;
 	    cmdpop();
@@ -1234,7 +1234,7 @@ par_if(int *complex)
 	    cmdpop();
 	    cmdpush(nc);
 	    zshlex();
-	    par_save_list(complex);
+	    par_save_list(cmplx);
 	    if (tok != OUTBRACE) {
 		cmdpop();
 		YYERRORV(oecused);
@@ -1252,7 +1252,7 @@ par_if(int *complex)
 	} else {
 	    cmdpop();
 	    cmdpush(nc);
-	    par_save_list1(complex);
+	    par_save_list1(cmplx);
 	    ecbuf[pp] = WCB_IF(type, ecused - 1 - pp);
 	    incmdpos = 1;
 	    break;
@@ -1266,13 +1266,13 @@ par_if(int *complex)
 	    zshlex();
 	if (tok == INBRACE && usebrace) {
 	    zshlex();
-	    par_save_list(complex);
+	    par_save_list(cmplx);
 	    if (tok != OUTBRACE) {
 		cmdpop();
 		YYERRORV(oecused);
 	    }
 	} else {
-	    par_save_list(complex);
+	    par_save_list(cmplx);
 	    if (tok != FI) {
 		cmdpop();
 		YYERRORV(oecused);
@@ -1293,33 +1293,33 @@ par_if(int *complex)
 
 /**/
 static void
-par_while(int *complex)
+par_while(int *cmplx)
 {
     int oecused = ecused, p;
     int type = (tok == UNTIL ? WC_WHILE_UNTIL : WC_WHILE_WHILE);
 
     p = ecadd(0);
     zshlex();
-    par_save_list(complex);
+    par_save_list(cmplx);
     incmdpos = 1;
     while (tok == SEPER)
 	zshlex();
     if (tok == DOLOOP) {
 	zshlex();
-	par_save_list(complex);
+	par_save_list(cmplx);
 	if (tok != DONE)
 	    YYERRORV(oecused);
 	incmdpos = 0;
 	zshlex();
     } else if (tok == INBRACE) {
 	zshlex();
-	par_save_list(complex);
+	par_save_list(cmplx);
 	if (tok != OUTBRACE)
 	    YYERRORV(oecused);
 	incmdpos = 0;
 	zshlex();
     } else if (isset(CSHJUNKIELOOPS)) {
-	par_save_list(complex);
+	par_save_list(cmplx);
 	if (tok != ZEND)
 	    YYERRORV(oecused);
 	zshlex();
@@ -1335,7 +1335,7 @@ par_while(int *complex)
 
 /**/
 static void
-par_repeat(int *complex)
+par_repeat(int *cmplx)
 {
     int oecused = ecused, p;
 
@@ -1352,27 +1352,27 @@ par_repeat(int *complex)
 	zshlex();
     if (tok == DOLOOP) {
 	zshlex();
-	par_save_list(complex);
+	par_save_list(cmplx);
 	if (tok != DONE)
 	    YYERRORV(oecused);
 	incmdpos = 0;
 	zshlex();
     } else if (tok == INBRACE) {
 	zshlex();
-	par_save_list(complex);
+	par_save_list(cmplx);
 	if (tok != OUTBRACE)
 	    YYERRORV(oecused);
 	incmdpos = 0;
 	zshlex();
     } else if (isset(CSHJUNKIELOOPS)) {
-	par_save_list(complex);
+	par_save_list(cmplx);
 	if (tok != ZEND)
 	    YYERRORV(oecused);
 	zshlex();
     } else if (unset(SHORTLOOPS)) {
 	YYERRORV(oecused);
     } else
-	par_save_list1(complex);
+	par_save_list1(cmplx);
 
     ecbuf[p] = WCB_REPEAT(ecused - 1 - p);
 }
@@ -1388,7 +1388,7 @@ par_repeat(int *complex)
 
 /**/
 static void
-par_subsh(int *complex, int zsh_construct)
+par_subsh(int *cmplx, int zsh_construct)
 {
     enum lextok otok = tok;
     int oecused = ecused, p, pp;
@@ -1397,7 +1397,7 @@ par_subsh(int *complex, int zsh_construct)
     /* Extra word only needed for always block */
     pp = ecadd(0);
     zshlex();
-    par_list(complex);
+    par_list(cmplx);
     ecadd(WCB_END());
     if (tok != ((otok == INPAR) ? OUTPAR : OUTBRACE))
 	YYERRORV(oecused);
@@ -1418,7 +1418,7 @@ par_subsh(int *complex, int zsh_construct)
 	cmdpush(CS_ALWAYS);
 
 	zshlex();
-	par_save_list(complex);
+	par_save_list(cmplx);
 	while (tok == SEPER)
 	    zshlex();
 
@@ -1441,7 +1441,7 @@ par_subsh(int *complex, int zsh_construct)
 
 /**/
 static void
-par_funcdef(int *complex)
+par_funcdef(int *cmplx)
 {
     int oecused = ecused, num = 0, onp, p, c = 0;
     int so, oecssub = ecssub;
@@ -1523,7 +1523,7 @@ par_funcdef(int *complex)
 	    num++;
 	    zshlex();
 	}
-	*complex = (num > 0);
+	*cmplx = (num > 0);
 	ecbuf[parg] = ecused - parg; /*?*/
 	ecbuf[parg+1] = num;
     }
@@ -1585,15 +1585,15 @@ par_dinbrack(void)
 
 /**/
 static int
-par_simple(int *complex, int nr)
+par_simple(int *cmplx, int nr)
 {
     int oecused = ecused, isnull = 1, r, argc = 0, p, isfunc = 0, sr = 0;
-    int c = *complex, nrediradd, assignments = 0;
+    int c = *cmplx, nrediradd, assignments = 0;
 
     r = ecused;
     for (;;) {
 	if (tok == NOCORRECT) {
-	    *complex = c = 1;
+	    *cmplx = c = 1;
 	    nocorrect = 1;
 	} else if (tok == ENVSTRING) {
 	    char *p, *name, *str;
@@ -1621,7 +1621,7 @@ par_simple(int *complex, int nr)
 		 */
 		if (p[1] == Inpar &&
 		    (*p == Equals || *p == Inang || *p == OutangProc)) {
-		    *complex = 1;
+		    *cmplx = 1;
 		    break;
 		}
 	    }
@@ -1633,10 +1633,10 @@ par_simple(int *complex, int nr)
 	    int oldcmdpos = incmdpos, n, type2;
 
 	    /*
-	     * We consider array setting complex because it can
+	     * We consider array setting cmplx because it can
 	     * contain process substitutions, which need a valid job.
 	     */
-	    *complex = c = 1;
+	    *cmplx = c = 1;
 	    p = ecadd(0);
 	    incmdpos = 0;
 	    if ((type2 = strlen(tokstr) - 1) && tokstr[type2] == '+') {
@@ -1668,7 +1668,7 @@ par_simple(int *complex, int nr)
 	if (tok == STRING) {
 	    int redir_var = 0;
 
-	    *complex = 1;
+	    *cmplx = 1;
 	    incmdpos = 0;
 
 	    if (!isset(IGNOREBRACES) && *tokstr == Inbrace)
@@ -1687,7 +1687,7 @@ par_simple(int *complex, int nr)
 
 			if (IS_REDIROP(tok) && tokfd == -1)
 			{
-			    *complex = c = 1;
+			    *cmplx = c = 1;
 			    nrediradd = par_redir(&r, idstring);
 			    p += nrediradd;
 			    sr += nrediradd;
@@ -1708,7 +1708,7 @@ par_simple(int *complex, int nr)
 		zshlex();
 	    }
 	} else if (IS_REDIROP(tok)) {
-	    *complex = c = 1;
+	    *cmplx = c = 1;
 	    nrediradd = par_redir(&r, NULL);
 	    p += nrediradd;
 	    sr += nrediradd;
@@ -1723,7 +1723,7 @@ par_simple(int *complex, int nr)
 	    if (assignments)
 		YYERROR(oecused);
 
-	    *complex = c;
+	    *cmplx = c;
 	    lineno = 0;
 	    incmdpos = 1;
 	    cmdpush(CS_FUNCDEF);
@@ -1773,7 +1773,7 @@ par_simple(int *complex, int nr)
 		if (argc == 0) {
 		    /*
 		     * Anonymous function, possibly with arguments.
-		     * N.B. for complex structures in particular
+		     * N.B. for cmplx structures in particular
 		     * ( ... ) we rely on lower level code doing this
 		     * to get the immediately following word (the
 		     * first token after the ")" has already been
@@ -1807,7 +1807,8 @@ par_simple(int *complex, int nr)
 		    argc++;
 		    zshlex();
 		}
-		*complex = (argc > 0);
+		if (argc > 0)
+		    *cmplx = 1;
 		ecbuf[parg] = ecused - parg; /*?*/
 		ecbuf[parg+1] = argc;
 	    }
diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst
index 1937570..10491a2 100644
--- a/Test/C04funcdef.ztst
+++ b/Test/C04funcdef.ztst
@@ -279,6 +279,10 @@
 >anon func
 >lsfoo
 
+ print foo | () cat
+0:Simple anonymous function should not simplify enclosing pipeline
+>foo
+
 %clean
 
  rm -f file.in file.out



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