fix tree printing multiple heredocs in one command, bug found by izabera

This commit is contained in:
tg
2015-09-05 20:20:48 +00:00
parent 4adcfe8b58
commit edc2acd61d
4 changed files with 76 additions and 29 deletions

84
check.t
View File

@ -1,9 +1,9 @@
# $MirOS: src/bin/mksh/check.t,v 1.705 2015/08/13 22:06:19 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.706 2015/09/05 20:20:42 tg Exp $
# -*- mode: sh -*- # -*- mode: sh -*-
#- #-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015 # 2011, 2012, 2013, 2014, 2015
# Thorsten Glaser <tg@mirbsd.org> # mirabilos <tg@mirbsd.org>
# #
# Provided that these terms and disclaimer and all copyright notices # Provided that these terms and disclaimer and all copyright notices
# are retained or reproduced in an accompanying document, permission # are retained or reproduced in an accompanying document, permission
@ -30,7 +30,7 @@
# (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date # (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R51 2015/08/13 @(#)MIRBSD KSH R51 2015/09/05
description: description:
Check version of shell. Check version of shell.
stdin: stdin:
@ -39,7 +39,7 @@ name: KSH_VERSION
category: shell:legacy-no category: shell:legacy-no
--- ---
expected-stdout: expected-stdout:
@(#)LEGACY KSH R51 2015/08/13 @(#)LEGACY KSH R51 2015/09/05
description: description:
Check version of legacy shell. Check version of legacy shell.
stdin: stdin:
@ -2423,7 +2423,7 @@ stdin:
print -r -- "| ${v//$'\n'/^} |" print -r -- "| ${v//$'\n'/^} |"
expected-stdout: expected-stdout:
function foo { function foo {
vc=<<-EOF vc=<<-EOF
=c $x \x40= =c $x \x40=
EOF EOF
@ -2476,11 +2476,11 @@ stdin:
print -r -- "| ${v//$'\n'/^} |" print -r -- "| ${v//$'\n'/^} |"
expected-stdout: expected-stdout:
function foo { function foo {
vc=<<- vc=<<-
=c $x \x40= =c $x \x40=
<< <<
vd=<<-"" vd=<<-""
=d $x \x40= =d $x \x40=
@ -2538,6 +2538,46 @@ expected-stdout:
3 baz a b baz 3 baz a b baz
3 bla "a b" bla 3 bla "a b" bla
--- ---
name: heredoc-14
description:
Check that using multiple here documents works
stdin:
foo() {
echo "got $(cat) on stdin"
echo "got $(cat <&4) on fd#4"
echo "got $(cat <&5) on fd#5"
}
bar() {
foo 4<<-a <<-b 5<<-c
four
a
zero
b
five
c
}
x=$(typeset -f bar)
eval "$x"
y=$(typeset -f bar)
[[ $x = "$y" ]]; echo $?
typeset -f bar
bar
expected-stdout:
0
bar() {
foo 4<<-a <<-b 5<<-c
four
a
zero
b
five
c
}
got zero on stdin
got four on fd#4
got five on fd#5
---
name: heredoc-comsub-1 name: heredoc-comsub-1
description: description:
Tests for here documents in COMSUB, taken from Austin ML Tests for here documents in COMSUB, taken from Austin ML
@ -10566,7 +10606,7 @@ expected-stdout:
)|tr u x); } )|tr u x); }
function reread_IOREAD_IOCAT { function reread_IOREAD_IOCAT {
x=$(( tr x u <foo >>bar ) | tr u x ) x=$(( tr x u <foo >>bar ) | tr u x )
} }
inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() { inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() {
cat >|bar <<'EOFN' cat >|bar <<'EOFN'
foo foo
@ -10577,7 +10617,7 @@ expected-stdout:
foo foo
EOFN EOFN
} }
function comsub_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$( function comsub_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$(
cat >|bar <<'EOFN' cat >|bar <<'EOFN'
foo foo
@ -10588,7 +10628,7 @@ expected-stdout:
foo foo
EOFN EOFN
) )
} }
function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$(( function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$((
cat >|bar <<'EOFN' cat >|bar <<'EOFN'
foo foo
@ -10599,7 +10639,7 @@ expected-stdout:
foo foo
EOFN EOFN
) | tr u x ) ) | tr u x )
} }
inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() { inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() {
cat 1>bar <<-EOFI cat 1>bar <<-EOFI
foo foo
@ -10610,7 +10650,7 @@ expected-stdout:
foo foo
EOFI EOFI
} }
function comsub_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$( function comsub_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$(
cat 1>bar <<-EOFI cat 1>bar <<-EOFI
foo foo
@ -10621,7 +10661,7 @@ expected-stdout:
foo foo
EOFI EOFI
) )
} }
function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$(( function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$((
cat 1>bar <<-EOFI cat 1>bar <<-EOFI
foo foo
@ -10712,7 +10752,7 @@ expected-stdout:
)|tr u x); } )|tr u x); }
function reread_OSUBST_CSUBST_OPAT_SPAT_CPAT { function reread_OSUBST_CSUBST_OPAT_SPAT_CPAT {
x=$(( [[ ${foo#bl\(u\)b} = @(bar|baz) ]] ) | tr u x ) x=$(( [[ ${foo#bl\(u\)b} = @(bar|baz) ]] ) | tr u x )
} }
inline_heredoc_closed() { inline_heredoc_closed() {
x=$(cat <<EOFN x=$(cat <<EOFN
note there must be no space between EOFN and ) note there must be no space between EOFN and )
@ -10724,7 +10764,7 @@ expected-stdout:
EOFN EOFN
) )
echo $x echo $x
} }
function comsub_heredoc_closed { x=$( function comsub_heredoc_closed { x=$(
x=$(cat <<EOFN x=$(cat <<EOFN
note there must be no space between EOFN and ) note there must be no space between EOFN and )
@ -10735,7 +10775,7 @@ expected-stdout:
note there must be no space between EOFN and ) note there must be no space between EOFN and )
EOFN EOFN
) ; echo $x ) ) ; echo $x )
} }
function reread_heredoc_closed { x=$(( function reread_heredoc_closed { x=$((
x=$(cat <<EOFN x=$(cat <<EOFN
note there must be no space between EOFN and ) note there must be no space between EOFN and )
@ -10746,7 +10786,7 @@ expected-stdout:
note there must be no space between EOFN and ) note there must be no space between EOFN and )
EOFN EOFN
) ; echo $x ) | tr u x ) ) ; echo $x ) | tr u x )
} }
inline_heredoc_space() { inline_heredoc_space() {
x=$(cat <<EOFN\ x=$(cat <<EOFN\
note the space between EOFN and ) is actually part of the here document marker note the space between EOFN and ) is actually part of the here document marker
@ -10758,7 +10798,7 @@ expected-stdout:
EOFN EOFN
) )
echo $x echo $x
} }
function comsub_heredoc_space { x=$( function comsub_heredoc_space { x=$(
x=$(cat <<EOFN\ x=$(cat <<EOFN\
note the space between EOFN and ) is actually part of the here document marker note the space between EOFN and ) is actually part of the here document marker
@ -10769,7 +10809,7 @@ expected-stdout:
note the space between EOFN and ) is actually part of the here document marker note the space between EOFN and ) is actually part of the here document marker
EOFN EOFN
) ; echo $x ) ) ; echo $x )
} }
function reread_heredoc_space { x=$(( function reread_heredoc_space { x=$((
x=$(cat <<EOFN\ x=$(cat <<EOFN\
note the space between EOFN and ) is actually part of the here document marker note the space between EOFN and ) is actually part of the here document marker
@ -10792,7 +10832,7 @@ expected-stdout:
. .
wq wq
EOF)" = @(?) ]] && rm -f /etc/motd EOF)" = @(?) ]] && rm -f /etc/motd
if [[ ! -s /etc/motd ]]; then if [[ ! -s /etc/motd ]]; then
install -c -o root -g wheel -m 664 /dev/null /etc/motd install -c -o root -g wheel -m 664 /dev/null /etc/motd
print -- "$x\n" >/etc/motd print -- "$x\n" >/etc/motd
fi fi
@ -10824,7 +10864,7 @@ expected-stdout:
. .
wq wq
EOF)" = @(?) ]] && rm -f /etc/motd EOF)" = @(?) ]] && rm -f /etc/motd
if [[ ! -s /etc/motd ]]; then if [[ ! -s /etc/motd ]]; then
install -c -o root -g wheel -m 664 /dev/null /etc/motd install -c -o root -g wheel -m 664 /dev/null /etc/motd
print -- "$x\n" >/etc/motd print -- "$x\n" >/etc/motd
@ -10851,7 +10891,7 @@ expected-stdout:
. .
wq wq
EOF)" = @(?) ]] && rm -f /etc/motd EOF)" = @(?) ]] && rm -f /etc/motd
if [[ ! -s /etc/motd ]]; then if [[ ! -s /etc/motd ]]; then
install -c -o root -g wheel -m 664 /dev/null /etc/motd install -c -o root -g wheel -m 664 /dev/null /etc/motd
print -- "$x\n" >/etc/motd print -- "$x\n" >/etc/motd

