mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix compile/regress fails on compiling without SHOPT_* options
Many compile-time options were broken so that they could not be turned off without causing compile errors and/or regression test failures. This commit now allows the following to be disabled: SHOPT_2DMATCH # two dimensional ${.sh.match} for ${var//pat/str} SHOPT_BGX # one SIGCHLD trap per completed job SHOPT_BRACEPAT # C-shell {...,...} expansions (, required) SHOPT_ESH # emacs/gmacs edit mode SHOPT_HISTEXPAND # csh-style history file expansions SHOPT_MULTIBYTE # multibyte character handling SHOPT_NAMESPACE # allow namespaces SHOPT_STATS # add .sh.stats variable SHOPT_VSH # vi edit mode The following still break ksh when disabled: SHOPT_FIXEDARRAY # fixed dimension indexed array SHOPT_RAWONLY # make viraw the only vi mode SHOPT_TYPEDEF # enable typeset type definitions Compiling without SHOPT_RAWONLY just gives four regression test failures in pty.sh, but turning off SHOPT_FIXEDARRAY and SHOPT_TYPEDEF causes compilation to fail. I've managed to tweak the code to make it compile without those two options, but then dozens of regression test failures occur, often in things nothing directly to do with those options. It looks like the separation between the code for these options and the rest was never properly maintained. Making it possible to disable SHOPT_FIXEDARRAY and SHOPT_TYPEDEF may involve major refactoring and testing and may not be worth it. This commit has far too many tweaks to list. Notables fixes are: src/cmd/ksh93/data/builtins.c, src/cmd/ksh93/data/options.c: - Do not compile in the shell options and documentation for disabled features (braceexpand, emacs/gmacs, vi/viraw), so the shell is not left with no-op options and inaccurate self-doc. src/cmd/ksh93/data/lexstates.c: - Comment the state tables to associte them with their IDs. - In the ST_MACRO table (sh_lexstate9[]), do not make the S_BRACE state for position 123 (ASCII for '{') conditional upon SHOPT_BRACEPAT (brace expansion), otherwise disabling this causes glob patterns of the form {3}(x) (matching 3 x'es) to stop working as well -- and that is ksh globbing, not brace expansion. src/cmd/ksh93/edit/edit.c: ed_read(): - Fixed a bug: SIGWINCH was not handled by the gmacs edit mode. src/cmd/ksh93/sh/name.c: nv_putval(): - The -L/-R left/right adjustment options to typeset do not count zero-width characters. This is the behaviour with SHOPT_MULTIBYTE enabled, regardless of locale. Of course, what a zero-width character is depends on the locale, but control characters are always considered zero-width. So, to avoid a regression, add some fallback code for non-SHOPT_MULTIBYTE builds that skips ASCII control characters (as per iscntrl(3)) so they are still considered to have zero width. src/cmd/ksh93/tests/shtests: - Export the SHOPT_* macros from SHOPT.sh to the tests as environment variables, so the tests can check for them and decide whether or how to run tests based on the compile-time options that the tested binary was presumably compiled with. - Do not run the C.UTF-8 tests if SHOPT_MULTIBYTE is not enabled. src/cmd/ksh93/tests/*.sh: - Add a bunch of checks for SHOPT_* env vars. Since most should have a value 0 (off) or 1 (on), the form ((SHOPT_FOO)) is a convenient way to use them as arithmetic booleans. .github/workflows/ci.yml: - Make GitHub do more testing: run two locale tests (Dutch and Japanese UTF-8 locales), then disable all the SHOPTs that we can currently disable, recompile ksh, and run the tests again.
This commit is contained in:
parent
a9d77bba40
commit
2182ecfa08
40 changed files with 413 additions and 157 deletions
|
@ -285,7 +285,7 @@ word=$(print $'foo\nbar' | ( read line; "$bincat") )
|
|||
if [[ $word != bar ]]
|
||||
then err_exit "pipe to ( read line; $bincat) not working"
|
||||
fi
|
||||
if [[ $(print x{a,b}y) != 'xay xby' ]]
|
||||
if ((SHOPT_BRACEPAT)) && [[ $(print x{a,b}y) != 'xay xby' ]]
|
||||
then err_exit 'brace expansion not working'
|
||||
fi
|
||||
if [[ $(for i in foo bar
|
||||
|
|
|
@ -316,7 +316,8 @@ function test_sub
|
|||
}
|
||||
alias test_sub='test_sub $LINENO'
|
||||
|
||||
set --noglob --nobraceexpand
|
||||
set --noglob
|
||||
((SHOPT_BRACEPAT)) && set --nobraceexpand
|
||||
|
||||
subject='A regular expressions test'
|
||||
|
||||
|
|
|
@ -698,10 +698,11 @@ got=$(export tmp; "$SHELL" -ec \
|
|||
|
||||
# ======
|
||||
# Redirections of the form {varname}>file stopped working if brace expansion was turned off
|
||||
set +B
|
||||
{ redirect {v}>$tmp/v.out && echo ok >&$v; } 2>/dev/null
|
||||
set -B
|
||||
((SHOPT_BRACEPAT)) && set +B
|
||||
{ redirect {v}>$tmp/v.out && echo ok >&$v; } 2>/dev/null && redirect {v}>&-
|
||||
((SHOPT_BRACEPAT)) && set -B
|
||||
[[ -r $tmp/v.out && $(<$tmp/v.out) == ok ]] || err_exit '{varname}>file not working with brace expansion turned off'
|
||||
|
||||
# ...and they didn't work in subshells: https://github.com/ksh93/ksh/issues/167
|
||||
(redirect {v}>$tmp/v.out; echo ok2 >&$v) 2>/dev/null
|
||||
[[ -r $tmp/v.out && $(<$tmp/v.out) == ok2 ]] || err_exit 'redirect {varname}>file not working in a subshell'
|
||||
|
|
|
@ -38,11 +38,12 @@ b=$($SHELL -c '(LC_ALL=debug / 2>/dev/null); /' 2>&1 | sed -e "s,.*: *,," -e "s,
|
|||
b=$($SHELL -c '(LC_ALL=debug; / 2>/dev/null); /' 2>&1 | sed -e "s,.*: *,," -e "s, *\[.*,,")
|
||||
[[ "$b" == "$a" ]] || err_exit "locale not restored after subshell -- expected '$a', got '$b'"
|
||||
|
||||
if((SHOPT_MULTIBYTE)); then
|
||||
# test shift-jis \x81\x40 ... \x81\x7E encodings
|
||||
# (shift char followed by 7 bit ascii)
|
||||
|
||||
typeset -i16 chr
|
||||
for locale in $(PATH=/bin:/usr/bin locale -a 2>/dev/null | grep -i jis)
|
||||
for locale in $(command -p locale -a 2>/dev/null | grep -i jis)
|
||||
do export LC_ALL=$locale
|
||||
for ((chr=0x40; chr<=0x7E; chr++))
|
||||
do c=${chr#16#}
|
||||
|
@ -56,11 +57,16 @@ do export LC_ALL=$locale
|
|||
done
|
||||
done
|
||||
done
|
||||
fi # SHOPT_MULTIBYTE
|
||||
|
||||
# this locale is supported by ast on all platforms
|
||||
# EU for { decimal_point="," thousands_sep="." }
|
||||
|
||||
if((SHOPT_MULTIBYTE)); then
|
||||
locale=C_EU.UTF-8
|
||||
else
|
||||
locale=C_EU
|
||||
fi
|
||||
|
||||
export LC_ALL=C
|
||||
|
||||
|
@ -104,7 +110,11 @@ fi
|
|||
|
||||
#$SHELL -c 'export LANG='$locale'; printf "\u[20ac]\u[20ac]" > $tmp/two_euro_chars.txt'
|
||||
printf $'\342\202\254\342\202\254' > $tmp/two_euro_chars.txt
|
||||
if((SHOPT_MULTIBYTE)); then
|
||||
exp="6 2 6"
|
||||
else
|
||||
exp="6 6 6"
|
||||
fi # SHOPT_MULTIBYTE
|
||||
set -- $($SHELL -c "
|
||||
if builtin wc 2>/dev/null || builtin -f cmd wc 2>/dev/null
|
||||
then unset LC_CTYPE
|
||||
|
@ -191,6 +201,7 @@ got="$(<out)"
|
|||
|
||||
# multibyte identifiers
|
||||
|
||||
if((SHOPT_MULTIBYTE)); then
|
||||
exp=OK
|
||||
got=$(set +x; LC_ALL=C.UTF-8 $SHELL -c $'\u[5929]=OK; print ${\u[5929]}' 2>&1)
|
||||
[[ $got == "$exp" ]] || err_exit "multibyte variable definition/expansion failed -- expected '$exp', got '$got'"
|
||||
|
@ -198,6 +209,7 @@ got=$(set +x; LC_ALL=C.UTF-8 $SHELL -c $'function \u[5929]\n{\nprint OK;\n}; \u[
|
|||
[[ $got == "$exp" ]] || err_exit "multibyte ksh function definition/execution failed -- expected '$exp', got '$got'"
|
||||
got=$(set +x; LC_ALL=C.UTF-8 $SHELL -c $'\u[5929]()\n{\nprint OK;\n}; \u[5929]' 2>&1)
|
||||
[[ $got == "$exp" ]] || err_exit "multibyte posix function definition/execution failed -- expected '$exp', got '$got'"
|
||||
fi # SHOPT_MULTIBYTE
|
||||
|
||||
# this locale is supported by ast on all platforms
|
||||
# mainly used to debug multibyte and message translation code
|
||||
|
@ -205,6 +217,7 @@ got=$(set +x; LC_ALL=C.UTF-8 $SHELL -c $'\u[5929]()\n{\nprint OK;\n}; \u[5929]'
|
|||
|
||||
locale=debug
|
||||
|
||||
if((SHOPT_MULTIBYTE)); then
|
||||
if [[ "$(LC_ALL=$locale $SHELL <<- \+EOF+
|
||||
x=a<1z>b<2yx>c
|
||||
print ${#x}
|
||||
|
@ -212,6 +225,7 @@ if [[ "$(LC_ALL=$locale $SHELL <<- \+EOF+
|
|||
]]
|
||||
then err_exit '${#x} not working with multibyte locales'
|
||||
fi
|
||||
fi # SHOPT_MULTIBYTE
|
||||
|
||||
dir=_not_found_
|
||||
exp=2
|
||||
|
@ -243,9 +257,11 @@ do for cmd in "($lc=$locale;cd $dir)" "$lc=$locale;cd $dir;unset $lc" "function
|
|||
done
|
||||
done
|
||||
|
||||
if((SHOPT_MULTIBYTE)); then
|
||||
exp=123
|
||||
got=$(LC_ALL=debug $SHELL -c "a<2A@>z=$exp; print \$a<2A@>z")
|
||||
[[ $got == $exp ]] || err_exit "multibyte debug locale \$a<2A@>z failed -- expected '$exp', got '$got'"
|
||||
fi # SHOPT_MULTIBYTE
|
||||
|
||||
unset LC_ALL LC_MESSAGES
|
||||
export LANG=debug
|
||||
|
@ -297,7 +313,11 @@ x=$( LC_ALL=debug $SHELL ./script$$.1)
|
|||
|
||||
|
||||
x=$(LC_ALL=debug $SHELL -c 'x="a<2b|>c";print -r -- ${#x}')
|
||||
if((SHOPT_MULTIBYTE)); then
|
||||
(( x == 3 )) || err_exit 'character length of multibyte character should be 3'
|
||||
else
|
||||
(( x == 7 )) || err_exit 'character length of multibyte character should be 7 with SHOPT_MULTIBYTE disabled'
|
||||
fi # SHOPT_MULTIBYTE
|
||||
x=$(LC_ALL=debug $SHELL -c 'typeset -R10 x="a<2b|>c";print -r -- "${x}"')
|
||||
[[ $x == ' a<2b|>c' ]] || err_exit 'typeset -R10 should begin with three spaces'
|
||||
x=$(LC_ALL=debug $SHELL -c 'typeset -L10 x="a<2b|>c";print -r -- "${x}"')
|
||||
|
|
|
@ -198,8 +198,27 @@ test_has_iszero
|
|||
# printf formatting options as well as checking for correct float scaling
|
||||
# of the fractional parts.
|
||||
|
||||
if ((SHOPT_BRACEPAT))
|
||||
then set -- {'','-'}{0..1}.{0,9}{0,9}{0,1,9}{0,1,9}
|
||||
else set -- 0.0000 0.0001 0.0009 0.0010 0.0011 0.0019 0.0090 0.0091 0.0099 \
|
||||
0.0900 0.0901 0.0909 0.0910 0.0911 0.0919 0.0990 0.0991 0.0999 \
|
||||
0.9000 0.9001 0.9009 0.9010 0.9011 0.9019 0.9090 0.9091 0.9099 \
|
||||
0.9900 0.9901 0.9909 0.9910 0.9911 0.9919 0.9990 0.9991 0.9999 \
|
||||
1.0000 1.0001 1.0009 1.0010 1.0011 1.0019 1.0090 1.0091 1.0099 \
|
||||
1.0900 1.0901 1.0909 1.0910 1.0911 1.0919 1.0990 1.0991 1.0999 \
|
||||
1.9000 1.9001 1.9009 1.9010 1.9011 1.9019 1.9090 1.9091 1.9099 \
|
||||
1.9900 1.9901 1.9909 1.9910 1.9911 1.9919 1.9990 1.9991 1.9999 \
|
||||
-0.0000 -0.0001 -0.0009 -0.0010 -0.0011 -0.0019 -0.0090 -0.0091 -0.0099 \
|
||||
-0.0900 -0.0901 -0.0909 -0.0910 -0.0911 -0.0919 -0.0990 -0.0991 -0.0999 \
|
||||
-0.9000 -0.9001 -0.9009 -0.9010 -0.9011 -0.9019 -0.9090 -0.9091 -0.9099 \
|
||||
-0.9900 -0.9901 -0.9909 -0.9910 -0.9911 -0.9919 -0.9990 -0.9991 -0.9999 \
|
||||
-1.0000 -1.0001 -1.0009 -1.0010 -1.0011 -1.0019 -1.0090 -1.0091 -1.0099 \
|
||||
-1.0900 -1.0901 -1.0909 -1.0910 -1.0911 -1.0919 -1.0990 -1.0991 -1.0999 \
|
||||
-1.9000 -1.9001 -1.9009 -1.9010 -1.9011 -1.9019 -1.9090 -1.9091 -1.9099 \
|
||||
-1.9900 -1.9901 -1.9909 -1.9910 -1.9911 -1.9919 -1.9990 -1.9991 -1.9999
|
||||
fi
|
||||
unset i tf pf; typeset -F 3 tf
|
||||
for i in {'','-'}{0..1}.{0,9}{0,9}{0,1,9}{0,1,9}
|
||||
for i
|
||||
do tf=$i
|
||||
pf=${ printf '%.3f' tf ;}
|
||||
if [[ $tf != "$pf" ]]
|
||||
|
@ -207,7 +226,7 @@ do tf=$i
|
|||
fi
|
||||
done
|
||||
unset i tf pf; typeset -lF 3 tf
|
||||
for i in {'','-'}{0..1}.{0,9}{0,9}{0,1,9}{0,1,9}
|
||||
for i
|
||||
do tf=$i
|
||||
pf=${ printf '%.3Lf' tf ;}
|
||||
if [[ $tf != "$pf" ]]
|
||||
|
@ -215,7 +234,7 @@ do tf=$i
|
|||
fi
|
||||
done
|
||||
unset i tf pf; typeset -E 3 tf
|
||||
for i in {'','-'}{0..1}.{0,9}{0,9}{0,1,9}{0,1,9}
|
||||
for i
|
||||
do tf=$i
|
||||
pf=${ printf '%.3g' tf ;}
|
||||
if [[ $tf != "$pf" ]]
|
||||
|
@ -223,7 +242,7 @@ do tf=$i
|
|||
fi
|
||||
done
|
||||
unset i tf pf; typeset -lE 3 tf
|
||||
for i in {'','-'}{0..1}.{0,9}{0,9}{0,1,9}{0,1,9}
|
||||
for i
|
||||
do tf=$i
|
||||
pf=${ printf '%.3Lg' tf ;}
|
||||
if [[ $tf != "$pf" ]]
|
||||
|
|
|
@ -30,6 +30,11 @@ integer Errors=0
|
|||
|
||||
[[ -d $tmp && -w $tmp && $tmp == "$PWD" ]] || { err\_exit "$LINENO" '$tmp not set; run this from shtests. Aborting.'; exit 1; }
|
||||
|
||||
if((!SHOPT_NAMESPACE))
|
||||
then err\_exit "$LINENO" 'warning: shell compiled without SHOPT_NAMESPACE; skipping tests'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
foo=abc
|
||||
typeset -C bar=(x=3 y=4 t=7)
|
||||
typeset -A z=([abc]=qqq)
|
||||
|
|
|
@ -202,20 +202,21 @@ rm .profile
|
|||
|
||||
# { exec interactive login_shell restricted xtrace } in the following test
|
||||
|
||||
for opt in \
|
||||
set -- \
|
||||
allexport all-export all_export \
|
||||
bgnice bg-nice bg_nice \
|
||||
clobber emacs \
|
||||
clobber \
|
||||
errexit err-exit err_exit \
|
||||
glob \
|
||||
globstar glob-star glob_star \
|
||||
gmacs \
|
||||
ignoreeof ignore-eof ignore_eof \
|
||||
keyword log markdirs monitor notify \
|
||||
pipefail pipe-fail pipe_fail \
|
||||
trackall track-all track_all \
|
||||
unset verbose vi \
|
||||
viraw vi-raw vi_raw
|
||||
unset verbose
|
||||
((SHOPT_ESH)) && set -- "$@" emacs gmacs
|
||||
((SHOPT_VSH)) && set -- "$@" vi viraw vi-raw vi_raw
|
||||
for opt
|
||||
do old=$opt
|
||||
if [[ ! -o $opt ]]
|
||||
then old=no$opt
|
||||
|
@ -394,15 +395,16 @@ got=$(
|
|||
[[ $got == @((12|21)(12|21)) ]] || err_exit "& job delayed by --pipefail, expected '$exp', got '$got'"
|
||||
$SHELL -c '[[ $- == *c* ]]' || err_exit 'option c not in $-'
|
||||
> $tmp/.profile
|
||||
for i in i l r s D E a b e f h k n t u v x B C G H
|
||||
for i in i l r s D E a b e f h k n t u v x $(let SHOPT_BRACEPAT && echo B) C G $(let SHOPT_HISTEXPAND && echo H)
|
||||
do HOME=$tmp ENV=/./dev/null $SHELL -$i >/dev/null 2>&1 <<- ++EOF++ || err_exit "option $i not in \$-"
|
||||
[[ \$- == *$i* ]] || exit 1
|
||||
++EOF++
|
||||
done
|
||||
letters=ilrabefhknuvxBCGE
|
||||
letters=ilrabefhknuvx$(let SHOPT_BRACEPAT && echo B)CGE
|
||||
integer j=0
|
||||
for i in interactive login restricted allexport notify errexit \
|
||||
noglob trackall keyword noexec nounset verbose xtrace braceexpand \
|
||||
noglob trackall keyword noexec nounset verbose xtrace \
|
||||
$(let SHOPT_BRACEPAT && echo braceexpand) \
|
||||
noclobber globstar rc
|
||||
do HOME=$tmp ENV=/./dev/null $SHELL -o $i >/dev/null 2>&1 <<- ++EOF++ || err_exit "option $i not equivalent to ${letters:j:1}"
|
||||
[[ \$- == *${letters:j:1}* ]] || exit 1
|
||||
|
@ -551,6 +553,7 @@ fi
|
|||
|
||||
# ======
|
||||
# Brace expansion could not be turned off in command substitutions (rhbz#1078698)
|
||||
if((SHOPT_BRACEPAT)); then
|
||||
set -B
|
||||
expect='test{1,2}'
|
||||
actual=$(set +B; echo `echo test{1,2}`)
|
||||
|
@ -562,6 +565,7 @@ actual=$(set +B; echo $(echo test{1,2}))
|
|||
actual=$(set +B; echo ${ echo test{1,2}; })
|
||||
[[ $actual == "$expect" ]] || err_exit 'Brace expansion not turned off in ${ comsub; }' \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
fi # SHOPT_BRACEPAT
|
||||
|
||||
# ======
|
||||
# ksh 93u+ did not correctly handle the combination of pipefail and (errexit or the ERR trap).
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
# called 'pty', which allows for scripting interactive sessions and which is
|
||||
# installed in arch/*/bin while building. To understand these tests, first
|
||||
# read the pty manual by running: arch/*/bin/pty --man
|
||||
|
||||
#
|
||||
# Do not globally set the locale; these tests must pass for all locales.
|
||||
#
|
||||
# The # err_exit # comments are to enable shtests to count the tests.
|
||||
|
||||
# the trickiest part of the tests is avoiding typeahead
|
||||
|
@ -52,19 +54,18 @@ stty erase ^H kill ^X
|
|||
|
||||
bintrue=$(whence -p true)
|
||||
|
||||
x=$( $SHELL <<- \EOF
|
||||
x=$( "$SHELL" 2>&1 <<- \EOF
|
||||
trap 'exit 0' EXIT
|
||||
bintrue=$(whence -p true)
|
||||
set -o monitor
|
||||
{
|
||||
eval $'set -o vi\npty $bintrue'
|
||||
eval $'command set -o vi 2>/dev/null\npty $bintrue'
|
||||
} < /dev/null & pid=$!
|
||||
#sleep 1
|
||||
jobs
|
||||
kill $$
|
||||
EOF
|
||||
)
|
||||
[[ $x == *Stop* ]] && err_exit 'monitor mode enabled incorrectly causes job to stop'
|
||||
[[ $x == *Stop* ]] && err_exit "monitor mode enabled incorrectly causes job to stop (got $(printf %q "$x"))"
|
||||
|
||||
if [[ -o xtrace ]]
|
||||
then debug=--debug=1
|
||||
|
@ -86,7 +87,10 @@ function tst
|
|||
done
|
||||
}
|
||||
|
||||
export PS1=':test-!: ' PS2='> ' PS4=': ' ENV=/./dev/null EXINIT= HISTFILE= TERM=dumb VISUAL=vi LC_ALL=C
|
||||
# VISUAL, or if that is not set, EDITOR, automatically sets vi, gmacs or emacs mode if
|
||||
# its value matches *[Vv][Ii]*, *gmacs* or *macs*, respectively. See put_ed() in init.c.
|
||||
unset EDITOR
|
||||
export VISUAL=vi PS1=':test-!: ' PS2='> ' PS4=': ' ENV=/./dev/null EXINIT= HISTFILE= TERM=dumb
|
||||
|
||||
if ! pty $bintrue < /dev/null
|
||||
then err_exit pty command hangs on $bintrue -- tests skipped
|
||||
|
@ -163,7 +167,7 @@ u (Killed|Done)
|
|||
!
|
||||
|
||||
# err_exit #
|
||||
tst $LINENO <<"!"
|
||||
((SHOPT_VSH)) && tst $LINENO <<"!"
|
||||
L POSIX sh 091(C)
|
||||
|
||||
# If the User Portability Utilities Option is supported and shell
|
||||
|
@ -179,7 +183,7 @@ u ^hello\r?\n$
|
|||
!
|
||||
|
||||
# err_exit #
|
||||
tst $LINENO <<"!"
|
||||
((SHOPT_VSH)) && tst $LINENO <<"!"
|
||||
L POSIX sh 093(C)
|
||||
|
||||
# If the User Portability Utilities Option is supported and shell
|
||||
|
@ -195,7 +199,7 @@ u ^goodbye\r?\n$
|
|||
!
|
||||
|
||||
# err_exit #
|
||||
tst $LINENO <<"!"
|
||||
((SHOPT_VSH)) && tst $LINENO <<"!"
|
||||
L POSIX sh 094(C)
|
||||
|
||||
# If the User Portability Utilities Option is supported and shell
|
||||
|
@ -242,7 +246,7 @@ r history
|
|||
fi
|
||||
|
||||
# err_exit #
|
||||
tst $LINENO <<"!"
|
||||
((SHOPT_VSH)) && tst $LINENO <<"!"
|
||||
L POSIX sh 097(C)
|
||||
|
||||
# If the User Portability Utilities Option is supported and shell
|
||||
|
@ -303,7 +307,7 @@ u ^ok\r?\n$
|
|||
!
|
||||
|
||||
# err_exit #
|
||||
tst $LINENO <<"!"
|
||||
((SHOPT_VSH)) && tst $LINENO <<"!"
|
||||
L POSIX sh 101(C)
|
||||
|
||||
# If the User Portability Utilities Option is supported and shell
|
||||
|
@ -368,7 +372,7 @@ if [[ $(id -u) == 0 ]]
|
|||
then print -u2 "\t${Command}[$LINENO]: warning: running as root: skipping test POSIX sh 111(C)"
|
||||
else
|
||||
# err_exit #
|
||||
tst $LINENO <<"!"
|
||||
((SHOPT_VSH)) && tst $LINENO <<"!"
|
||||
L POSIX sh 111(C)
|
||||
|
||||
# If the User Portability Utilities Option is supported and shell
|
||||
|
@ -395,7 +399,7 @@ fi
|
|||
# It is left here for re-enabling temporarily if related changes in ksh need testing.
|
||||
: <<\end_disabled
|
||||
# err_(don't count me)_exit #
|
||||
TMPDIR=/tmp tst $LINENO <<"!"
|
||||
((SHOPT_VSH)) && TMPDIR=/tmp tst $LINENO <<"!"
|
||||
L POSIX sh 137(C)
|
||||
|
||||
# If the User Portability Utilities Option is supported and shell
|
||||
|
@ -420,7 +424,7 @@ if [[ $(id -u) == 0 ]]
|
|||
then print -u2 "\t${Command}[$LINENO]: warning: running as root: skipping test POSIX sh 251(C)"
|
||||
else
|
||||
# err_exit #
|
||||
tst $LINENO <<"!"
|
||||
((SHOPT_VSH)) && tst $LINENO <<"!"
|
||||
L POSIX sh 251(C)
|
||||
|
||||
# If the User Portability Utilities Option is supported and shell
|
||||
|
@ -480,6 +484,7 @@ disabled
|
|||
|
||||
# err_exit #
|
||||
# Test file name completion in vi mode
|
||||
if((SHOPT_VSH)); then
|
||||
mkdir "/tmp/fakehome_$$" && tst $LINENO <<!
|
||||
L vi mode file name completion
|
||||
|
||||
|
@ -492,49 +497,33 @@ w echo ~/tes\t
|
|||
u ^/tmp/fakehome_$$/testfile_$$\r?\n$
|
||||
!
|
||||
rm -r "/tmp/fakehome_$$"
|
||||
fi # SHOPT_VSH
|
||||
|
||||
# err_exit #
|
||||
LC_ALL=C tst $LINENO <<"!"
|
||||
L raw Bourne mode literal tab characters with wide characters disabled
|
||||
VISUAL='' tst $LINENO <<"!"
|
||||
L raw Bourne mode literal tab characters
|
||||
|
||||
# This gets handled by ed_read() in edit.c; it does not expand tab
|
||||
# characters on the command line.
|
||||
# With wide characters (e.g. UTF-8) disabled, raw mode is handled by ed_read()
|
||||
# in edit.c; it does not expand tab characters on the command line.
|
||||
# With wide characters enabled, and if vi mode is compiled in, raw mode is
|
||||
# handled by ed_viread() in vi.c (even though vi mode is off); it expands tab
|
||||
# characters to spaces on the command line. See slowread() in io.c.
|
||||
|
||||
d 20
|
||||
p :test-1:
|
||||
w set +o vi +o emacs
|
||||
p :test-2:
|
||||
w true /de\tv/nu\tl\tl
|
||||
r ^:test-2: true (/de\tv/nu\tl\tl|/de v/nu l l)\r\n$
|
||||
p :test-3:
|
||||
r ^:test-1: true (/de\tv/nu\tl\tl|/de v/nu l l)\r\n$
|
||||
p :test-2:
|
||||
!
|
||||
|
||||
# err_exit #
|
||||
LC_ALL=C.UTF-8 tst $LINENO <<"!"
|
||||
L raw Bourne mode literal tab characters with wide characters enabled
|
||||
|
||||
# This gets handled by ed_viread() in vi.c (even though vi mode is off);
|
||||
# it expands tab characters to spaces on the command line.
|
||||
|
||||
d 20
|
||||
p :test-1:
|
||||
w set +o vi +o emacs
|
||||
p :test-2:
|
||||
w true /de\tv/nu\tl\tl
|
||||
r ^:test-2: true /de v/nu l l\r\n$
|
||||
p :test-3:
|
||||
!
|
||||
|
||||
# err_exit #
|
||||
LC_ALL=C.UTF-8 tst $LINENO <<"!"
|
||||
VISUAL='' tst $LINENO <<"!"
|
||||
L raw Bourne mode backslash handling
|
||||
|
||||
# The escaping backslash feature should be disabled in the raw Bourne mode.
|
||||
# This is tested with both erase and kill characters.
|
||||
|
||||
d 20
|
||||
p :test-1:
|
||||
w set +o vi +o emacs; stty erase ^H kill ^X
|
||||
w stty erase ^H kill ^X
|
||||
p :test-2:
|
||||
w true string\\\\\cH\cH
|
||||
r ^:test-2: true string\r\n$
|
||||
|
@ -545,16 +534,19 @@ r ^:test-3: true correct\r\n$
|
|||
|
||||
# err_exit #
|
||||
# err_exit #
|
||||
for mode in emacs vi; do
|
||||
tst $LINENO << !
|
||||
set --
|
||||
((SHOPT_VSH)) && set -- "$@" vi
|
||||
((SHOPT_ESH)) && set -- "$@" emacs gmacs
|
||||
for mode do
|
||||
VISUAL=$mode tst $LINENO << !
|
||||
L escaping backslashes in $mode mode
|
||||
|
||||
# Backslashes should only be escaped if the previous input was a backslash.
|
||||
# Other backslashes stored in the input buffer should be erased normally.
|
||||
|
||||
d 20
|
||||
d 10
|
||||
p :test-1:
|
||||
w set -o $mode; stty erase ^H
|
||||
w stty erase ^H
|
||||
p :test-2:
|
||||
w true string\\\\\\\\\\cH\\cH\\cH
|
||||
r ^:test-2: true string\\r\\n$
|
||||
|
|
|
@ -8,7 +8,7 @@ valgrindflags='--xml=yes --log-file=/dev/null --track-origins=yes --read-var-inf
|
|||
|
||||
USAGE=$'
|
||||
[-s8?
|
||||
@(#)$Id: shtests (ksh 93u+m) 2020-09-02 $
|
||||
@(#)$Id: shtests (ksh 93u+m) 2021-02-04 $
|
||||
]
|
||||
[-author?David Korn <dgk@research.att.com>]
|
||||
[-author?Glenn Fowler <gsf@research.att.com>]
|
||||
|
@ -270,8 +270,8 @@ case $SHELL in
|
|||
*) SHELL=$(whence $SHELL);;
|
||||
esac
|
||||
PATH=$(
|
||||
PATH=/run/current-system/sw/bin:/usr/xpg7/bin:/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin:$PATH
|
||||
getconf PATH 2>/dev/null || { builtin getconf 2>/dev/null && getconf PATH; }
|
||||
builtin getconf 2>/dev/null || PATH=/run/current-system/sw/bin:/usr/xpg7/bin:/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin:$PATH
|
||||
getconf PATH 2>/dev/null
|
||||
) || PATH=/bin:/usr/bin
|
||||
if [[ -d /usr/ucb ]]
|
||||
then PATH=$PATH:/usr/ucb
|
||||
|
@ -310,6 +310,18 @@ fi
|
|||
# (some tests must unset or modify $HISTFILE, so set $HOME instead)
|
||||
export HOME=$tmp
|
||||
|
||||
# make the SHOPT_* macros available to the tests as environment variables
|
||||
SHOPT()
|
||||
{
|
||||
[[ $1 == *=* ]] && eval "export SHOPT_${ printf %q "${1%%=*}"; }=${ printf %q "${1#*=}"; }"
|
||||
}
|
||||
. "${SHOPTFILE:-../SHOPT.sh}"
|
||||
unset -f SHOPT
|
||||
if (( !SHOPT_MULTIBYTE && utf8 && !posix && !compile ))
|
||||
then echo "The -u/--utf8 option is unavailable as SHOPT_MULTIBYTE is turned off in ${SHOPTFILE:-SHOPT.sh}." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if (( compile ))
|
||||
then if whence $SHCOMP > /dev/null
|
||||
then :
|
||||
|
@ -352,7 +364,7 @@ do [[ $i == *.sh ]] || i+='.sh'
|
|||
if (( posix || utf8 ))
|
||||
then locales=
|
||||
(( posix )) && locales+=" ${LANG:-C}"
|
||||
[[ $utf8 == 0 || $i == $setslocale ]] || locales+=" C.UTF-8"
|
||||
[[ $utf8 == 0 || $i == $setslocale ]] || ((!SHOPT_MULTIBYTE)) || locales+=" C.UTF-8"
|
||||
for lang in $locales
|
||||
do o=$u
|
||||
tmp_s=$tmp/$u.$lang
|
||||
|
|
|
@ -260,8 +260,12 @@ fi
|
|||
if [[ ${var//+(\S)/Q} != 'Q Q' ]]
|
||||
then err_exit '${var//+(\S)/Q} not workding'
|
||||
fi
|
||||
|
||||
var=$($SHELL -c 'v=/vin:/usr/vin r=vin; : ${v//vin/${r//v/b}};typeset -p .sh.match') 2> /dev/null
|
||||
[[ $var == 'typeset -a .sh.match=((vin vin) )' ]] || err_exit '.sh.match not correct when replacement pattern contains a substring match'
|
||||
((SHOPT_2DMATCH)) && exp='typeset -a .sh.match=((vin vin) )' || exp='typeset -a .sh.match=(vin)'
|
||||
[[ $var == "$exp" ]] || err_exit '.sh.match not correct when replacement pattern contains a substring match' \
|
||||
"(expected $(printf %q "$exp"), got $(printf %q "$var"))"
|
||||
|
||||
foo='foo+bar+'
|
||||
[[ $(print -r -- ${foo//+/'|'}) != 'foo|bar|' ]] && err_exit "\${foobar//+/'|'}"
|
||||
[[ $(print -r -- ${foo//+/"|"}) != 'foo|bar|' ]] && err_exit '${foobar//+/"|"}'
|
||||
|
@ -523,7 +527,8 @@ fi
|
|||
string='foo(d:\nt\box\something)bar'
|
||||
expected='d:\nt\box\something'
|
||||
[[ ${string/*\(+([!\)])\)*/\1} == "$expected" ]] || err_exit "substring expansion failed '${string/*\(+([!\)])\)*/\1}' returned -- '$expected' expected"
|
||||
if [[ $($SHELL -c $'export LC_ALL=C.UTF-8; print -r "\342\202\254\342\202\254\342\202\254\342\202\254w\342\202\254\342\202\254\342\202\254\342\202\254" | wc -m' 2>/dev/null) == 10 ]]
|
||||
if ((SHOPT_MULTIBYTE)) &&
|
||||
[[ $($SHELL -c $'export LC_ALL=C.UTF-8; print -r "\342\202\254\342\202\254\342\202\254\342\202\254w\342\202\254\342\202\254\342\202\254\342\202\254" | wc -m' 2>/dev/null) == 10 ]]
|
||||
then LC_ALL=C.UTF-8 $SHELL -c b1=$'"\342\202\254\342\202\254\342\202\254\342\202\254w\342\202\254\342\202\254\342\202\254\342\202\254"; [[ ${b1:4:1} == w ]]' || err_exit 'multibyte ${var:offset:len} not working correctly'
|
||||
fi
|
||||
{ $SHELL -c 'unset x;[[ ${SHELL:$x} == $SHELL ]]';} 2> /dev/null || err_exit '${var:$x} fails when x is not set'
|
||||
|
@ -581,6 +586,7 @@ do i=$1
|
|||
done
|
||||
|
||||
#multibyte locale tests
|
||||
if((SHOPT_MULTIBYTE)); then
|
||||
x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:0:1}" == a || err_exit ${x:0:1} should be a'
|
||||
x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:1:1}" == "<2b|>" || err_exit ${x:1:1} should be <2b|>'
|
||||
x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:3:1}" == "<3d|\\>" || err_exit ${x:3:1} should be <3d|\>'
|
||||
|
@ -591,6 +597,7 @@ x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x: -2:1}" == "<3d|\\>" || err
|
|||
x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:1:3}" == "<2b|>c<3d|\\>" || err_exit ${x:1:3} should be <2b|>c<3d|\>'
|
||||
x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:1:20}" == "<2b|>c<3d|\\>e" || err_exit ${x:1:20} should be <2b|>c<3d|\>e'
|
||||
x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x#??}" == "c<3d|\\>e" || err_exit "${x#??} should be c<3d|\>e'
|
||||
fi # SHOPT_MULTIBYTE
|
||||
|
||||
x='a one and a two'
|
||||
[[ "${x//~(E)\<.\>/}" == ' one and two' ]] || err_exit "\< and \> not working in with ere's"
|
||||
|
|
|
@ -717,7 +717,11 @@ actual=$(
|
|||
expect=$'4\n3\n3\n2\n1'
|
||||
[[ $actual == "$expect" ]] || err_exit "\${.sh.subshell} failure (expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
set -- {1..32768}
|
||||
unset IFS
|
||||
if ((SHOPT_BRACEPAT)) && command set -o braceexpand
|
||||
then set -- {1..32768}
|
||||
else set -- $(awk 'BEGIN { for(i=1;i<=32768;i++) print i; }')
|
||||
fi
|
||||
(( $# == 32768 )) || err_exit "\$# failed -- expected 32768, got $#"
|
||||
set --
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue