Skip to content

Commit

Permalink
global: suppress missing locale errors
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Jan 17, 2021
1 parent 0f01cab commit 4d3c595
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 39 deletions.
5 changes: 3 additions & 2 deletions lib/core-syntax.sh
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions memo/ChangeLog.md
Expand Up @@ -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

Expand Down
46 changes: 46 additions & 0 deletions 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
13 changes: 13 additions & 0 deletions note.txt
Expand Up @@ -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 正規表現はシステムの <regex.h> を使用するので環境依存である。

Linux においては bash 正規表現の POSIX 文字クラス ([[:alpha:]] など) は
Expand Down Expand Up @@ -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]
Expand Down
27 changes: 13 additions & 14 deletions src/canvas.sh
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:* ]] ||
Expand Down Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/color.sh
Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions src/decode.sh
Expand Up @@ -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}
Expand All @@ -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 {
Expand Down
4 changes: 3 additions & 1 deletion src/edit.sh
Expand Up @@ -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[*]} ]]
Expand Down
68 changes: 49 additions & 19 deletions src/util.sh
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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'
Expand Down Expand Up @@ -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
#
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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' ]]
}

Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit 4d3c595

Please sign in to comment.