diff options
author | jilles <jilles@FreeBSD.org> | 2011-05-20 16:03:36 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2011-05-20 16:03:36 +0000 |
commit | 343e29c6261eb1e038805e04b47f83ff8e6f90c8 (patch) | |
tree | d36d4f985b72c55479a85a920658c3ee1fdf0b01 | |
parent | 4037bb644a26c751349e8cb47049a4f571047956 (diff) | |
download | FreeBSD-src-343e29c6261eb1e038805e04b47f83ff8e6f90c8.zip FreeBSD-src-343e29c6261eb1e038805e04b47f83ff8e6f90c8.tar.gz |
sh: Allow terminating a heredoc with a terminator at EOF without a newline.
This is sometimes used with eval or old-style command substitution, and most
shells other than ash derivatives allow it.
It can also be used with scripts that violate POSIX's requirement on the
application that they end in a newline (scripts must be text files except
that line length is unlimited).
Example:
v=`cat <<EOF
foo
EOF`
echo $v
This commit does not add support for the similar construct with new-style
command substitution, like
v=$(cat <<EOF
foo
EOF)
This continues to require a newline after the terminator.
-rw-r--r-- | bin/sh/parser.c | 8 | ||||
-rw-r--r-- | tools/regression/bin/sh/parser/heredoc11.0 | 26 |
2 files changed, 31 insertions, 3 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c index cc1860d..192769b 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -1513,10 +1513,12 @@ checkend: { p = line; for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); - if (*p == '\n' && *q == '\0') { + if ((*p == '\0' || *p == '\n') && *q == '\0') { c = PEOF; - plinno++; - needprompt = doprompt; + if (*p == '\n') { + plinno++; + needprompt = doprompt; + } } else { pushstring(line, strlen(line), NULL); } diff --git a/tools/regression/bin/sh/parser/heredoc11.0 b/tools/regression/bin/sh/parser/heredoc11.0 new file mode 100644 index 0000000..5839e46 --- /dev/null +++ b/tools/regression/bin/sh/parser/heredoc11.0 @@ -0,0 +1,26 @@ +# $FreeBSD$ + +failures='' + +check() { + if eval "[ $* ]"; then + : + else + echo "Failed: $*" + failures=x$failures + fi +} + +check '`cat <<EOF +foo +EOF` = foo' + +check '"`cat <<EOF +foo +EOF`" = foo' + +check '`eval "cat <<EOF +foo +EOF"` = foo' + +test "x$failures" = x |