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 <ncopa@alpinelinux.org> Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
6bd2fabc52
commit
c0e007663d
63
shell/ash.c
63
shell/ash.c
@ -10524,7 +10524,7 @@ static union node *andor(void);
|
|||||||
static union node *pipeline(void);
|
static union node *pipeline(void);
|
||||||
static union node *parse_command(void);
|
static union node *parse_command(void);
|
||||||
static void parseheredoc(void);
|
static void parseheredoc(void);
|
||||||
static char peektoken(void);
|
static int peektoken(void);
|
||||||
static int readtoken(void);
|
static int readtoken(void);
|
||||||
|
|
||||||
static union node *
|
static union node *
|
||||||
@ -10533,11 +10533,27 @@ list(int nlflag)
|
|||||||
union node *n1, *n2, *n3;
|
union node *n1, *n2, *n3;
|
||||||
int tok;
|
int tok;
|
||||||
|
|
||||||
checkkwd = CHKNL | CHKKWD | CHKALIAS;
|
|
||||||
if (nlflag == 2 && peektoken())
|
|
||||||
return NULL;
|
|
||||||
n1 = NULL;
|
n1 = NULL;
|
||||||
for (;;) {
|
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();
|
n2 = andor();
|
||||||
tok = readtoken();
|
tok = readtoken();
|
||||||
if (tok == TBACKGND) {
|
if (tok == TBACKGND) {
|
||||||
@ -10563,30 +10579,15 @@ list(int nlflag)
|
|||||||
n1 = n3;
|
n1 = n3;
|
||||||
}
|
}
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
|
case TNL:
|
||||||
|
case TEOF:
|
||||||
|
tokpushback = 1;
|
||||||
|
/* fall through */
|
||||||
case TBACKGND:
|
case TBACKGND:
|
||||||
case TSEMI:
|
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;
|
break;
|
||||||
case TEOF:
|
|
||||||
if (heredoclist)
|
|
||||||
parseheredoc();
|
|
||||||
else
|
|
||||||
pungetc(); /* push back EOF on input */
|
|
||||||
return n1;
|
|
||||||
default:
|
default:
|
||||||
if (nlflag == 1)
|
if ((nlflag & 1))
|
||||||
raise_error_unexpected_syntax(-1);
|
raise_error_unexpected_syntax(-1);
|
||||||
tokpushback = 1;
|
tokpushback = 1;
|
||||||
return n1;
|
return n1;
|
||||||
@ -11954,14 +11955,14 @@ readtoken(void)
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char
|
static int
|
||||||
peektoken(void)
|
peektoken(void)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
t = readtoken();
|
t = readtoken();
|
||||||
tokpushback = 1;
|
tokpushback = 1;
|
||||||
return tokname_array[t][0];
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -11971,18 +11972,12 @@ peektoken(void)
|
|||||||
static union node *
|
static union node *
|
||||||
parsecmd(int interact)
|
parsecmd(int interact)
|
||||||
{
|
{
|
||||||
int t;
|
|
||||||
|
|
||||||
tokpushback = 0;
|
tokpushback = 0;
|
||||||
|
checkkwd = 0;
|
||||||
|
heredoclist = 0;
|
||||||
doprompt = interact;
|
doprompt = interact;
|
||||||
setprompt_if(doprompt, doprompt);
|
setprompt_if(doprompt, doprompt);
|
||||||
needprompt = 0;
|
needprompt = 0;
|
||||||
t = readtoken();
|
|
||||||
if (t == TEOF)
|
|
||||||
return NODE_EOF;
|
|
||||||
if (t == TNL)
|
|
||||||
return NULL;
|
|
||||||
tokpushback = 1;
|
|
||||||
return list(1);
|
return list(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user