From c0e007663d30f83b0e5e074db34dcffaa8915e99 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 29 Oct 2015 11:30:55 +0000 Subject: [PATCH] ash: simplify EOF/newline handling in list parser Processing of here documents in ash has had a couple of breakages which are now the subject of tests. This commit should fix both. It is based on the following commit in dash git by Herbert Xu: <7c245aa> [PARSER] Simplify EOF/newline handling in list parser (See git://git.kernel.org/pub/scm/utils/dash/dash.git) Reported-by: Natanael Copa Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 63 ++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 72fc7d524..9a8bab5ab 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -10524,7 +10524,7 @@ static union node *andor(void); static union node *pipeline(void); static union node *parse_command(void); static void parseheredoc(void); -static char peektoken(void); +static int peektoken(void); static int readtoken(void); static union node * @@ -10533,11 +10533,27 @@ list(int nlflag) union node *n1, *n2, *n3; int tok; - checkkwd = CHKNL | CHKKWD | CHKALIAS; - if (nlflag == 2 && peektoken()) - return NULL; n1 = NULL; for (;;) { + switch (peektoken()) { + case TNL: + if (!(nlflag & 1)) + break; + parseheredoc(); + return n1; + + case TEOF: + if (!n1 && (nlflag & 1)) + n1 = NODE_EOF; + parseheredoc(); + return n1; + } + + checkkwd = CHKNL | CHKKWD | CHKALIAS; + if (nlflag == 2 && tokname_array[peektoken()][0]) + return n1; + nlflag |= 2; + n2 = andor(); tok = readtoken(); if (tok == TBACKGND) { @@ -10563,30 +10579,15 @@ list(int nlflag) n1 = n3; } switch (tok) { + case TNL: + case TEOF: + tokpushback = 1; + /* fall through */ case TBACKGND: case TSEMI: - tok = readtoken(); - /* fall through */ - case TNL: - if (tok == TNL) { - parseheredoc(); - if (nlflag == 1) - return n1; - } else { - tokpushback = 1; - } - checkkwd = CHKNL | CHKKWD | CHKALIAS; - if (peektoken()) - return n1; break; - case TEOF: - if (heredoclist) - parseheredoc(); - else - pungetc(); /* push back EOF on input */ - return n1; default: - if (nlflag == 1) + if ((nlflag & 1)) raise_error_unexpected_syntax(-1); tokpushback = 1; return n1; @@ -11954,14 +11955,14 @@ readtoken(void) return t; } -static char +static int peektoken(void) { int t; t = readtoken(); tokpushback = 1; - return tokname_array[t][0]; + return t; } /* @@ -11971,18 +11972,12 @@ peektoken(void) static union node * parsecmd(int interact) { - int t; - tokpushback = 0; + checkkwd = 0; + heredoclist = 0; doprompt = interact; setprompt_if(doprompt, doprompt); needprompt = 0; - t = readtoken(); - if (t == TEOF) - return NODE_EOF; - if (t == TNL) - return NULL; - tokpushback = 1; return list(1); }