[PATCH 3/3] ash: simplify EOF/newline handling in list parser
Natanael Copa
ncopa at alpinelinux.org
Thu Oct 29 12:16:01 UTC 2015
On Thu, 29 Oct 2015 11:30:55 +0000
Ron Yorston <rmy at pobox.com> wrote:
> 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 <ncopa at alpinelinux.org>
> Signed-off-by: Ron Yorston <rmy at pobox.com>
> ---
> shell/ash.c | 63
> ++++++++++++++++++++++++++++--------------------------------- 1 file
> changed, 29 insertions(+), 34 deletions(-)
>
> diff --git a/shell/ash.c b/shell/ash.c
> index 86d648a..9d0226c 100644
> --- a/shell/ash.c
> +++ b/shell/ash.c
> @@ -10516,7 +10516,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 *
> @@ -10525,11 +10525,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])
probably want nexttoken_ends_list() for this. (which i think is use
more places?)
> + return n1;
> + nlflag |= 2;
> +
> n2 = andor();
> tok = readtoken();
> if (tok == TBACKGND) {
> @@ -10555,30 +10571,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;
> @@ -11947,14 +11948,14 @@ readtoken(void)
> return t;
> }
>
> -static char
> +static int
> peektoken(void)
> {
> int t;
>
> t = readtoken();
> tokpushback = 1;
> - return tokname_array[t][0];
> + return t;
> }
>
> /*
> @@ -11964,18 +11965,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);
> }
>
you forgot the last hunk in Herbert Xu's patch.
-nc
More information about the busybox
mailing list