This is an internally visible change - no effect visible to the

user is expected. With the previous commits to parser.c, we no
longer need to handle reading here documents in the (massive)
readtoken1() function. That allows its code to be simplified and
made easier to read and understand (several goto's goto goto heaven.
RIP) (from kre@)
This commit is contained in:
christos 2016-03-31 16:12:09 +00:00
parent f6e1dd671e
commit 21cf17379f

View File

@ -1,4 +1,4 @@
/* $NetBSD: parser.c,v 1.112 2016/03/27 14:40:20 christos Exp $ */
/* $NetBSD: parser.c,v 1.113 2016/03/31 16:12:09 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95";
#else
__RCSID("$NetBSD: parser.c,v 1.112 2016/03/27 14:40:20 christos Exp $");
__RCSID("$NetBSD: parser.c,v 1.113 2016/03/31 16:12:09 christos Exp $");
#endif
#endif /* not lint */
@ -1460,7 +1460,7 @@ parseredir(const char *out, int c)
STATIC int
readtoken1(int firstc, char const *syn, int magicq)
{
int c = firstc;
int c;
char * out;
int len;
struct nodelist *bqlist;
@ -1484,161 +1484,160 @@ readtoken1(int firstc, char const *syn, int magicq)
parenlevel = 0;
STARTSTACKSTR(out);
loop: { /* for each line, until end of word */
for (;;) { /* until end of line or end of word */
CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */
switch(syntax[c]) {
case CNL: /* '\n' */
if (syntax == BASESYNTAX)
goto endword; /* exit outer loop */
USTPUTC(c, out);
for (c = firstc ;; c = pgetc_macro()) { /* until of token */
CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */
switch (syntax[c]) {
case CNL: /* '\n' */
if (syntax == BASESYNTAX)
break; /* exit loop */
USTPUTC(c, out);
plinno++;
if (doprompt)
setprompt(2);
else
setprompt(0);
continue;
case CWORD:
USTPUTC(c, out);
continue;
case CCTL:
if (!magicq || ISDBLQUOTE())
USTPUTC(CTLESC, out);
USTPUTC(c, out);
continue;
case CBACK: /* backslash */
c = pgetc();
if (c == PEOF) {
USTPUTC('\\', out);
pungetc();
continue;
}
if (c == '\n') {
plinno++;
if (doprompt)
setprompt(2);
else
setprompt(0);
c = pgetc();
goto loop; /* continue outer loop */
case CWORD:
continue;
}
quotef = 1; /* current token is quoted */
if (ISDBLQUOTE() && c != '\\' && c != '`' &&
c != '$' && (c != '"' || magicq))
USTPUTC('\\', out);
if (SQSYNTAX[c] == CCTL)
USTPUTC(CTLESC, out);
else if (!magicq) {
USTPUTC(CTLQUOTEMARK, out);
USTPUTC(c, out);
break;
case CCTL:
if (!magicq || ISDBLQUOTE())
USTPUTC(CTLESC, out);
USTPUTC(c, out);
break;
case CBACK: /* backslash */
c = pgetc();
if (c == PEOF) {
USTPUTC('\\', out);
pungetc();
break;
}
if (c == '\n') {
plinno++;
if (doprompt)
setprompt(2);
else
setprompt(0);
break;
}
quotef = 1;
if (ISDBLQUOTE() && c != '\\' &&
c != '`' && c != '$' &&
(c != '"' || magicq))
USTPUTC('\\', out);
if (SQSYNTAX[c] == CCTL)
USTPUTC(CTLESC, out);
else if (!magicq) {
USTPUTC(CTLQUOTEMARK, out);
USTPUTC(c, out);
if (varnest != 0)
USTPUTC(CTLQUOTEEND, out);
break;
}
USTPUTC(c, out);
break;
case CSQUOTE:
if (syntax != SQSYNTAX) {
if (!magicq)
USTPUTC(CTLQUOTEMARK, out);
quotef = 1;
TS_PUSH();
syntax = SQSYNTAX;
quoted = SQ;
break;
}
if (magicq && arinest == 0 && varnest == 0) {
/* Ignore inside quoted here document */
USTPUTC(c, out);
break;
}
/* End of single quotes... */
TS_POP();
if (syntax == BASESYNTAX && varnest != 0)
if (varnest != 0)
USTPUTC(CTLQUOTEEND, out);
break;
case CDQUOTE:
if (magicq && arinest == 0 && varnest == 0) {
/* Ignore inside here document */
USTPUTC(c, out);
break;
}
continue;
}
USTPUTC(c, out);
continue;
case CSQUOTE:
if (syntax != SQSYNTAX) {
if (!magicq)
USTPUTC(CTLQUOTEMARK, out);
quotef = 1;
if (arinest) {
if (ISDBLQUOTE()) {
TS_POP();
} else {
TS_PUSH();
syntax = DQSYNTAX;
SETDBLQUOTE();
USTPUTC(CTLQUOTEMARK, out);
}
break;
}
if (magicq)
break;
TS_PUSH();
syntax = SQSYNTAX;
quoted = SQ;
continue;
}
if (magicq && arinest == 0 && varnest == 0) {
/* Ignore inside quoted here document */
USTPUTC(c, out);
continue;
}
/* End of single quotes... */
TS_POP();
if (syntax == BASESYNTAX && varnest != 0)
USTPUTC(CTLQUOTEEND, out);
continue;
case CDQUOTE:
if (magicq && arinest == 0 && varnest == 0) {
/* Ignore inside here document */
USTPUTC(c, out);
continue;
}
quotef = 1;
if (arinest) {
if (ISDBLQUOTE()) {
TS_POP();
if (varnest != 0)
USTPUTC(CTLQUOTEEND, out);
} else {
TS_PUSH();
syntax = DQSYNTAX;
SETDBLQUOTE();
USTPUTC(CTLQUOTEMARK, out);
}
break;
case CVAR: /* '$' */
PARSESUB(); /* parse substitution */
break;
case CENDVAR: /* CLOSEBRACE */
if (varnest > 0 && !ISDBLQUOTE()) {
TS_POP();
USTPUTC(CTLENDVAR, out);
} else {
USTPUTC(c, out);
}
break;
case CLP: /* '(' in arithmetic */
parenlevel++;
USTPUTC(c, out);
break;
case CRP: /* ')' in arithmetic */
if (parenlevel > 0) {
USTPUTC(c, out);
--parenlevel;
} else {
if (pgetc() == ')') {
if (--arinest == 0) {
TS_POP();
USTPUTC(CTLENDARI, out);
} else
USTPUTC(')', out);
} else {
/*
* unbalanced parens
* (don't 2nd guess - no error)
*/
pungetc();
USTPUTC(')', out);
}
}
break;
case CBQUOTE: /* '`' */
out = parsebackq(stack, out, &bqlist, 1);
break;
case CEOF:
goto endword; /* exit outer loop */
default:
if (varnest == 0 && !ISDBLQUOTE())
goto endword; /* exit outer loop */
continue;
}
if (magicq)
continue;
if (ISDBLQUOTE()) {
TS_POP();
if (varnest != 0)
USTPUTC(CTLQUOTEEND, out);
} else {
TS_PUSH();
syntax = DQSYNTAX;
SETDBLQUOTE();
USTPUTC(CTLQUOTEMARK, out);
}
continue;
case CVAR: /* '$' */
PARSESUB(); /* parse substitution */
continue;
case CENDVAR: /* CLOSEBRACE */
if (varnest > 0 && !ISDBLQUOTE()) {
TS_POP();
USTPUTC(CTLENDVAR, out);
} else {
USTPUTC(c, out);
}
c = pgetc_macro();
continue;
case CLP: /* '(' in arithmetic */
parenlevel++;
USTPUTC(c, out);
continue;;
case CRP: /* ')' in arithmetic */
if (parenlevel > 0) {
USTPUTC(c, out);
--parenlevel;
} else {
if (pgetc() == ')') {
if (--arinest == 0) {
TS_POP();
USTPUTC(CTLENDARI, out);
} else
USTPUTC(')', out);
} else {
/*
* unbalanced parens
* (don't 2nd guess - no error)
*/
pungetc();
USTPUTC(')', out);
}
}
continue;
case CBQUOTE: /* '`' */
out = parsebackq(stack, out, &bqlist, 1);
continue;
case CEOF: /* --> c == PEOF */
break; /* will exit loop */
default:
if (varnest == 0 && !ISDBLQUOTE())
break; /* exit loop */
USTPUTC(c, out);
continue;
}
break; /* break from switch -> break from for loop too */
}
endword:
if (syntax == ARISYNTAX) {
cleanup_state_stack(stack);
synerror("Missing '))'");
@ -1653,13 +1652,14 @@ endword:
/* { */
synerror("Missing '}'");
}
USTPUTC('\0', out);
len = out - stackblock();
out = stackblock();
if (!magicq) {
if ((c == '<' || c == '>')
&& quotef == 0
&& (*out == '\0' || is_number(out))) {
&& quotef == 0 && (*out == '\0' || is_number(out))) {
parseredir(out, c);
cleanup_state_stack(stack);
return lasttoken = TREDIR;
@ -1667,6 +1667,7 @@ endword:
pungetc();
}
}
quoteflag = quotef;
backquotelist = bqlist;
grabstackblock(len);