Merge remote-tracking branch 'mksh/master'

This commit is contained in:
KO Myung-Hun 2015-12-13 17:59:43 +09:00
commit 0c41f2fdc8
22 changed files with 488 additions and 353 deletions

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.691 2015/10/05 17:58:55 tg Exp $' srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.693 2015/12/12 22:25:10 tg Exp $'
#- #-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015 # 2011, 2012, 2013, 2014, 2015
@ -100,6 +100,7 @@ do_genopt() {
srcfile=$1 srcfile=$1
test -f "$srcfile" || genopt_die Source file \$srcfile not set. test -f "$srcfile" || genopt_die Source file \$srcfile not set.
bn=`basename "$srcfile" | sed 's/.opt$//'` bn=`basename "$srcfile" | sed 's/.opt$//'`
o_hdr='/* +++ GENERATED FILE +++ DO NOT EDIT +++ */'
o_gen= o_gen=
o_str= o_str=
o_sym= o_sym=
@ -128,6 +129,9 @@ do_genopt() {
;; ;;
*:@@*) *:@@*)
genopt_die ;; genopt_die ;;
0:/\*-|0:\ \**|0:)
o_hdr=$o_hdr$nl$line
;;
0:@*|1:@*) 0:@*|1:@*)
# begin of a definition block # begin of a definition block
sym=`echo "$line" | sed 's/^@//'` sym=`echo "$line" | sed 's/^@//'`
@ -177,6 +181,7 @@ do_genopt() {
echo "\"$opts\"" echo "\"$opts\""
test -n "$cond" && echo "#endif" test -n "$cond" && echo "#endif"
done | { done | {
echo "$o_hdr"
echo "#ifndef $o_sym$o_gen" echo "#ifndef $o_sym$o_gen"
echo "#else" echo "#else"
cat cat
@ -1197,7 +1202,7 @@ tcc)
;; ;;
tendra) tendra)
vv '|' "$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN $LIBS -V 2>&1 | \ vv '|' "$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN $LIBS -V 2>&1 | \
fgrep -i -e version -e release" grep -F -i -e version -e release"
;; ;;
ucode) ucode)
vv '|' "$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN $LIBS -V" vv '|' "$CC $CFLAGS $CPPFLAGS $LDFLAGS $NOWARN $LIBS -V"
@ -2339,7 +2344,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c
addsrcs USE_PRINTF_BUILTIN printf.c addsrcs USE_PRINTF_BUILTIN printf.c
test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose" test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
add_cppflags -DMKSH_BUILD_R=511 add_cppflags -DMKSH_BUILD_R=521
$e $bi$me: Finished configuration testing, now producing output.$ao $e $bi$me: Finished configuration testing, now producing output.$ao
@ -2411,7 +2416,7 @@ cat >test.sh <<-EOF
args[\${#args[*]}]=\$TMPDIR args[\${#args[*]}]=\$TMPDIR
fi fi
print Testing mksh for conformance: print Testing mksh for conformance:
fgrep -e Mir''OS: -e MIRBSD "\$sflag" grep -F -e Mir''OS: -e MIRBSD "\$sflag"
print "This shell is actually:\\n\\t\$KSH_VERSION" print "This shell is actually:\\n\\t\$KSH_VERSION"
print 'test.sh built for mksh $dstversion' print 'test.sh built for mksh $dstversion'
cstr='\$os = defined \$^O ? \$^O : "unknown";' cstr='\$os = defined \$^O ? \$^O : "unknown";'

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/Makefile,v 1.144 2015/10/05 17:58:56 tg Exp $ # $MirOS: src/bin/mksh/Makefile,v 1.145 2015/12/12 22:25:11 tg Exp $
#- #-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015 # 2011, 2012, 2013, 2014, 2015
@ -57,7 +57,7 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \
-DHAVE_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \ -DHAVE_SETGROUPS=1 -DHAVE_STRERROR=0 -DHAVE_STRSIGNAL=0 \
-DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \ -DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \
-DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \ -DHAVE_SYS_ERRLIST_DECL=1 -DHAVE_SYS_SIGLIST_DECL=1 \
-DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=511 -DHAVE_PERSISTENT_HISTORY=1 -DMKSH_BUILD_R=521
CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U} CPPFLAGS+= -D${${PROG:L}_tf:C/(Mir${MAN:E}{0,1}){2}/4/:S/x/mksh_BUILD/:U}
CPPFLAGS+= -I. CPPFLAGS+= -I.
COPTS+= -std=c89 -Wall COPTS+= -std=c89 -Wall

View File

@ -1,9 +1,9 @@
# $MirOS: src/bin/mksh/check.pl,v 1.41 2015/09/05 19:19:01 tg Exp $ # $MirOS: src/bin/mksh/check.pl,v 1.42 2015/11/29 17:05:00 tg Exp $
# $OpenBSD: th,v 1.1 2013/12/02 20:39:44 millert Exp $ # $OpenBSD: th,v 1.1 2013/12/02 20:39:44 millert Exp $
#- #-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
# 2012, 2013, 2014, 2015 # 2012, 2013, 2014, 2015
# mirabilos <tg@mirbsd.org> # mirabilos <m@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

489
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.712 2015/10/24 19:46:07 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.716 2015/12/12 23:31:15 tg Exp $
# -*- mode: sh -*- # -*- mode: sh -*-
#- #-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@ -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/10/24 @(#)MIRBSD KSH R52 2015/12/12
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/10/24 @(#)LEGACY KSH R52 2015/12/12
description: description:
Check version of legacy shell. Check version of legacy shell.
stdin: stdin:
@ -270,6 +270,14 @@ stdin:
expected-stdout: expected-stdout:
bar - baz,z bar - baz,z
--- ---
name: arith-compound
description:
Check that arithmetic expressions are compound constructs
stdin:
{ ! (( 0$(cat >&2) )) <<<1; } <<<2
expected-stderr:
1
---
name: arith-lazy-1 name: arith-lazy-1
description: description:
Check that only one side of ternary operator is evaluated Check that only one side of ternary operator is evaluated
@ -1668,6 +1676,17 @@ expected-stdout:
1=02. 1=02.
2=02. 2=02.
--- ---
name: expand-weird-4
description:
Check that tilde expansion is enabled in ${x#~}
and cases that are modelled after it (${x/~/~})
stdin:
HOME=/etc
a="~/x"
echo "<${a#~}> <${a#\~}> <${b:-~}> <${b:-\~}> <${c:=~}><$c> <${a/~}> <${a/x/~}> <${a/x/\~}>"
expected-stdout:
<~/x> </x> <~> <\~> <~><~> <~/x> <~//etc> <~/~>
---
name: expand-number-1 name: expand-number-1
description: description:
Check that positional arguments do not overflow Check that positional arguments do not overflow
@ -1861,13 +1880,15 @@ stdin:
echo 20: ${x/\//.} echo 20: ${x/\//.}
echo 21: ${x//\//.} echo 21: ${x//\//.}
echo 22: ${x///.} echo 22: ${x///.}
echo 23: ${x//#1/9} echo 23: ${x/#1/9}
echo 24: ${x//%1/9} echo 24: ${x//#1/9}
echo 25: ${x//\%1/9} echo 25: ${x/%1/9}
echo 26: ${x//\\%1/9} echo 26: ${x//%1/9}
echo 27: ${x//\a/9} echo 27: ${x//\%1/9}
echo 28: ${x//\\a/9} echo 28: ${x//\\%1/9}
echo 29: ${x/2/$y} echo 29: ${x//\a/9}
echo 30: ${x//\\a/9}
echo 31: ${x/2/$y}
expected-stdout: expected-stdout:
1: 122321_ab/cde_b/c_1221 1: 122321_ab/cde_b/c_1221
2: 131_ab/cde_b/c_11 2: 131_ab/cde_b/c_11
@ -1892,12 +1913,14 @@ expected-stdout:
21: 1222321_ab.cde_b.c_1221 21: 1222321_ab.cde_b.c_1221
22: 1222321_ab/cde_b/c_1221 22: 1222321_ab/cde_b/c_1221
23: 9222321_ab/cde_b/c_1221 23: 9222321_ab/cde_b/c_1221
24: 1222321_ab/cde_b/c_1229 24: 1222321_ab/cde_b/c_1221
25: 1222321_ab/cde_b/c_1229 25: 1222321_ab/cde_b/c_1229
26: 1222321_ab/cde_b/c_1221 26: 1222321_ab/cde_b/c_1221
27: 1222321_9b/cde_b/c_1221 27: 1222321_ab/cde_b/c_1221
28: 1222321_9b/cde_b/c_1221 28: 1222321_ab/cde_b/c_1221
29: 1xyz22321_ab/cde_b/c_1221 29: 1222321_9b/cde_b/c_1221
30: 1222321_ab/cde_b/c_1221
31: 1xyz22321_ab/cde_b/c_1221
--- ---
name: eglob-substrpl-2 name: eglob-substrpl-2
description: description:
@ -1922,6 +1945,7 @@ name: eglob-substrpl-3a
description: description:
Check substring replacement works with variables and slashes, too Check substring replacement works with variables and slashes, too
stdin: stdin:
HOME=/etc
pfx=/home/user pfx=/home/user
wd=/home/user/tmp wd=/home/user/tmp
echo "${wd/#$pfx/~}" echo "${wd/#$pfx/~}"
@ -1931,9 +1955,9 @@ stdin:
echo "${wd/#"\$pfx"/~}" echo "${wd/#"\$pfx"/~}"
echo "${wd/#'\$pfx'/~}" echo "${wd/#'\$pfx'/~}"
expected-stdout: expected-stdout:
~/tmp /etc/tmp
/home/user/tmp /home/user/tmp
~/tmp /etc/tmp
/home/user/tmp /home/user/tmp
/home/user/tmp /home/user/tmp
/home/user/tmp /home/user/tmp
@ -1942,20 +1966,22 @@ name: eglob-substrpl-3b
description: description:
More of this, bash fails it (bash4 passes) More of this, bash fails it (bash4 passes)
stdin: stdin:
HOME=/etc
pfx=/home/user pfx=/home/user
wd=/home/user/tmp wd=/home/user/tmp
echo "${wd/#$(echo /home/user)/~}" echo "${wd/#$(echo /home/user)/~}"
echo "${wd/#"$(echo /home/user)"/~}" echo "${wd/#"$(echo /home/user)"/~}"
echo "${wd/#'$(echo /home/user)'/~}" echo "${wd/#'$(echo /home/user)'/~}"
expected-stdout: expected-stdout:
~/tmp /etc/tmp
~/tmp /etc/tmp
/home/user/tmp /home/user/tmp
--- ---
name: eglob-substrpl-3c name: eglob-substrpl-3c
description: description:
Even more weird cases Even more weird cases
stdin: stdin:
HOME=/etc
pfx=/home/user pfx=/home/user
wd='$pfx/tmp' wd='$pfx/tmp'
echo 1: ${wd/#$pfx/~} echo 1: ${wd/#$pfx/~}
@ -1981,31 +2007,31 @@ stdin:
echo 17: ${ts/+($tp)/$tr} echo 17: ${ts/+($tp)/$tr}
echo 18: ${ts/+($tp)/c/d} echo 18: ${ts/+($tp)/c/d}
echo 19: ${ts/+($tp)/c\/d} echo 19: ${ts/+($tp)/c\/d}
echo 25: ${ts//a\/b/$tr} echo 20: ${ts//a\/b/$tr}
echo 26: ${ts//a\/b/\$tr} echo 21: ${ts//a\/b/\$tr}
echo 27: ${ts//$tp/$tr} echo 22: ${ts//$tp/$tr}
echo 28: ${ts//$tp/c/d} echo 23: ${ts//$tp/c/d}
echo 29: ${ts//$tp/c\/d} echo 24: ${ts//$tp/c\/d}
echo 30: ${ts//+(a\/b)/$tr} echo 25: ${ts//+(a\/b)/$tr}
echo 31: ${ts//+(a\/b)/\$tr} echo 26: ${ts//+(a\/b)/\$tr}
echo 32: ${ts//+($tp)/$tr} echo 27: ${ts//+($tp)/$tr}
echo 33: ${ts//+($tp)/c/d} echo 28: ${ts//+($tp)/c/d}
echo 34: ${ts//+($tp)/c\/d} echo 29: ${ts//+($tp)/c\/d}
tp="+($tp)" tp="+($tp)"
echo 40: ${ts/$tp/$tr} echo 30: ${ts/$tp/$tr}
echo 41: ${ts//$tp/$tr} echo 31: ${ts//$tp/$tr}
expected-stdout: expected-stdout:
1: $pfx/tmp 1: $pfx/tmp
2: ~/tmp 2: /etc/tmp
3: $pfx/tmp 3: $pfx/tmp
4: ~/tmp 4: /etc/tmp
5: ~/tmp 5: /etc/tmp
6: ~/tmp 6: $pfx/tmp
7: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp) 7: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
8: $tra/b$tp$tp_a/b$tp_*(a/b)_*($tp) 8: $tra/b$tp$tp_a/b$tp_*(a/b)_*($tp)
9: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp) 9: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
10: a/ba/bc/d$tp_a/b$tp_*(a/b)_*($tp) 10: a/ba/bc/d$tp_a/b$tp_*(a/b)_*($tp)
11: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp) 11: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
12: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp) 12: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
13: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp) 13: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
14: c\/da/b$tp$tp_a/b$tp_*(a/b)_*($tp) 14: c\/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
@ -2014,21 +2040,21 @@ expected-stdout:
17: c/d$tp$tp_a/b$tp_*(a/b)_*($tp) 17: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
18: c/d$tp$tp_a/b$tp_*(a/b)_*($tp) 18: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
19: c/d$tp$tp_a/b$tp_*(a/b)_*($tp) 19: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
25: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp) 20: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
26: $tr$tr$tp$tp_$tr$tp_*($tr)_*($tp) 21: $tr$tr$tp$tp_$tr$tp_*($tr)_*($tp)
27: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp) 22: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
28: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp) 23: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
29: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp) 24: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
30: c/d$tp$tp_c/d$tp_*(c/d)_*($tp) 25: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
31: $tr$tp$tp_$tr$tp_*($tr)_*($tp) 26: $tr$tp$tp_$tr$tp_*($tr)_*($tp)
32: c/d$tp$tp_c/d$tp_*(c/d)_*($tp) 27: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
33: c/d$tp$tp_c/d$tp_*(c/d)_*($tp) 28: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
34: c/d$tp$tp_c/d$tp_*(c/d)_*($tp) 29: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
40: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp) 30: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
41: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp) 31: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
# This is what GNU bash does: # This is what GNU bash does:
# 40: c/d$tp$tp_a/b$tp_*(a/b)_*($tp) # 30: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
# 41: c/d$tp$tp_c/d$tp_*(c/d)_*($tp) # 31: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
--- ---
name: eglob-utf8-1 name: eglob-utf8-1
description: description:
@ -5068,7 +5094,7 @@ description:
called - I don't know what this will break. called - I don't know what this will break.
stdin: stdin:
: "${PWD:-`pwd 2> /dev/null`}" : "${PWD:-`pwd 2> /dev/null`}"
: "${PWD:?"PWD not set - can't do test"}" : "${PWD:?"PWD not set - cannot do test"}"
mkdir Y mkdir Y
cat > Y/xxxscript << EOF cat > Y/xxxscript << EOF
#!/bin/sh #!/bin/sh
@ -6384,6 +6410,41 @@ expected-stderr-pattern:
/bad substitution/ /bad substitution/
expected-exit: 1 expected-exit: 1
--- ---
name: xxx-variable-syntax-4
description:
Not all kinds of trims are currently impossible, check those who do
stdin:
foo() {
echo "<$*> X${*:+ }X"
}
foo a b
foo "" c
foo ""
foo "" ""
IFS=:
foo a b
foo "" c
foo ""
foo "" ""
IFS=
foo a b
foo "" c
foo ""
foo "" ""
expected-stdout:
<a b> X X
< c> X X
<> XX
< > X X
<a:b> X X
<:c> X X
<> XX
<:> X X
<ab> X X
<c> X X
<> XX
<> XX
---
name: xxx-substitution-eval-order name: xxx-substitution-eval-order
description: description:
Check order of evaluation of expressions Check order of evaluation of expressions
@ -7025,6 +7086,131 @@ expected-stdout:
2- 1 1 1 = 2- 1 1 1 =
3- 0 0 0 = 3- 0 0 0 =
--- ---
name: test-stnze-1
description:
Check that the short form [ $x ] works
stdin:
i=0
[ -n $x ]
rv=$?; echo $((++i)) $rv
[ $x ]
rv=$?; echo $((++i)) $rv
[ -n "$x" ]
rv=$?; echo $((++i)) $rv
[ "$x" ]
rv=$?; echo $((++i)) $rv
x=0
[ -n $x ]
rv=$?; echo $((++i)) $rv
[ $x ]
rv=$?; echo $((++i)) $rv
[ -n "$x" ]
rv=$?; echo $((++i)) $rv
[ "$x" ]
rv=$?; echo $((++i)) $rv
x='1 -a 1 = 2'
[ -n $x ]
rv=$?; echo $((++i)) $rv
[ $x ]
rv=$?; echo $((++i)) $rv
[ -n "$x" ]
rv=$?; echo $((++i)) $rv
[ "$x" ]
rv=$?; echo $((++i)) $rv
expected-stdout:
1 0
2 1
3 1
4 1
5 0
6 0
7 0
8 0
9 1
10 1
11 0
12 0
---
name: test-stnze-2
description:
Check that the short form [[ $x ]] works (ksh93 extension)
stdin:
i=0
[[ -n $x ]]
rv=$?; echo $((++i)) $rv
[[ $x ]]
rv=$?; echo $((++i)) $rv
[[ -n "$x" ]]
rv=$?; echo $((++i)) $rv
[[ "$x" ]]
rv=$?; echo $((++i)) $rv
x=0
[[ -n $x ]]
rv=$?; echo $((++i)) $rv
[[ $x ]]
rv=$?; echo $((++i)) $rv
[[ -n "$x" ]]
rv=$?; echo $((++i)) $rv
[[ "$x" ]]
rv=$?; echo $((++i)) $rv
x='1 -a 1 = 2'
[[ -n $x ]]
rv=$?; echo $((++i)) $rv
[[ $x ]]
rv=$?; echo $((++i)) $rv
[[ -n "$x" ]]
rv=$?; echo $((++i)) $rv
[[ "$x" ]]
rv=$?; echo $((++i)) $rv
expected-stdout:
1 1
2 1
3 1
4 1
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
---
name: test-numeq
description:
Check numeric -eq works (R40d regression); spotted by Martijn Dekker
stdin:
tst() {
eval "$2"
case $? in
(0) echo yepp 0 \#"$*" ;;
(1) echo nope 1 \#"$*" ;;
(2) echo terr 2 \#"$*" ;;
(*) echo wtf\? $? \#"$*" ;;
esac
}
tst 1 'test 2 -eq 2'
tst 2 'test 2 -eq 2a'
tst 3 'test 2 -eq 3'
tst 4 'test 2 -ne 2'
tst 5 'test 2 -ne 2a'
tst 6 'test 2 -ne 3'
tst 7 'test \! 2 -eq 2'
tst 8 'test \! 2 -eq 2a'
tst 9 'test \! 2 -eq 3'
expected-stdout:
yepp 0 #1 test 2 -eq 2
terr 2 #2 test 2 -eq 2a
nope 1 #3 test 2 -eq 3
nope 1 #4 test 2 -ne 2
terr 2 #5 test 2 -ne 2a
yepp 0 #6 test 2 -ne 3
nope 1 #7 test \! 2 -eq 2
terr 2 #8 test \! 2 -eq 2a
yepp 0 #9 test \! 2 -eq 3
expected-stderr-pattern:
/bad number/
---
name: mkshrc-1 name: mkshrc-1
description: description:
Check that ~/.mkshrc works correctly. Check that ~/.mkshrc works correctly.
@ -7565,7 +7751,6 @@ expected-stdout:
name: aliases-funcdef-1 name: aliases-funcdef-1
description: description:
Check if POSIX functions take precedences over aliases Check if POSIX functions take precedences over aliases
category: shell:legacy-no
stdin: stdin:
alias foo='echo makro' alias foo='echo makro'
foo() { foo() {
@ -7575,23 +7760,9 @@ stdin:
expected-stdout: expected-stdout:
makro makro
--- ---
name: aliases-funcdef-1-legacy
description:
Check if POSIX functions take precedences over aliases
category: shell:legacy-yes
stdin:
alias foo='echo makro'
foo() {
echo funktion
}
foo
expected-stdout:
funktion
---
name: aliases-funcdef-2 name: aliases-funcdef-2
description: description:
Check if POSIX functions take precedences over aliases Check if POSIX functions take precedences over aliases
category: shell:legacy-no
stdin: stdin:
alias foo='echo makro' alias foo='echo makro'
foo () { foo () {
@ -7601,19 +7772,6 @@ stdin:
expected-stdout: expected-stdout:
makro makro
--- ---
name: aliases-funcdef-2-legacy
description:
Check if POSIX functions take precedences over aliases
category: shell:legacy-yes
stdin:
alias foo='echo makro'
foo () {
echo funktion
}
foo
expected-stdout:
funktion
---
name: aliases-funcdef-3 name: aliases-funcdef-3
description: description:
Check if aliases take precedences over Korn functions Check if aliases take precedences over Korn functions
@ -8845,52 +9003,9 @@ expected-exit: e != 0
expected-stderr-pattern: expected-stderr-pattern:
/\.: missing argument.*\n.*source: missing argument/ /\.: missing argument.*\n.*source: missing argument/
--- ---
name: alias-function-no-conflict-legacy
description:
make aliases not conflict with functions, legacy version:
undefine these aliases upon definition of the function
note: for ksh functions, the order of preference differs in GNU bash
category: shell:legacy-yes
stdin:
# POSIX function overrides and removes alias
alias foo='echo bar'
foo
foo() {
echo baz
}
foo
unset -f foo
foo 2>/dev/null || echo rab
# alias overrides ksh function
alias korn='echo bar'
korn
function korn {
echo baz
}
korn
# alias temporarily overrides POSIX function
bla() {
echo bfn
}
bla
alias bla='echo bal'
bla
unalias bla
bla
expected-stdout:
bar
baz
rab
bar
bar
bfn
bal
bfn
---
name: alias-function-no-conflict name: alias-function-no-conflict
description: description:
make aliases not conflict with function definitions make aliases not conflict with function definitions
category: shell:legacy-no
stdin: stdin:
# POSIX function can be defined, but alias overrides it # POSIX function can be defined, but alias overrides it
alias foo='echo bar' alias foo='echo bar'
@ -10380,7 +10495,9 @@ expected-stdout:
} }
inline_TWHILE() { inline_TWHILE() {
i=1 i=1
while \let] " i < 10 " while {
\let] " i < 10 "
}
do do
echo $i echo $i
let ++i let ++i
@ -10390,20 +10507,22 @@ expected-stdout:
i=1; while (( i < 10 )); do echo $i; let ++i; done i=1; while (( i < 10 )); do echo $i; let ++i; done
); } ); }
function comsub_TWHILE { function comsub_TWHILE {
x=$(i=1 ; while \let] " i < 10 " ; do echo $i ; let ++i ; done ) x=$(i=1 ; while { \let] " i < 10 " ; } ; do echo $i ; let ++i ; done )
} }
function reread_TWHILE { x=$(( function reread_TWHILE { x=$((
i=1; while (( i < 10 )); do echo $i; let ++i; done i=1; while (( i < 10 )); do echo $i; let ++i; done
)|tr u x); } )|tr u x); }
function reread_TWHILE { function reread_TWHILE {
x=$(( i=1 ; while \let] " i < 10 " ; do echo $i ; let ++i ; done ) | tr u x ) x=$(( i=1 ; while { \let] " i < 10 " ; } ; do echo $i ; let ++i ; done ) | tr u x )
} }
inline_TUNTIL() { inline_TUNTIL() {
i=10; until (( !--i )) ; do echo $i; done i=10; until (( !--i )) ; do echo $i; done
} }
inline_TUNTIL() { inline_TUNTIL() {
i=10 i=10
until \let] " !--i " until {
\let] " !--i "
}
do do
echo $i echo $i
done done
@ -10412,13 +10531,13 @@ expected-stdout:
i=10; until (( !--i )) ; do echo $i; done i=10; until (( !--i )) ; do echo $i; done
); } ); }
function comsub_TUNTIL { function comsub_TUNTIL {
x=$(i=10 ; until \let] " !--i " ; do echo $i ; done ) x=$(i=10 ; until { \let] " !--i " ; } ; do echo $i ; done )
} }
function reread_TUNTIL { x=$(( function reread_TUNTIL { x=$((
i=10; until (( !--i )) ; do echo $i; done i=10; until (( !--i )) ; do echo $i; done
)|tr u x); } )|tr u x); }
function reread_TUNTIL { function reread_TUNTIL {
x=$(( i=10 ; until \let] " !--i " ; do echo $i ; done ) | tr u x ) x=$(( i=10 ; until { \let] " !--i " ; } ; do echo $i ; done ) | tr u x )
} }
inline_TCOPROC() { inline_TCOPROC() {
cat * |& ls cat * |& ls
@ -11032,7 +11151,9 @@ expected-stdout:
} }
inline_TWHILE() { inline_TWHILE() {
i=1 i=1
while \let] " i < 10 " >&3 while {
\let] " i < 10 "
} >&3
do do
echo $i echo $i
let ++i let ++i
@ -11042,20 +11163,22 @@ expected-stdout:
i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3 i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
); } ); }
function comsub_TWHILE { function comsub_TWHILE {
x=$(i=1 ; while \let] " i < 10 " >&3 ; do echo $i ; let ++i ; done >&3 ) x=$(i=1 ; while { \let] " i < 10 " ; } >&3 ; do echo $i ; let ++i ; done >&3 )
} }
function reread_TWHILE { x=$(( function reread_TWHILE { x=$((
i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3 i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
)|tr u x); } )|tr u x); }
function reread_TWHILE { function reread_TWHILE {
x=$(( i=1 ; while \let] " i < 10 " >&3 ; do echo $i ; let ++i ; done >&3 ) | tr u x ) x=$(( i=1 ; while { \let] " i < 10 " ; } >&3 ; do echo $i ; let ++i ; done >&3 ) | tr u x )
} }
inline_TUNTIL() { inline_TUNTIL() {
i=10; until (( !--i )) >&3 ; do echo $i; done >&3 i=10; until (( !--i )) >&3 ; do echo $i; done >&3
} }
inline_TUNTIL() { inline_TUNTIL() {
i=10 i=10
until \let] " !--i " >&3 until {
\let] " !--i "
} >&3
do do
echo $i echo $i
done >&3 done >&3
@ -11064,13 +11187,13 @@ expected-stdout:
i=10; until (( !--i )) >&3 ; do echo $i; done >&3 i=10; until (( !--i )) >&3 ; do echo $i; done >&3
); } ); }
function comsub_TUNTIL { function comsub_TUNTIL {
x=$(i=10 ; until \let] " !--i " >&3 ; do echo $i ; done >&3 ) x=$(i=10 ; until { \let] " !--i " ; } >&3 ; do echo $i ; done >&3 )
} }
function reread_TUNTIL { x=$(( function reread_TUNTIL { x=$((
i=10; until (( !--i )) >&3 ; do echo $i; done >&3 i=10; until (( !--i )) >&3 ; do echo $i; done >&3
)|tr u x); } )|tr u x); }
function reread_TUNTIL { function reread_TUNTIL {
x=$(( i=10 ; until \let] " !--i " >&3 ; do echo $i ; done >&3 ) | tr u x ) x=$(( i=10 ; until { \let] " !--i " ; } >&3 ; do echo $i ; done >&3 ) | tr u x )
} }
inline_TCOPROC() { inline_TCOPROC() {
cat * >&3 |& >&3 ls cat * >&3 |& >&3 ls
@ -11202,96 +11325,6 @@ expected-stdout:
typeset t=$'foo\n\n' typeset t=$'foo\n\n'
this used to segfault. this used to segfault.
--- ---
name: test-stnze-1
description:
Check that the short form [ $x ] works
stdin:
i=0
[ -n $x ]
rv=$?; echo $((++i)) $rv
[ $x ]
rv=$?; echo $((++i)) $rv
[ -n "$x" ]
rv=$?; echo $((++i)) $rv
[ "$x" ]
rv=$?; echo $((++i)) $rv
x=0
[ -n $x ]
rv=$?; echo $((++i)) $rv
[ $x ]
rv=$?; echo $((++i)) $rv
[ -n "$x" ]
rv=$?; echo $((++i)) $rv
[ "$x" ]
rv=$?; echo $((++i)) $rv
x='1 -a 1 = 2'
[ -n $x ]
rv=$?; echo $((++i)) $rv
[ $x ]
rv=$?; echo $((++i)) $rv
[ -n "$x" ]
rv=$?; echo $((++i)) $rv
[ "$x" ]
rv=$?; echo $((++i)) $rv
expected-stdout:
1 0
2 1
3 1
4 1
5 0
6 0
7 0
8 0
9 1
10 1
11 0
12 0
---
name: test-stnze-2
description:
Check that the short form [[ $x ]] works (ksh93 extension)
stdin:
i=0
[[ -n $x ]]
rv=$?; echo $((++i)) $rv
[[ $x ]]
rv=$?; echo $((++i)) $rv
[[ -n "$x" ]]
rv=$?; echo $((++i)) $rv
[[ "$x" ]]
rv=$?; echo $((++i)) $rv
x=0
[[ -n $x ]]
rv=$?; echo $((++i)) $rv
[[ $x ]]
rv=$?; echo $((++i)) $rv
[[ -n "$x" ]]
rv=$?; echo $((++i)) $rv
[[ "$x" ]]
rv=$?; echo $((++i)) $rv
x='1 -a 1 = 2'
[[ -n $x ]]
rv=$?; echo $((++i)) $rv
[[ $x ]]
rv=$?; echo $((++i)) $rv
[[ -n "$x" ]]
rv=$?; echo $((++i)) $rv
[[ "$x" ]]
rv=$?; echo $((++i)) $rv
expected-stdout:
1 1
2 1
3 1
4 1
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
---
name: event-subst-3 name: event-subst-3
description: description:
Check that '!' substitution in noninteractive mode is ignored Check that '!' substitution in noninteractive mode is ignored
@ -11657,6 +11690,16 @@ stdin:
expected-stdout: expected-stdout:
fxbar 0 fxbar 0
--- ---
name: better-parens-5
description:
Another corner case
stdin:
( (echo 'fo o$bar' "baz\$bla\"" m\$eh) | tr a A)
((echo 'fo o$bar' "baz\$bla\"" m\$eh) | tr a A)
expected-stdout:
fo o$bAr bAz$blA" m$eh
fo o$bAr bAz$blA" m$eh
---
name: echo-test-1 name: echo-test-1
description: description:
Test what the echo builtin does (mksh) Test what the echo builtin does (mksh)

View File

@ -1,5 +1,5 @@
# $Id$ # $Id$
# $MirOS: src/bin/mksh/dot.mkshrc,v 1.102 2015/10/09 21:36:54 tg Exp $ # $MirOS: src/bin/mksh/dot.mkshrc,v 1.103 2015/12/12 18:47:40 tg Exp $
#- #-
# Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014, 2015 # 2011, 2012, 2013, 2014, 2015
@ -40,7 +40,7 @@ PS4='[$EPOCHREALTIME] '; PS1=$'\001\r''${|
(( e )) && REPLY+="$e|" (( e )) && REPLY+="$e|"
REPLY+=${USER}@${HOSTNAME%%.*}: REPLY+=${USER}@${HOSTNAME%%.*}:
\typeset d=${PWD:-?} p=~; [[ $p = ?(*/) ]] || d=${d/#$p/~} \typeset d=${PWD:-?} p=~; [[ $p = ?(*/) ]] || d=${d/#$p/\~}
\typeset m=${%d} n p=...; (( m > 0 )) || m=${#d} \typeset m=${%d} n p=...; (( m > 0 )) || m=${#d}
(( m > (n = (COLUMNS/3 < 7 ? 7 : COLUMNS/3)) )) && d=${d:(-n)} || p= (( m > (n = (COLUMNS/3 < 7 ? 7 : COLUMNS/3)) )) && d=${d:(-n)} || p=
REPLY+=$p$d REPLY+=$p$d
@ -109,7 +109,7 @@ function chpwd {
DIRSTACK[0]=$(\builtin realpath . 2>/dev/null || \ DIRSTACK[0]=$(\builtin realpath . 2>/dev/null || \
\builtin print -r -- "$PWD") \builtin print -r -- "$PWD")
[[ $DIRSTACKBASE = ?(*/) ]] || \ [[ $DIRSTACKBASE = ?(*/) ]] || \
DIRSTACK[0]=${DIRSTACK[0]/#$DIRSTACKBASE/~} DIRSTACK[0]=${DIRSTACK[0]/#$DIRSTACKBASE/\~}
\: \:
} }
\chpwd . \chpwd .
@ -118,7 +118,7 @@ cd() {
\chpwd "$@" \chpwd "$@"
} }
function cd_csh { function cd_csh {
\typeset d t=${1/#~/$DIRSTACKBASE} \typeset d t=${1/#\~/$DIRSTACKBASE}
if ! d=$(\builtin cd "$t" 2>&1); then if ! d=$(\builtin cd "$t" 2>&1); then
\builtin print -u2 "${1}: ${d##*cd: $t: }." \builtin print -u2 "${1}: ${d##*cd: $t: }."
@ -148,7 +148,7 @@ function dirs {
fv=0 fv=0
while (( fv < ${#DIRSTACK[*]} )); do while (( fv < ${#DIRSTACK[*]} )); do
d=${DIRSTACK[fv]} d=${DIRSTACK[fv]}
(( fl )) && d=${d/#~/$DIRSTACKBASE} (( fl )) && d=${d/#\~/$DIRSTACKBASE}
\builtin print -r -- "$fv $d" \builtin print -r -- "$fv $d"
\builtin let fv++ \builtin let fv++
done done
@ -156,7 +156,7 @@ function dirs {
fv=0 fv=0
while (( fv < ${#DIRSTACK[*]} )); do while (( fv < ${#DIRSTACK[*]} )); do
d=${DIRSTACK[fv]} d=${DIRSTACK[fv]}
(( fl )) && d=${d/#~/$DIRSTACKBASE} (( fl )) && d=${d/#\~/$DIRSTACKBASE}
(( dwidth = (${%d} > 0 ? ${%d} : ${#d}) )) (( dwidth = (${%d} > 0 ? ${%d} : ${#d}) ))
if (( fn && (cpos += dwidth + 1) >= 79 && \ if (( fn && (cpos += dwidth + 1) >= 79 && \
dwidth < 80 )); then dwidth < 80 )); then

View File

@ -1,5 +1,25 @@
/*-
* Copyright (c) 2009, 2010, 2015
* mirabilos <m@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission
* is granted to deal in this work without restriction, including un-
* limited rights to use, publicly perform, distribute, sell, modify,
* merge, give away, or sublicence.
*
* This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
* the utmost extent permitted by applicable law, neither express nor
* implied; without malicious intent or gross negligence. In no event
* may a licensor, author or contributor be held liable for indirect,
* direct, other damage, loss, or other issues arising in any way out
* of dealing in the work, even if advised of the possibility of such
* damage or existence of a defect, except proven that it results out
* of said person's immediate fault when using the work as intended.
*/
#if defined(EMACSFN_DEFNS) #if defined(EMACSFN_DEFNS)
__RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.6 2015/07/10 18:41:07 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/emacsfn.h,v 1.7 2015/12/12 21:08:44 tg Exp $");
#define FN(cname,sname,flags) static int x_##cname(int); #define FN(cname,sname,flags) static int x_##cname(int);
#elif defined(EMACSFN_ENUMS) #elif defined(EMACSFN_ENUMS)
#define FN(cname,sname,flags) XFUNC_##cname, #define FN(cname,sname,flags) XFUNC_##cname,

89
eval.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.174 2015/10/09 19:29:47 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.178 2015/12/12 22:24:07 tg Exp $");
/* /*
* string expansion * string expansion
@ -483,7 +483,7 @@ expand(
case '/': { case '/': {
char *s, *p, *d, *sbeg, *end; char *s, *p, *d, *sbeg, *end;
char *pat, *rrep; char *pat, *rrep;
char *tpat0, *tpat1, *tpat2; char fpat = 0, *tpat1, *tpat2;
s = wdcopy(sp, ATEMP); s = wdcopy(sp, ATEMP);
p = s + (wdscan(sp, ADELIM) - sp); p = s + (wdscan(sp, ADELIM) - sp);
@ -496,43 +496,26 @@ expand(
else else
d[-2] = EOS; d[-2] = EOS;
sp += (d ? d : p) - s - 1; sp += (d ? d : p) - s - 1;
tpat0 = wdstrip(s, if (!(stype & 0x80) &&
WDS_KEEPQ | WDS_MAGIC); s[0] == CHAR &&
pat = substitute(tpat0, 0); (s[1] == '#' || s[1] == '%'))
if (d) { fpat = s[1];
d = wdstrip(p, WDS_KEEPQ); pat = evalstr(s + (fpat ? 2 : 0),
rrep = substitute(d, 0); DOTILDE | DOSCALAR | DOPAT);
afree(d, ATEMP); rrep = d ? evalstr(p,
} else DOTILDE | DOSCALAR) : null;
rrep = null;
afree(s, ATEMP); afree(s, ATEMP);
s = d = pat;
while (*s)
if (*s != '\\' ||
s[1] == '%' ||
s[1] == '#' ||
s[1] == '\0' ||
/* XXX really? */ s[1] == '\\' ||
s[1] == '/')
*d++ = *s++;
else
s++;
*d = '\0';
afree(tpat0, ATEMP);
/* check for special cases */ /* check for special cases */
switch (*pat) { if (!*pat && !fpat) {
case '#': /*
case '%': * empty unanchored
tpat0 = pat + 1; * pattern => reject
break; */
case '\0':
/* empty pattern, reject */
goto no_repl; goto no_repl;
default:
tpat0 = pat;
} }
if (gmatchx(null, tpat0, false)) { if ((stype & 0x80) &&
gmatchx(null, pat, false)) {
/* /*
* pattern matches empty * pattern matches empty
* string => don't loop * string => don't loop
@ -545,15 +528,14 @@ expand(
sbeg = s; sbeg = s;
/* first see if we have any match at all */ /* first see if we have any match at all */
tpat0 = pat; if (fpat == '#') {
if (*pat == '#') {
/* anchor at the beginning */ /* anchor at the beginning */
tpat1 = shf_smprintf("%s%c*", ++tpat0, MAGIC); tpat1 = shf_smprintf("%s%c*", pat, MAGIC);
tpat2 = tpat1; tpat2 = tpat1;
} else if (*pat == '%') { } else if (fpat == '%') {
/* anchor at the end */ /* anchor at the end */
tpat1 = shf_smprintf("%c*%s", MAGIC, ++tpat0); tpat1 = shf_smprintf("%c*%s", MAGIC, pat);
tpat2 = tpat0; tpat2 = pat;
} else { } else {
/* float */ /* float */
tpat1 = shf_smprintf("%c*%s%c*", MAGIC, pat, MAGIC); tpat1 = shf_smprintf("%c*%s%c*", MAGIC, pat, MAGIC);
@ -568,7 +550,7 @@ expand(
goto end_repl; goto end_repl;
end = strnul(s); end = strnul(s);
/* now anchor the beginning of the match */ /* now anchor the beginning of the match */
if (*pat != '#') if (fpat != '#')
while (sbeg <= end) { while (sbeg <= end) {
if (gmatchx(sbeg, tpat2, false)) if (gmatchx(sbeg, tpat2, false))
break; break;
@ -577,13 +559,13 @@ expand(
} }
/* now anchor the end of the match */ /* now anchor the end of the match */
p = end; p = end;
if (*pat != '%') if (fpat != '%')
while (p >= sbeg) { while (p >= sbeg) {
bool gotmatch; bool gotmatch;
c = *p; c = *p;
*p = '\0'; *p = '\0';
gotmatch = tobool(gmatchx(sbeg, tpat0, false)); gotmatch = tobool(gmatchx(sbeg, pat, false));
*p = c; *p = c;
if (gotmatch) if (gotmatch)
break; break;
@ -608,9 +590,11 @@ expand(
} }
case '#': case '#':
case '%': case '%':
/* ! DOBLANK,DOBRACE,DOTILDE */ /* ! DOBLANK,DOBRACE */
f = (f & DONTRUNCOMMAND) | f = (f & DONTRUNCOMMAND) |
DOPAT | DOTEMP | DOSCALAR; DOPAT | DOTILDE |
DOTEMP | DOSCALAR;
tilde_ok = 1;
st->quotew = quote = 0; st->quotew = quote = 0;
/* /*
* Prepend open pattern (so | * Prepend open pattern (so |
@ -1059,6 +1043,17 @@ expand(
} }
} }
static bool
hasnonempty(const char **strv)
{
size_t i = 0;
while (strv[i])
if (*strv[i++])
return (true);
return (false);
}
/* /*
* Prepare to generate the string returned by ${} substitution. * Prepare to generate the string returned by ${} substitution.
*/ */
@ -1287,7 +1282,9 @@ varsub(Expand *xp, const char *sp, const char *word,
c = stype & 0x7F; c = stype & 0x7F;
/* test the compiler's code generator */ /* test the compiler's code generator */
if (((stype < 0x100) && (ctype(c, C_SUBOP2) || c == '/' || if (((stype < 0x100) && (ctype(c, C_SUBOP2) || c == '/' ||
(((stype & 0x80) ? *xp->str == '\0' : xp->str == null) ? (((stype & 0x80) ? *xp->str == '\0' : xp->str == null) &&
(state != XARG || (ifs0 || xp->split ?
(xp->u.strv[0] == NULL) : !hasnonempty(xp->u.strv))) ?
c == '=' || c == '-' || c == '?' : c == '+'))) || c == '=' || c == '-' || c == '?' : c == '+'))) ||
stype == (0x80 | '0') || stype == (0x100 | '#') || stype == (0x80 | '0') || stype == (0x100 | '#') ||
stype == (0x100 | 'Q')) stype == (0x100 | 'Q'))

4
expr.c
View File

@ -3,7 +3,7 @@
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2014 * 2011, 2012, 2013, 2014
* mirabilos <tg@mirbsd.org> * mirabilos <m@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
@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.79 2015/10/24 19:45:23 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/expr.c,v 1.80 2015/11/29 17:05:00 tg Exp $");
/* the order of these enums is constrained by the order of opinfo[] */ /* the order of these enums is constrained by the order of opinfo[] */
enum token { enum token {

View File

@ -38,7 +38,7 @@
#endif #endif
#endif #endif
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.287 2015/10/24 19:46:09 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.288 2015/12/12 19:27:36 tg Exp $");
#if HAVE_KILLPG #if HAVE_KILLPG
/* /*
@ -2856,7 +2856,7 @@ c_test(const char **wp)
/* /*
* Attempt to conform to POSIX special cases. This is pretty * Attempt to conform to POSIX special cases. This is pretty
* dumb code straight-forward from the 2008 spec, but unless * dumb code straight-forward from the 2008 spec, but unlike
* the old pdksh code doesn't live from so many assumptions. * the old pdksh code doesn't live from so many assumptions.
* It does, though, inline some calls to '(*te.funcname)()'. * It does, though, inline some calls to '(*te.funcname)()'.
*/ */
@ -2877,6 +2877,8 @@ c_test(const char **wp)
ptest_unary: ptest_unary:
rv = test_eval(&te, op, *te.pos.wp++, NULL, true); rv = test_eval(&te, op, *te.pos.wp++, NULL, true);
ptest_out: ptest_out:
if (te.flags & TEF_ERROR)
return (T_ERR_EXIT);
return ((invert & 1) ? rv : !rv); return ((invert & 1) ? rv : !rv);
} }
/* let the parser deal with anything else */ /* let the parser deal with anything else */

View File

@ -4,7 +4,7 @@
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2014, 2015 * 2011, 2012, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@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
@ -27,7 +27,7 @@
#include <sys/file.h> #include <sys/file.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.150 2015/09/05 19:19:05 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.151 2015/11/29 17:05:01 tg Exp $");
Trap sigtraps[ksh_NSIG + 1]; Trap sigtraps[ksh_NSIG + 1];
static struct sigaction Sigact_ign; static struct sigaction Sigact_ign;

View File

@ -1,6 +1,6 @@
/*- /*-
* Copyright (c) 2009, 2010, 2011, 2013, 2014 * Copyright (c) 2009, 2010, 2011, 2013, 2014
* mirabilos <tg@mirbsd.org> * mirabilos <m@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
@ -20,7 +20,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.22 2015/09/05 19:19:06 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.23 2015/11/29 17:05:01 tg Exp $");
/* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */ /* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */
#if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0) #if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0)

4
lex.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.213 2015/10/24 19:46:10 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.214 2015/12/12 19:05:52 tg Exp $");
/* /*
* states while lexing word * states while lexing word
@ -784,7 +784,7 @@ yylex(int cf)
*/ */
*wp = EOS; *wp = EOS;
sp = Xstring(ws, wp); sp = Xstring(ws, wp);
dp = wdstrip(sp, WDS_KEEPQ); dp = wdstrip(sp + 1, WDS_TPUTS);
s = pushs(SREREAD, source->areap); s = pushs(SREREAD, source->areap);
s->start = s->str = s->u.freeme = dp; s->start = s->str = s->u.freeme = dp;
s->next = source; s->next = source;

10
lksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/lksh.1,v 1.15 2015/10/09 21:36:56 tg Exp $ .\" $MirOS: src/bin/mksh/lksh.1,v 1.16 2015/12/12 22:25:14 tg Exp $
.\"- .\"-
.\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015 .\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015
.\" mirabilos <m@mirbsd.org> .\" mirabilos <m@mirbsd.org>
@ -72,7 +72,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to .\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always. .\" use our own definition. And .Dd must come *first*, always.
.\" .\"
.Dd $Mdocdate: October 9 2015 $ .Dd $Mdocdate: December 12 2015 $
.\" .\"
.\" Check which macro package we use, and do other -mdoc setup. .\" Check which macro package we use, and do other -mdoc setup.
.\" .\"
@ -302,6 +302,12 @@ instead of locally scoping them.
.Pp .Pp
.Pa https://www.mirbsd.org/ksh\-chan.htm .Pa https://www.mirbsd.org/ksh\-chan.htm
.Sh CAVEATS .Sh CAVEATS
The distinction between the shell variants
.Pq Nm lksh / Nm mksh
and shell flags
.Pq Fl o Ic posix / Ic sh
will be reworked for an upcoming release.
.Pp
To use To use
.Nm .Nm
as as

View File

@ -1,6 +1,6 @@
/*- /*-
* Copyright © 2011, 2014, 2015 * Copyright © 2011, 2014, 2015
* mirabilos <tg@mirbsd.org> * mirabilos <m@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
@ -44,7 +44,7 @@
#include <sys/types.h> #include <sys/types.h>
__RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.5 2015/09/05 19:19:07 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.6 2015/11/29 17:05:02 tg Exp $");
/*- /*-
* BAFH itself is defined by the following primitives: * BAFH itself is defined by the following primitives:

64
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.382 2015/10/09 21:36:57 tg Exp $ .\" $MirOS: src/bin/mksh/mksh.1,v 1.383 2015/12/12 22:25:14 tg Exp $
.\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $
.\"- .\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
@ -74,7 +74,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to .\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always. .\" use our own definition. And .Dd must come *first*, always.
.\" .\"
.Dd $Mdocdate: October 9 2015 $ .Dd $Mdocdate: December 12 2015 $
.\" .\"
.\" Check which macro package we use, and do other -mdoc setup. .\" Check which macro package we use, and do other -mdoc setup.
.\" .\"
@ -914,7 +914,7 @@ is evaluated; equivalent to
.Sx Arithmetic expressions .Sx Arithmetic expressions
and the and the
.Ic let .Ic let
command, below). command, below) in a compound construct.
.It Bq Bq Ar \ \&expression\ \& .It Bq Bq Ar \ \&expression\ \&
Similar to the Similar to the
.Ic test .Ic test
@ -1625,31 +1625,40 @@ Cannot be applied to a vector.
.Xc .Xc
.It Xo .It Xo
.Pf ${ Ar name .Pf ${ Ar name
.Pf /# Ar pattern / Ar string No }
.Xc
.It Xo
.Pf ${ Ar name
.Pf /% Ar pattern / Ar string No }
.Xc
.It Xo
.Pf ${ Ar name
.Pf // Ar pattern / Ar string No } .Pf // Ar pattern / Ar string No }
.Xc .Xc
.Sm on .Sm on
Similar to ${..##..} substitution, but it replaces the longest match of The longest match of
.Ar pattern ,
anchored anywhere in the value, with
.Ar string .
If
.Ar pattern .Ar pattern
begins with in the value of parameter
.Ql # , .Ar name
it is anchored at the beginning of the value; if it begins with is replaced with
.Ql % , .Ar string
it is anchored at the end. (deleted if
Empty patterns cause no replacement to happen. .Ar string
A single leading is empty; the trailing slash
.Ql / .Pq Ql /
or use of a pattern that matches the empty string causes the may be omitted in that case).
replacement to happen only once; two leading slashes cause A leading slash followed by
all occurrences of matches in the value to be replaced. .Ql #
If the trailing or
.Pf / Ar string .Ql %
is omitted, any matches of causes the pattern to be anchored at the beginning or end of
the value, respectively; empty unanchored
.Ar pattern Ns s
cause no replacement; a single leading slash or use of a
.Ar pattern .Ar pattern
are replaced by the empty string, i.e. deleted. that matches the empty string causes the replacement to
happen only once; two leading slashes cause all occurrences
of matches in the value to be replaced.
Cannot be applied to a vector. Cannot be applied to a vector.
Inefficiently implemented, may be slow. Inefficiently implemented, may be slow.
.Pp .Pp
@ -3633,7 +3642,7 @@ the parsing or evaluation of an expression, the exit status is greater than 1.
Since expressions may need to be quoted, Since expressions may need to be quoted,
.No \&(( Ar expr No )) .No \&(( Ar expr No ))
is syntactic sugar for is syntactic sugar for
.No let \&" Ns Ar expr Ns \&" . .No "{ let '" Ns Ar expr Ns "'; }" .
.Pp .Pp
.It Ic let] .It Ic let]
Internally used alias for Internally used alias for
@ -5320,7 +5329,7 @@ The
builtin does not interpret backslashes and only supports the exact option builtin does not interpret backslashes and only supports the exact option
.Dq Fl n . .Dq Fl n .
.It .It
\&... (list is incomplete) \&... (list is incomplete and may change for R53)
.El .El
.Ss SH mode .Ss SH mode
Compatibility mode; intended for use with legacy scripts that Compatibility mode; intended for use with legacy scripts that
@ -5341,7 +5350,7 @@ The
builtin does not interpret backslashes and only supports the exact option builtin does not interpret backslashes and only supports the exact option
.Dq Fl n . .Dq Fl n .
.It .It
\&... (list is incomplete) \&... (list is incomplete and may change for R53)
.El .El
.Ss Interactive input line editing .Ss Interactive input line editing
The shell supports three modes of reading command lines from a The shell supports three modes of reading command lines from a
@ -6345,6 +6354,7 @@ contains the system and suid profile.
.Xr cat 1 , .Xr cat 1 ,
.Xr ed 1 , .Xr ed 1 ,
.Xr getopt 1 , .Xr getopt 1 ,
.Xr lksh 1 ,
.Xr sed 1 , .Xr sed 1 ,
.Xr sh 1 , .Xr sh 1 ,
.Xr stty 1 , .Xr stty 1 ,
@ -6565,7 +6575,7 @@ for the in-memory portion of the history is slow, should use
.Xr memmove 3 . .Xr memmove 3 .
.Pp .Pp
This document attempts to describe This document attempts to describe
.Nm mksh\ R51 Ns -CVS .Nm mksh\ R52
and up, and up,
.\" with vendor patches from insert-your-name-here, .\" with vendor patches from insert-your-name-here,
compiled without any options impacting functionality, such as compiled without any options impacting functionality, such as

View File

@ -1,5 +1,25 @@
/*-
* Copyright (c) 2013, 2015
* mirabilos <m@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission
* is granted to deal in this work without restriction, including un-
* limited rights to use, publicly perform, distribute, sell, modify,
* merge, give away, or sublicence.
*
* This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
* the utmost extent permitted by applicable law, neither express nor
* implied; without malicious intent or gross negligence. In no event
* may a licensor, author or contributor be held liable for indirect,
* direct, other damage, loss, or other issues arising in any way out
* of dealing in the work, even if advised of the possibility of such
* damage or existence of a defect, except proven that it results out
* of said person's immediate fault when using the work as intended.
*/
@RLIMITS_DEFNS @RLIMITS_DEFNS
__RCSID("$MirOS: src/bin/mksh/rlimits.opt,v 1.2 2015/05/01 23:16:31 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/rlimits.opt,v 1.3 2015/12/12 21:08:44 tg Exp $");
@RLIMITS_ITEMS @RLIMITS_ITEMS
#define FN(lname,lid,lfac,lopt) (const struct limits *)(&rlimits_ ## lid), #define FN(lname,lid,lfac,lopt) (const struct limits *)(&rlimits_ ## lid),
@@ @@

8
sh.h
View File

@ -175,9 +175,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.750 2015/10/24 19:45:23 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.751 2015/12/12 22:25:15 tg Exp $");
#endif #endif
#define MKSH_VERSION "R51 2015/10/24" #define MKSH_VERSION "R52 2015/12/12"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES
@ -576,7 +576,7 @@ char *ucstrstr(char *, const char *);
#define mkssert(e) do { } while (/* CONSTCOND */ 0) #define mkssert(e) do { } while (/* CONSTCOND */ 0)
#endif #endif
#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 511) #if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 521)
#error Must run Build.sh to compile this. #error Must run Build.sh to compile this.
extern void thiswillneverbedefinedIhope(void); extern void thiswillneverbedefinedIhope(void);
int int
@ -2006,8 +2006,6 @@ struct op *tcopy(struct op *, Area *);
char *wdcopy(const char *, Area *); char *wdcopy(const char *, Area *);
const char *wdscan(const char *, int); const char *wdscan(const char *, int);
#define WDS_TPUTS BIT(0) /* tputS (dumpwdvar) mode */ #define WDS_TPUTS BIT(0) /* tputS (dumpwdvar) mode */
#define WDS_KEEPQ BIT(1) /* keep quote characters */
#define WDS_MAGIC BIT(2) /* make MAGIC */
char *wdstrip(const char *, int); char *wdstrip(const char *, int);
void tfree(struct op *, Area *); void tfree(struct op *, Area *);
void dumpchar(struct shf *, int); void dumpchar(struct shf *, int);

View File

@ -1,5 +1,25 @@
/*-
* Copyright (c) 2013, 2014, 2015
* mirabilos <m@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission
* is granted to deal in this work without restriction, including un-
* limited rights to use, publicly perform, distribute, sell, modify,
* merge, give away, or sublicence.
*
* This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
* the utmost extent permitted by applicable law, neither express nor
* implied; without malicious intent or gross negligence. In no event
* may a licensor, author or contributor be held liable for indirect,
* direct, other damage, loss, or other issues arising in any way out
* of dealing in the work, even if advised of the possibility of such
* damage or existence of a defect, except proven that it results out
* of said person's immediate fault when using the work as intended.
*/
@SHFLAGS_DEFNS @SHFLAGS_DEFNS
__RCSID("$MirOS: src/bin/mksh/sh_flags.opt,v 1.3 2015/05/01 23:16:31 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh_flags.opt,v 1.4 2015/12/12 21:08:44 tg Exp $");
@SHFLAGS_ENUMS @SHFLAGS_ENUMS
#define FN(sname,cname,flags,ochar) cname, #define FN(sname,cname,flags,ochar) cname,
#define F0(sname,cname,flags,ochar) cname = 0, #define F0(sname,cname,flags,ochar) cname = 0,

View File

@ -1,6 +1,6 @@
/*- /*-
* Copyright (c) 2006, 2008, 2009, 2013 * Copyright (c) 2006, 2008, 2009, 2013
* mirabilos <tg@mirbsd.org> * mirabilos <m@mirbsd.org>
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@ -18,7 +18,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/strlcpy.c,v 1.9 2015/09/05 19:19:11 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/strlcpy.c,v 1.10 2015/11/29 17:05:02 tg Exp $");
/* /*
* Copy src to string dst of size siz. At most siz-1 characters * Copy src to string dst of size siz. At most siz-1 characters

8
syn.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.106 2015/10/09 19:29:50 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.107 2015/12/12 21:03:53 tg Exp $");
struct nesting_state { struct nesting_state {
int start_token; /* token than began nesting (eg, FOR) */ int start_token; /* token than began nesting (eg, FOR) */
@ -520,6 +520,12 @@ get_command(int cf)
XPfree(vars); XPfree(vars);
} }
if (c == MDPAREN) {
t = block(TBRACE, t, NULL);
t->ioact = t->left->ioact;
t->left->ioact = NULL;
}
return (t); return (t);
} }

16
tree.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.78 2015/10/09 19:29:50 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/tree.c,v 1.79 2015/12/12 19:08:58 tg Exp $");
#define INDENT 8 #define INDENT 8
@ -308,7 +308,7 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
* `...` -> $(...) * `...` -> $(...)
* 'foo' -> "foo" * 'foo' -> "foo"
* x${foo:-"hi"} -> x${foo:-hi} unless WDS_TPUTS * x${foo:-"hi"} -> x${foo:-hi} unless WDS_TPUTS
* x${foo:-'hi'} -> x${foo:-hi} unless WDS_KEEPQ * x${foo:-'hi'} -> x${foo:-hi}
* could change encoding to: * could change encoding to:
* OQUOTE ["'] ... CQUOTE ["'] * OQUOTE ["'] ... CQUOTE ["']
* COMSUB [(`] ...\0 (handle $ ` \ and maybe " in `...` case) * COMSUB [(`] ...\0 (handle $ ` \ and maybe " in `...` case)
@ -320,10 +320,6 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
case ADELIM: case ADELIM:
case CHAR: case CHAR:
c = *wp++; c = *wp++;
if ((opmode & WDS_MAGIC) &&
(ISMAGIC(c) || c == '[' || c == '!' ||
c == '-' || c == ']' || c == '*' || c == '?'))
shf_putc(MAGIC, shf);
shf_putc(c, shf); shf_putc(c, shf);
break; break;
case QCHAR: { case QCHAR: {
@ -335,7 +331,6 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
if (quotelevel == 0) if (quotelevel == 0)
doq = true; doq = true;
} else { } else {
if (!(opmode & WDS_KEEPQ))
doq = false; doq = false;
} }
if (doq) if (doq)
@ -392,21 +387,14 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
shf_putc('}', shf); shf_putc('}', shf);
return (wp); return (wp);
case OPAT: case OPAT:
if (opmode & WDS_MAGIC) {
shf_putc(MAGIC, shf);
shf_putchar(*wp++ | 0x80, shf);
} else {
shf_putchar(*wp++, shf); shf_putchar(*wp++, shf);
shf_putc('(', shf); shf_putc('(', shf);
}
break; break;
case SPAT: case SPAT:
c = '|'; c = '|';
if (0) if (0)
case CPAT: case CPAT:
c = /*(*/ ')'; c = /*(*/ ')';
if (opmode & WDS_MAGIC)
shf_putc(MAGIC, shf);
shf_putc(c, shf); shf_putc(c, shf);
break; break;
} }

View File

@ -1,5 +1,25 @@
/*-
* Copyright (c) 2009, 2011, 2012
* mirabilos <m@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission
* is granted to deal in this work without restriction, including un-
* limited rights to use, publicly perform, distribute, sell, modify,
* merge, give away, or sublicence.
*
* This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
* the utmost extent permitted by applicable law, neither express nor
* implied; without malicious intent or gross negligence. In no event
* may a licensor, author or contributor be held liable for indirect,
* direct, other damage, loss, or other issues arising in any way out
* of dealing in the work, even if advised of the possibility of such
* damage or existence of a defect, except proven that it results out
* of said person's immediate fault when using the work as intended.
*/
#if defined(VARSPEC_DEFNS) #if defined(VARSPEC_DEFNS)
__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.6 2012/11/30 16:45:25 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.7 2015/12/12 21:08:44 tg Exp $");
#define FN(name) /* nothing */ #define FN(name) /* nothing */
#elif defined(VARSPEC_ENUMS) #elif defined(VARSPEC_ENUMS)
#define FN(name) V_##name, #define FN(name) V_##name,