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: 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 $
@ -2249,6 +2249,7 @@ stdin:
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<'$bar'
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<\$bar
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<-foo
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<"$(echo "foo bar")"
expected-stdout:
sbb
sbb
@ -2257,6 +2258,7 @@ expected-stdout:
$one
$one
-sbb
sbb one
---
name: heredoc-9b
description:

72
lex.c
View File

@ -23,7 +23,7 @@
#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
@ -792,58 +792,59 @@ yylex(int cf)
/* <<, <<-, <<< delimiter */
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
* $ and `...` are not to be treated specially
*/
if (c == '\\') {
c = getsc();
if (c) {
switch (c) {
case '\\':
if ((c = getsc())) {
/* trailing \ is lost */
*wp++ = QCHAR;
*wp++ = c;
}
} else if (c == '$') {
break;
case '$':
if ((c2 = getsc()) == '\'') {
PUSH_STATE(SEQUOTE);
statep->ls_bool = false;
goto sheredelim_quoted;
} else if (c2 == '"')
goto sheredelim_dquoted;
if (0)
/* FALLTHROUGH */
case '\'':
PUSH_STATE(SSQUOTE);
*wp++ = OQUOTE;
ignore_backslash_newline++;
break;
} else if (c2 == '"') {
/* FALLTHROUGH */
case '"':
state = statep->type = SHEREDQUOTE;
PUSH_SRETRACE();
break;
}
ungetsc(c2);
goto sheredelim_regular;
} else if (c == '\'') {
PUSH_STATE(SSQUOTE);
sheredelim_quoted:
*wp++ = OQUOTE;
ignore_backslash_newline++;
} else if (c == '"') {
sheredelim_dquoted:
state = statep->type = SHEREDQUOTE;
*wp++ = OQUOTE;
} else {
sheredelim_regular:
/* FALLTHROUGH */
default:
*wp++ = CHAR;
*wp++ = c;
}
break;
/* " in <<,<<- delimiter */
/* " in <<, <<-, <<< delimiter */
case SHEREDQUOTE:
if (c == '"') {
*wp++ = CQUOTE;
state = statep->type = SHEREDELIM;
} else {
if (c != '"')
goto Subst;
POP_SRETRACE();
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 == '\\') {
switch (c = getsc()) {
case 0:
/* trailing \ is lost */
switch ((c = *dp++)) {
case '\\':
case '"':
case '$':
@ -858,6 +859,9 @@ yylex(int cf)
*wp++ = CHAR;
*wp++ = c;
}
afree(sp, ATEMP);
*wp++ = CQUOTE;
state = statep->type = SHEREDELIM;
break;
/* in *(...|...) pattern (*+?@!) */