fix reentry of here documents (LP#1030581)
This commit is contained in:
56
check.t
56
check.t
@ -1,4 +1,4 @@
|
|||||||
# $MirOS: src/bin/mksh/check.t,v 1.551 2012/07/20 23:22:07 tg Exp $
|
# $MirOS: src/bin/mksh/check.t,v 1.552 2012/07/30 19:58:03 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 $
|
||||||
@ -2268,7 +2268,13 @@ stdin:
|
|||||||
=c $x \x40=
|
=c $x \x40=
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
typeset -f foo
|
fnd=$(typeset -f foo)
|
||||||
|
print -r -- "$fnd"
|
||||||
|
function foo {
|
||||||
|
echo blub
|
||||||
|
}
|
||||||
|
foo
|
||||||
|
eval "$fnd"
|
||||||
foo
|
foo
|
||||||
# rather nonsensical, but…
|
# rather nonsensical, but…
|
||||||
vd=<<<"=d $x \x40="
|
vd=<<<"=d $x \x40="
|
||||||
@ -2278,11 +2284,12 @@ stdin:
|
|||||||
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} ve={$ve} vf={$vf} |"
|
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} ve={$ve} vf={$vf} |"
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
function foo {
|
function foo {
|
||||||
vc= <<-EOF
|
vc=<<-EOF
|
||||||
=c $x \x40=
|
=c $x \x40=
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
}
|
}
|
||||||
|
blub
|
||||||
| va={=a u \x40=
|
| va={=a u \x40=
|
||||||
} vb={=b $x \x40=
|
} vb={=b $x \x40=
|
||||||
} vc={=c u \x40=
|
} vc={=c u \x40=
|
||||||
@ -2310,20 +2317,27 @@ stdin:
|
|||||||
=d $x \x40=
|
=d $x \x40=
|
||||||
|
|
||||||
}
|
}
|
||||||
typeset -f foo
|
fnd=$(typeset -f foo)
|
||||||
|
print -r -- "$fnd"
|
||||||
|
function foo {
|
||||||
|
echo blub
|
||||||
|
}
|
||||||
|
foo
|
||||||
|
eval "$fnd"
|
||||||
foo
|
foo
|
||||||
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} |"
|
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} |"
|
||||||
expected-stdout:
|
expected-stdout:
|
||||||
function foo {
|
function foo {
|
||||||
vc= <<-
|
vc=<<-
|
||||||
=c $x \x40=
|
=c $x \x40=
|
||||||
<<
|
<<
|
||||||
|
|
||||||
vd= <<-""
|
vd=<<-""
|
||||||
=d $x \x40=
|
=d $x \x40=
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
blub
|
||||||
| va={=a u \x40=
|
| va={=a u \x40=
|
||||||
} vb={=b $x \x40=
|
} vb={=b $x \x40=
|
||||||
} vc={=c u \x40=
|
} vc={=c u \x40=
|
||||||
@ -8859,7 +8873,7 @@ expected-stdout:
|
|||||||
EOFN
|
EOFN
|
||||||
}
|
}
|
||||||
inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() {
|
inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() {
|
||||||
cat >|bar <<"EOFN"
|
cat >|bar <<"EOFN"
|
||||||
foo
|
foo
|
||||||
EOFN
|
EOFN
|
||||||
|
|
||||||
@ -8870,7 +8884,7 @@ expected-stdout:
|
|||||||
EOFN
|
EOFN
|
||||||
); }
|
); }
|
||||||
function comsub_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
|
function comsub_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
|
||||||
x=$(cat >|bar <<"EOFN"
|
x=$(cat >|bar <<"EOFN"
|
||||||
foo
|
foo
|
||||||
EOFN
|
EOFN
|
||||||
)
|
)
|
||||||
@ -8881,7 +8895,7 @@ expected-stdout:
|
|||||||
EOFN
|
EOFN
|
||||||
)|tr u x); }
|
)|tr u x); }
|
||||||
function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
|
function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
|
||||||
x=$(( cat >|bar <<"EOFN"
|
x=$(( cat >|bar <<"EOFN"
|
||||||
foo
|
foo
|
||||||
EOFN
|
EOFN
|
||||||
) | tr u x )
|
) | tr u x )
|
||||||
@ -8892,7 +8906,7 @@ expected-stdout:
|
|||||||
EOFI
|
EOFI
|
||||||
}
|
}
|
||||||
inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() {
|
inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() {
|
||||||
cat >bar <<-EOFI
|
cat >bar <<-EOFI
|
||||||
foo
|
foo
|
||||||
EOFI
|
EOFI
|
||||||
|
|
||||||
@ -8903,7 +8917,7 @@ expected-stdout:
|
|||||||
EOFI
|
EOFI
|
||||||
); }
|
); }
|
||||||
function comsub_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
|
function comsub_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
|
||||||
x=$(cat >bar <<-EOFI
|
x=$(cat >bar <<-EOFI
|
||||||
foo
|
foo
|
||||||
EOFI
|
EOFI
|
||||||
)
|
)
|
||||||
@ -8914,7 +8928,7 @@ expected-stdout:
|
|||||||
EOFI
|
EOFI
|
||||||
)|tr u x); }
|
)|tr u x); }
|
||||||
function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
|
function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
|
||||||
x=$(( cat >bar <<-EOFI
|
x=$(( cat >bar <<-EOFI
|
||||||
foo
|
foo
|
||||||
EOFI
|
EOFI
|
||||||
) | tr u x )
|
) | tr u x )
|
||||||
@ -9005,7 +9019,7 @@ expected-stdout:
|
|||||||
EOFN); echo $x
|
EOFN); echo $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 )
|
||||||
EOFN
|
EOFN
|
||||||
)
|
)
|
||||||
@ -9017,7 +9031,7 @@ expected-stdout:
|
|||||||
EOFN); echo $x
|
EOFN); echo $x
|
||||||
); }
|
); }
|
||||||
function comsub_heredoc_closed {
|
function comsub_heredoc_closed {
|
||||||
x=$(x=$(cat <<EOFN
|
x=$(x=$(cat <<EOFN
|
||||||
note there must be no space between EOFN and )
|
note there must be no space between EOFN and )
|
||||||
EOFN
|
EOFN
|
||||||
) ; echo $x )
|
) ; echo $x )
|
||||||
@ -9028,7 +9042,7 @@ expected-stdout:
|
|||||||
EOFN); echo $x
|
EOFN); echo $x
|
||||||
)|tr u x); }
|
)|tr u x); }
|
||||||
function reread_heredoc_closed {
|
function reread_heredoc_closed {
|
||||||
x=$(( x=$(cat <<EOFN
|
x=$(( x=$(cat <<EOFN
|
||||||
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 )
|
||||||
@ -9039,7 +9053,7 @@ expected-stdout:
|
|||||||
EOFN ); echo $x
|
EOFN ); echo $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
|
||||||
EOFN
|
EOFN
|
||||||
)
|
)
|
||||||
@ -9051,7 +9065,7 @@ expected-stdout:
|
|||||||
EOFN ); echo $x
|
EOFN ); echo $x
|
||||||
); }
|
); }
|
||||||
function comsub_heredoc_space {
|
function comsub_heredoc_space {
|
||||||
x=$(x=$(cat <<EOFN\
|
x=$(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
|
||||||
EOFN
|
EOFN
|
||||||
) ; echo $x )
|
) ; echo $x )
|
||||||
@ -9062,7 +9076,7 @@ expected-stdout:
|
|||||||
EOFN ); echo $x
|
EOFN ); echo $x
|
||||||
)|tr u x); }
|
)|tr u x); }
|
||||||
function reread_heredoc_space {
|
function reread_heredoc_space {
|
||||||
x=$(( x=$(cat <<EOFN\
|
x=$(( 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
|
||||||
EOFN
|
EOFN
|
||||||
) ; echo $x ) | tr u x )
|
) ; echo $x ) | tr u x )
|
||||||
@ -9085,7 +9099,7 @@ expected-stdout:
|
|||||||
}
|
}
|
||||||
inline_patch_motd() {
|
inline_patch_motd() {
|
||||||
x=$(sysctl -n kern.version | sed 1q )
|
x=$(sysctl -n kern.version | sed 1q )
|
||||||
[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd )" != $x ]] && ed -s /etc/motd 2>&1 <<-EOF
|
[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd )" != $x ]] && ed -s /etc/motd 2>&1 <<-EOF
|
||||||
1,/^\$/d
|
1,/^\$/d
|
||||||
0a
|
0a
|
||||||
$x
|
$x
|
||||||
@ -9117,7 +9131,7 @@ expected-stdout:
|
|||||||
fi
|
fi
|
||||||
); }
|
); }
|
||||||
function comsub_patch_motd {
|
function comsub_patch_motd {
|
||||||
x=$(x=$(sysctl -n kern.version | sed 1q ) ; [[ -s /etc/motd && "$([[ "$(head -1 /etc/motd )" != $x ]] && ed -s /etc/motd 2>&1 <<-EOF
|
x=$(x=$(sysctl -n kern.version | sed 1q ) ; [[ -s /etc/motd && "$([[ "$(head -1 /etc/motd )" != $x ]] && ed -s /etc/motd 2>&1 <<-EOF
|
||||||
1,/^\$/d
|
1,/^\$/d
|
||||||
0a
|
0a
|
||||||
$x
|
$x
|
||||||
@ -9144,7 +9158,7 @@ expected-stdout:
|
|||||||
fi
|
fi
|
||||||
)|tr u x); }
|
)|tr u x); }
|
||||||
function reread_patch_motd {
|
function reread_patch_motd {
|
||||||
x=$(( x=$(sysctl -n kern.version | sed 1q ) ; [[ -s /etc/motd && "$([[ "$(head -1 /etc/motd )" != $x ]] && ed -s /etc/motd 2>&1 <<-EOF
|
x=$(( x=$(sysctl -n kern.version | sed 1q ) ; [[ -s /etc/motd && "$([[ "$(head -1 /etc/motd )" != $x ]] && ed -s /etc/motd 2>&1 <<-EOF
|
||||||
1,/^\$/d
|
1,/^\$/d
|
||||||
0a
|
0a
|
||||||
$x
|
$x
|
||||||
|
30
tree.c
30
tree.c
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.61 2012/06/28 20:17:39 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.62 2012/07/30 19:58:05 tg Exp $");
|
||||||
|
|
||||||
#define INDENT 8
|
#define INDENT 8
|
||||||
|
|
||||||
@ -53,6 +53,25 @@ ptree(struct op *t, int indent, struct shf *shf)
|
|||||||
return;
|
return;
|
||||||
switch (t->type) {
|
switch (t->type) {
|
||||||
case TCOM:
|
case TCOM:
|
||||||
|
prevent_semicolon = false;
|
||||||
|
/*
|
||||||
|
* special-case 'var=<<EOF' (rough; see
|
||||||
|
* exec.c:execute() for full code)
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
/* we have zero arguments, i.e. no programme to run */
|
||||||
|
t->args[0] == NULL &&
|
||||||
|
/* we have exactly one variable assignment */
|
||||||
|
t->vars[0] != NULL && t->vars[1] == NULL &&
|
||||||
|
/* we have exactly one I/O redirection */
|
||||||
|
t->ioact != NULL && t->ioact[0] != NULL &&
|
||||||
|
t->ioact[1] == NULL &&
|
||||||
|
/* of type "here document" (or "here string") */
|
||||||
|
(t->ioact[0]->flag & IOTYPE) == IOHERE) {
|
||||||
|
fptreef(shf, indent, "%S", t->vars[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (t->vars) {
|
if (t->vars) {
|
||||||
w = (const char **)t->vars;
|
w = (const char **)t->vars;
|
||||||
while (*w)
|
while (*w)
|
||||||
@ -65,7 +84,6 @@ ptree(struct op *t, int indent, struct shf *shf)
|
|||||||
fptreef(shf, indent, "%S ", *w++);
|
fptreef(shf, indent, "%S ", *w++);
|
||||||
} else
|
} else
|
||||||
shf_puts("#no-args# ", shf);
|
shf_puts("#no-args# ", shf);
|
||||||
prevent_semicolon = false;
|
|
||||||
break;
|
break;
|
||||||
case TEXEC:
|
case TEXEC:
|
||||||
t = t->left;
|
t = t->left;
|
||||||
@ -216,8 +234,10 @@ ptree(struct op *t, int indent, struct shf *shf)
|
|||||||
* often leads to an extra blank line, but it's not
|
* often leads to an extra blank line, but it's not
|
||||||
* worth worrying about)
|
* worth worrying about)
|
||||||
*/
|
*/
|
||||||
if (need_nl)
|
if (need_nl) {
|
||||||
shf_putc('\n', shf);
|
shf_putc('\n', shf);
|
||||||
|
prevent_semicolon = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,8 +278,8 @@ pioact(struct shf *shf, int indent, struct ioword *iop)
|
|||||||
/* name/delim are NULL when printing syntax errors */
|
/* name/delim are NULL when printing syntax errors */
|
||||||
if (type == IOHERE) {
|
if (type == IOHERE) {
|
||||||
if (iop->delim)
|
if (iop->delim)
|
||||||
fptreef(shf, indent, "%S ", iop->delim);
|
wdvarput(shf, iop->delim, 0, WDS_TPUTS);
|
||||||
else
|
if (iop->flag & IOHERESTR)
|
||||||
shf_putc(' ', shf);
|
shf_putc(' ', shf);
|
||||||
} else if (iop->name)
|
} else if (iop->name)
|
||||||
fptreef(shf, indent, (iop->flag & IONAMEXP) ? "%s " : "%S ",
|
fptreef(shf, indent, (iop->flag & IONAMEXP) ? "%s " : "%S ",
|
||||||
|
Reference in New Issue
Block a user