use a different approach to the $"…" problem:

take the states that may open a string, only permit them by virtue of
moving the code out of Subst: to handle $+" and $+' at all; then add
S[Q]BRACE to that

side benefits:
• clearer, cleaner code flow
• smaller code
• better “business logic” ☺
• defuses one heavy use of duff’s device a bit
This commit is contained in:
tg
2013-02-17 06:05:02 +00:00
parent b684a7c6bd
commit e21a2166f7

54
lex.c
View File

@@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.180 2013/02/17 05:40:16 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.181 2013/02/17 06:05:02 tg Exp $");
/* /*
* states while lexing word * states while lexing word
@@ -348,6 +348,22 @@ yylex(int cf)
*wp++ = OQUOTE; *wp++ = OQUOTE;
PUSH_STATE(SDQUOTE); PUSH_STATE(SDQUOTE);
break; break;
case '$':
/*
* processing of dollar sign belongs into
* Subst, except for those which can open
* a string: $'…' and $"…"
*/
subst_dollar_ex:
c = getsc();
switch (c) {
case '"':
goto open_sdquote;
case '\'':
goto open_sequote;
default:
goto SubstS;
}
default: default:
goto Subst; goto Subst;
} }
@@ -382,8 +398,8 @@ yylex(int cf)
} }
break; break;
case '$': case '$':
subst_dollar:
c = getsc(); c = getsc();
SubstS:
if (c == '(') /*)*/ { if (c == '(') /*)*/ {
c = getsc(); c = getsc();
if (c == '(') /*)*/ { if (c == '(') /*)*/ {
@@ -504,30 +520,9 @@ yylex(int cf)
*wp++ = '\0'; *wp++ = '\0';
*wp++ = CSUBST; *wp++ = CSUBST;
*wp++ = 'X'; *wp++ = 'X';
} else if (c == '\'' || c == '"') {
switch (state) {
/*
* states in which $'…'/$"…" are
* invalid; still not too sure about
* which must be included/excluded…
*/
case SWORD:
case SDQUOTE:
goto DNQUOTE;
}
if (c == '"')
goto DEQUOTE;
/* c == '\'' */
*wp++ = OQUOTE;
ignore_backslash_newline++;
PUSH_STATE(SEQUOTE);
statep->ls_bool = false;
break;
} else { } else {
DNQUOTE:
*wp++ = CHAR; *wp++ = CHAR;
*wp++ = '$'; *wp++ = '$';
DEQUOTE:
ungetsc(c); ungetsc(c);
} }
break; break;
@@ -705,7 +700,7 @@ yylex(int cf)
if (c == '"') if (c == '"')
goto open_sdquote; goto open_sdquote;
else if (c == '$') else if (c == '$')
goto subst_dollar; goto subst_dollar_ex;
else if (c == '`') else if (c == '`')
goto subst_gravis; goto subst_gravis;
else if (c != /*{*/ '}') else if (c != /*{*/ '}')
@@ -816,16 +811,15 @@ yylex(int cf)
*wp++ = c; *wp++ = c;
} }
break; break;
case '\'':
goto open_ssquote;
case '$': case '$':
if ((c2 = getsc()) == '\'') { if ((c2 = getsc()) == '\'') {
PUSH_STATE(SEQUOTE); open_sequote:
statep->ls_bool = false;
if (0)
/* FALLTHROUGH */
case '\'':
PUSH_STATE(SSQUOTE);
*wp++ = OQUOTE; *wp++ = OQUOTE;
ignore_backslash_newline++; ignore_backslash_newline++;
PUSH_STATE(SEQUOTE);
statep->ls_bool = false;
break; break;
} else if (c2 == '"') { } else if (c2 == '"') {
/* FALLTHROUGH */ /* FALLTHROUGH */