Skip to content

Commit

Permalink
test: fix compatibility issues for old Bash versions
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Apr 10, 2020
1 parent 6c2f863 commit b2c7d1c
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 56 deletions.
17 changes: 11 additions & 6 deletions lib/core-test.sh
Expand Up @@ -97,6 +97,7 @@ function ble/test/section#report {

function ble/test/.read-arguments {
local _stdout _stderr _exit _ret
local qstdout qstderr qexit qret
local -a buff=()
while (($#)); do
local arg=$1; shift
Expand All @@ -105,14 +106,18 @@ function ble/test/.read-arguments {
local ret; ble/string#trim "${arg#'#'}"
title=$ret ;;
(stdout[:=]*)
[[ ${_stdout+set} ]] && _stdout=$_stdout$'\n'
[[ $qstdout ]] && _stdout=$_stdout$'\n'
qstdout=1
_stdout=$_stdout${arg#*[:=]} ;;
(stderr[:=]*)
[[ ${_stderr+set} ]] && _stderr=$_stderr$'\n'
[[ $qstderr ]] && _stderr=$_stderr$'\n'
qstderr=1
_stderr=$_stderr${arg#*[:=]} ;;
(ret[:=]*)
qret=1
_ret=${arg#*[:=]} ;;
(exit[:=]*)
qexit=1
_exit=${arg#*[:=]} ;;
(code[:=]*)
((${#buff[@]})) && ble/array#push buff $'\n'
Expand All @@ -123,10 +128,10 @@ function ble/test/.read-arguments {
esac
done

[[ ${_stdout+set} ]] && item_expect[0]=$_stdout
[[ ${_stderr+set} ]] && item_expect[1]=$_stderr
[[ ${_exit+set} ]] && item_expect[2]=$_exit
[[ ${_ret+set} ]] && item_expect[3]=$_ret
[[ $qstdout ]] && item_expect[0]=$_stdout
[[ $qstderr ]] && item_expect[1]=$_stderr
[[ $qexit ]] && item_expect[2]=$_exit
[[ $qret ]] && item_expect[3]=$_ret

# 何もチェックが指定されなかった時は終了ステータスをチェックする
((${#item_expect[@]})) || item_expect[2]=0
Expand Down
127 changes: 89 additions & 38 deletions lib/test-util.sh
Expand Up @@ -2,7 +2,7 @@

ble-import lib/core-test

ble/test/start-section 'util' 616
ble/test/start-section 'util' 648

# bleopt

Expand Down Expand Up @@ -497,7 +497,7 @@ ble/test ble/util/setexit 255 exit=255

# ble/string#split
(
function status { echo "${#a[@]}:(${a[*]})"; }
function status { echo "${#a[@]}:(""${a[*]}"")"; }
nl=$'\n'
ble/test 'ble/string#split a , "" ; status' stdout='1:()'
ble/test 'ble/string#split a , "1" ; status' stdout='1:(1)'
Expand Down Expand Up @@ -528,7 +528,7 @@ ble/test ble/util/setexit 255 exit=255

# ble/string#split-lines
(
function status { echo "${#a[@]}:(${a[*]})"; }
function status { echo "${#a[@]}:(""${a[*]}"")"; }
nl=$'\n' ht=$'\t'
ble/test 'ble/string#split-lines a "" ; status' stdout='1:()'
ble/test 'ble/string#split-lines a "1" ; status' stdout='1:(1)'
Expand Down Expand Up @@ -762,6 +762,43 @@ ble/test ble/util/setexit 255 exit=255
ble/test 'ble/util/strlen aαあ' ret=6
)

# ble/util/substr
(
ble/test 'ble/util/substr' ret=
ble/test 'ble/util/substr ""' ret=
ble/test 'ble/util/substr a' ret=
ble/test 'ble/util/substr "" 0' ret=
ble/test 'ble/util/substr "" 1' ret=
ble/test 'ble/util/substr a 0' ret=
ble/test 'ble/util/substr a 1' ret=
ble/test 'ble/util/substr a 2' ret=
ble/test 'ble/util/substr "" 0 0' ret=
ble/test 'ble/util/substr "" 0 1' ret=
ble/test 'ble/util/substr "" 1 1' ret=
ble/test 'ble/util/substr a 0 0' ret=
ble/test 'ble/util/substr a 1 0' ret=
ble/test 'ble/util/substr a 0 1' ret=a
ble/test 'ble/util/substr a 1 1' ret=
ble/test 'ble/util/substr abc 1 0' ret=
ble/test 'ble/util/substr abc 1 1' ret=b
ble/test 'ble/util/substr abc 1 2' ret=bc
ble/test 'ble/util/substr abc 0 0' ret=
ble/test 'ble/util/substr abc 0 1' ret=a
ble/test 'ble/util/substr abc 0 3' ret=abc
ble/test 'ble/util/substr abc 0 4' ret=abc
ble/test 'ble/util/substr abc 3 0' ret=
ble/test 'ble/util/substr abc 3 1' ret=
ble/test 'ble/util/substr abc 4 0' ret=
ble/test 'ble/util/substr abc 4 1' ret=

ble/test 'ble/util/substr あいう 0 3' ret=あ
ble/test 'ble/util/substr あいう 3 6' ret=いう
ble/test 'ble/util/substr あいう 0 1' ret=$'\xe3'
ble/test 'ble/util/substr あいう 1 2' ret=$'\x81\x82'
ble/test 'ble/util/substr あいう 1 4' ret=$'\x81\x82\xe3\x81'
ble/test 'ble/util/substr あいう 7 5' ret=$'\x81\x86'
)

# ble/path#remove{,-glob}
(
for cmd in ble/path#{remove,remove-glob}; do
Expand Down Expand Up @@ -875,37 +912,37 @@ ble/test ble/util/setexit 255 exit=255
# ble/builtin/trap
(
# 0 / EXIT (special trap)
ble/builtin/trap 'echo TRAPEXIT' 0
ble/test 'ble/builtin/trap/invoke 0' stdout=TRAPEXIT
ble/test 'ble/builtin/trap/invoke EXIT' stdout=TRAPEXIT
ble/builtin/trap 'echo TRAPEXIT1' 0
ble/test 'ble/builtin/trap/invoke 0' stdout=TRAPEXIT1
ble/test 'ble/builtin/trap/invoke EXIT' stdout=TRAPEXIT1
ble/builtin/trap 0
ble/test 'ble/builtin/trap/invoke 0' stdout=

ble/builtin/trap 'echo TRAPEXIT' EXIT
ble/test 'ble/builtin/trap/invoke 0' stdout=TRAPEXIT
ble/test 'ble/builtin/trap/invoke EXIT' stdout=TRAPEXIT
ble/builtin/trap 'echo TRAPEXIT2' EXIT
ble/test 'ble/builtin/trap/invoke 0' stdout=TRAPEXIT2
ble/test 'ble/builtin/trap/invoke EXIT' stdout=TRAPEXIT2
ble/builtin/trap EXIT
ble/test 'ble/builtin/trap/invoke 0' stdout=

# 1 / HUP / SIGHUP (signal trap)
ble/builtin/trap 'echo TRAPHUP' 1
ble/test 'ble/builtin/trap/invoke 1' stdout=TRAPHUP
ble/test 'ble/builtin/trap/invoke HUP' stdout=TRAPHUP
ble/test 'ble/builtin/trap/invoke SIGHUP' stdout=TRAPHUP
ble/builtin/trap 'echo TRAPHUP1' 1
ble/test 'ble/builtin/trap/invoke 1' stdout=TRAPHUP1
ble/test 'ble/builtin/trap/invoke HUP' stdout=TRAPHUP1
ble/test 'ble/builtin/trap/invoke SIGHUP' stdout=TRAPHUP1
ble/builtin/trap 1
ble/test 'ble/builtin/trap/invoke 1' stdout=

ble/builtin/trap 'echo TRAPHUP' HUP
ble/test 'ble/builtin/trap/invoke 1' stdout=TRAPHUP
ble/test 'ble/builtin/trap/invoke HUP' stdout=TRAPHUP
ble/test 'ble/builtin/trap/invoke SIGHUP' stdout=TRAPHUP
ble/builtin/trap 'echo TRAPHUP2' HUP
ble/test 'ble/builtin/trap/invoke 1' stdout=TRAPHUP2
ble/test 'ble/builtin/trap/invoke HUP' stdout=TRAPHUP2
ble/test 'ble/builtin/trap/invoke SIGHUP' stdout=TRAPHUP2
ble/builtin/trap HUP
ble/test 'ble/builtin/trap/invoke HUP' stdout=

ble/builtin/trap 'echo TRAPHUP' SIGHUP
ble/test 'ble/builtin/trap/invoke 1' stdout=TRAPHUP
ble/test 'ble/builtin/trap/invoke HUP' stdout=TRAPHUP
ble/test 'ble/builtin/trap/invoke SIGHUP' stdout=TRAPHUP
ble/builtin/trap 'echo TRAPHUP3' SIGHUP
ble/test 'ble/builtin/trap/invoke 1' stdout=TRAPHUP3
ble/test 'ble/builtin/trap/invoke HUP' stdout=TRAPHUP3
ble/test 'ble/builtin/trap/invoke SIGHUP' stdout=TRAPHUP3
ble/builtin/trap SIGHUP
ble/test 'ble/builtin/trap/invoke HUP' stdout=

Expand All @@ -932,12 +969,12 @@ ble/test ble/util/setexit 255 exit=255
ble/test 'ble/util/readfile ret <(:)' ret=

# mapfile
function status { echo "${#a[*]}:(${a[*]})"; }
function status { echo "${#a[*]}:(""${a[*]}"")"; }
ble/test "ble/util/mapfile a < <(echo hello); status" stdout='1:(hello)'
ble/test "ble/util/mapfile a < <(echo -n hello); status" stdout='1:(hello)'
ble/test "ble/util/mapfile a < <(echo hello; echo world); status" stdout='2:(hello world)'
ble/test "ble/util/mapfile a < <(echo hello; echo -n world); status" stdout='2:(hello world)'
ble/test "ble/util/mapfile a < <(printf '%s\n' h{1..4}); status" stdout='4:(h1 h2 h3 h4)'
ble/test "ble/util/mapfile a < <(printf '%s\n' h1 h2 h3 h4); status" stdout='4:(h1 h2 h3 h4)'
ble/test "ble/util/mapfile a < <(:); status" stdout='0:()'
ble/test "ble/util/mapfile a < <(echo); status" stdout='1:()'
ble/test "ble/util/mapfile a < <(echo;echo); status" stdout='2:( )'
Expand Down Expand Up @@ -1134,35 +1171,46 @@ ble/test ble/util/setexit 255 exit=255
)

# ble/util/is-stdin-ready
(
ble/test 'echo 1 | { sleep 0.01; ble/util/is-stdin-ready; }'
ble/test 'sleep 0.01 | ble/util/is-stdin-ready' exit=1
ble/test 'ble/util/is-stdin-ready <<< a'
ble/test 'ble/util/is-stdin-ready <<< ""'

# EOF は成功してしまう? これは意図しない振る舞いである。
# しかし bash 自体が終了するので関係ないのかもしれない。
ble/test ': | { sleep 0.01; ble/util/is-stdin-ready; }'
ble/test 'ble/util/is-stdin-ready < /dev/null'
)
if ((_ble_bash>=40000)); then
(
ble/test 'echo 1 | { sleep 0.01; ble/util/is-stdin-ready; }'
ble/test 'sleep 0.01 | ble/util/is-stdin-ready' exit=1
ble/test 'ble/util/is-stdin-ready <<< a'
ble/test 'ble/util/is-stdin-ready <<< ""'

# EOF は成功してしまう? これは意図しない振る舞いである。
# しかし bash 自体が終了するので関係ないのかもしれない。
ble/test ': | { sleep 0.01; ble/util/is-stdin-ready; }'
ble/test 'ble/util/is-stdin-ready < /dev/null'
)
fi

# ble/util/is-running-in-subshell
ble/test ble/util/is-running-in-subshell exit=1
( ble/test ble/util/is-running-in-subshell )

# ble/util/getpid
(
ble/test/chdir
function getpid {
sh -c 'echo -n $PPID' > a.txt
ble/util/readfile ppid a.txt
}

dummy=modification_to_environment.1
ble/util/getpid
ble/test '[[ $BASHPID != $$ ]]'
ble/test "[[ \$BASHPID == \$(sh -c 'echo \$PPID') ]]"
getpid
ble/test '[[ $BASHPID == $ppid ]]'
pid1=$BASHPID
(
dummy=modification_to_environment.2
ble/util/getpid
ble/test '[[ $BASHPID != $$ && $BASHPID != $pid1 ]]'
ble/test "[[ \$BASHPID == \$(sh -c 'echo \$PPID') ]]"
getpid
ble/test '[[ $BASHPID == $ppid ]]'
)
ble/test/rmdir
)

# ble/fd#is-open
Expand All @@ -1184,8 +1232,11 @@ ble/test ble/util/is-running-in-subshell exit=1
ble/fd#alloc fd '> a.txt'
echo hello >&$fd
echo world >&$fd
ble/test 'ble/fd#close fd; echo test >&$fd' exit=1
ble/test 'cat a.txt' stdout={hello,world}
if ((_ble_bash/100!=301)); then
# bash-3.1 はバグがあって一度開いた fd を閉じれない。
ble/test 'ble/fd#close fd; echo test >&$fd' exit=1
ble/test 'cat a.txt' stdout={hello,world}
fi
ble/test/rmdir
)

Expand Down
28 changes: 28 additions & 0 deletions note.txt
Expand Up @@ -373,6 +373,10 @@ bashbug: 実装上で注意するべき事・バグ
\C-x 単体に bind -x して C-x に続けて何か打つと segfault する。
$ bind -x '"\C-x":echo' → 続けて C-x a 等と入力

* bash-4.1 以下: LC_CTYPE=C eval 'echo ${#var}' としても
${#var} が元のロケールで計算される。"変数代入 コマンド"
の形式だとロケールの初期化が間に合わないのだろうか。

* bash-4.0 segfault

以下で segfault を起こすことが分かった。bash-4.1 以降では直っている。
Expand All @@ -388,6 +392,15 @@ bashbug: 実装上で注意するべき事・バグ
$'' 内に \' を入れていると履歴展開が '' の中で起こる?
例えば rex='a'$'\'\'''!a' とすると !a の部分が展開される。

* bash-3.2 以下ではプロセス置換に含まれるブレース展開は
プロセス置換ごと複製してしまう。
例えば echo <(echo {1..3}) は、
echo <(echo 1 2 3) ではなくて、
echo <(echo 1) <(echo 2) <(echo 3) に展開されてしまう。

* bash-3.2 以下では declare a としただけで空の値で初期化される。
unset 状態になるという事はないので注意を要する。

* bash-3.2, bash-3.1 では source にプロセス置換を渡しても読み取ってくれない。
つまり source <( ... ) としても何も起こらない。
代わりに eval -- "$( ... )" すると良い。
Expand All @@ -399,6 +412,14 @@ bashbug: 実装上で注意するべき事・バグ
リダイレクションで新しい出力先を設定しようとしても失敗する。
これは fd>&- として一旦閉じてからリダイレクションすれば良い。

bash-3.1 では一度開いた fd を改めて開き直したり、
或いは閉じたりすることができない。
exec 34>/dev/null とすると、exec 34>&- としても閉じれないし、
exec 34>a.txt としても /dev/null に繋がったままになってしまう。

* bash-3.1 では a=(""); echo "a${a[*]}b" | cat -A とすると
a^?b となって謎の文字が入る。echo "a""${a[*]}""b" 等とすれば大丈夫。

* bash-3.1 では declare -f funcname の funcname に + 等の文字を含める事ができない。
一応 declare -F 等とすれば名前は列挙される様ではある。
bash-3.2 未満では declare -f ではなく type -t で関数かどうかの確認を行う。
Expand Down Expand Up @@ -985,6 +1006,13 @@ bash_tips
-------------------------------------------------------------------------------

2020-04-09

* complete: bash-dev で 10# のエラーが出ている。
"0>10#: invalid integer constant (エラーのあるトークンは "10#")"

* failglob: bash-4.3 で $? を入力するとエラーメッセージが出る。

* _ble_decode_input_buffer で不正な添字というエラーが発生する。

* 別の bash の枠組みについて
https://github.com/sio/bash-complete-partial-path
Expand Down
2 changes: 1 addition & 1 deletion src/decode.sh
Expand Up @@ -3153,7 +3153,7 @@ function ble/builtin/bind/.parse-keyname {
(return|ret) ch=$'\r' ;;
(space|spc) ch=' ' ;;
(tab) ch=$'\t' ;;
(*) LC_ALL= LC_CTYPE=C builtin eval 'ch=${value::1}' 2>/dev/null ;;
(*) ble/util/substr "$value" 0 1; ch=$ret ;;
esac
ble/util/s2c "$ch"; local key=$ret

Expand Down
5 changes: 3 additions & 2 deletions src/edit.sh
Expand Up @@ -2905,7 +2905,7 @@ function ble/widget/bracketed-paste.hook {
IFS=: builtin eval '_ble_edit_bracketed_paste=("${_ble_edit_bracketed_paste[*]}")' # contract

_ble_edit_bracketed_paste[_ble_edit_bracketed_paste_count++]=$1
(($1==126)) && ble/widget/bracketed-paste.hook/check-terminate && return
(($1==126)) && ble/widget/bracketed-paste.hook/check-end && return

# ble-decode-char にある次の文字を取り出してできるだけここで処理する。
if ((!_ble_debug_keylog_enabled)) && [[ ! $_ble_decode_keylog_chars_enabled ]]; then
Expand Down Expand Up @@ -7089,7 +7089,8 @@ function ble/widget/command-help.core {
local pager=ble/util/pager
type -t source-highlight &>/dev/null &&
pager='source-highlight -s sh -f esc | '$pager
LESS="$LESS -r" builtin eval 'declare -f "$command" | '"$pager" && return
local def; ble/function#getdef "$command"
LESS="$LESS -r" builtin eval -- "$pager" <<< "$def" && return
fi

if ble/is-function ble/bin/man; then
Expand Down

0 comments on commit b2c7d1c

Please sign in to comment.