sh: Add a function for the case where one token is required in the parse.

This commit is contained in:
Jilles Tjoelker 2013-08-30 13:25:15 +00:00
parent 65519ccb4d
commit 6ab99f87b7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=255073

View File

@ -121,6 +121,7 @@ static int readtoken(void);
static int xxreadtoken(void); static int xxreadtoken(void);
static int readtoken1(int, const char *, const char *, int); static int readtoken1(int, const char *, const char *, int);
static int noexpand(char *); static int noexpand(char *);
static void consumetoken(int);
static void synexpect(int) __dead2; static void synexpect(int) __dead2;
static void synerror(const char *) __dead2; static void synerror(const char *) __dead2;
static void setprompt(int); static void setprompt(int);
@ -413,8 +414,7 @@ command(void)
n1->type = NIF; n1->type = NIF;
if ((n1->nif.test = list(0, 0)) == NULL) if ((n1->nif.test = list(0, 0)) == NULL)
synexpect(-1); synexpect(-1);
if (readtoken() != TTHEN) consumetoken(TTHEN);
synexpect(TTHEN);
n1->nif.ifpart = list(0, 0); n1->nif.ifpart = list(0, 0);
n2 = n1; n2 = n1;
while (readtoken() == TELIF) { while (readtoken() == TELIF) {
@ -423,8 +423,7 @@ command(void)
n2->type = NIF; n2->type = NIF;
if ((n2->nif.test = list(0, 0)) == NULL) if ((n2->nif.test = list(0, 0)) == NULL)
synexpect(-1); synexpect(-1);
if (readtoken() != TTHEN) consumetoken(TTHEN);
synexpect(TTHEN);
n2->nif.ifpart = list(0, 0); n2->nif.ifpart = list(0, 0);
} }
if (lasttoken == TELSE) if (lasttoken == TELSE)
@ -433,27 +432,20 @@ command(void)
n2->nif.elsepart = NULL; n2->nif.elsepart = NULL;
tokpushback++; tokpushback++;
} }
if (readtoken() != TFI) consumetoken(TFI);
synexpect(TFI);
checkkwd = CHKKWD | CHKALIAS; checkkwd = CHKKWD | CHKALIAS;
break; break;
case TWHILE: case TWHILE:
case TUNTIL: { case TUNTIL:
int got;
n1 = (union node *)stalloc(sizeof (struct nbinary)); n1 = (union node *)stalloc(sizeof (struct nbinary));
n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL; n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL;
if ((n1->nbinary.ch1 = list(0, 0)) == NULL) if ((n1->nbinary.ch1 = list(0, 0)) == NULL)
synexpect(-1); synexpect(-1);
if ((got=readtoken()) != TDO) { consumetoken(TDO);
TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
synexpect(TDO);
}
n1->nbinary.ch2 = list(0, 0); n1->nbinary.ch2 = list(0, 0);
if (readtoken() != TDONE) consumetoken(TDONE);
synexpect(TDONE);
checkkwd = CHKKWD | CHKALIAS; checkkwd = CHKKWD | CHKALIAS;
break; break;
}
case TFOR: case TFOR:
if (readtoken() != TWORD || quoteflag || ! goodname(wordtext)) if (readtoken() != TWORD || quoteflag || ! goodname(wordtext))
synerror("Bad for loop variable"); synerror("Bad for loop variable");
@ -501,15 +493,13 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
else else
synexpect(-1); synexpect(-1);
n1->nfor.body = list(0, 0); n1->nfor.body = list(0, 0);
if (readtoken() != t) consumetoken(t);
synexpect(t);
checkkwd = CHKKWD | CHKALIAS; checkkwd = CHKKWD | CHKALIAS;
break; break;
case TCASE: case TCASE:
n1 = (union node *)stalloc(sizeof (struct ncase)); n1 = (union node *)stalloc(sizeof (struct ncase));
n1->type = NCASE; n1->type = NCASE;
if (readtoken() != TWORD) consumetoken(TWORD);
synexpect(TWORD);
n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg)); n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg));
n2->type = NARG; n2->type = NARG;
n2->narg.text = wordtext; n2->narg.text = wordtext;
@ -562,15 +552,13 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
n1->type = NSUBSHELL; n1->type = NSUBSHELL;
n1->nredir.n = list(0, 0); n1->nredir.n = list(0, 0);
n1->nredir.redirect = NULL; n1->nredir.redirect = NULL;
if (readtoken() != TRP) consumetoken(TRP);
synexpect(TRP);
checkkwd = CHKKWD | CHKALIAS; checkkwd = CHKKWD | CHKALIAS;
is_subshell = 1; is_subshell = 1;
break; break;
case TBEGIN: case TBEGIN:
n1 = list(0, 0); n1 = list(0, 0);
if (readtoken() != TEND) consumetoken(TEND);
synexpect(TEND);
checkkwd = CHKKWD | CHKALIAS; checkkwd = CHKKWD | CHKALIAS;
break; break;
/* A simple command must have at least one redirection or word. */ /* A simple command must have at least one redirection or word. */
@ -659,8 +647,7 @@ simplecmd(union node **rpp, union node *redir)
} else if (lasttoken == TLP && app == &args->narg.next } else if (lasttoken == TLP && app == &args->narg.next
&& rpp == orig_rpp) { && rpp == orig_rpp) {
/* We have a function */ /* We have a function */
if (readtoken() != TRP) consumetoken(TRP);
synexpect(TRP);
funclinno = plinno; funclinno = plinno;
/* /*
* - Require plain text. * - Require plain text.
@ -734,8 +721,7 @@ parsefname(void)
{ {
union node *n = redirnode; union node *n = redirnode;
if (readtoken() != TWORD) consumetoken(TWORD);
synexpect(-1);
if (n->type == NHERE) { if (n->type == NHERE) {
struct heredoc *here = heredoc; struct heredoc *here = heredoc;
struct heredoc *p; struct heredoc *p;
@ -1094,10 +1080,8 @@ parsebackq(char *out, struct nodelist **pbqlist,
if (oldstyle) if (oldstyle)
doprompt = saveprompt; doprompt = saveprompt;
else { else
if (readtoken() != TRP) consumetoken(TRP);
synexpect(TRP);
}
(*nlpp)->n = n; (*nlpp)->n = n;
if (oldstyle) { if (oldstyle) {
@ -1880,6 +1864,14 @@ isassignment(const char *p)
} }
static void
consumetoken(int token)
{
if (readtoken() != token)
synexpect(token);
}
/* /*
* Called when an unexpected token is read during the parse. The argument * Called when an unexpected token is read during the parse. The argument
* is the token that is expected, or -1 if more than one type of token can * is the token that is expected, or -1 if more than one type of token can