[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