From e307cb34c407937198a990502802c922a7163abd Mon Sep 17 00:00:00 2001 From: tg Date: Sat, 19 Jan 2013 18:32:56 +0000 Subject: [PATCH] use the full parser code for handling here strings (and here document words) as ormaaj requested, including a testcase --- check.t | 4 +++- lex.c | 72 ++++++++++++++++++++++++++++++--------------------------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/check.t b/check.t index 9db82d0..c4ca7d6 100644 --- a/check.t +++ b/check.t @@ -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: diff --git a/lex.c b/lex.c index ce5913c..81ade90 100644 --- a/lex.c +++ b/lex.c @@ -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 (*+?@!) */