Skip to content

Commit

Permalink
util: work around bash-3.0 bug "${scal[@]/xxx}"
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed May 27, 2021
1 parent 7732eed commit 24f79da
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 28 deletions.
2 changes: 1 addition & 1 deletion archive/getopt1.sh
Expand Up @@ -3,7 +3,7 @@

# Usage
#
# local "${ble_getopt_vars[@]/%/=}"
# local "${ble_getopt_vars[@]/%/=}" # WA #D1570 checked
# ble-getopt-begin "progname" "m:n c:n,n k:n,n" "$@"
# ble-getopt
#
Expand Down
22 changes: 11 additions & 11 deletions lib/core-complete.sh
Expand Up @@ -3440,7 +3440,7 @@ function ble/complete/source:dynamic-history {
## 補完候補のデータを一つの配列に纏めたもの。
## 要素を使用する際は以下の様に変数に展開して使う。
##
## local "${_ble_complete_cand_varnames[@]/%/=}"
## local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
## ble/complete/cand/unpack "${cand_pack[0]}"
##
## 先頭に ACTION が格納されているので
Expand Down Expand Up @@ -4164,7 +4164,7 @@ function ble/complete/menu-complete.class/render-item {
local menu_common_part=$_ble_complete_menu_common_part
fi

local "${_ble_complete_cand_varnames[@]/%/=}"
local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
ble/complete/cand/unpack "$1"

local prefix_len=$PREFIX_LEN
Expand Down Expand Up @@ -4264,7 +4264,7 @@ function ble/complete/menu-complete.class/render-item {

function ble/complete/menu-complete.class/get-desc {
local item=$1
local "${_ble_complete_cand_varnames[@]/%/=}"
local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
ble/complete/cand/unpack "$item"
desc="(action: $ACTION)"
ble/function#try ble/complete/action:"$ACTION"/get-desc
Expand All @@ -4274,7 +4274,7 @@ function ble/complete/menu-complete.class/onselect {
local nsel=$1 osel=$2
local insert=${_ble_complete_menu_original:-${_ble_complete_menu_comp[2]}}
if ((nsel>=0)); then
local "${_ble_complete_cand_varnames[@]/%/=}"
local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
ble/complete/cand/unpack "${_ble_complete_menu_items[nsel]}"
insert=$INSERT
fi
Expand Down Expand Up @@ -4421,7 +4421,7 @@ function ble/complete/menu/generate-candidates-from-menu {
# remaining candidates
cand_count=${#_ble_complete_menu_items[@]}
cand_cand=() cand_word=() cand_pack=()
local pack "${_ble_complete_cand_varnames[@]}"
local pack "${_ble_complete_cand_varnames[@]/=}" # #D1570 WA checked
for pack in "${_ble_complete_menu_items[@]}"; do
ble/complete/cand/unpack "$pack"
ble/array#push cand_cand "$CAND"
Expand Down Expand Up @@ -4523,7 +4523,7 @@ function ble/complete/insert-common {
# 一意確定の時
local ACTION=${cand_pack[0]%%:*}
if ble/is-function ble/complete/action:"$ACTION"/complete; then
local "${_ble_complete_cand_varnames[@]/%/=}"
local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
ble/complete/cand/unpack "${cand_pack[0]}"
ble/complete/action:"$ACTION"/complete
(($?==148)) && return 148
Expand Down Expand Up @@ -4575,7 +4575,7 @@ function ble/complete/insert-common {
## @var[out] COMP1 COMP2 COMPS COMPV comp_type comps_flags comps_fixed
## @var[out] cand_count cand_cand cand_word cand_pack
function ble/complete/insert-all {
local "${_ble_complete_cand_varnames[@]/%/=}"
local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
local pack beg=$COMP1 end=$COMP2 insert= suffix= index=0
for pack in "${cand_pack[@]}"; do
ble/complete/cand/unpack "$pack"
Expand Down Expand Up @@ -5239,7 +5239,7 @@ function ble/complete/menu-filter/.filter-candidates {
cand_pack=()

local iloop=0 interval=$bleopt_complete_polling_cycle
local filter_type pack "${_ble_complete_cand_varnames[@]}"
local filter_type pack "${_ble_complete_cand_varnames[@]/=}" # #D1570 WA checked
for filter_type in head substr hsubseq subseq; do
ble/path#remove-glob comp_type '[maA]'
case $filter_type in
Expand Down Expand Up @@ -5511,7 +5511,7 @@ function ble/widget/menu_complete/exit {
local comps_fixed=${_ble_complete_menu0_comp[6]}

# 補完候補のロード
local "${_ble_complete_cand_varnames[@]/%/=}"
local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
ble/complete/cand/unpack "$pack"

ble/complete/action:"$ACTION"/complete
Expand Down Expand Up @@ -5745,7 +5745,7 @@ function ble/complete/auto-complete/.check-context {
local insert=$word suffix=
local ACTION=${cand_pack[0]%%:*}
if ble/is-function ble/complete/action:"$ACTION"/complete; then
local "${_ble_complete_cand_varnames[@]/%/=}"
local "${_ble_complete_cand_varnames[@]/%/=}" # WA #D1570 checked
ble/complete/cand/unpack "${cand_pack[0]}"
ble/complete/action:"$ACTION"/complete
fi
Expand Down Expand Up @@ -6660,7 +6660,7 @@ function ble/cmdinfo/complete:cd/.impl {
((ext==148||ext==0)) && return "$ext"

local is_pwd_visited= is_cdpath_generated=
"${_ble_util_set_declare[@]//NAME/visited}"
"${_ble_util_set_declare[@]//NAME/visited}" # WA #D1570 checked

# Check CDPATH first
local name names; ble/string#split names : "$CDPATH"
Expand Down
8 changes: 4 additions & 4 deletions lib/core-syntax.sh
Expand Up @@ -4580,7 +4580,7 @@ function ble/syntax:bash/is-complete {

# 構文 if..fi, etc が閉じているか?
local attrs ret
IFS= builtin eval 'attrs="::${_ble_syntax_attr[*]/%/::}"'
IFS= builtin eval 'attrs="::${_ble_syntax_attr[*]/%/::}"' # WA #D1570 checked
ble/string#count-string "$attrs" ":$ATTR_KEYWORD_BEGIN:"; local nbeg=$ret
ble/string#count-string "$attrs" ":$ATTR_KEYWORD_END:"; local nend=$ret
((nbeg>nend)) && return 1
Expand Down Expand Up @@ -5117,7 +5117,7 @@ function ble/syntax/highlight {
ble/array#push vars "${_ble_highlight_layer_plain_VARNAMES[@]}"
ble/array#push vars "${_ble_highlight_layer_syntax_VARNAMES[@]}"

local "${vars[@]/%/=}"
local "${vars[@]/%/=}" # WA #D1570 checked
if [[ $cache_prefix ]] && ((${cache_prefix}_INITIALIZED++)); then
ble/util/restore-vars "$cache_prefix" "${vars[@]}"

Expand Down Expand Up @@ -6861,7 +6861,7 @@ function ble/syntax/progcolor/word:default {
## @var[in] tree_words
## @var[in,out] color_umin color_umax
function ble/syntax/progcolor/default {
local i "${_ble_syntax_progcolor_vars[@]}"
local i "${_ble_syntax_progcolor_vars[@]/%/=}" # WA #D1570 checked
for ((i=1;i<${#comp_words[@]};i++)); do
local ref=${tree_words[i]}
[[ $ref ]] || continue
Expand Down Expand Up @@ -6926,7 +6926,7 @@ function ble/syntax/progcolor {

# コマンド名に対しては既定の着色を実行
if [[ ${tree_words[0]} ]]; then
local "${_ble_syntax_progcolor_vars[@]/%/=}"
local "${_ble_syntax_progcolor_vars[@]/%/=}" # WA #D1570 checked
ble/syntax/progcolor/load-word-data "${tree_words[0]}"
[[ $wattr == - ]] && ble/syntax/progcolor/word:default
fi
Expand Down
2 changes: 1 addition & 1 deletion lib/test-util.sh
Expand Up @@ -141,7 +141,7 @@ ble/test ble/util/setexit 255 exit=255
}

function f1 {
local "${VARNAMES[@]/%/=}"
local "${VARNAMES[@]/%/=}" # WA #D1570 checked

name=1 x=2 y=3 count=4 data=(aa bb cc dd)
print-status
Expand Down
11 changes: 11 additions & 0 deletions make_command.sh
Expand Up @@ -276,6 +276,11 @@ function sub:scan/bash300bug {
# bash-3.0 では local -a arr=("$hello") とすると
# クォートしているにも拘らず $hello の中身が単語分割されてしまう。
grc 'local -a [[:alnum:]_]+=\([^)]*[\"'\''`]' --exclude=./{test,ext} --exclude=./make_command.sh

# bash-3.0 では "${scalar[@]/xxxx}" は全て空になる
grc '\$\{[a-zA-Z_0-9]+\[[*@]\]/' --exclude=./{text,ext} --exclude=./make_command.sh --exclude=\*.md --color |
grep -v '#D1570'

}

function sub:scan/bash301bug-array-element-length {
Expand Down Expand Up @@ -351,6 +356,11 @@ function sub:scan/eval-literal {
g'
}

function sub:scan/WA-localvar_inherit {
echo "--- $FUNCNAME ---"
grc 'local [^;&|()]*"\$\{[a-zA-Z_0-9]+\[@*\]\}"'
}

function sub:scan {
if ! type grc >/dev/null; then
echo 'blesh check: grc not found. grc can be found in github.com:akinomyoga/mshex.git/' >&2
Expand Down Expand Up @@ -429,6 +439,7 @@ function sub:scan {
\Zreadonly -f unsetZd
g'
sub:scan/eval-literal
sub:scan/WA-localvar_inherit

sub:scan/memo-numbering
}
Expand Down
1 change: 1 addition & 0 deletions memo/ChangeLog.md
Expand Up @@ -116,6 +116,7 @@
- main: work around `. ble.sh --{test,update,clear-cache}` in intereactive sessions `#D1555` bbc2a90
- Makefile: create `run` directory instead of `tmp` `#D1557` 9bdb37d
- main: fix the workaround for `set -e` `#D1564` ab2f70b
- util: work around bash-3.0 bug `"${scal[@]/xxx}"` `#D1570` 0000000

## Compatibility

Expand Down
31 changes: 31 additions & 0 deletions note.txt
Expand Up @@ -649,6 +649,9 @@ bash 配列の宣言に関する仕様・バグと注意点
a="123 345"; declare -a arr=("$a"); このようにしても駄目だ。
a="123 345"; declare -a arr; arr=("$a"); こうする必要がある。

* BUG bash-3.0: "${var[@]/xxx/yyy}" はスカラー変数に対して空の結果を生む。
${var[@]//xxx/yyy}, ${var[@]/%/yyy}, ${var[@]/#/yyy} についても同様である。

* 配列要素を連結する時

動く例:
Expand Down Expand Up @@ -4652,6 +4655,34 @@ bash_tips

2021-05-27

* bash-3.0 の初期化時に bleopt が出力されてしまっている [#D1570]

% bash-3.1 では特に問題は起こっていない。という事はまた何かの bash bug に嵌っ
% ているのか或いは場合分けのコードで bash-3.0 専用の部分に問題があるのか。
%
% --norc で source すると問題は起こらない。後で source ~/.blerc すると再現
% する。同じセッションで再度呼び出せば再度発生する。これも解析のバグである
% 様な気がする。不思議な事に一回目と二回目で起こる bleopt の位置が異なる。
% 或いは、起こる回数が変わっているという事か。
%
% どうやら bleopt a:=1 という形で呼び出すと read-arguments の結果が空になる
% 様だ。調べるとスカラーに対して ${var[@]/%/=value} 等とすると失敗する様だ。

これはまた bash-3.0 のバグである。うーん。調べた限りだと、
${scalar[@]/xxxx} の形式は全て空になる。

$ grc '\$\{[a-zA-Z_0-9]+\[[*@]\]/'

で検索してみるとそんなに沢山は存在しない。取り敢えず全て確認 or 対策をする
必要がある。また、m scan に含めるべきである。

* 確認した所、既存のコードは全て配列に対して異実行していたので問題ない
* m scan にも含めた。

x local i "${vars[@]}" に変更漏れがあった。これも後で修正する。

* 後これは遡って適用するべき項目である。なので独立した項目にする事にする。

* util: gdict 再考 [#D1569]

gdict について質問された。説明しようとして思ったのだが、現在の gdict の実装
Expand Down
2 changes: 1 addition & 1 deletion src/color.sh
Expand Up @@ -1070,7 +1070,7 @@ function ble/color/initialize-faces {

if ((${#_ble_color_faces_errors[@]})); then
if ((_ble_edit_attached)) && [[ ! $_ble_textarea_invalidated && $_ble_term_state == internal ]]; then
IFS=$'\n' builtin eval 'local message="${_ble_color_faces_errors[@]}"'
IFS=$'\n' builtin eval 'local message="${_ble_color_faces_errors[*]}"'
ble/widget/print "$message"
else
printf '%s\n' "${_ble_color_faces_errors[@]}" >&2
Expand Down
2 changes: 1 addition & 1 deletion src/decode.sh
Expand Up @@ -1333,7 +1333,7 @@ function ble-decode-char/print {
else
ble-decode-unkbd "$key"
qkspec="'${ret//$q/$Q}'"
qcnames="'${cnames[*]//$q/$Q}'"
qcnames="'${cnames[*]//$q/$Q}'" # WA #D1570 checked
fi
ble/util/print "${sgrf}ble-bind$sgr0 $sgro-k$sgr0 $qcnames $qkspec"
fi
Expand Down
19 changes: 10 additions & 9 deletions src/util.sh
Expand Up @@ -93,7 +93,8 @@ function bleopt/.read-arguments {
fi

if [[ $op ]]; then
ble/array#push specs "${var[@]/%/=$value}"
var=("${var[@]}") # #D1570: WA bash-3.0 ${scal[@]/x} bug
ble/array#push specs "${var[@]/%/=$value}" # #D1570 WA checked
else
ble/array#push pvars "${var[@]}"
fi
Expand Down Expand Up @@ -709,7 +710,7 @@ function ble/dense-array#fill-range {
ble/array#reserve-prototype $(($3-$2))
local _ble_script='
local -a sARR; sARR=("${_ble_array_prototype[@]::$3-$2}")
ARR=("${ARR[@]::$2}" "${sARR[@]/#/$4}" "${ARR[@]:$3}")'
ARR=("${ARR[@]::$2}" "${sARR[@]/#/$4}" "${ARR[@]:$3}")' # WA #D1570 checked
builtin eval -- "${_ble_script//ARR/$1}"
}

Expand Down Expand Up @@ -1149,15 +1150,15 @@ else
function ble/string#quote-words {
local q=\' Q="'\''" IFS=$_ble_term_IFS
ret=("${@//$q/$Q}")
ret=("${ret[@]/%/$q}")
ret="${ret[*]/#/$q}"
ret=("${ret[@]/%/$q}") # WA #D1570 checked
ret="${ret[*]/#/$q}" # WA #D1570 checked
}
function ble/string#quote-command {
local q=\' Q="'\''" IFS=$_ble_term_IFS
ret=("${@:2}")
ret=("${ret[@]//$q/$Q}")
ret=("${ret[@]/%/$q}")
ret="$1 ${ret[*]/#/$q}"
ret=("${ret[@]//$q/$Q}") # WA #D1570 checked
ret=("${ret[@]/%/$q}") # WA #D1570 checked
ret="$1 ${ret[*]/#/$q}" # WA #D1570 checked
}
fi
## @fn ble/string#quote-word text opts
Expand Down Expand Up @@ -1409,8 +1410,8 @@ function ble/adict#keys {
local keylist=${1}_keylist; keylist=${!keylist%:}
ble/string#split ret : "$keylist"
if [[ $keylist == *"$_ble_term_FS"* ]]; then
ret=("${ret[@]//$_ble_term_FS./:}")
ret=("${ret[@]//$_ble_term_FS,/$_ble_term_FS}")
ret=("${ret[@]//$_ble_term_FS./:}") # WA #D1570 checked
ret=("${ret[@]//$_ble_term_FS,/$_ble_term_FS}") # WA #D1570 checked
fi
}

Expand Down

0 comments on commit 24f79da

Please sign in to comment.