I thought of making COMSUB pass a pointer to the struct op *t->left around

instead, but the parser for the so-called “backticks” (U+0060) still emits
plaintext COMSUB wdstrings, and the evaluation code emits plaintext if the
code is not run (‘-n’ option), so it’s not worth the effort and memory ma-
nagement issues, even though it _would_ optimise the most common case…

Bump version numbers, sync regression tests; add one testcase from the old
webpages too. Sync manpage, this now works, but keep the workaround in, as
“portability issue” with slightly changed wording.

Also, /bin/sleep must be used in one manpage example if sleep is built in.
This commit is contained in:
tg 2011-03-06 01:50:11 +00:00
parent 25905b91a7
commit c995f7ca98
3 changed files with 48 additions and 42 deletions

36
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.413 2011/02/27 19:41:17 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.414 2011/03/06 01:50:08 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 $
@ -25,7 +25,7 @@
# http://www.research.att.com/~gsf/public/ifs.sh
expected-stdout:
@(#)MIRBSD KSH R39 2011/02/18
@(#)MIRBSD KSH R39 2011/03/05
description:
Check version of shell.
stdin:
@ -6933,11 +6933,10 @@ expected-stdout:
---
name: comsub-1
description:
COMSUB are currently parsed by hacking lex.c instead of
recursively (see regression-6): matching parenthesēs bug
Fails on: pdksh mksh bash2 bash3 zsh
Passes on: bash4 ksh93
expected-fail: yes
COMSUB are now parsed recursively, so this works
see also regression-6: matching parenthesēs bug
Fails on: pdksh bash2 bash3 zsh
Passes on: bash4 ksh93 mksh(20110305+)
stdin:
echo $(case 1 in (1) echo yes;; (2) echo no;; esac)
echo $(case 1 in 1) echo yes;; 2) echo no;; esac)
@ -6949,10 +6948,9 @@ name: comsub-2
description:
RedHat BZ#496791 another case of missing recursion
in parsing COMSUB expressions
Fails on: pdksh mksh bash2 bash3¹ bash4¹ zsh
Passes on: ksh93
Fails on: pdksh bash2 bash3¹ bash4¹ zsh
Passes on: ksh93 mksh(20110305+)
bash[34] seem to choke on comment ending with backslash-newline
expected-fail: yes
stdin:
# a comment with " ' \
x=$(
@ -6963,6 +6961,24 @@ stdin:
expected-stdout:
yes
---
name: comsub-3
description:
Extended test for COMSUB explaining why a recursive parser
is a must (a non-recursive parser cannot pass all three of
these test cases, especially the # is difficult)
stdin:
echo $(typeset -i10 x=16#20; echo $x)
echo $(typeset -Uui16 x=16#$(id -u)
) .
echo $(c=1; d=1
typeset -Uui16 a=36#foo; c=2
typeset -Uui16 b=36 #foo; d=2
echo $a $b $c $d)
expected-stdout:
32
.
16#4F68 16#24 2 1
---
name: test-stnze-1
description:
Check that the short form [ $x ] works

50
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.251 2011/02/18 22:26:11 tg Exp $
.\" $MirOS: src/bin/mksh/mksh.1,v 1.252 2011/03/06 01:50:09 tg Exp $
.\" $OpenBSD: ksh.1,v 1.138 2010/09/20 07:41:17 jmc Exp $
.\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
@ -72,7 +72,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always.
.\"
.Dd $Mdocdate: February 18 2011 $
.Dd $Mdocdate: March 6 2011 $
.\"
.\" Check which macro package we use
.\"
@ -1238,12 +1238,23 @@ Note that
has the same effect as
.Ic $(cat foo) .
.Pp
.Sy Note :
.Pf $( Ns Ar command Ns \&)
expressions are currently parsed by finding matching parentheses,
regardless of quoting; comments containing quote characters are
not handled correctly.
This should be fixed soon.
Note that some shells do not use a recursive parser for command substitutions,
leading to failure for certain constructs; to be portable, use as workaround
.Ql x=$(cat) \*(Lt\*(Lt"EOF"
(or the newline-keeping
.Ql x=\*(Lt\*(Lt"EOF"
extension) instead to merely slurp the string.
.St -p1003.1
recommends to use case statements of the form
.Ql "x=$(case $foo in (bar) echo $bar ;; (*) echo $baz ;; esac)"
instead, which would work but not serve as example for this portability issue.
.Bd -literal -offset indent
x=$(case $foo in bar) echo $bar ;; *) echo $baz ;; esac)
# above fails to parse on old shells; below is the workaround
x=$(eval $(cat)) \*(Lt\*(Lt"EOF"
case $foo in bar) echo $bar ;; *) echo $baz ;; esac
EOF
.Ed
.Pp
Arithmetic substitutions are replaced by the value of the specified expression.
For example, the command
@ -6107,28 +6118,7 @@ the currently running part of the pipeline; in this example,
is immediately printed on suspension (but not later after an
.Ic fg ) .
.Bd -literal -offset indent
$ sleep 666 && echo fubar
.Ed
.Pp
Some parts of the parser are not recursive; the following
code fails because of the parenthesis asymmetry
.Pq RedHat BZ#496791 .
A workaround exists; use
.Ql x=$(cat) \*(Lt\*(Lt"EOF"
or the newline-keeping
.Ql x=\*(Lt\*(Lt"EOF"
instead to merely slurp the string.
Of course, in this case, the form
.Ql x=$(case $foo in (bar) ...
actually recommended by
.St -p1003.1
would work as well, but we use it as an example of this parser bug.
.Bd -literal -offset indent
x=$(case $foo in bar) echo $bar ;; *) echo $baz ;; esac)
# above fails to parse; below is the workaround
x=$(eval $(cat)) \*(Lt\*(Lt"EOF"
case $foo in bar) echo $bar ;; *) echo $baz ;; esac
EOF
$ /bin/sleep 666 && echo fubar
.Ed
.Pp
This document attempts to describe

4
sh.h
View File

@ -154,9 +154,9 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.436 2011/03/06 01:25:33 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.437 2011/03/06 01:50:11 tg Exp $");
#endif
#define MKSH_VERSION "R39 2011/02/18"
#define MKSH_VERSION "R39 2011/03/05"
#ifndef MKSH_INCLUDES_ONLY