From 4d3c59559ddbd97e969ea3f4e637739bb36b5615 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 17 Jan 2021 12:01:57 +0900 Subject: [PATCH] global: suppress missing locale errors --- lib/core-syntax.sh | 5 ++- memo/ChangeLog.md | 1 + memo/D1440.suppress-locale-error.sh | 46 +++++++++++++++++++ note.txt | 13 ++++++ src/canvas.sh | 27 ++++++------ src/color.sh | 4 +- src/decode.sh | 8 +++- src/edit.sh | 4 +- src/util.sh | 68 +++++++++++++++++++++-------- 9 files changed, 137 insertions(+), 39 deletions(-) create mode 100644 memo/D1440.suppress-locale-error.sh diff --git a/lib/core-syntax.sh b/lib/core-syntax.sh index bcdffa8e..f41b5772 100644 --- a/lib/core-syntax.sh +++ b/lib/core-syntax.sh @@ -5894,8 +5894,9 @@ function ble/syntax/highlight/cmdtype1 { esac } -# #D1341 #D1355 locale 対策 -function ble/syntax/highlight/cmdtype/.jobs { local LC_ALL=C; jobs; } 2>/dev/null +# #D1341 #D1355 #D1440 locale 対策 +function ble/syntax/highlight/cmdtype/.jobs { local LC_ALL=C; jobs; } +ble/function#suppress-stderr ble/syntax/highlight/cmdtype/.jobs function ble/syntax/highlight/cmdtype/.is-job-name { ble/util/joblist.check diff --git a/memo/ChangeLog.md b/memo/ChangeLog.md index 1dba99bd..c6a5f09f 100644 --- a/memo/ChangeLog.md +++ b/memo/ChangeLog.md @@ -21,6 +21,7 @@ - complete/mandb: fix BS contamination used by nroff to represent bold (reported by rlnore) `#D1429` b5c875a - edit: work around the wrong job information of Bash in trap handlers (reported by 3ximus) `#D1435` `#D1436` bc4735e - edit (command-help): work around the Bash bug that tempenv vanishes with `builtin eval` `#D1438` 0000000 +- global: suppress missing locale errors `#D1440` 0000000 ## Internal changes and fixes diff --git a/memo/D1440.suppress-locale-error.sh b/memo/D1440.suppress-locale-error.sh new file mode 100644 index 00000000..71feeb3a --- /dev/null +++ b/memo/D1440.suppress-locale-error.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +{ + LC_CTYPE=pt_PT.UTF-8 +} 2>/dev/null + +checkA1() { local LC_ALL= LC_CTYPE=C; builtin read -t 0; } 2>/dev/null +checkB1() { local LC_ALL= LC_CTYPE=C; builtin eval 'echo ${#a}'; } 2>/dev/null + +# x [bash-bug] この方法だと LC_CTYPE が反映されない。 +checkA2() { LC_ALL= LC_CTYPE=C builtin read -t 0; } 2>/dev/null +checkB2() { LC_ALL= LC_CTYPE=C eval 'echo ${#a}'; } 2>/dev/null + +# checkB3 +# - この方法だと余分に関数呼び出しが入る +# o 然し、unlocal は共通関数なのでその場で定義するのは一つの関数だけで良い。 +# - 終了ステータスが意味を持つ場合には一旦ステータスを保存しなければならない。 +checkB3() { + local LC_ALL= LC_CTYPE=C + echo ${#a} + ble/util/unlocal LC_CTYPE LC_ALL +} 2>/dev/null + +# checkB4 +# - これは動くが、これも余分に関数呼び出しが入る。 +# - その場で関数を複数定義しなければならない。 +checkB4.impl() { local LC_ALL= LC_CTYPE=C; echo ${#a}; } +checkB4() { + checkB4.impl 2>/dev/null +} + +# x bash-4.1 以下で LC_CTYPE が反映されない。 +checkB5.impl() { echo ${#a}; } +checkB5() { + LC_ALL= LC_CTYPE=C checkB5.impl 2>/dev/null +} + +a=あいう +echo A +# checkA1 +# checkB1 +#checkA2 +#checkB3 +#checkB4 +checkB5 +echo Z diff --git a/note.txt b/note.txt index 869eabfb..2b8f0a50 100644 --- a/note.txt +++ b/note.txt @@ -307,6 +307,9 @@ bash 実装上で注意するべき事 ok$ echo あいうえお | LC_CTYPE=C awk '{print length($0)}' ok$ echo あいうえお | LC_CTYPE=C ble/bin/awk '{print length($0)}' + * 2021-01-15 aaa() { local LC_ALL= LC_CTYPE=C; ... ; } 2>/dev/null の形式でも + 駄目だという事が判明した。ちゃんとする為には関数内で unlocal までする必要がある? + * Bash 正規表現はシステムの を使用するので環境依存である。 Linux においては bash 正規表現の POSIX 文字クラス ([[:alpha:]] など) は @@ -3704,6 +3707,16 @@ bash_tips Done (実装ログ) ------------------------------------------------------------------------------- +2021-01-17 + + * LC_CTYPE の切り替えエラーが出る (reported by 3ximus) [#D1440] + https://github.com/akinomyoga/ble.sh/issues/81 + + 実際に確かめてみたら確かにエラーメッセージが出る。 + 過去に対策したつもりだったが対策の仕方が間違っていた。 + 色々実験した所、結局余計に一つ関数呼び出しをしなければ駄目な様だ。 + 自動で stderr を抑制するように書き換える汎関数を作って対応する事にした。 + 2021-01-01 * decode (ble-decode-kbd): support various keyseq specifications [#D1439] diff --git a/src/canvas.sh b/src/canvas.sh index 6c153451..cc808649 100644 --- a/src/canvas.sh +++ b/src/canvas.sh @@ -833,6 +833,10 @@ function ble/canvas/trace/.process-esc-sequence { function ble/canvas/trace/.impl { local text=$1 opts=$2 + # cygwin では LC_COLLATE=C にしないと + # 正規表現の range expression が期待通りに動かない。 + local LC_ALL= LC_COLLATE=C + # Note: 文字符号化方式によっては対応する文字が存在しない可能性がある。 # その時は st='\u009C' になるはず。2文字以上のとき変換に失敗したと見做す。 local ret @@ -1021,17 +1025,13 @@ function ble/canvas/trace/.impl { [[ $opt_measure ]] && ((y2++)) } function ble/canvas/trace.draw { - # cygwin では LC_COLLATE=C にしないと - # 正規表現の range expression が期待通りに動かない。 - local LC_ALL= LC_COLLATE=C - ble/canvas/trace/.impl "$@" -} 2>/dev/null # Note: suppress LC_COLLATE errors #D1205, #D1341 + ble/canvas/trace/.impl "$@" 2>/dev/null # Note: suppress LC_COLLATE errors #D1205 #D1341 #D1440 +} function ble/canvas/trace { - local LC_ALL= LC_COLLATE=C local -a DRAW_BUFF=() - ble/canvas/trace/.impl "$@" + ble/canvas/trace/.impl "$@" 2>/dev/null # Note: suppress LC_COLLATE errors #D1205 #D1341 #D1440 ble/canvas/sflush.draw # -> ret -} 2>/dev/null # Note: suppress LC_COLLATE errors #D1205, #D1341 +} #------------------------------------------------------------------------------ # ble/canvas/construct-text @@ -1120,7 +1120,9 @@ function ble/canvas/trace-text/.put-nl-if-eol { ## @var[out] ret ## @exit ## 指定した範囲に文字列が収まった時に成功します。 -function ble/canvas/trace-text/.impl { +function ble/canvas/trace-text { + local LC_ALL= LC_COLLATE=C + local out= glob='*[! -~]*' local opts=$2 flag_overflow= [[ :$opts: == *:external-sgr:* ]] || @@ -1166,11 +1168,8 @@ function ble/canvas/trace-text/.impl { ((y>=lines)) && flag_overflow=1 [[ ! $flag_overflow ]] } -function ble/canvas/trace-text { - # Note: suppress LC_COLLATE errors #D1205 #D1262 #1341 - local LC_ALL= LC_COLLATE=C - ble/canvas/trace-text/.impl "$@" -} 2>/dev/null +# Note: suppress LC_COLLATE errors #D1205 #D1262 #1341 #D1440 +ble/function#suppress-stderr ble/canvas/trace-text { #------------------------------------------------------------------------------ # ble/textmap diff --git a/src/color.sh b/src/color.sh index 25eccd7d..008895a1 100644 --- a/src/color.sh +++ b/src/color.sh @@ -1177,7 +1177,9 @@ function ble/highlight/layer:plain/update { PREV_BUFF=_ble_highlight_layer_plain_buff ((PREV_UMIN=DMIN,PREV_UMAX=DMAX)) -} 2>/dev/null # Note: suppress LC_COLLATE errors #D1205 +} +# Note: suppress LC_COLLATE errors #D1205 #D1440 +ble/function#suppress-stderr ble/highlight/layer:plain/update ## 関数 ble/highlight/layer:plain/getg index ## @var[out] g diff --git a/src/decode.sh b/src/decode.sh index e8cbe830..7efc3f71 100644 --- a/src/decode.sh +++ b/src/decode.sh @@ -632,7 +632,9 @@ if ((_ble_bash>=40400)); then [[ $line ]] && printf %s "$line" } | ble/bin/od -A n -t u1 -v' ble/string#split-words ret "$ret" - } 2>/dev/null # LC_CTYPE=C + } + # suppress locale error #D1440 + ble/function#suppress-stderr ble/decode/nonblocking-read elif ((_ble_bash>=40000)); then function ble/decode/nonblocking-read { local timeout=${1:-0.01} ntimeout=${2:-1} loop=${3:-100} @@ -655,7 +657,9 @@ elif ((_ble_bash>=40000)); then [[ $line ]] && printf %s "$line" } | ble/bin/od -A n -t u1 -v' ble/string#split-words ret "$ret" - } 2>/dev/null # LC_CTYPE=C + } + # suppress locale error #D1440 + ble/function#suppress-stderr ble/decode/nonblocking-read fi function ble-decode/.hook { diff --git a/src/edit.sh b/src/edit.sh index 55807791..6666eb64 100644 --- a/src/edit.sh +++ b/src/edit.sh @@ -776,9 +776,11 @@ function ble/prompt/.instantiate-control-string { local LC_ALL= LC_COLLATE=C ret=${esc//[! -~]/'#'} - fi 2>/dev/null + fi builtin eval -- "$name=(\"\${prompt_data[@]}\")" } +# suppress locale error #D1440 +ble/function#suppress-stderr ble/prompt/.instantiate-control-string function ble/prompt/update/.has-prompt_command { [[ ${PROMPT_COMMAND[*]} ]] diff --git a/src/util.sh b/src/util.sh index 214279f6..82238fbf 100644 --- a/src/util.sh +++ b/src/util.sh @@ -741,7 +741,7 @@ function ble/string#last-index-of { ## @var[out] ret _ble_util_string_lower_list=abcdefghijklmnopqrstuvwxyz _ble_util_string_upper_list=ABCDEFGHIJKLMNOPQRSTUVWXYZ -function ble/string#toggle-case { +function ble/string#toggle-case.impl { local LC_ALL= LC_COLLATE=C local text=$* ch i local -a buff @@ -757,7 +757,10 @@ function ble/string#toggle-case { ble/array#push buff "$ch" done IFS= builtin eval 'ret="${buff[*]-}"' -} 2>/dev/null +} +function ble/string#toggle-case { + ble/string#toggle-case.impl "$@" 2>/dev/null # suppress locale error #D1440 +} ## 関数 ble/string#tolower text... ## 関数 ble/string#toupper text... ## @var[out] ret @@ -766,6 +769,7 @@ if ((_ble_bash>=40000)); then function ble/string#toupper { ret="${*^^}"; } else function ble/string#tolower.impl { + local LC_ALL= LC_COLLATE=C local i text="$*" local -a buff ch for ((i=0;i<${#text};i++)); do @@ -779,6 +783,7 @@ else IFS= builtin eval 'ret="${buff[*]-}"' } function ble/string#toupper.impl { + local LC_ALL= LC_COLLATE=C local i text="$*" local -a buff ch for ((i=0;i<${#text};i++)); do @@ -792,13 +797,11 @@ else IFS= builtin eval 'ret="${buff[*]-}"' } function ble/string#tolower { - local LC_ALL= LC_COLLATE=C - ble/string#tolower.impl "$@" - } 2>/dev/null + ble/string#tolower.impl "$@" 2>/dev/null # suppress locale error #D1440 + } function ble/string#toupper { - local LC_ALL= LC_COLLATE=C - ble/string#toupper.impl "$@" 2>/dev/null - } 2>/dev/null + ble/string#toupper.impl "$@" 2>/dev/null # suppress locale error #D1440 + } fi function ble/string#capitalize { @@ -1106,14 +1109,20 @@ function ble/string#create-unicode-progress-bar { } # Note: Bash-4.1 以下では "LC_CTYPE=C 組み込みコマンド" の形式だと # locale がその場で適用されないバグがある。 -function ble/util/strlen { +function ble/util/strlen.impl { local LC_ALL= LC_CTYPE=C ret=${#1} -} 2>/dev/null -function ble/util/substr { +} +function ble/util/strlen { + ble/util/strlen.impl "$@" 2>/dev/null # suppress locale error #D1440 +} +function ble/util/substr.impl { local LC_ALL= LC_CTYPE=C ret=${1:$2:$3} -} 2>/dev/null +} +function ble/util/substr { + ble/util/substr.impl "$@" 2>/dev/null # suppress locale error #D1440 +} function ble/path#append { local _ble_local_script='opts=$opts${opts:+:}$2' @@ -1897,6 +1906,24 @@ function ble/function#lambda { builtin eval -- "function ${!1} { builtin eval -- '${2//$_ble_local_q/$_ble_local_Q}'; }" } +## 関数 ble/function#suppress-stderr function_name +## @param[in] function_name +function ble/function#suppress-stderr { + local name=$1 + if ! ble/is-function "$name"; then + echo "$FUNCNAME: '$name' is not a function name" >&2 + return 2 + fi + + local def; ble/function#getdef "$name" + builtin eval "ble/function#suppress-stderr:$def" + local lambda=ble/function#suppress-stderr:$name + + local q=\' Q="'\''" + builtin eval "function $name { $lambda \"\$@\" 2>/dev/null; }" + return 0 +} + # # miscallaneous utils # @@ -1946,7 +1973,9 @@ if ((_ble_bash>=40000)); then function ble/util/is-stdin-ready { local IFS= LC_ALL= LC_CTYPE=C builtin read -t 0 - } &>/dev/null + } + # suppress locale error #D1440 + ble/function#suppress-stderr ble/util/is-stdin-ready else function ble/util/is-stdin-ready { false; } fi @@ -2236,13 +2265,11 @@ _ble_util_rex_isprint='^[ -~]+' ## ## @var[out] BASH_REMATCH ble-exit/text/update/position で使用する。 function ble/util/isprint+ { - # LC_COLLATE=C ... &>/dev/null for cygwin collation local LC_ALL= LC_COLLATE=C - ble/util/isprint+.impl "$@" -} 2>/dev/null # Note: suppress LC_COLLATE errors #D1205 -function ble/util/isprint+.impl { [[ $1 =~ $_ble_util_rex_isprint ]] } +# suppress locale error #D1440 +ble/function#suppress-stderr ble/util/isprint+ if ((_ble_bash>=40200)); then function ble/util/strftime { @@ -2280,7 +2307,7 @@ function ble/util/msleep/.check-builtin-sleep { fi } function ble/util/msleep/.check-sleep-decimal-support { - local version; ble/util/assign version 'LC_ALL=C ble/bin/sleep --version 2>&1' + local version; ble/util/assign version 'LC_ALL=C ble/bin/sleep --version 2>&1' 2>/dev/null # suppress locale error #D1440 [[ $version == *'GNU coreutils'* || $OSTYPE == darwin* && $version == 'usage: sleep seconds' ]] } @@ -4422,7 +4449,10 @@ if ((_ble_bash>=40200)); then builtin printf -v ret '\uFFFF' ((${#ret}==2)) } - if ble/util/.has-bashbug-printf-uffff 2>/dev/null; then # #D1262 suppress LC_ALL error messages + # suppress locale error #D1440 + ble/function#suppress-stderr ble/util/.has-bashbug-printf-uffff + + if ble/util/.has-bashbug-printf-uffff; then function ble/util/c2s.impl { if ((0xE000<=$1&&$1<=0xFFFF)) && [[ $_ble_util_locale_encoding == UTF-8 ]]; then builtin printf -v ret '\\x%02x' $((0xE0|$1>>12&0x0F)) $((0x80|$1>>6&0x3F)) $((0x80|$1&0x3F))