use the full parser code for handling here strings (and here document words)

as ormaaj requested, including a testcase
This commit is contained in:
tg
2013-01-19 18:32:56 +00:00
parent 72402c4990
commit e307cb34c4
2 changed files with 41 additions and 35 deletions

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.586 2013/01/06 18:51:39 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.587 2013/01/19 18:32:54 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -2249,6 +2249,7 @@ stdin:
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<'$bar' tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<'$bar'
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<\$bar tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<\$bar
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<-foo tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<-foo
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<"$(echo "foo bar")"
expected-stdout: expected-stdout:
sbb sbb
sbb sbb
@ -2257,6 +2258,7 @@ expected-stdout:
$one $one
$one $one
-sbb -sbb
sbb one
--- ---
name: heredoc-9b name: heredoc-9b
description: description:

66
lex.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.176 2013/01/19 17:49:46 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.177 2013/01/19 18:32:56 tg Exp $");
/* /*
* states while lexing word * states while lexing word
@ -792,58 +792,59 @@ yylex(int cf)
/* <<, <<-, <<< delimiter */ /* <<, <<-, <<< delimiter */
case SHEREDELIM: case SHEREDELIM:
/*
* XXX chuck this state (and the next) - use
* the existing states ($ and \`...` should be
* stripped of their specialness after the
* fact).
*/
/* /*
* here delimiters need a special case since * here delimiters need a special case since
* $ and `...` are not to be treated specially * $ and `...` are not to be treated specially
*/ */
if (c == '\\') { switch (c) {
c = getsc(); case '\\':
if (c) { if ((c = getsc())) {
/* trailing \ is lost */ /* trailing \ is lost */
*wp++ = QCHAR; *wp++ = QCHAR;
*wp++ = c; *wp++ = c;
} }
} else if (c == '$') { break;
case '$':
if ((c2 = getsc()) == '\'') { if ((c2 = getsc()) == '\'') {
PUSH_STATE(SEQUOTE); PUSH_STATE(SEQUOTE);
statep->ls_bool = false; statep->ls_bool = false;
goto sheredelim_quoted; if (0)
} else if (c2 == '"') /* FALLTHROUGH */
goto sheredelim_dquoted; case '\'':
ungetsc(c2);
goto sheredelim_regular;
} else if (c == '\'') {
PUSH_STATE(SSQUOTE); PUSH_STATE(SSQUOTE);
sheredelim_quoted:
*wp++ = OQUOTE; *wp++ = OQUOTE;
ignore_backslash_newline++; ignore_backslash_newline++;
} else if (c == '"') { break;
sheredelim_dquoted: } else if (c2 == '"') {
/* FALLTHROUGH */
case '"':
state = statep->type = SHEREDQUOTE; state = statep->type = SHEREDQUOTE;
*wp++ = OQUOTE; PUSH_SRETRACE();
} else { break;
sheredelim_regular: }
ungetsc(c2);
/* FALLTHROUGH */
default:
*wp++ = CHAR; *wp++ = CHAR;
*wp++ = c; *wp++ = c;
} }
break; break;
/* " in <<,<<- delimiter */ /* " in <<, <<-, <<< delimiter */
case SHEREDQUOTE: case SHEREDQUOTE:
if (c == '"') { if (c != '"')
*wp++ = CQUOTE; goto Subst;
state = statep->type = SHEREDELIM; POP_SRETRACE();
} else { dp = strnul(sp) - 1;
/* remove the trailing double quote */
*dp = '\0';
/* store the quoted string */
*wp++ = OQUOTE;
XcheckN(ws, wp, (dp - sp));
dp = sp;
while ((c = *dp++)) {
if (c == '\\') { if (c == '\\') {
switch (c = getsc()) { switch ((c = *dp++)) {
case 0:
/* trailing \ is lost */
case '\\': case '\\':
case '"': case '"':
case '$': case '$':
@ -858,6 +859,9 @@ yylex(int cf)
*wp++ = CHAR; *wp++ = CHAR;
*wp++ = c; *wp++ = c;
} }
afree(sp, ATEMP);
*wp++ = CQUOTE;
state = statep->type = SHEREDELIM;
break; break;
/* in *(...|...) pattern (*+?@!) */ /* in *(...|...) pattern (*+?@!) */