1
0
Fork 0
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:
Martijn Dekker 2021-02-08 17:16:43 +00:00
parent a9d77bba40
commit 2182ecfa08
40 changed files with 413 additions and 157 deletions

View file

@ -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

View file

@ -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'

View file

@ -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'

View file

@ -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}"')

View file

@ -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" ]]

View file

@ -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)

View file

@ -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).

View file

@ -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$

View file

@ -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

View file

@ -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"

View file

@ -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 --