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:
54
lex.c
54
lex.c
@@ -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 */
|
||||||
|
Reference in New Issue
Block a user