10
lex.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.206 2015/09/05 19:19:06 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.207 2015/09/05 20:20:46 tg Exp $");
/* /*
* states while lexing word * states while lexing word
@ -946,6 +946,14 @@ yylex(int cf)
c2 = getsc(); c2 = getsc();
} else if (c2 == '<') } else if (c2 == '<')
iop->ioflag |= IOHERESTR; iop->ioflag |= IOHERESTR;
if (c2 == ' ') {
/*XXX reentrancy hack IONDELIM */
c2 = getsc();
if (c2 != '\n') {
ungetsc(c2);
c2 = ' ';
}
}
ungetsc(c2); ungetsc(c2);
if (c2 == '\n') if (c2 == '\n')
iop->ioflag |= IONDELIM; iop->ioflag |= IONDELIM;

4
sh.h
View File

@ -172,9 +172,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.742 2015/09/05 19:19:10 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.743 2015/09/05 20:20:46 tg Exp $");
#endif #endif
#define MKSH_VERSION "R51 2015/08/13" #define MKSH_VERSION "R51 2015/09/05"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES

7
tree.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.75 2015/09/05 19:19:11 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/tree.c,v 1.76 2015/09/05 20:20:48 tg Exp $");
#define INDENT 8 #define INDENT 8
@ -285,15 +285,14 @@ pioact(struct shf *shf, struct ioword *iop)
if (type == IOHERE) { if (type == IOHERE) {
if (iop->delim) if (iop->delim)
wdvarput(shf, iop->delim, 0, WDS_TPUTS); wdvarput(shf, iop->delim, 0, WDS_TPUTS);
if (flag & IOHERESTR) /*XXX see IONDELIM hack */
shf_putc(' ', shf);
} else if (iop->name) { } else if (iop->name) {
if (flag & IONAMEXP) if (flag & IONAMEXP)
print_value_quoted(shf, iop->name); print_value_quoted(shf, iop->name);
else else
wdvarput(shf, iop->name, 0, WDS_TPUTS); wdvarput(shf, iop->name, 0, WDS_TPUTS);
shf_putc(' ', shf);
} }
shf_putc(' ', shf);
prevent_semicolon = false; prevent_semicolon = false;
} }