sistema_progs

Programas para customizar o meu entorno de traballo nos meus equipos persoais
Log | Files | Refs

ble.pp (88385B)


      1 #!/bin/bash
      2 #%$> out/ble.sh
      3 #%[release = 0]
      4 #%[measure_load_time = 0]
      5 #%[debug_keylogger = 1]
      6 #%[leakvar = ""]
      7 #%#----------------------------------------------------------------------------
      8 #%if measure_load_time
      9 _ble_debug_measure_fork_count=$(echo $BASHPID)
     10 TIMEFORMAT='[Elapsed %Rs; CPU U:%Us S:%Ss (%P%%)]'
     11 function ble/debug/measure-set-timeformat {
     12   local title=$1 opts=$2
     13   local new=$(echo $BASHPID)
     14   local fork=$(((new-_ble_debug_measure_fork_count-1)&0xFFFF))
     15   _ble_debug_measure_fork_count=$new
     16   TIMEFORMAT="[Elapsed %Rs; CPU U:%Us S:%Ss (%P%%)] $title"
     17   [[ :$opts: != *:nofork:* ]] &&
     18     TIMEFORMAT=$TIMEFORMAT" ($fork forks)"
     19 }
     20 #%end
     21 #%if leakvar
     22 #%%expand
     23 $"leakvar"=__t1wJltaP9nmow__
     24 #%%end.i
     25 function ble/bin/grep { command grep "$@"; }
     26 function ble/util/print { printf '%s\n' "$1"; }
     27 source "${BASH_SOURCE%/*}/lib/core-debug.sh"
     28 #%end
     29 #%define inc
     30 #%%[guard_name = "@_included".replace("[^_a-zA-Z0-9]", "_")]
     31 #%%expand
     32 #%%%if $"guard_name" != 1
     33 #%%%%[$"guard_name" = 1]
     34 ###############################################################################
     35 # Included from @.sh
     36 
     37 #%%%%if leakvar
     38 ble/debug/leakvar#check $"leakvar" "[before include @.sh]"
     39 #%%%%end.i
     40 #%%%%if measure_load_time
     41 time {
     42 #%%%%%include @.sh
     43 ble/debug/measure-set-timeformat '@.sh'
     44 }
     45 #%%%%else
     46 #%%%%%include @.sh
     47 #%%%%end
     48 #%%%%if leakvar
     49 ble/debug/leakvar#check $"leakvar" "[after include @.sh]"
     50 #%%%%end.i
     51 #%%%end
     52 #%%end.i
     53 #%end
     54 #%#----------------------------------------------------------------------------
     55 # ble.sh -- Bash Line Editor (https://github.com/akinomyoga/ble.sh)
     56 #
     57 #   Bash configuration designed to be sourced in interactive bash sessions.
     58 #
     59 #   Copyright: 2013, 2015-2019, Koichi Murase <myoga.murase@gmail.com>
     60 #
     61 
     62 #%if measure_load_time
     63 echo "ble.sh: $EPOCHREALTIME load start" >&2
     64 time {
     65 echo "ble.sh: $EPOCHREALTIME parsed" >&2
     66 # load_time (2015-12-03)
     67 #   core           12ms
     68 #   decode         10ms
     69 #   color           2ms
     70 #   edit            9ms
     71 #   syntax          5ms
     72 #   ble-initialize 14ms
     73 time {
     74 #%end
     75 #------------------------------------------------------------------------------
     76 # check --help or --version
     77 
     78 {
     79   #%[commit_hash = system("git show -s --format=%h")]
     80   #%[ble_version = getenv("FULLVER") + "+" + commit_hash]
     81   #%expand
     82   ##%if commit_hash != ""
     83   _ble_init_version=$"ble_version"
     84   ##%else
     85   ###%error Failed to get the commit id (version = $"ble_version").
     86   ##%end
     87   #%end.i
     88   _ble_init_exit=
     89   _ble_init_command=
     90   for _ble_init_arg; do
     91     case $_ble_init_arg in
     92     --version)
     93       _ble_init_exit=0
     94       echo "ble.sh (Bash Line Editor), version $_ble_init_version" ;;
     95     --help)
     96       _ble_init_exit=0
     97       printf '%s\n' \
     98              "# ble.sh (Bash Line Editor), version $_ble_init_version" \
     99              'usage: source ble.sh [OPTION...]' \
    100              '' \
    101              'OPTION' \
    102              '' \
    103              '  --help' \
    104              '    Show this help and exit' \
    105              '  --version' \
    106              '    Show version and exit' \
    107              '  --test' \
    108              '    Run test and exit' \
    109              '  --update' \
    110              '    Update ble.sh and exit' \
    111              '  --clear-cache' \
    112              '    Clear ble.sh cache and exit' \
    113              '' \
    114              '  --rcfile=BLERC' \
    115              '  --init-file=BLERC' \
    116              '    Specify the ble init file. The default is ~/.blerc if any, or' \
    117              '    ~/.config/blesh/init.sh.' \
    118              '' \
    119              '  --norc' \
    120              '    Do not load the ble init file.' \
    121              '' \
    122              '  --attach=ATTACH' \
    123              '  --noattach' \
    124              '    The option "--attach" selects the strategy of "ble-attach" from the list:' \
    125              '    ATTACH = "attach" | "prompt" | "none". The default strategy is "prompt".' \
    126              '    When "attach" is specified, ble.sh immediately attaches to the session in' \
    127              '    "source ble.sh".  When "prompt" is specified, ble.sh attaches to the' \
    128              '    session before the first prompt using PROMPT_COMMAND.  When "none" is' \
    129              '    specified, ble.sh does not attach to the session automatically, so' \
    130              '    ble-attach needs to be called explicitly.  The option "--noattach" is a' \
    131              '    synonym for "--attach=none".' \
    132              '' \
    133              '  --inputrc=TYPE' \
    134              '  --noinputrc' \
    135              '    The option "--inputrc" selects the strategy of reconstructing user' \
    136              '    keybindings from the list: "auto" (default), "diff", "all", "user", "none".' \
    137              '    When "diff" is specified, user keybindings are extracted by the diff of the' \
    138              '    outputs of the "bind" builtin between the current session and the plain' \
    139              '    Bash.  When "all" is specified, the user keybindings are extracted from' \
    140              '    /etc/inputrc and ${INPUTRC:-~/.inputrc*}.  When "user" is specified, the' \
    141              '    user keybindings are extracted from ${INPUTRC:-~/.inputrc*}.  When "none"' \
    142              '    is specified, the user keybindings are not reconstructed from the state of' \
    143              '    Readline, and only the bindings by "ble-bind" are applied.  The option' \
    144              '    "--noinputrc" is a synonym for "--inputrc=none".' \
    145              '' \
    146              '  --keep-rlvars' \
    147              '    Do not change readline settings for ble.sh' \
    148              '' \
    149              '  -o BLEOPT=VALUE' \
    150              '    Set a value for the specified bleopt option.' \
    151              '  --debug-bash-output' \
    152              '    Internal settings for debugging' \
    153              '' ;;
    154     --test | --update | --clear-cache | --lib) _ble_init_command=1 ;;
    155     esac
    156   done
    157   if [ -n "$_ble_init_exit" ]; then
    158     unset _ble_init_version
    159     unset _ble_init_arg
    160     unset _ble_init_exit
    161     unset _ble_init_command
    162     return 0 2>/dev/null || exit 0
    163   fi
    164 } 2>/dev/null # set -x 対策 #D0930
    165 
    166 #------------------------------------------------------------------------------
    167 # check shell
    168 
    169 if [ -z "${BASH_VERSION-}" ]; then
    170   echo "ble.sh: This shell is not Bash. Please use this script with Bash." >&3
    171   return 1 2>/dev/null || exit 1
    172 fi 3>&2 >/dev/null 2>&1 # set -x 対策 #D0930
    173 
    174 if [ -z "${BASH_VERSINFO-}" ] || [ "${BASH_VERSINFO-0}" -lt 3 ]; then
    175   echo "ble.sh: Bash with a version under 3.0 is not supported." >&3
    176   return 1 2>/dev/null || exit 1
    177 fi 3>&2 >/dev/null 2>&1 # set -x 対策 #D0930
    178 
    179 if [[ ! $_ble_init_command ]]; then
    180   if [[ ${BASH_EXECUTION_STRING+set} ]]; then
    181     # builtin echo "ble.sh: ble.sh will not be activated for Bash started with '-c' option." >&3
    182     return 1 2>/dev/null || builtin exit 1
    183   fi
    184 
    185   if ((BASH_SUBSHELL)); then
    186     builtin echo "ble.sh: ble.sh cannot be loaded into a subshell." >&3
    187     return 1 2>/dev/null || builtin exit 1
    188   elif [[ $- != *i* ]]; then
    189     case " ${BASH_SOURCE[*]##*/} " in
    190     (*' .bashrc '* | *' .bash_profile '* | *' .profile '* | *' bashrc '* | *' profile '*) ((0)) ;;
    191     esac &&
    192       builtin echo "ble.sh: This is not an interactive session." >&3 || ((1))
    193     return 1 2>/dev/null || builtin exit 1
    194   elif ! [[ -t 4 && -t 5 ]] && ! ((1)) >/dev/tty; then
    195     builtin echo "ble.sh: cannot find a controlling TTY/PTY in this session." >&3
    196     return 1 2>/dev/null || builtin exit 1
    197   fi
    198 fi 3>&2 4<&0 5>&1 &>/dev/null # set -x 対策 #D0930
    199 
    200 {
    201   ## @var _ble_bash_POSIXLY_CORRECT_adjusted
    202   ##   現在 POSIXLY_CORRECT 状態を待避した状態かどうかを保持します。
    203   ## @var _ble_bash_POSIXLY_CORRECT_set
    204   ##   待避した POSIXLY_CORRECT の設定・非設定状態を保持します。
    205   ## @var _ble_bash_POSIXLY_CORRECT_set
    206   ##   待避した POSIXLY_CORRECT の値を保持します。
    207   _ble_bash_POSIXLY_CORRECT_adjusted=1
    208   _ble_bash_POSIXLY_CORRECT_set=${POSIXLY_CORRECT+set}
    209   _ble_bash_POSIXLY_CORRECT=${POSIXLY_CORRECT-}
    210 
    211   POSIXLY_CORRECT=y
    212 
    213   # 暫定対策 expand_aliases (ble/base/adjust-bash-options を呼び出す迄の暫定)
    214   _ble_bash_expand_aliases=
    215   \shopt -q expand_aliases &&
    216     _ble_bash_expand_aliases=1 &&
    217     \shopt -u expand_aliases || ((1))
    218 
    219   # 対策 FUNCNEST
    220   _ble_bash_FUNCNEST_adjusted=
    221   _ble_bash_FUNCNEST=
    222   _ble_bash_FUNCNEST_set=
    223   _ble_bash_FUNCNEST_adjust='
    224     if [[ ! $_ble_bash_FUNCNEST_adjusted ]]; then
    225       _ble_bash_FUNCNEST_adjusted=1
    226       _ble_bash_FUNCNEST_set=${FUNCNEST+set}
    227       _ble_bash_FUNCNEST=${FUNCNEST-}
    228       builtin unset -v FUNCNEST
    229     fi 2>/dev/null'
    230   _ble_bash_FUNCNEST_restore='
    231     if [[ $_ble_bash_FUNCNEST_adjusted ]]; then
    232       _ble_bash_FUNCNEST_adjusted=
    233       if [[ $_ble_bash_FUNCNEST_set ]]; then
    234         FUNCNEST=$_ble_bash_FUNCNEST
    235       else
    236         builtin unset -v FUNCNEST
    237       fi
    238     fi 2>/dev/null'
    239   \builtin eval -- "$_ble_bash_FUNCNEST_adjust"
    240 
    241   \builtin unset -v POSIXLY_CORRECT
    242 } 2>/dev/null
    243 
    244 function ble/base/workaround-POSIXLY_CORRECT {
    245   # This function will be overwritten by ble-decode
    246   true
    247 }
    248 function ble/base/unset-POSIXLY_CORRECT {
    249   if [[ ${POSIXLY_CORRECT+set} ]]; then
    250     builtin unset -v POSIXLY_CORRECT
    251     ble/base/workaround-POSIXLY_CORRECT
    252   fi
    253 }
    254 function ble/base/adjust-POSIXLY_CORRECT {
    255   if [[ $_ble_bash_POSIXLY_CORRECT_adjusted ]]; then return 0; fi # Note: set -e 対策
    256   _ble_bash_POSIXLY_CORRECT_adjusted=1
    257   _ble_bash_POSIXLY_CORRECT_set=${POSIXLY_CORRECT+set}
    258   _ble_bash_POSIXLY_CORRECT=${POSIXLY_CORRECT-}
    259   if [[ $_ble_bash_POSIXLY_CORRECT_set ]]; then
    260     builtin unset -v POSIXLY_CORRECT
    261   fi
    262 
    263   # ユーザが触ったかもしれないので何れにしても workaround を呼び出す。
    264   ble/base/workaround-POSIXLY_CORRECT
    265 }
    266 function ble/base/restore-POSIXLY_CORRECT {
    267   if [[ ! $_ble_bash_POSIXLY_CORRECT_adjusted ]]; then return 0; fi # Note: set -e の為 || は駄目
    268   _ble_bash_POSIXLY_CORRECT_adjusted=
    269   if [[ $_ble_bash_POSIXLY_CORRECT_set ]]; then
    270     POSIXLY_CORRECT=$_ble_bash_POSIXLY_CORRECT
    271   else
    272     ble/base/unset-POSIXLY_CORRECT
    273   fi
    274 }
    275 function ble/base/is-POSIXLY_CORRECT {
    276   if [[ $_ble_bash_POSIXLY_CORRECT_adjusted ]]; then
    277     [[ $_ble_bash_POSIXLY_CORRECT_set ]]
    278   else
    279     [[ ${POSIXLY_CORRECT+set} ]]
    280   fi
    281 }
    282 
    283 {
    284   _ble_bash_builtins_adjusted=
    285   _ble_bash_builtins_save=
    286 } 2>/dev/null # set -x 対策
    287 ## @fn ble/base/adjust-builtin-wrappers/.assign
    288 ##   @remarks This function may be called with POSIXLY_CORRECT=y
    289 function ble/base/adjust-builtin-wrappers/.assign {
    290   if [[ ${_ble_util_assign_base-} ]]; then
    291     local _ble_local_tmpfile; ble/util/assign/mktmp
    292     builtin eval -- "$1" >| "$_ble_local_tmpfile"
    293     local IFS=
    294     ble/bash/read -d '' defs < "$_ble_local_tmpfile"
    295     IFS=$_ble_term_IFS
    296     ble/util/assign/rmtmp
    297   else
    298     defs=$(builtin eval -- "$1")
    299   fi || ((1))
    300 }
    301 function ble/base/adjust-builtin-wrappers-1 {
    302   # Note: 何故か local POSIXLY_CORRECT の効果が
    303   #   builtin unset -v POSIXLY_CORRECT しても残存するので関数に入れる。
    304   # Note: set -o posix にしても read, type, builtin, local 等は上書き
    305   #   された儘なので難しい。unset -f builtin さえすれば色々動く様になる
    306   #   ので builtin は unset -f builtin してしまう。
    307   unset -f builtin
    308   builtin local POSIXLY_CORRECT=y builtins1 keywords1
    309   builtins1=(builtin unset enable unalias return break continue declare local typeset eval exec set)
    310   keywords1=(if then elif else case esac while until for select do done '{' '}' '[[' function)
    311   if [[ ! $_ble_bash_builtins_adjusted ]]; then
    312     _ble_bash_builtins_adjusted=1
    313 
    314     builtin local defs
    315     ble/base/adjust-builtin-wrappers/.assign '
    316       \builtin declare -f "${builtins1[@]}" || ((1))
    317       \builtin alias "${builtins1[@]}" "${keywords1[@]}" || ((1))' # set -e 対策
    318     _ble_bash_builtins_save=$defs
    319   fi
    320   builtin unset -f "${builtins1[@]}"
    321   builtin unalias "${builtins1[@]}" "${keywords1[@]}" || ((1)) # set -e 対策
    322   ble/base/unset-POSIXLY_CORRECT
    323 } 2>/dev/null
    324 function ble/base/adjust-builtin-wrappers-2 {
    325   # Workaround (bash-3.0..4.3) #D0722
    326   #
    327   #   builtin unset -v POSIXLY_CORRECT でないと unset -f : できないが、
    328   #   bash-3.0 -- 4.3 のバグで、local POSIXLY_CORRECT の時、
    329   #   builtin unset -v POSIXLY_CORRECT しても POSIXLY_CORRECT が有効であると判断されるので、
    330   #   "unset -f :" (非POSIX関数名) は別関数で adjust-POSIXLY_CORRECT の後で実行することにする。
    331 
    332   # function :, alias : の保存
    333   local defs
    334   ble/base/adjust-builtin-wrappers/.assign 'LC_ALL= LC_MESSAGES=C builtin type :; alias :' || ((1)) # set -e 対策
    335   defs=${defs#$': is a function\n'}
    336   _ble_bash_builtins_save=$_ble_bash_builtins_save$'\n'$defs
    337 
    338   builtin unset -f :
    339   builtin unalias : || ((1)) # set -e 対策
    340 } 2>/dev/null
    341 function ble/base/restore-builtin-wrappers {
    342   if [[ $_ble_bash_builtins_adjusted ]]; then
    343     _ble_bash_builtins_adjusted=
    344     builtin eval -- "$_ble_bash_builtins_save"
    345   fi
    346 }
    347 {
    348   ble/base/adjust-builtin-wrappers-1
    349   ble/base/adjust-builtin-wrappers-2
    350 
    351   # 対策 expand_aliases (暫定) 終了
    352   if [[ $_ble_bash_expand_aliases ]]; then
    353     shopt -s expand_aliases
    354   fi
    355 } 2>/dev/null # set -x 対策
    356 
    357 # From src/util.sh
    358 function ble/variable#copy-state {
    359   local src=$1 dst=$2
    360   if [[ ${!src+set} ]]; then
    361     builtin eval -- "$dst=\${$src}"
    362   else
    363     builtin unset -v "$dst[0]" 2>/dev/null || builtin unset -v "$dst"
    364   fi
    365 }
    366 
    367 # BASH_XTRACEFD は書き換えると勝手に元々設定されていた fd を閉じてしまうので、
    368 # 元々の fd を dup しておくなど特別な配慮が必要。
    369 {
    370   _ble_bash_xtrace=()
    371   _ble_bash_xtrace_debug_enabled=
    372   _ble_bash_xtrace_debug_filename=
    373   _ble_bash_xtrace_debug_fd=
    374   _ble_bash_XTRACEFD=
    375   _ble_bash_XTRACEFD_set=
    376   _ble_bash_XTRACEFD_dup=
    377   _ble_bash_PS4=
    378 } 2>/dev/null # set -x 対策
    379 # From src/util.sh (ble/fd#is-open and ble/fd#alloc/.nextfd)
    380 function ble/base/xtrace/.fdcheck { builtin : >&"$1"; } 2>/dev/null
    381 function ble/base/xtrace/.fdnext {
    382   local _ble_local_init=${_ble_util_openat_nextfd:=${bleopt_openat_base:-30}}
    383   for (($1=_ble_local_init;$1<_ble_local_init+1024;$1++)); do
    384     ble/base/xtrace/.fdcheck "${!1}" || break
    385   done
    386   (($1<_ble_local_init+1024)) ||
    387     { (($1=_ble_local_init,_ble_util_openat_nextfd++)); builtin eval "exec ${!1}>&-"; } ||
    388     ((1))
    389 } 
    390 function ble/base/xtrace/.log {
    391   local bash=${_ble_bash:-$((BASH_VERSINFO[0]*10000+BASH_VERSINFO[1]*100+BASH_VERSINFO[2]))}
    392   local open=---- close=----
    393   if ((bash>=40200)); then
    394     builtin printf '%s [%(%F %T %Z)T] %s %s\n' "$open" -1 "$1" "$close"
    395   else
    396     builtin printf '%s [%s] %s %s\n' "$open" "$(date 2>/dev/null)" "$1" "$close"
    397   fi >&"${BASH_XTRACEFD:-2}"
    398 }
    399 function ble/base/xtrace/adjust {
    400   local level=${#_ble_bash_xtrace[@]} IFS=$' \t\n'
    401   if [[ $- == *x* ]]; then
    402     _ble_bash_xtrace[level]=1
    403   else
    404     _ble_bash_xtrace[level]=
    405   fi
    406   set +x
    407 
    408   ((level==0)) || return 0
    409   _ble_bash_xtrace_debug_enabled=
    410   if [[ ${bleopt_debug_xtrace:-/dev/null} == /dev/null ]]; then
    411     if [[ $_ble_bash_xtrace_debug_fd ]]; then
    412       builtin eval "exec $_ble_bash_xtrace_debug_fd>&-" || return 0
    413       _ble_bash_xtrace_debug_filename=
    414       _ble_bash_xtrace_debug_fd=
    415     fi
    416   else
    417     if [[ $_ble_bash_xtrace_debug_filename != "$bleopt_debug_xtrace" ]]; then
    418       _ble_bash_xtrace_debug_filename=$bleopt_debug_xtrace
    419       [[ $_ble_bash_xtrace_debug_fd ]] || ble/base/xtrace/.fdnext _ble_bash_xtrace_debug_fd
    420       builtin eval "exec $_ble_bash_xtrace_debug_fd>>\"$bleopt_debug_xtrace\"" || return 0
    421     fi
    422 
    423     _ble_bash_XTRACEFD=${BASH_XTRACEFD-}
    424     _ble_bash_XTRACEFD_set=${BASH_XTRACEFD+set}
    425     if [[ ${BASH_XTRACEFD-} =~ ^[0-9]+$ ]] && ble/base/xtrace/.fdcheck "$BASH_XTRACEFD"; then
    426       ble/base/xtrace/.fdnext _ble_bash_XTRACEFD_dup
    427       builtin eval "exec $_ble_bash_XTRACEFD_dup>&$BASH_XTRACEFD" || return 0
    428       builtin eval "exec $BASH_XTRACEFD>&$_ble_bash_xtrace_debug_fd" || return 0
    429     else
    430       _ble_bash_XTRACEFD_dup=
    431       local newfd; ble/base/xtrace/.fdnext newfd
    432       builtin eval "exec $newfd>&$_ble_bash_xtrace_debug_fd" || return 0
    433       BASH_XTRACEFD=$newfd
    434     fi
    435 
    436     ble/variable#copy-state PS4 _ble_base_PS4
    437     PS4=${bleopt_debug_xtrace_ps4:-'+ '}
    438 
    439     _ble_bash_xtrace_debug_enabled=1
    440     ble/base/xtrace/.log "$FUNCNAME"
    441     set -x
    442   fi
    443 }
    444 function ble/base/xtrace/restore {
    445   local level=$((${#_ble_bash_xtrace[@]}-1)) IFS=$' \t\n'
    446   ((level>=0)) || return 0
    447   if [[ ${_ble_bash_xtrace[level]-} ]]; then
    448     set -x
    449   else
    450     set +x
    451   fi
    452   builtin unset -v '_ble_bash_xtrace[level]'
    453 
    454   ((level==0)) || return 0
    455   if [[ $_ble_bash_xtrace_debug_enabled ]]; then
    456     ble/base/xtrace/.log "$FUNCNAME"
    457     _ble_bash_xtrace_debug_enabled=
    458 
    459     # Note: ユーザーの BASH_XTRACEFD にごみが混入しない様にする為、
    460     # BASH_XTRACEFD を書き換える前に先に PS4 を戻す。
    461     ble/variable#copy-state _ble_base_PS4 PS4
    462 
    463     if [[ $_ble_bash_XTRACEFD_dup ]]; then
    464       # BASH_XTRACEFD の fd を元の出力先に繋ぎ直す
    465       builtin eval "exec $BASH_XTRACEFD>&$_ble_bash_XTRACEFD_dup" &&
    466         builtin eval "exec $_ble_bash_XTRACEFD_dup>&-" || ((1))
    467     else
    468       # BASH_XTRACEFD の fd は新しく割り当てた fd なので値上書きで閉じて良い
    469       if [[ $_ble_bash_XTRACEFD_set ]]; then
    470         BASH_XTRACEFD=$_ble_bash_XTRACEFD
    471       else
    472         builtin unset -v BASH_XTRACEFD
    473       fi
    474     fi
    475   fi
    476 }
    477 
    478 function ble/base/.adjust-bash-options {
    479   builtin eval -- "$1=\$-"
    480   set +evukT -B
    481   ble/base/xtrace/adjust
    482 
    483   [[ $2 == shopt ]] || local shopt
    484   if ((_ble_bash>=40100)); then
    485     shopt=$BASHOPTS
    486   else
    487     # Note: nocasematch は bash-3.1 以上
    488     shopt=
    489     shopt -q extdebug 2>/dev/null && shopt=$shopt:extdebug
    490     shopt -q nocasematch 2>/dev/null && shopt=$shopt:nocasematch
    491   fi
    492   [[ $2 == shopt ]] || builtin eval -- "$2=\$shopt"
    493   shopt -u extdebug
    494   shopt -u nocasematch 2>/dev/null
    495   return 0
    496 } 2>/dev/null # set -x 対策
    497 ## @fn ble/base/.restore-bash-options var_set var_shopt
    498 ##   @param[out] var_set var_shopt
    499 function ble/base/.restore-bash-options {
    500   local set=${!1} shopt=${!2}
    501   [[ :$shopt: == *:nocasematch:* ]] && shopt -s nocasematch
    502   [[ :$shopt: == *:extdebug:* ]] && shopt -s extdebug
    503   ble/base/xtrace/restore
    504   [[ $set == *B* ]] || set +B
    505   [[ $set == *T* ]] && set -T
    506   [[ $set == *k* ]] && set -k
    507   [[ $set == *u* ]] && set -u
    508   [[ $set == *v* ]] && set -v
    509   [[ $set == *e* ]] && set -e # set -e は最後
    510   return 0
    511 } 2>/dev/null # set -x 対策
    512 
    513 {
    514   : "${_ble_bash_options_adjusted=}"
    515   _ble_bash_set=$-
    516   _ble_bash_shopt=${BASHOPTS-}
    517 } 2>/dev/null # set -x 対策
    518 function ble/base/adjust-bash-options {
    519   [[ $_ble_bash_options_adjusted ]] && return 1 || ((1)) # set -e 対策
    520   _ble_bash_options_adjusted=1
    521 
    522   ble/base/.adjust-bash-options _ble_bash_set _ble_bash_shopt
    523 
    524   # Note: expand_aliases はユーザー設定を復元する為に記録する
    525   _ble_bash_expand_aliases=
    526   shopt -q expand_aliases 2>/dev/null &&
    527     _ble_bash_expand_aliases=1
    528 
    529   # locale 待避
    530   # Note #D1854: ble/widget/display-shell-version で此処で待避した変数を参照す
    531   #   る事に注意する。此処に新しい変数を追加する時は display-shell-version の方
    532   #   にも処理スキップを追加する必要がある。
    533   ble/variable#copy-state LC_ALL _ble_bash_LC_ALL
    534   if [[ ${LC_ALL-} ]]; then
    535     ble/variable#copy-state LC_CTYPE    _ble_bash_LC_CTYPE
    536     ble/variable#copy-state LC_MESSAGES _ble_bash_LC_MESSAGES
    537     ble/variable#copy-state LC_NUMERIC  _ble_bash_LC_NUMERIC
    538     ble/variable#copy-state LC_TIME     _ble_bash_LC_TIME
    539     ble/variable#copy-state LANG        _ble_bash_LANG
    540     [[ ${LC_CTYPE-}    ]] && LC_CTYPE=$LC_ALL
    541     [[ ${LC_MESSAGES-} ]] && LC_MESSAGES=$LC_ALL
    542     [[ ${LC_NUMERIC-}  ]] && LC_NUMERIC=$LC_ALL
    543     [[ ${LC_TIME-}     ]] && LC_TIME=$LC_ALL
    544     LANG=$LC_ALL
    545     LC_ALL=
    546   fi
    547   ble/variable#copy-state LC_COLLATE _ble_bash_LC_COLLATE
    548   LC_COLLATE=C
    549 
    550   # TMOUT 確認 #D1630 WA readonly TMOUT
    551   if local TMOUT= 2>/dev/null; then # #D1630 WA
    552     _ble_bash_tmout_wa=()
    553   else
    554     _ble_bash_tmout_wa=(-t 2147483647)
    555   fi
    556 } 2>/dev/null # set -x 対策 #D0930 / locale 変更
    557 function ble/base/restore-bash-options {
    558   [[ $_ble_bash_options_adjusted ]] || return 1
    559   _ble_bash_options_adjusted=
    560 
    561   # locale 復元
    562   ble/variable#copy-state _ble_bash_LC_COLLATE LC_COLLATE
    563   if [[ $_ble_bash_LC_ALL ]]; then
    564     ble/variable#copy-state _ble_bash_LC_CTYPE    LC_CTYPE
    565     ble/variable#copy-state _ble_bash_LC_MESSAGES LC_MESSAGES
    566     ble/variable#copy-state _ble_bash_LC_NUMERIC  LC_NUMERIC
    567     ble/variable#copy-state _ble_bash_LC_TIME     LC_TIME
    568     ble/variable#copy-state _ble_bash_LANG        LANG
    569   fi
    570   ble/variable#copy-state _ble_bash_LC_ALL LC_ALL
    571 
    572   [[ $_ble_bash_nocasematch ]] && shopt -s nocasematch
    573 
    574   ble/base/.restore-bash-options _ble_bash_set _ble_bash_shopt
    575 } 2>/dev/null # set -x 対策 #D0930 / locale 変更
    576 function ble/base/recover-bash-options {
    577   # bind -x が終わる度に設定が復元されてしまうので毎回設定し直す #D1526 #D1574
    578   if [[ $_ble_bash_expand_aliases ]]; then
    579     shopt -s expand_aliases
    580   else
    581     shopt -u expand_aliases
    582   fi
    583 }
    584 
    585 { ble/base/adjust-bash-options; } &>/dev/null # set -x 対策 #D0930
    586 
    587 builtin bind &>/dev/null # force to load .inputrc
    588 
    589 # WA #D1534 workaround for msys2 .inputrc
    590 if [[ $OSTYPE == msys* ]]; then
    591   [[ $(builtin bind -m emacs -p 2>/dev/null | grep '"\\C-?"') == '"\C-?": backward-kill-line' ]] &&
    592     builtin bind -m emacs '"\C-?": backward-delete-char' 2>/dev/null
    593 fi
    594 
    595 if [[ ! -o emacs && ! -o vi && ! $_ble_init_command ]]; then
    596   builtin echo "ble.sh: ble.sh is not intended to be used with the line-editing mode disabled (--noediting)." >&2
    597   ble/base/restore-bash-options
    598   ble/base/restore-builtin-wrappers
    599   ble/base/restore-POSIXLY_CORRECT
    600   builtin eval -- "$_ble_bash_FUNCNEST_restore"
    601   return 1 2>/dev/null || builtin exit 1
    602 fi
    603 
    604 if shopt -q restricted_shell; then
    605   builtin echo "ble.sh: ble.sh is not intended to be used in restricted shells (--restricted)." >&2
    606   ble/base/restore-bash-options
    607   ble/base/restore-builtin-wrappers
    608   ble/base/restore-POSIXLY_CORRECT
    609   builtin eval -- "$_ble_bash_FUNCNEST_restore"
    610   return 1 2>/dev/null || builtin exit 1
    611 fi
    612 
    613 #--------------------------------------
    614 # save IFS / BASH_REMATCH
    615 
    616 function ble/init/adjust-IFS {
    617   _ble_init_original_IFS_set=${IFS+set}
    618   _ble_init_original_IFS=$IFS
    619   IFS=$' \t\n'
    620 }
    621 function ble/init/restore-IFS {
    622   if [[ $_ble_init_original_IFS_set ]]; then
    623     IFS=$_ble_init_original_IFS
    624   else
    625     builtin unset -v IFS
    626   fi
    627   builtin unset -v _ble_init_original_IFS_set
    628   builtin unset -v _ble_init_original_IFS
    629 }
    630 
    631 if ((_ble_bash>=50100)); then
    632   _ble_bash_BASH_REMATCH_level=0
    633   _ble_bash_BASH_REMATCH=()
    634   function ble/base/adjust-BASH_REMATCH {
    635     ((_ble_bash_BASH_REMATCH_level++==0)) || return 0
    636     _ble_bash_BASH_REMATCH=("${BASH_REMATCH[@]}")
    637   }
    638   function ble/base/restore-BASH_REMATCH {
    639     ((_ble_bash_BASH_REMATCH_level>0&&
    640         --_ble_bash_BASH_REMATCH_level==0)) || return 0
    641     BASH_REMATCH=("${_ble_bash_BASH_REMATCH[@]}")
    642   }
    643 
    644 else
    645   _ble_bash_BASH_REMATCH_level=0
    646   _ble_bash_BASH_REMATCH=()
    647   _ble_bash_BASH_REMATCH_rex=none
    648 
    649   ## @fn ble/base/adjust-BASH_REMATCH/increase delta
    650   ##   @param[in] delta
    651   ##   @var[in,out] i rex
    652   function ble/base/adjust-BASH_REMATCH/increase {
    653     local delta=$1
    654     ((delta)) || return 1
    655     ((i+=delta))
    656     if ((delta==1)); then
    657       rex=$rex.
    658     else
    659       rex=$rex.{$delta}
    660     fi
    661   }
    662   function ble/base/adjust-BASH_REMATCH/is-updated {
    663     local i n=${#_ble_bash_BASH_REMATCH[@]}
    664     ((n!=${#BASH_REMATCH[@]})) && return 0
    665     for ((i=0;i<n;i++)); do
    666       [[ ${_ble_bash_BASH_REMATCH[i]} != "${BASH_REMATCH[i]}" ]] && return 0
    667     done
    668     return 1
    669   }
    670   # This is a simplified version of ble/string#index-of text sub
    671   function ble/base/adjust-BASH_REMATCH/.find-substr {
    672     local t=${1#*"$2"}
    673     ((ret=${#1}-${#t}-${#2},ret<0&&(ret=-1),ret>=0))
    674   }
    675   function ble/base/adjust-BASH_REMATCH {
    676     ((_ble_bash_BASH_REMATCH_level++==0)) || return 0
    677     ble/base/adjust-BASH_REMATCH/is-updated || return 1
    678 
    679     local size=${#BASH_REMATCH[@]}
    680     if ((size==0)); then
    681       _ble_bash_BASH_REMATCH=()
    682       _ble_bash_BASH_REMATCH_rex=none
    683       return 0
    684     fi
    685 
    686     local rex= i=0
    687     local text=$BASH_REMATCH sub ret isub
    688 
    689     local -a rparens=()
    690     local isub rex i=0 count=0
    691     for ((isub=1;isub<size;isub++)); do
    692       local sub=${BASH_REMATCH[isub]}
    693 
    694       # 既存の子一致の孫一致になるか確認
    695       while ((count>=1)); do
    696         local end=${rparens[count-1]}
    697         if ble/base/adjust-BASH_REMATCH/.find-substr "${text:i:end-i}" "$sub"; then
    698           ble/base/adjust-BASH_REMATCH/increase "$ret"
    699           ((rparens[count++]=i+${#sub}))
    700           rex=$rex'('
    701           break
    702         else
    703           ble/base/adjust-BASH_REMATCH/increase "$((end-i))"
    704           rex=$rex')'
    705           builtin unset -v 'rparens[--count]'
    706         fi
    707       done
    708 
    709       ((count>0)) && continue
    710 
    711       # 新しい子一致
    712       if ble/base/adjust-BASH_REMATCH/.find-substr "${text:i}" "$sub"; then
    713         ble/base/adjust-BASH_REMATCH/increase "$ret"
    714         ((rparens[count++]=i+${#sub}))
    715         rex=$rex'('
    716       else
    717         break # 復元失敗
    718       fi
    719     done
    720 
    721     while ((count>=1)); do
    722       local end=${rparens[count-1]}
    723       ble/base/adjust-BASH_REMATCH/increase "$((end-i))"
    724       rex=$rex')'
    725       builtin unset -v 'rparens[--count]'
    726     done
    727 
    728     ble/base/adjust-BASH_REMATCH/increase "$((${#text}-i))"
    729 
    730     _ble_bash_BASH_REMATCH=("${BASH_REMATCH[@]}")
    731     _ble_bash_BASH_REMATCH_rex=$rex
    732   }
    733   function ble/base/restore-BASH_REMATCH {
    734     ((_ble_bash_BASH_REMATCH_level>0&&
    735         --_ble_bash_BASH_REMATCH_level==0)) || return 0
    736     [[ $_ble_bash_BASH_REMATCH =~ $_ble_bash_BASH_REMATCH_rex ]]
    737   }
    738 fi
    739 
    740 ble/init/adjust-IFS
    741 ble/base/adjust-BASH_REMATCH
    742 
    743 ## @fn ble/init/clean-up [opts]
    744 function ble/init/clean-up {
    745   local ext=$? opts=$1 # preserve exit status
    746 
    747   # 一時グローバル変数消去
    748   builtin unset -v _ble_init_version
    749   builtin unset -v _ble_init_arg
    750   builtin unset -v _ble_init_exit
    751   builtin unset -v _ble_init_command
    752   builtin unset -v _ble_init_attached
    753 
    754   # 状態復元
    755   ble/base/restore-BASH_REMATCH
    756   ble/init/restore-IFS
    757   if [[ :$opts: != *:check-attach:* || ! $_ble_attached ]]; then
    758     ble/base/restore-bash-options
    759     ble/base/restore-POSIXLY_CORRECT
    760     ble/base/restore-builtin-wrappers
    761     builtin eval -- "$_ble_bash_FUNCNEST_restore"
    762   fi
    763   return "$ext"
    764 }
    765 
    766 #------------------------------------------------------------------------------
    767 # read arguments
    768 
    769 function ble/util/put { builtin printf '%s' "$1"; }
    770 function ble/util/print { builtin printf '%s\n' "$1"; }
    771 function ble/util/print-lines { builtin printf '%s\n' "$@"; }
    772 
    773 _ble_base_arguments_opts=
    774 _ble_base_arguments_attach=
    775 _ble_base_arguments_rcfile=
    776 ## @fn ble/base/read-blesh-arguments args
    777 ##   @var[out] _ble_base_arguments_opts
    778 ##   @var[out] _ble_base_arguments_attach
    779 ##   @var[out] _ble_base_arguments_rcfile
    780 function ble/base/read-blesh-arguments {
    781   local opts=
    782   local opt_attach=prompt
    783   local opt_inputrc=auto
    784 
    785   builtin unset -v _ble_init_command # 再解析
    786   while (($#)); do
    787     local arg=$1; shift
    788     case $arg in
    789     (--noattach|noattach)
    790       opt_attach=none ;;
    791     (--attach=*) opt_attach=${arg#*=} ;;
    792     (--attach)
    793       if (($#)); then
    794         opt_attach=$1; shift
    795       else
    796         opt_attach=attach
    797         opts=$opts:E
    798         ble/util/print "ble.sh ($arg): an option argument is missing." >&2
    799       fi ;;
    800 
    801     (--noinputrc)
    802       opt_inputrc=none ;;
    803     (--inputrc=*) opt_inputrc=${arg#*=} ;;
    804     (--inputrc)
    805       if (($#)); then
    806         opt_inputrc=$1; shift
    807       else
    808         opt_inputrc=inputrc
    809         opts=$opts:E
    810         ble/util/print "ble.sh ($arg): an option argument is missing." >&2
    811       fi ;;
    812 
    813     (--rcfile=*|--init-file=*|--rcfile|--init-file)
    814       if [[ $arg != *=* ]]; then
    815         local rcfile=$1; shift
    816       else
    817         local rcfile=${arg#*=}
    818       fi
    819 
    820       _ble_base_arguments_rcfile=${rcfile:-/dev/null}
    821       if [[ ! $rcfile || ! -e $rcfile ]]; then
    822         ble/util/print "ble.sh ($arg): '$rcfile' does not exist." >&2
    823         opts=$opts:E
    824       elif [[ ! -r $rcfile ]]; then
    825         ble/util/print "ble.sh ($arg): '$rcfile' is not readable." >&2
    826         opts=$opts:E
    827       fi ;;
    828     (--norc)
    829       _ble_base_arguments_rcfile=/dev/null ;;
    830     (--keep-rlvars)
    831       opts=$opts:keep-rlvars ;;
    832     (--debug-bash-output)
    833       bleopt_internal_suppress_bash_output= ;;
    834     (--test | --update | --clear-cache | --lib)
    835       if [[ $_ble_init_command ]]; then
    836         ble/util/print "ble.sh ($arg): the option '--$_ble_init_command' has already been specified." >&2
    837         opts=$opts:E
    838       else
    839         _ble_init_command=${arg#--}
    840       fi ;;
    841     (--*)
    842       ble/util/print "ble.sh: unrecognized long option '$arg'" >&2
    843       opts=$opts:E ;;
    844     (-?*)
    845       local i c
    846       for ((i=1;i<${#arg};i++)); do
    847         c=${arg:i:1}
    848         case -$c in
    849         (-o)
    850           if ((i+1<${#arg})); then
    851             local oarg=${arg:i+1}
    852             i=${#arg}
    853           elif (($#)); then
    854             local oarg=$1; shift
    855           else
    856             opts=$opts:E
    857             i=${#arg}
    858             continue
    859           fi
    860           local rex='^[_a-zA-Z][_a-zA-Z0-9]*='
    861           if [[ $oarg =~ $rex ]]; then
    862             builtin eval -- "bleopt_${oarg%%=*}=\${oarg#*=}"
    863           else
    864             ble/util/print "ble.sh: unrecognized option '-o $oarg'" >&2
    865             opts=$opts:E
    866           fi ;;
    867         (-*)
    868           ble/util/print "ble.sh: unrecognized option '-$c'" >&2
    869           opts=$opts:E ;;
    870         esac
    871       done
    872       ;;
    873     (*)
    874       if [[ ${_ble_init_command-} ]]; then
    875         _ble_init_command[${#_ble_init_command[@]}]=$arg
    876       else
    877         ble/util/print "ble.sh: unrecognized argument '$arg'" >&2
    878         opts=$opts:E
    879       fi ;;
    880     esac
    881   done
    882 
    883   _ble_base_arguments_opts=$opts
    884   _ble_base_arguments_attach=$opt_attach
    885   _ble_base_arguments_inputrc=$opt_inputrc
    886   [[ :$opts: != *:E:* ]]
    887 }
    888 if ! ble/base/read-blesh-arguments "$@"; then
    889   builtin echo "ble.sh: cancel initialization." >&2
    890   ble/init/clean-up 2>/dev/null # set -x 対策 #D0930
    891   return 2 2>/dev/null || builtin exit 2
    892 fi
    893 
    894 if [[ ${_ble_base-} ]]; then
    895   [[ $_ble_init_command ]] && _ble_init_attached=$_ble_attached
    896   if ! ble/base/unload-for-reload; then
    897     builtin echo "ble.sh: an old version of ble.sh seems to be already loaded." >&2
    898     ble/init/clean-up 2>/dev/null # set -x 対策 #D0930
    899     return 1 2>/dev/null || builtin exit 1
    900   fi
    901 fi
    902 
    903 #------------------------------------------------------------------------------
    904 # Initialize version information
    905 
    906 # DEBUG version の Bash では遅いという通知
    907 case ${BASH_VERSINFO[4]} in
    908 (alp*|bet*|dev*|rc*|releng*|maint*)
    909   ble/util/print-lines \
    910     "ble.sh may become very slow because this is a debug version of Bash" \
    911     "  (version '$BASH_VERSION', release status: '${BASH_VERSINFO[4]}')." \
    912     "  We recommend using ble.sh with a release version of Bash." >&2 ;;
    913 esac
    914 
    915 _ble_bash=$((BASH_VERSINFO[0]*10000+BASH_VERSINFO[1]*100+BASH_VERSINFO[2]))
    916 _ble_bash_loaded_in_function=0
    917 local _ble_local_test 2>/dev/null && _ble_bash_loaded_in_function=1
    918 
    919 _ble_version=0
    920 BLE_VERSION=$_ble_init_version
    921 function ble/base/initialize-version-information {
    922   local version=$BLE_VERSION
    923 
    924   local hash=
    925   if [[ $version == *+* ]]; then
    926     hash=${version#*+}
    927     version=${version%%+*}
    928   fi
    929 
    930   local status=release
    931   if [[ $version == *-* ]]; then
    932     status=${version#*-}
    933     version=${version%%-*}
    934   fi
    935 
    936   local major=${version%%.*}; version=${version#*.}
    937   local minor=${version%%.*}; version=${version#*.}
    938   local patch=${version%%.*}
    939   BLE_VERSINFO=("$major" "$minor" "$patch" "$hash" "$status" noarch)
    940   ((_ble_version=major*10000+minor*100+patch))
    941 }
    942 ble/base/initialize-version-information
    943 
    944 #------------------------------------------------------------------------------
    945 # workarounds for builtin read
    946 
    947 function ble/bash/read {
    948   local TMOUT= 2>/dev/null # #D1630 WA readonly TMOUT
    949   builtin read "${_ble_bash_tmout_wa[@]}" -r "$@"
    950 }
    951 function ble/bash/read-timeout { builtin read -t "$@"; }
    952 
    953 # WA for bash-5.2 nested read by WINCH causes corrupted "running_trap" (#D1982)
    954 _ble_bash_read_winch=
    955 if ((50200<=_ble_bash&&_ble_bash<50300)); then
    956   function ble/bash/read/.process-winch {
    957     if [[ $_ble_bash_read_winch != - ]]; then
    958       local _ble_local_handler=$_ble_bash_read_winch
    959       local _ble_bash_read_winch=
    960       builtin eval -- "$_ble_local_handler"
    961     fi
    962   }
    963   function ble/bash/read {
    964     local TMOUT= 2>/dev/null # #D1630 WA readonly TMOUT
    965     local _ble_bash_read_winch=-
    966     builtin read "${_ble_bash_tmout_wa[@]}" -r "$@"; local _ble_local_ext=$?
    967     ble/bash/read/.process-winch
    968     return "$_ble_local_ext"
    969   }
    970   function ble/bash/read-timeout {
    971     local _ble_bash_read_winch=-
    972     builtin read -t "$@"; local _ble_local_ext=$?
    973     ble/bash/read/.process-winch
    974     return "$_ble_local_ext"
    975   }
    976 fi
    977 
    978 #------------------------------------------------------------------------------
    979 # check environment
    980 
    981 # will be overwritten by src/util.sh
    982 if ((_ble_bash>=50300)); then
    983   function ble/util/assign { builtin eval "$1=\${ builtin eval -- \"\$2\"; }"; }
    984 else
    985   function ble/util/assign { builtin eval "$1=\$(builtin eval -- \"\$2\")"; }
    986 fi
    987 
    988 # ble/bin
    989 
    990 ## @fn ble/bin/.default-utility-path commands...
    991 ##   取り敢えず ble/bin/* からコマンドを呼び出せる様にします。
    992 function ble/bin/.default-utility-path {
    993   local cmd
    994   for cmd; do
    995     builtin eval "function ble/bin/$cmd { command $cmd \"\$@\"; }"
    996   done
    997 }
    998 ## @fn ble/bin#freeze-utility-path [-n] commands...
    999 ##   PATH が破壊された後でも ble が動作を続けられる様に、
   1000 ##   現在の PATH で基本コマンドのパスを固定して ble/bin/* から使える様にする。
   1001 ##
   1002 ##   実装に ble/util/assign を使用しているので ble-core 初期化後に実行する必要がある。
   1003 ##
   1004 function ble/bin#freeze-utility-path {
   1005   local cmd path q=\' Q="'\''" fail= flags=
   1006   for cmd; do
   1007     if [[ $cmd == -n ]]; then
   1008       flags=n$flags
   1009       continue
   1010     fi
   1011     [[ $flags == *n* ]] && ble/bin#has "ble/bin/$cmd" && continue
   1012     ble/bin#has "ble/bin/.frozen:$cmd" && continue
   1013     if ble/util/assign path "builtin type -P -- $cmd 2>/dev/null" && [[ $path ]]; then
   1014       builtin eval "function ble/bin/$cmd { '${path//$q/$Q}' \"\$@\"; }"
   1015     else
   1016       fail=1
   1017     fi
   1018   done
   1019   ((!fail))
   1020 }
   1021 
   1022 if ((_ble_bash>=40000)); then
   1023   function ble/bin#has { type -t "$@" &>/dev/null; }
   1024 else
   1025   function ble/bin#has {
   1026     local cmd
   1027     for cmd; do type -t "$cmd" || return 1; done &>/dev/null
   1028     return 0
   1029   }
   1030 fi
   1031 
   1032 # POSIX utilities
   1033 
   1034 _ble_init_posix_command_list=(sed date rm mkdir mkfifo sleep stty tty sort awk chmod grep cat wc mv sh od cp ps)
   1035 function ble/init/check-environment {
   1036   if ! ble/bin#has "${_ble_init_posix_command_list[@]}"; then
   1037     local cmd commandMissing=
   1038     for cmd in "${_ble_init_posix_command_list[@]}"; do
   1039       if ! type "$cmd" &>/dev/null; then
   1040         commandMissing="$commandMissing\`$cmd', "
   1041       fi
   1042     done
   1043     ble/util/print "ble.sh: insane environment: The command(s), ${commandMissing}not found. Check your environment variable PATH." >&2
   1044 
   1045     # try to fix PATH
   1046     local default_path=$(command -p getconf PATH 2>/dev/null)
   1047     [[ $default_path ]] || return 1
   1048 
   1049     local original_path=$PATH
   1050     export PATH=${default_path}${PATH:+:}${PATH}
   1051     [[ :$PATH: == *:/bin:* ]] || PATH=/bin${PATH:+:}$PATH
   1052     [[ :$PATH: == *:/usr/bin:* ]] || PATH=/usr/bin${PATH:+:}$PATH
   1053     if ! ble/bin#has "${_ble_init_posix_command_list[@]}"; then
   1054       PATH=$original_path
   1055       return 1
   1056     fi
   1057     ble/util/print "ble.sh: modified PATH=${PATH::${#PATH}-${#original_path}}\$PATH" >&2
   1058   fi
   1059 
   1060   if [[ ! ${USER-} ]]; then
   1061     ble/util/print "ble.sh: insane environment: \$USER is empty." >&2
   1062     if USER=$(id -un 2>/dev/null) && [[ $USER ]]; then
   1063       export USER
   1064       ble/util/print "ble.sh: modified USER=$USER" >&2
   1065     fi
   1066   fi
   1067   _ble_base_env_USER=$USER
   1068 
   1069   if [[ ! ${HOSTNAME-} ]]; then
   1070     ble/util/print "ble.sh: suspicious environment: \$HOSTNAME is empty."
   1071     if HOSTNAME=$(uname -n 2>/dev/null) && [[ $HOSTNAME ]]; then
   1072       export HOSTNAME
   1073       ble/util/print "ble.sh: fixed HOSTNAME=$HOSTNAME" >&2
   1074     fi
   1075   fi
   1076   _ble_base_env_HOSTNAME=$HOSTNAME
   1077 
   1078   if [[ ! ${LANG-} ]]; then
   1079     ble/util/print "ble.sh: suspicious environment: \$LANG is empty." >&2
   1080   fi
   1081 
   1082   # Check locale and work around `convert-meta on' in bash >= 5.2
   1083   if ((_ble_bash>=50200)); then
   1084     # Note #D2069: In bash >= 5.2, when the specified locale does not exist,
   1085     # the readline setting `convert-meta' is automatically turned on when
   1086     # Readline is first initialized.  This interferes with ble.sh's trick to
   1087     # distinguish isolated ESCs from meta ESCs, i.e., the combination "ESC ["
   1088     # is converted to "<C0> <9B> [" by ble.sh's macro, <C0> is converted to
   1089     # "ESC @" by `convert-meta', and "ESC @" is again converted to "<C0> <9B>
   1090     # @".  This forms an infinite loop.  ble.sh tries to adjust `convert-meta',
   1091     # but Readline's adjustment takes place at a random timing which is not
   1092     # controllable.  To work around this, we need to forcibly initialize
   1093     # Readline before ble.sh adjusts `convert-meta'.
   1094 
   1095     local error
   1096     # Note: We check if the current locale setting produces an error message.
   1097     # We try the workaround only when the locale appears to be broken because
   1098     # the workaround may have a side effect of consuming user's input.
   1099     ble/util/assign error '{ LC_ALL= LC_CTYPE=C ble/util/put; } 2>&1'
   1100     if [[ $error ]]; then
   1101       ble/util/print "$error" >&2
   1102       ble/util/print "ble.sh: please check the locale settings (LANG and LC_*)." >&2
   1103 
   1104       # Note: Somehow, the workaround of using "read -et" only works after
   1105       # running `LC_ALL= LC_CTYPE=C cmd'.  In bash < 5.3, ble/util/assign at
   1106       # this point is executed under a subshell, so we need to run `LC_ALL=
   1107       # LC_CTYPE=C ble/util/put' again in the main shell
   1108       ((_ble_bash>=50300)) || { LC_ALL= LC_CTYPE=C ble/util/put; } 2>/dev/null
   1109 
   1110       # We here forcibly initialize locales of Readline to make Readline's
   1111       # adjustment of convert-meta take place here.
   1112       local dummy
   1113       builtin read -et 0.000001 dummy </dev/tty
   1114     fi
   1115   fi
   1116 
   1117   # 暫定的な ble/bin/$cmd 設定
   1118   ble/bin/.default-utility-path "${_ble_init_posix_command_list[@]}"
   1119 
   1120   return 0
   1121 }
   1122 if ! ble/init/check-environment; then
   1123   ble/util/print "ble.sh: failed to adjust the environment. canceling the load of ble.sh." 1>&2
   1124   builtin unset -v _ble_bash BLE_VERSION BLE_VERSINFO
   1125   ble/init/clean-up 2>/dev/null # set -x 対策 #D0930
   1126   return 1
   1127 fi
   1128 
   1129 # Note: src/util.sh で ble/util/assign を定義した後に呼び出される。
   1130 _ble_bin_awk_type=
   1131 function ble/bin/awk/.instantiate {
   1132   local path q=\' Q="'\''" ext=1
   1133 
   1134   if ble/util/assign path "builtin type -P -- nawk 2>/dev/null" && [[ $path ]]; then
   1135     # Note: Some distribution (like Ubuntu) provides gawk as "nawk" by
   1136     # default. To avoid wrongly picking gawk as nawk, we need to check the
   1137     # version output from the command.
   1138     ble/util/assign version '"$path" -W version' 2>/dev/null </dev/null
   1139     if [[ $version != *'GNU Awk'* && $version != *mawk* ]]; then
   1140       builtin eval "function ble/bin/nawk { '${path//$q/$Q}' -v AWKTYPE=nawk \"\$@\"; }"
   1141       if [[ ! $_ble_bin_awk_type ]]; then
   1142         _ble_bin_awk_type=nawk
   1143         builtin eval "function ble/bin/awk { '${path//$q/$Q}' -v AWKTYPE=nawk \"\$@\"; }" && ext=0
   1144       fi
   1145     fi
   1146   fi
   1147 
   1148   if ble/util/assign path "builtin type -P -- mawk 2>/dev/null" && [[ $path ]]; then
   1149     builtin eval "function ble/bin/mawk { '${path//$q/$Q}' -v AWKTYPE=mawk \"\$@\"; }"
   1150     if [[ ! $_ble_bin_awk_type ]]; then
   1151       _ble_bin_awk_type=mawk
   1152       builtin eval "function ble/bin/awk { '${path//$q/$Q}' -v AWKTYPE=mawk \"\$@\"; }" && ext=0
   1153     fi
   1154   fi
   1155 
   1156   if ble/util/assign path "builtin type -P -- gawk 2>/dev/null" && [[ $path ]]; then
   1157     builtin eval "function ble/bin/gawk { '${path//$q/$Q}' -v AWKTYPE=gawk \"\$@\"; }"
   1158     if [[ ! $_ble_bin_awk_type ]]; then
   1159       _ble_bin_awk_type=gawk
   1160       builtin eval "function ble/bin/awk { '${path//$q/$Q}' -v AWKTYPE=gawk \"\$@\"; }" && ext=0
   1161     fi
   1162   fi
   1163 
   1164   if [[ ! $_ble_bin_awk_type ]]; then
   1165     if [[ $OSTYPE == solaris* ]] && type /usr/xpg4/bin/awk >/dev/null; then
   1166       # Solaris の既定の awk は全然駄目なので /usr/xpg4 以下の awk を使う。
   1167       _ble_bin_awk_type=xpg4
   1168       function ble/bin/awk { /usr/xpg4/bin/awk -v AWKTYPE=xpg4 "$@"; } && ext=0
   1169     elif ble/util/assign path "builtin type -P -- awk 2>/dev/null" && [[ $path ]]; then
   1170       local version
   1171       ble/util/assign version '"$path" -W version || "$path" --version' 2>/dev/null </dev/null
   1172       if [[ $version == *'GNU Awk'* ]]; then
   1173         _ble_bin_awk_type=gawk
   1174       elif [[ $version == *mawk* ]]; then
   1175         _ble_bin_awk_type=mawk
   1176       elif [[ $version == 'awk version '[12][0-9][0-9][0-9][01][0-9][0-3][0-9] ]]; then
   1177         _ble_bin_awk_type=nawk
   1178       else
   1179         _ble_bin_awk_type=unknown
   1180       fi
   1181       builtin eval "function ble/bin/awk { '${path//$q/$Q}' -v AWKTYPE=$_ble_bin_awk_type \"\$@\"; }" && ext=0
   1182       if [[ $OSTYPE == darwin* && $path == /usr/bin/awk && $_ble_bin_awk_type == nawk ]]; then
   1183         # Note #D1974: macOS の awk-32 の multibyte character support が怪しい。
   1184         #   問題は GitHub Actions の上では再現できていないが特別の入力で失敗す
   1185         #   るのかもしれない。または、報告者の環境が壊れているだけの可能性もあ
   1186         #   る。テスト不可能だが、そもそも nawk は UTF-8 に対応していない前提な
   1187         #   ので、取り敢えず LC_CTYPE=C で実行する。
   1188         function ble/bin/awk {
   1189           local LC_ALL= LC_CTYPE=C 2>/dev/null
   1190           /usr/bin/awk -v AWKTYPE=nawk "$@"; local ext=$?
   1191           ble/util/unlocal LC_ALL LC_CTYPE 2>/dev/null
   1192           return "$ext"
   1193         }
   1194       elif [[ $_ble_bin_awk_type == [gmn]awk ]] && ! ble/is-function "ble/bin/$_ble_bin_awk_type" ; then
   1195         builtin eval "function ble/bin/$_ble_bin_awk_type { '${path//$q/$Q}' -v AWKTYPE=$_ble_bin_awk_type \"\$@\"; }"
   1196       fi
   1197     fi
   1198   fi
   1199   return "$ext"
   1200 }
   1201 
   1202 # Note: ble//bin/awk/.instantiate が実行される前に使おうとした時の為の暫定実装
   1203 function ble/bin/awk {
   1204   if ble/bin/awk/.instantiate; then
   1205     ble/bin/awk "$@"
   1206   else
   1207     awk "$@"
   1208   fi
   1209 }
   1210 
   1211 # Do not overwrite by .freeze-utility-path
   1212 function ble/bin/.frozen:awk { :; }
   1213 function ble/bin/.frozen:nawk { :; }
   1214 function ble/bin/.frozen:mawk { :; }
   1215 function ble/bin/.frozen:gawk { :; }
   1216 
   1217 ## @fn ble/bin/awk0
   1218 ##   awk implementation that supports NUL record separator
   1219 ## @fn ble/bin/awk0.available
   1220 ##   initialize ble/bin/awk0 and returns whether ble/bin/awk0 is available
   1221 function ble/bin/awk0.available/test {
   1222   local count=0 cmd_awk=$1 awk_script='BEGIN { RS = "\0"; } { count++; } END { print count; }'
   1223   ble/util/assign count 'printf "a\0b\0" | "$cmd_awk" "$awk_script"'
   1224   ((count==2))
   1225 }
   1226 function ble/bin/awk0.available {
   1227   local awk
   1228   for awk in mawk gawk; do
   1229     if ble/bin#freeze-utility-path -n "$awk" &&
   1230         ble/bin/awk0.available/test ble/bin/"$awk" &&
   1231         builtin eval -- "function ble/bin/awk0 { ble/bin/$awk -v AWKTYPE=$awk \"\$@\"; }"; then
   1232       function ble/bin/awk0.available { ((1)); }
   1233       return 0
   1234     fi
   1235   done
   1236 
   1237   if ble/bin/awk0.available/test ble/bin/awk &&
   1238       function ble/bin/awk0 { ble/bin/awk "$@"; }; then
   1239     function ble/bin/awk0.available { ((1)); }
   1240     return 0
   1241   fi
   1242 
   1243   function ble/bin/awk0.available { ((0)); }
   1244   return 1
   1245 }
   1246 
   1247 function ble/util/mkd {
   1248   local dir
   1249   for dir; do
   1250     [[ -d $dir ]] && continue
   1251     [[ -e $dir || -L $dir ]] && ble/bin/rm -f "$dir"
   1252     ble/bin/mkdir -p "$dir"
   1253   done
   1254 }
   1255 
   1256 #------------------------------------------------------------------------------
   1257 # readlink -f (Originally taken from akinomyoga/mshex.git)
   1258 
   1259 ## @fn ble/util/readlink path
   1260 ##   @var[out] ret
   1261 
   1262 if ((_ble_bash>=40000)); then
   1263   _ble_util_readlink_visited_init='local -A visited=()'
   1264   function ble/util/readlink/.visited {
   1265     [[ ${visited[$1]+set} ]] && return 0
   1266     visited[$1]=1
   1267     return 1
   1268   }
   1269 else
   1270   _ble_util_readlink_visited_init="local -a visited=()"
   1271   function ble/util/readlink/.visited {
   1272     local key
   1273     for key in "${visited[@]}"; do
   1274       [[ $1 == "$key" ]] && return 0
   1275     done
   1276     visited=("$1" "${visited[@]}")
   1277     return 1
   1278   }
   1279 fi
   1280 
   1281 ## @fn ble/util/readlink/.readlink path
   1282 ##   @var[out] link
   1283 function ble/util/readlink/.readlink {
   1284   local path=$1
   1285   if ble/bin#has ble/bin/readlink; then
   1286     ble/util/assign link 'ble/bin/readlink -- "$path"'
   1287     [[ $link ]]
   1288   elif ble/bin#has ble/bin/ls; then
   1289     ble/util/assign link 'ble/bin/ls -ld -- "$path"' &&
   1290       [[ $link == *" $path -> "?* ]] &&
   1291       link=${link#*" $path -> "}
   1292   else
   1293     false
   1294   fi
   1295 } 2>/dev/null
   1296 ## @fn  ble/util/readlink/.resolve-physical-directory
   1297 ##   @var[in,out] path
   1298 function ble/util/readlink/.resolve-physical-directory {
   1299   [[ $path == */?* ]] || return 0
   1300   local PWD=$PWD OLDPWD=$OLDPWD CDPATH=
   1301   if builtin cd -L .; then
   1302     local pwd=$PWD
   1303     builtin cd -P "${path%/*}/" &&
   1304       path=${PWD%/}/${path##*/}
   1305 
   1306     # Note #D1849: 現在ディレクトリが他者により改名されている場合や PWD がユー
   1307     #   ザーに書き換えられている場合にも元のディレクトリに戻る為、cd -L . した
   1308     #   後のパスに cd する。但し pwd の結果はこの関数の呼び出し前と変わってしま
   1309     #   う (が実際にはこの方が良いだろう)。PWD は local にして元の値に戻すので
   1310     #   変わらない。
   1311     builtin cd "$pwd"
   1312   fi
   1313   return 0
   1314 }
   1315 function ble/util/readlink/.resolve-loop {
   1316   local path=$ret
   1317   while [[ $path == ?*/ ]]; do path=${path%/}; done
   1318   builtin eval -- "$_ble_util_readlink_visited_init"
   1319   while [[ -h $path ]]; do
   1320     local link
   1321     ble/util/readlink/.visited "$path" && break
   1322     ble/util/readlink/.readlink "$path" || break
   1323     if [[ $link == /* || $path != */* ]]; then
   1324       path=$link
   1325     else
   1326       # 相対パス ../ は物理ディレクトリ構造に従って遡る。
   1327       ble/util/readlink/.resolve-physical-directory
   1328       path=${path%/*}/$link
   1329     fi
   1330     while [[ $path == ?*/ ]]; do path=${path%/}; done
   1331   done
   1332   ret=$path
   1333 }
   1334 function ble/util/readlink/.resolve {
   1335   # 初回呼び出し時に実装を選択
   1336   _ble_util_readlink_type=
   1337 
   1338   # より効率的な実装が可能な場合は ble/util/readlink/.resolve を独自定義。
   1339   case $OSTYPE in
   1340   (cygwin | msys | linux-gnu)
   1341     # これらのシステムの標準 readlink では readlink -f が使える。
   1342     #
   1343     # Note: 例えば NixOS では標準の readlink を使おうとすると問題が起こるらしい
   1344     #   ので、見えている readlink を使う。見えている readlink が非標準の時は -f
   1345     #   が使えるか分からないので readlink -f による実装は有効化しない。
   1346     #
   1347     local readlink
   1348     ble/util/assign readlink 'type -P readlink'
   1349     case $readlink in
   1350     (/bin/readlink | /usr/bin/readlink)
   1351       _ble_util_readlink_type=readlink-f
   1352       builtin eval "function ble/util/readlink/.resolve { ble/util/assign ret '$readlink -f -- \"\$ret\"'; }" ;;
   1353     esac ;;
   1354   esac
   1355 
   1356   if [[ ! $_ble_util_readlink_type ]]; then
   1357     _ble_util_readlink_type=loop
   1358     ble/bin#freeze-utility-path readlink ls
   1359     function ble/util/readlink/.resolve { ble/util/readlink/.resolve-loop; }
   1360   fi
   1361 
   1362   ble/util/readlink/.resolve
   1363 }
   1364 function ble/util/readlink {
   1365   ret=$1
   1366   if [[ -h $ret ]]; then ble/util/readlink/.resolve; fi
   1367 }
   1368 
   1369 #---------------------------------------
   1370 
   1371 _ble_bash_path=
   1372 function ble/bin/.load-builtin {
   1373   local name=$1 path=$2
   1374   if [[ ! $_ble_bash_path ]]; then
   1375     local ret; ble/util/readlink "$BASH"
   1376     _ble_bash_path=$ret
   1377   fi
   1378 
   1379   if [[ ! $path ]]; then
   1380     local bash_prefix=${ret%/*/*}
   1381     path=$bash_prefix/lib/bash/$name
   1382     [[ -s $path ]] || return 1
   1383   fi
   1384 
   1385   if (enable -f "$path" "$name") &>/dev/null; then
   1386     enable -f "$path" "$name"
   1387     builtin eval -- "function ble/bin/$name { builtin $name \"\$@\"; }"
   1388     return 0
   1389   else
   1390     return 1
   1391   fi
   1392 }
   1393 # ble/bin/.load-builtin mkdir
   1394 # ble/bin/.load-builtin mkfifo
   1395 # ble/bin/.load-builtin rm
   1396 
   1397 #------------------------------------------------------------------------------
   1398 
   1399 function ble/base/.create-user-directory {
   1400   local var=$1 dir=$2
   1401   if [[ ! -d $dir ]]; then
   1402     # dangling symlinks are silently removed
   1403     [[ ! -e $dir && -h $dir ]] && ble/bin/rm -f "$dir"
   1404     if [[ -e $dir || -h $dir ]]; then
   1405       ble/util/print "ble.sh: cannot create a directory '$dir' since there is already a file." >&2
   1406       return 1
   1407     fi
   1408     if ! (umask 077; ble/bin/mkdir -p "$dir" && [[ -O $dir ]]); then
   1409       ble/util/print "ble.sh: failed to create a directory '$dir'." >&2
   1410       return 1
   1411     fi
   1412   elif ! [[ -r $dir && -w $dir && -x $dir ]]; then
   1413     ble/util/print "ble.sh: permission of '$dir' is not correct." >&2
   1414     return 1
   1415   elif [[ ! -O $dir ]]; then
   1416     ble/util/print "ble.sh: owner of '$dir' is not correct." >&2
   1417     return 1
   1418   fi
   1419   builtin eval "$var=\$dir"
   1420 }
   1421 
   1422 ##
   1423 ## @var _ble_base
   1424 ## @var _ble_base_blesh
   1425 ## @var _ble_base_blesh_raw
   1426 ##
   1427 ##   ble.sh のインストール先ディレクトリ。
   1428 ##   読み込んだ ble.sh の実体があるディレクトリとして解決される。
   1429 ##
   1430 function ble/base/initialize-base-directory {
   1431   local src=$1
   1432   local defaultDir=${2-}
   1433 
   1434   # resolve symlink
   1435   _ble_base_blesh_raw=$src
   1436   if [[ -h $src ]]; then
   1437     local ret; ble/util/readlink "$src"; src=$ret
   1438   fi
   1439   _ble_base_blesh=$src
   1440 
   1441   if [[ -s $src && $src != */* ]]; then
   1442     _ble_base=$PWD
   1443   elif [[ $src == */* ]]; then
   1444     local dir=${src%/*}
   1445     if [[ ! $dir ]]; then
   1446       _ble_base=/
   1447     elif [[ $dir != /* ]]; then
   1448       _ble_base=$PWD/$dir
   1449     else
   1450       _ble_base=$dir
   1451     fi
   1452   else
   1453     _ble_base=${defaultDir:-$HOME/.local/share/blesh}
   1454   fi
   1455 
   1456   [[ -d $_ble_base ]]
   1457 }
   1458 if ! ble/base/initialize-base-directory "${BASH_SOURCE[0]}"; then
   1459   ble/util/print "ble.sh: ble base directory not found!" 1>&2
   1460   builtin unset -v _ble_bash BLE_VERSION BLE_VERSINFO
   1461   ble/init/clean-up 2>/dev/null # set -x 対策 #D0930
   1462   return 1
   1463 fi
   1464 
   1465 ##
   1466 ## @var _ble_base_run
   1467 ##
   1468 ##   実行時の一時ファイルを格納するディレクトリ。以下の手順で決定する。
   1469 ##
   1470 ##   1. ${XDG_RUNTIME_DIR:=/run/user/$UID} が存在すればその下に blesh を作成して使う。
   1471 ##   2. /tmp/blesh/$UID を作成可能ならば、それを使う。
   1472 ##   3. $_ble_base/tmp/$UID を使う。
   1473 ##
   1474 function ble/base/initialize-runtime-directory/.xdg {
   1475   local runtime_dir=
   1476   if [[ $XDG_RUNTIME_DIR ]]; then
   1477     if [[ ! -d $XDG_RUNTIME_DIR ]]; then
   1478       ble/util/print "ble.sh: XDG_RUNTIME_DIR='$XDG_RUNTIME_DIR' is not a directory." >&2
   1479       return 1
   1480     elif [[ -O $XDG_RUNTIME_DIR ]]; then
   1481       runtime_dir=$XDG_RUNTIME_DIR
   1482     else
   1483       # When XDG_RUNTIME_DIR is not owned by the current user, maybe "su" is
   1484       # used to enter this session keeping the environment variables of the
   1485       # original user.  We just ignore XDG_RUNTIME_DIR (without issueing
   1486       # warnings) for such a case.
   1487       false
   1488     fi
   1489   fi
   1490   if [[ ! $runtime_dir ]]; then
   1491     runtime_dir=/run/user/$UID
   1492     [[ -d $runtime_dir && -O $runtime_dir ]] || return 1
   1493   fi
   1494 
   1495   if ! [[ -r $runtime_dir && -w $runtime_dir && -x $runtime_dir ]]; then
   1496     [[ $runtime_dir == "$XDG_RUNTIME_DIR" ]] &&
   1497       ble/util/print "ble.sh: XDG_RUNTIME_DIR='$XDG_RUNTIME_DIR' doesn't have a proper permission." >&2
   1498     return 1
   1499   fi
   1500 
   1501   ble/base/.create-user-directory _ble_base_run "$runtime_dir/blesh"
   1502 }
   1503 function ble/base/initialize-runtime-directory/.tmp {
   1504   [[ -r /tmp && -w /tmp && -x /tmp ]] || return 1
   1505 
   1506   local tmp_dir=/tmp/blesh
   1507   if [[ ! -d $tmp_dir ]]; then
   1508     [[ ! -e $tmp_dir && -h $tmp_dir ]] && ble/bin/rm -f "$tmp_dir"
   1509     if [[ -e $tmp_dir || -h $tmp_dir ]]; then
   1510       ble/util/print "ble.sh: cannot create a directory '$tmp_dir' since there is already a file." >&2
   1511       return 1
   1512     fi
   1513     ble/bin/mkdir -p "$tmp_dir" || return 1
   1514     ble/bin/chmod a+rwxt "$tmp_dir" || return 1
   1515   elif ! [[ -r $tmp_dir && -w $tmp_dir && -x $tmp_dir ]]; then
   1516     ble/util/print "ble.sh: permission of '$tmp_dir' is not correct." >&2
   1517     return 1
   1518   fi
   1519 
   1520   ble/base/.create-user-directory _ble_base_run "$tmp_dir/$UID"
   1521 }
   1522 function ble/base/initialize-runtime-directory {
   1523   ble/base/initialize-runtime-directory/.xdg && return 0
   1524   ble/base/initialize-runtime-directory/.tmp && return 0
   1525 
   1526   # fallback
   1527   local tmp_dir=$_ble_base/run
   1528   if [[ ! -d $tmp_dir ]]; then
   1529     ble/bin/mkdir -p "$tmp_dir" || return 1
   1530     ble/bin/chmod a+rwxt "$tmp_dir" || return 1
   1531   fi
   1532   ble/base/.create-user-directory _ble_base_run "$tmp_dir/${USER:-$UID}@$HOSTNAME"
   1533 }
   1534 if ! ble/base/initialize-runtime-directory; then
   1535   ble/util/print "ble.sh: failed to initialize \$_ble_base_run." 1>&2
   1536   builtin unset -v _ble_bash BLE_VERSION BLE_VERSINFO
   1537   ble/init/clean-up 2>/dev/null # set -x 対策 #D0930
   1538   return 1
   1539 fi
   1540 
   1541 # ロード時刻の記録 (ble-update で使う為)
   1542 : >| "$_ble_base_run/$$.load"
   1543 
   1544 ## @fn ble/base/clean-up-runtime-directory [opts]
   1545 ##   既に存在しないプロセスに属する実行時ファイルを削除します。*.pid のファイル
   1546 ##   名を持つ実行時ファイルはについては、子バックグラウンドプロセスのプロセスID
   1547 ##   を含むと見做し、ファイルの内容を読み取ってそれが整数であればその整数に対し
   1548 ##   て kill を実行します。
   1549 ##
   1550 ##   @param[in,opt] opts
   1551 ##     finalize ... 自プロセス $$ に関連するファイルも削除します。現セッション
   1552 ##       における ble.sh の終了処理時に呼び出される事を想定しています。
   1553 ##
   1554 function ble/base/clean-up-runtime-directory {
   1555   local opts=$1 failglob= noglob=
   1556   if [[ $- == *f* ]]; then
   1557     noglob=1
   1558     set +f
   1559   fi
   1560   if shopt -q failglob &>/dev/null; then
   1561     failglob=1
   1562     shopt -u failglob
   1563   fi
   1564 
   1565   local -a alive=() removed=() bgpids=()
   1566   [[ :$opts: == *:finalize:* ]] && alive[$$]=0
   1567 
   1568   local file pid iremoved=0 ibgpid=0
   1569   for file in "$_ble_base_run"/[1-9]*.*; do
   1570     [[ -e $file || -h $file ]] || continue
   1571 
   1572     # extract pid (skip if it is not a number)
   1573     pid=${file##*/}; pid=${pid%%.*}
   1574     [[ $pid && ! ${pid//[0-9]} ]] || continue
   1575 
   1576     if [[ ! ${alive[pid]+set} ]]; then
   1577       builtin kill -0 "$pid" &>/dev/null
   1578       ((alive[pid]=$?==0))
   1579     fi
   1580     ((alive[pid])) && continue
   1581 
   1582     # kill process specified by the pid file
   1583     if [[ $file == *.pid && -s $file ]]; then
   1584       local run_pid IFS=
   1585       ble/bash/read run_pid < "$file"
   1586       if [[ $run_pid && ! ${run_pid//[0-9]} ]]; then
   1587         if ((pid==$$)); then
   1588           # 現セッションの背景プロセスの場合は遅延させる
   1589           kill -0 "$run_pid" &>/dev/null && bgpids[ibgpid++]=$run_pid
   1590         else
   1591           kill "$run_pid"
   1592         fi
   1593       fi
   1594     fi
   1595 
   1596     removed[iremoved++]=$file
   1597   done
   1598   ((iremoved)) && ble/bin/rm -rf "${removed[@]}" 2>/dev/null
   1599   ((ibgpid)) && (ble/util/nohup 'ble/bin/sleep 3; kill "${bgpids[@]}"')
   1600 
   1601   [[ $failglob ]] && shopt -s failglob
   1602   [[ $noglob ]] && set -f
   1603   return 0
   1604 }
   1605 
   1606 # initialization time = 9ms (for 70 files)
   1607 ble/base/clean-up-runtime-directory
   1608 
   1609 ##
   1610 ## @var _ble_base_cache
   1611 ##
   1612 ##   環境毎の初期化ファイルを格納するディレクトリ。以下の手順で決定する。
   1613 ##
   1614 ##   1. ${XDG_CACHE_HOME:=$HOME/.cache} が存在すればその下に blesh を作成して使う。
   1615 ##   2. $_ble_base/cache.d/$UID を使う。
   1616 ##
   1617 function ble/base/initialize-cache-directory/.xdg {
   1618   [[ $_ble_base != */out ]] || return 1
   1619 
   1620   local cache_dir=${XDG_CACHE_HOME:-$HOME/.cache}
   1621   if [[ ! -d $cache_dir ]]; then
   1622     [[ $XDG_CACHE_HOME ]] &&
   1623       ble/util/print "ble.sh: XDG_CACHE_HOME='$XDG_CACHE_HOME' is not a directory." >&2
   1624     return 1
   1625   fi
   1626   if ! [[ -r $cache_dir && -w $cache_dir && -x $cache_dir ]]; then
   1627     [[ $XDG_CACHE_HOME ]] &&
   1628       ble/util/print "ble.sh: XDG_CACHE_HOME='$XDG_CACHE_HOME' doesn't have a proper permission." >&2
   1629     return 1
   1630   fi
   1631 
   1632   local ver=${BLE_VERSINFO[0]}.${BLE_VERSINFO[1]}
   1633   ble/base/.create-user-directory _ble_base_cache "$cache_dir/blesh/$ver"
   1634 }
   1635 function ble/base/initialize-cache-directory {
   1636   ble/base/initialize-cache-directory/.xdg && return 0
   1637 
   1638   # fallback
   1639   local cache_dir=$_ble_base/cache.d
   1640   if [[ ! -d $cache_dir ]]; then
   1641     ble/bin/mkdir -p "$cache_dir" || return 1
   1642     ble/bin/chmod a+rwxt "$cache_dir" || return 1
   1643 
   1644     # relocate an old cache directory if any
   1645     local old_cache_dir=$_ble_base/cache
   1646     if [[ -d $old_cache_dir && ! -h $old_cache_dir ]]; then
   1647       mv "$old_cache_dir" "$cache_dir/$UID"
   1648       ln -s "$cache_dir/$UID" "$old_cache_dir"
   1649     fi
   1650   fi
   1651   ble/base/.create-user-directory _ble_base_cache "$cache_dir/$UID"
   1652 }
   1653 function ble/base/migrate-cache-directory/.move {
   1654   local old=$1 new=$2
   1655   [[ -e $old ]] || return 0
   1656   if [[ -e $new || -L $old ]]; then
   1657     ble/bin/rm -rf "$old"
   1658   else
   1659     ble/bin/mv "$old" "$new"
   1660   fi
   1661 }
   1662 function ble/base/migrate-cache-directory/.check-old-prefix {
   1663   local old_prefix=$_ble_base_cache/$1
   1664   local new_prefix=$_ble_base_cache/$2
   1665   local file
   1666   for file in "$old_prefix"*; do
   1667     local old=$file
   1668     local new=$new_prefix${file#"$old_prefix"}
   1669     ble/base/migrate-cache-directory/.move "$old" "$new"
   1670   done
   1671 }
   1672 function ble/base/migrate-cache-directory {
   1673   local failglob=
   1674   shopt -q failglob && { failglob=1; shopt -u failglob; }
   1675 
   1676   ble/base/migrate-cache-directory/.check-old-prefix cmap+default.binder-source decode.cmap.allseq
   1677   ble/base/migrate-cache-directory/.check-old-prefix cmap+default decode.cmap
   1678   ble/base/migrate-cache-directory/.check-old-prefix ble-decode-bind decode.bind
   1679 
   1680   local file
   1681   for file in "$_ble_base_cache"/*.term; do
   1682     local old=$file
   1683     local new=$_ble_base_cache/term.${file#"$_ble_base_cache/"}; new=${new%.term}
   1684     ble/base/migrate-cache-directory/.move "$old" "$new"
   1685   done
   1686 
   1687   ble/base/migrate-cache-directory/.move "$_ble_base_cache/man" "$_ble_base_cache/complete.mandb"
   1688 
   1689   [[ $failglob ]] && shopt -s failglob
   1690 }
   1691 if ! ble/base/initialize-cache-directory; then
   1692   ble/util/print "ble.sh: failed to initialize \$_ble_base_cache." 1>&2
   1693   builtin unset -v _ble_bash BLE_VERSION BLE_VERSINFO
   1694   ble/init/clean-up 2>/dev/null # set -x 対策 #D0930
   1695   return 1
   1696 fi
   1697 ble/base/migrate-cache-directory
   1698 
   1699 ##
   1700 ## @var _ble_base_state
   1701 ##
   1702 ##   環境毎の初期化ファイルを格納するディレクトリ。以下の手順で決定する。
   1703 ##
   1704 ##   1. ${XDG_STATE_HOME:=$HOME/.state} (存在しなくても強制的に作成) の下に blesh を作成して使う。
   1705 ##   2. (1. に失敗した時) $_ble_base/state.d/$UID を使う。
   1706 ##
   1707 function ble/base/initialize-state-directory/.xdg {
   1708   local state_dir=${XDG_STATE_HOME:-$HOME/.local/state}
   1709   if [[ -e $state_dir || -L $state_dir ]]; then
   1710     if [[ ! -d $state_dir ]]; then
   1711       if [[ $XDG_STATE_HOME ]]; then
   1712         ble/util/print "ble.sh: XDG_STATE_HOME='$XDG_STATE_HOME' is not a directory." >&2
   1713       else
   1714         ble/util/print "ble.sh: '$state_dir' is not a directory." >&2
   1715       fi
   1716       return 1
   1717     fi
   1718     if ! [[ -r $state_dir && -w $state_dir && -x $state_dir ]]; then
   1719       if [[ $XDG_STATE_HOME ]]; then
   1720         ble/util/print "ble.sh: XDG_STATE_HOME='$XDG_STATE_HOME' doesn't have a proper permission." >&2
   1721       else
   1722         ble/util/print "ble.sh: '$state_dir' doesn't have a proper permission." >&2
   1723       fi
   1724       return 1
   1725     fi
   1726   fi
   1727 
   1728   ble/base/.create-user-directory _ble_base_state "$state_dir/blesh"
   1729 }
   1730 function ble/base/initialize-state-directory {
   1731   ble/base/initialize-state-directory/.xdg && return 0
   1732 
   1733   # fallback
   1734   local state_dir=$_ble_base/state.d
   1735   if [[ ! -d $state_dir ]]; then
   1736     ble/bin/mkdir -p "$state_dir" || return 1
   1737     ble/bin/chmod a+rwxt "$state_dir" || return 1
   1738 
   1739     # relocate an old state directory if any
   1740     local old_state_dir=$_ble_base/state
   1741     if [[ -d $old_state_dir && ! -h $old_state_dir ]]; then
   1742       mv "$old_state_dir" "$state_dir/$UID"
   1743       ln -s "$state_dir/$UID" "$old_state_dir"
   1744     fi
   1745   fi
   1746   ble/util/print "ble.sh: using the non-standard position of the state directory: '$state_dir/$UID'" >&2
   1747   ble/base/.create-user-directory _ble_base_state "$state_dir/$UID"
   1748 }
   1749 if ! ble/base/initialize-state-directory; then
   1750   ble/util/print "ble.sh: failed to initialize \$_ble_base_state." 1>&2
   1751   builtin unset -v _ble_bash BLE_VERSION BLE_VERSINFO
   1752   ble/init/clean-up 2>/dev/null # set -x 対策 #D0930
   1753   return 1
   1754 fi
   1755 
   1756 
   1757 function ble/base/print-usage-for-no-argument-command {
   1758   local name=${FUNCNAME[1]} desc=$1; shift
   1759   ble/util/print-lines \
   1760     "usage: $name" \
   1761     "$desc" >&2
   1762   [[ $1 != --help ]] && return 2
   1763   return 0
   1764 }
   1765 function ble-reload {
   1766   local -a options=()
   1767   [[ ! -e $_ble_base_rcfile ]] ||
   1768     ble/array#push options --rcfile="${_ble_base_rcfile:-/dev/null}"
   1769   [[ $_ble_base_arguments_inputrc == auto ]] ||
   1770     ble/array#push options --inputrc="$_ble_base_arguments_inputrc"
   1771   local name
   1772   for name in keep-rlvars; do
   1773     if [[ :$_ble_base_arguments_opts: == *:"$name":* ]]; then
   1774       ble/array#push options "--$name"
   1775     fi
   1776   done
   1777   source "$_ble_base/ble.sh" "${options[@]}"
   1778 }
   1779 
   1780 #%$ pwd=$(pwd) q=\' Q="'\''" bash -c 'echo "_ble_base_repository=$q${pwd//$q/$Q}$q"'
   1781 #%$ echo "_ble_base_branch=$(git rev-parse --abbrev-ref HEAD)"
   1782 _ble_base_repository_url=https://github.com/akinomyoga/ble.sh
   1783 #%$ echo "_ble_base_build_git_version=\"$BUILD_GIT_VERSION\""
   1784 #%$ echo "_ble_base_build_make_version=\"$BUILD_MAKE_VERSION\""
   1785 #%$ echo "_ble_base_build_gawk_version=\"$BUILD_GAWK_VERSION\""
   1786 function ble-update/.check-install-directory-ownership {
   1787   if [[ ! -O $_ble_base ]]; then
   1788     ble/util/print 'ble-update: install directory is owned by another user:' >&2
   1789     ls -ld "$_ble_base"
   1790     return 1
   1791   elif [[ ! -r $_ble_base || ! -w $_ble_base || ! -x $_ble_base ]]; then
   1792     ble/util/print 'ble-update: install directory permission denied:' >&2
   1793     ls -ld "$_ble_base"
   1794     return 1
   1795   fi
   1796 }
   1797 function ble-update/.make {
   1798   local sudo=
   1799   if [[ $1 == --sudo ]]; then
   1800     sudo=1
   1801     shift
   1802   fi
   1803 
   1804   if ! "$make" -q "$@"; then
   1805     if [[ $sudo ]]; then
   1806       sudo "$make" "$@"
   1807     else
   1808       "$make" "$@"
   1809     fi
   1810   else
   1811     # インストール先に更新がなくても現在の session でロードされている ble.sh が
   1812     # 古いかもしれないのでチェックしてリロードする。
   1813     return 6
   1814   fi
   1815 }
   1816 function ble-update/.reload {
   1817   local ext=$1
   1818   if [[ $ext -eq 0 || $ext -eq 6 && $_ble_base/ble.sh -nt $_ble_base_run/$$.load ]]; then
   1819     if [[ ! -e $_ble_base/ble.sh ]]; then
   1820       ble/util/print "ble-update: new ble.sh not found at '$_ble_base/ble.sh'." >&2
   1821       return 1
   1822     elif [[ ! -s $_ble_base/ble.sh ]]; then
   1823       ble/util/print "ble-update: new ble.sh '$_ble_base/ble.sh' is empty." >&2
   1824       return 1
   1825     elif [[ $- == *i* && $_ble_attached ]] && ! ble/util/is-running-in-subshell; then
   1826       ble-reload
   1827     fi
   1828     return "$?"
   1829   fi
   1830   ((ext==6)) && ext=0
   1831   return "$ext"
   1832 }
   1833 function ble-update/.download-nightly-build {
   1834   if ! ble/bin#has tar xz; then
   1835     local command
   1836     for command in tar xz; do
   1837       ble/bin#has "$command" ||
   1838         ble/util/print "ble-update (nightly): '$command' command is not available." >&2
   1839     done
   1840     return 1
   1841   fi
   1842 
   1843   if ((EUID!=0)) && ! ble-update/.check-install-directory-ownership; then
   1844     # _ble_base が自分の物でない時は sudo でやり直す
   1845     sudo "$BASH" "$_ble_base/ble.sh" --update &&
   1846       ble-update/.reload 6
   1847     return "$?"
   1848   fi
   1849 
   1850   local tarname=ble-nightly.tar.xz
   1851   local url_tar=$_ble_base_repository_url/releases/download/nightly/$tarname
   1852   (
   1853     set +f
   1854     shopt -u failglob nullglob
   1855 
   1856     # mkcd "$_ble_base/src"
   1857     if ! ble/bin/mkdir -p "$_ble_base/src"; then
   1858       ble/util/print "ble-update (nightly): failed to create the directory '$_ble_base/src'" >&2
   1859       return 1
   1860     fi
   1861     if ! builtin cd "$_ble_base/src"; then
   1862       ble/util/print "ble-update (nightly): failed to enter the directory '$_ble_base/src'" >&2
   1863       return 1
   1864     fi
   1865 
   1866     local ret
   1867     ble/file#hash "$tarname"; local ohash=$ret
   1868 
   1869     # download "$url_tar" "$tarname"
   1870     # Note: アップロードした直後は暫く 404 Not Found になるようなので何回か再試
   1871     # 行する。
   1872     local retry max_retry=5
   1873     for ((retry=0;retry<=max_retry;retry++)); do
   1874       if ((retry>0)); then
   1875         local wait=$((retry<3?retry*10:30))
   1876         ble/util/print "ble-update (nightly): retry downloading in $wait seconds... ($retry/$max_retry)" >&2
   1877         ble/util/sleep "$wait"
   1878       fi
   1879 
   1880       if ble/bin#has wget; then
   1881         wget -N "$url_tar" && break
   1882       elif ble/bin#has curl; then
   1883         curl -LRo "$tarname" -z "$tarname" "$url_tar" && break
   1884       else
   1885         ble/util/print "ble-update (nightly): command 'wget' nor 'curl' is available." >&2
   1886         return 1
   1887       fi
   1888     done
   1889     if ((retry>max_retry)); then
   1890       ble/util/print "ble-update (nightly): failed to download the archive from '$url_tar'." >&2
   1891       return 7
   1892     fi
   1893 
   1894     # 前回ダウンロードした物と同じ場合は省略
   1895     ble/file#hash "$tarname"; local nhash=$ret
   1896     [[ $ohash == "$nhash" ]] && return 6
   1897 
   1898     # tar xJf "$tarname"
   1899     ble/bin/rm -rf ble-nightly*/
   1900     if ! tar xJf "$tarname"; then
   1901       ble/util/print 'ble-update (nightly): failed to extract the tarball. Removing possibly broken tarball.' >&2
   1902       ble/bin/rm -rf "$tarname"
   1903       return 1
   1904     fi
   1905 
   1906     # cp -T ble-nightly* "$_ble_base"
   1907     local extracted_dir=ble-nightly
   1908     if [[ ! -d $extracted_dir ]]; then
   1909       ble/util/print "ble-update (nightly): the directory 'ble-nightly' not found in the tarball '$PWD/$tarname'." >&2
   1910       return 1
   1911     fi
   1912     ble/bin/cp -Rf "$extracted_dir"/* "$_ble_base/" || return 1
   1913     ble/bin/rm -rf "$extracted_dir"
   1914   ) &&
   1915     ble-update/.reload
   1916 }
   1917 function ble-update {
   1918   if (($#)); then
   1919     ble/base/print-usage-for-no-argument-command 'Update and reload ble.sh.' "$@"
   1920     return "$?"
   1921   fi
   1922 
   1923   if [[ ${_ble_base_package_type-} ]] && ble/is-function ble/base/package:"$_ble_base_package_type"/update; then
   1924     ble/util/print "ble-update: delegate to '$_ble_base_package_type' package manager..." >&2
   1925     ble/base/package:"$_ble_base_package_type"/update; local ext=$?
   1926     if ((ext==125)); then
   1927       ble/util/print 'ble-update: fallback to the default update process.' >&2
   1928     else
   1929       ble-update/.reload "$ext"
   1930       return "$?"
   1931     fi
   1932   fi
   1933 
   1934   if [[ ${_ble_base_repository-} == release:nightly-* ]]; then
   1935     if ble-update/.download-nightly-build; local ext=$?; ((ext==0||ext==6||ext==7)); then
   1936       if ((ext==6)); then
   1937         ble/util/print 'ble-update (nightly): Already up to date.' >&2
   1938       elif ((ext==7)); then
   1939         ble/util/print 'ble-update (nightly): Remote temporarily unavailable. Try it again later.' >&2
   1940       fi
   1941       return 0
   1942     fi
   1943   fi
   1944 
   1945   # check make
   1946   local make=
   1947   if ble/bin#has gmake; then
   1948     make=gmake
   1949   elif ble/bin#has make && make --version 2>&1 | ble/bin/grep -qiF 'GNU Make'; then
   1950     make=make
   1951   else
   1952     ble/util/print "ble-update: GNU Make is not available." >&2
   1953     return 1
   1954   fi
   1955 
   1956   # check git, gawk
   1957   if ! ble/bin#has git gawk; then
   1958     local command
   1959     for command in git gawk; do
   1960       ble/bin#has "$command" ||
   1961         ble/util/print "ble-update: '$command' command is not available." >&2
   1962     done
   1963     return 1
   1964   fi
   1965 
   1966   local insdir_doc=$_ble_base/doc
   1967   [[ ! -d $insdir_doc && -d ${_ble_base%/*}/doc/blesh ]] &&
   1968     insdir_doc=${_ble_base%/*}/doc/blesh
   1969 
   1970   if [[ ${_ble_base_repository-} && $_ble_base_repository != release:* ]]; then
   1971     if [[ ! -e $_ble_base_repository/.git ]]; then
   1972       ble/util/print "ble-update: git repository not found at '$_ble_base_repository'." >&2
   1973     elif [[ ! -O $_ble_base_repository ]]; then
   1974       ble/util/print "ble-update: git repository is owned by another user:" >&2
   1975       ls -ld "$_ble_base_repository"
   1976     elif [[ ! -r $_ble_base_repository || ! -w $_ble_base_repository || ! -x $_ble_base_repository ]]; then
   1977       ble/util/print 'ble-update: git repository permission denied:' >&2
   1978       ls -ld "$_ble_base_repository"
   1979     else
   1980       ( ble/util/print "cd into $_ble_base_repository..." >&2 &&
   1981           builtin cd "$_ble_base_repository" &&
   1982           git pull && git submodule update --recursive --remote &&
   1983           if [[ $_ble_base == "$_ble_base_repository"/out ]]; then
   1984             ble-update/.make all
   1985           elif ((EUID!=0)) && ! ble-update/.check-install-directory-ownership; then
   1986             ble-update/.make all
   1987             ble-update/.make --sudo INSDIR="$_ble_base" INSDIR_DOC="$insdir_doc" install
   1988           else
   1989             ble-update/.make INSDIR="$_ble_base" INSDIR_DOC="$insdir_doc" install
   1990           fi )
   1991       ble-update/.reload "$?"
   1992       return "$?"
   1993     fi
   1994   fi
   1995   
   1996   if ((EUID!=0)) && ! ble-update/.check-install-directory-ownership; then
   1997     # _ble_base が自分の物でない時は sudo でやり直す
   1998     sudo "$BASH" "$_ble_base/ble.sh" --update &&
   1999       ble-update/.reload 6
   2000     return "$?"
   2001   else
   2002     # _ble_base/src 内部に clone して make install
   2003     local branch=${_ble_base_branch:-master}
   2004     ( ble/bin/mkdir -p "$_ble_base/src" && builtin cd "$_ble_base/src" &&
   2005         git clone --recursive --depth 1 "$_ble_base_repository_url" "$_ble_base/src/ble.sh" -b "$branch" &&
   2006         builtin cd ble.sh && "$make" all &&
   2007         "$make" INSDIR="$_ble_base" INSDIR_DOC="$insdir_doc" install ) &&
   2008       ble-update/.reload
   2009     return "$?"
   2010   fi
   2011   return 1
   2012 }
   2013 #%if measure_load_time
   2014 ble/debug/measure-set-timeformat ble.pp/prologue
   2015 }
   2016 #%end
   2017 
   2018 
   2019 #------------------------------------------------------------------------------
   2020 _ble_attached=
   2021 BLE_ATTACHED=
   2022 
   2023 #%x inc.r|@|src/def|
   2024 #%x inc.r|@|src/util|
   2025 
   2026 bleopt/declare -v debug_xtrace ''
   2027 bleopt/declare -v debug_xtrace_ps4 '+ '
   2028 
   2029 ble/bin#freeze-utility-path "${_ble_init_posix_command_list[@]}" # <- this uses ble/util/assign.
   2030 ble/bin#freeze-utility-path man
   2031 ble/bin#freeze-utility-path groff nroff mandoc gzip bzcat lzcat xzcat # used by core-complete.sh
   2032 
   2033 ble/function#trace trap ble/builtin/trap ble/builtin/trap/finalize
   2034 ble/function#trace ble/builtin/trap/.handler ble/builtin/trap/invoke ble/builtin/trap/invoke.sandbox
   2035 ble/builtin/trap/install-hook EXIT
   2036 ble/builtin/trap/install-hook INT
   2037 ble/builtin/trap/install-hook ERR inactive
   2038 ble/builtin/trap/install-hook RETURN inactive
   2039 
   2040 # @var _ble_base_session
   2041 # @var BLE_SESSION_ID
   2042 function ble/base/initialize-session {
   2043   [[ $_ble_base_session == */"$$" ]] && return 0
   2044 
   2045   local start_time=
   2046   if ((_ble_bash>=50000)); then
   2047     start_time=${EPOCHREALTIME//[!0-9]}
   2048   elif ((_ble_bash>=40200)); then
   2049     printf -v start_time '%(%s)T' -1
   2050     ((start_time*=1000000))
   2051   else
   2052     ble/util/assign start_time 'ble/bin/date +%s'
   2053     ((start_time*=1000000))
   2054   fi
   2055   ((start_time-=SECONDS*1000000))
   2056 
   2057   _ble_base_session=${start_time::${#start_time}-6}.${start_time:${#start_time}-6}/$$
   2058   BLE_SESSION_ID=$_ble_base_session
   2059 }
   2060 ble/base/initialize-session
   2061 
   2062 #%x inc.r|@|src/decode|
   2063 #%x inc.r|@|src/color|
   2064 #%x inc.r|@|src/canvas|
   2065 #%x inc.r|@|src/history|
   2066 #%x inc.r|@|src/edit|
   2067 #%x inc.r|@|lib/core-cmdspec-def|
   2068 #%x inc.r|@|lib/core-syntax-def|
   2069 #%x inc.r|@|lib/core-complete-def|
   2070 #%x inc.r|@|lib/core-debug-def|
   2071 #%x inc.r|@|contrib/integration/bash-preexec-def|
   2072 
   2073 bleopt -I
   2074 #------------------------------------------------------------------------------
   2075 #%if measure_load_time
   2076 time {
   2077 #%end
   2078 
   2079 ## @fn ble [SUBCOMMAND]
   2080 ##
   2081 ##   無引数で呼び出した時、現在 ble.sh の内部空間に居るかどうかを判定します。
   2082 ##
   2083 # Bluetooth Low Energy のツールが存在するかもしれない
   2084 ble/bin#freeze-utility-path ble
   2085 function ble/dispatch/.help {
   2086   ble/util/print-lines \
   2087     'usage: ble [SUBCOMMAND [ARGS...]]' \
   2088     '' \
   2089     'SUBCOMMAND' \
   2090     '  # Manage ble.sh' \
   2091     '  attach  ... alias of ble-attach' \
   2092     '  detach  ... alias of ble-detach'  \
   2093     '  update  ... alias of ble-update' \
   2094     '  reload  ... alias of ble-reload' \
   2095     '  help    ... Show this help' \
   2096     '  version ... Show version' \
   2097     '  check   ... Run unit tests' \
   2098     '' \
   2099     '  # Configuration' \
   2100     '  opt     ... alias of bleopt' \
   2101     '  bind    ... alias of ble-bind' \
   2102     '  face    ... alias of ble-face' \
   2103     '  hook    ... alias of blehook' \
   2104     '  sabbrev ... alias of ble-sabbrev' \
   2105     '  palette ... alias of ble-color-show' \
   2106     ''
   2107 }
   2108 function ble/dispatch {
   2109   if (($#==0)); then
   2110     [[ $_ble_attached && ! $_ble_edit_exec_inside_userspace ]]
   2111     return "$?"
   2112   fi
   2113 
   2114   # import autoload measure assert stackdump color-show decode-{byte,char,key}
   2115   local cmd=$1; shift
   2116   case $cmd in
   2117   (attach)  ble-attach "$@" ;;
   2118   (detach)  ble-detach "$@" ;;
   2119   (update)  ble-update "$@" ;;
   2120   (reload)  ble-reload "$@" ;;
   2121   (face)    ble-face "$@" ;;
   2122   (bind)    ble-bind "$@" ;;
   2123   (opt)     bleopt "$@" ;;
   2124   (hook)    blehook "$@" ;;
   2125   (sabbrev) ble-sabbrev "$@" ;;
   2126   (palette) ble-palette "$@" ;;
   2127   (help|--help) ble/dispatch/.help "$@" ;;
   2128   (version|--version) ble/util/print "ble.sh, version $BLE_VERSION (noarch)" ;;
   2129   (check|--test) ble/base/sub:test "$@" ;;
   2130   (*)
   2131     if ble/string#match "$cmd" '^[-a-z0-9]+$' && ble/is-function "ble-$cmd"; then
   2132       "ble-$cmd" "$@"
   2133     elif ble/is-function ble/bin/ble; then
   2134       ble/bin/ble "$cmd" "$@"
   2135     else
   2136       ble/util/print "ble (ble.sh): unrecognized subcommand '$cmd'." >&2
   2137       return 2
   2138     fi
   2139   esac
   2140 }
   2141 function ble { ble/dispatch "$@"; }
   2142 
   2143 
   2144 # blerc
   2145 _ble_base_rcfile=
   2146 _ble_base_rcfile_initialized=
   2147 function ble/base/load-rcfile {
   2148   [[ $_ble_base_rcfile_initialized ]] && return 0
   2149   _ble_base_rcfile_initialized=1
   2150 
   2151   # blerc
   2152   if [[ ! $_ble_base_rcfile ]]; then
   2153     { _ble_base_rcfile=$HOME/.blerc; [[ -f $_ble_base_rcfile ]]; } ||
   2154       { _ble_base_rcfile=${XDG_CONFIG_HOME:-$HOME/.config}/blesh/init.sh; [[ -f $_ble_base_rcfile ]]; } ||
   2155       _ble_base_rcfile=$HOME/.blerc
   2156   fi
   2157   if [[ -s $_ble_base_rcfile ]]; then
   2158     source "$_ble_base_rcfile"
   2159     blehook/.compatibility-ble-0.3/check
   2160   fi
   2161 }
   2162 
   2163 ## @fn ble-attach [opts]
   2164 function ble-attach {
   2165 #%if leakvar
   2166 ble/debug/leakvar#check $"leakvar" A1-begin
   2167 #%end.i
   2168   if (($# >= 2)); then
   2169     ble/util/print-lines \
   2170       'usage: ble-attach [opts]' \
   2171       'Attach to ble.sh.' >&2
   2172     [[ $1 != --help ]] && return 2
   2173     return 0
   2174   fi
   2175 
   2176 #%if leakvar
   2177 ble/debug/leakvar#check $"leakvar" A2-arg
   2178 #%end.i
   2179   # when detach flag is present
   2180   if [[ $_ble_edit_detach_flag ]]; then
   2181     case $_ble_edit_detach_flag in
   2182     (exit) return 0 ;;
   2183     (*) _ble_edit_detach_flag= ;; # cancel "detach"
   2184     esac
   2185   fi
   2186 
   2187   [[ ! $_ble_attached ]] || return 0
   2188   _ble_attached=1
   2189   BLE_ATTACHED=1
   2190 
   2191 #%if leakvar
   2192 ble/debug/leakvar#check $"leakvar" A3-guard
   2193 #%end.i
   2194   # 特殊シェル設定を待避
   2195   builtin eval -- "$_ble_bash_FUNCNEST_adjust"
   2196   ble/base/adjust-builtin-wrappers-1
   2197   ble/base/adjust-bash-options
   2198   ble/base/adjust-POSIXLY_CORRECT
   2199   ble/base/adjust-builtin-wrappers-2
   2200   ble/base/adjust-BASH_REMATCH
   2201 
   2202 #%if leakvar
   2203 ble/debug/leakvar#check $"leakvar" A4-adjust
   2204 #%end.i
   2205   if [[ ${IN_NIX_SHELL-} ]]; then
   2206     # nix-shell rc の中から実行している時は強制的に prompt-attach にする
   2207     if [[ "${BASH_SOURCE[*]}" == */rc && $1 != *:force:* ]]; then
   2208       ble/base/install-prompt-attach
   2209       _ble_attached=
   2210       BLE_ATTACHED=
   2211       ble/base/restore-BASH_REMATCH
   2212       ble/base/restore-bash-options
   2213       ble/base/restore-POSIXLY_CORRECT
   2214       ble/base/restore-builtin-wrappers
   2215 #%if leakvar
   2216 ble/debug/leakvar#check $"leakvar" A4b1
   2217 #%end.i
   2218       builtin eval -- "$_ble_bash_FUNCNEST_restore"
   2219       return 0
   2220     fi
   2221 
   2222     # nix-shell は BASH を誤った値に書き換えるので上書きする。
   2223     local ret
   2224     ble/util/readlink "/proc/$$/exe"
   2225     [[ -x $ret ]] && BASH=$ret
   2226 #%if leakvar
   2227 ble/debug/leakvar#check $"leakvar" A4b2
   2228 #%end.i
   2229   fi
   2230 
   2231   # char_width_mode=auto
   2232   ble/canvas/attach
   2233 #%if leakvar
   2234 ble/debug/leakvar#check $"leakvar" A5-canvas
   2235 #%end.i
   2236 
   2237   # 取り敢えずプロンプトを表示する
   2238   ble/term/enter      # 3ms (起動時のずれ防止の為 stty)
   2239   ble-edit/initialize # 3ms
   2240   ble-edit/attach     # 0ms (_ble_edit_PS1 他の初期化)
   2241   ble/canvas/panel/render # 37ms
   2242   ble/util/buffer.flush >&2
   2243 #%if leakvar
   2244 ble/debug/leakvar#check $"leakvar" A6-term/edit
   2245 #%end.i
   2246 
   2247   # keymap 初期化
   2248   local IFS=$_ble_term_IFS
   2249   ble/decode/initialize # 7ms
   2250   ble/decode/reset-default-keymap # 264ms (keymap/vi.sh)
   2251 #%if leakvar
   2252 ble/debug/leakvar#check $"leakvar" A7-decode
   2253 #%end.i
   2254   if ! ble/decode/attach; then # 53ms
   2255     _ble_attached=
   2256     BLE_ATTACHED=
   2257     ble-edit/detach
   2258     ble/term/leave
   2259     ble/base/restore-BASH_REMATCH
   2260     ble/base/restore-bash-options
   2261     ble/base/restore-POSIXLY_CORRECT
   2262     ble/base/restore-builtin-wrappers
   2263     builtin eval -- "$_ble_bash_FUNCNEST_restore"
   2264 #%if leakvar
   2265 ble/debug/leakvar#check $"leakvar" A7b1
   2266 #%end.i
   2267     return 1
   2268   fi
   2269 
   2270   ble/history:bash/reset # 27s for bash-3.0
   2271 #%if leakvar
   2272 ble/debug/leakvar#check $"leakvar" A8-history
   2273 #%end.i
   2274 
   2275   blehook/invoke ATTACH
   2276 #%if leakvar
   2277 ble/debug/leakvar#check $"leakvar" A9-ATTACH
   2278 #%end.i
   2279 
   2280   # Note: 再描画 (初期化中のエラーメッセージ・プロンプト変更等の為)
   2281   ble/textarea#redraw
   2282 #%if leakvar
   2283 ble/debug/leakvar#check $"leakvar" A10-redraw
   2284 #%end.i
   2285 
   2286   # Note: ble-decode/{initialize,reset-default-keymap} 内で
   2287   #   info を設定する事があるので表示する。
   2288   ble/edit/info/default
   2289 #%if leakvar
   2290 ble/debug/leakvar#check $"leakvar" A11-info
   2291 #%end.i
   2292   ble-edit/bind/.tail
   2293 #%if leakvar
   2294 ble/debug/leakvar#check $"leakvar" A12-tail
   2295 #%end.i
   2296 }
   2297 
   2298 function ble-detach {
   2299   if (($#)); then
   2300     ble/base/print-usage-for-no-argument-command 'Detach from ble.sh.' "$@"
   2301     return "$?"
   2302   fi
   2303 
   2304   [[ $_ble_attached && ! $_ble_edit_detach_flag ]] || return 1
   2305 
   2306   # Note: 実際の detach 処理は ble-edit/bind/.check-detach で実行される
   2307   _ble_edit_detach_flag=${1:-detach} # schedule detach
   2308 }
   2309 function ble-detach/impl {
   2310   [[ $_ble_attached ]] || return 1
   2311   _ble_attached=
   2312   BLE_ATTACHED=
   2313   blehook/invoke DETACH
   2314 
   2315   ble-edit/detach
   2316   ble/decode/detach
   2317   READLINE_LINE='' READLINE_POINT=0
   2318 }
   2319 function ble-detach/message {
   2320   ble/util/buffer.flush >&2
   2321   printf '%s\n' "$@" 1>&2
   2322   ble/edit/info/clear
   2323   ble/textarea#render
   2324   ble/util/buffer.flush >&2
   2325 }
   2326 
   2327 function ble/base/unload-for-reload {
   2328   if [[ $_ble_attached ]]; then
   2329     ble-detach/impl
   2330     ble/util/print "${_ble_term_setaf[12]}[ble: reload]$_ble_term_sgr0" 1>&2
   2331     [[ $_ble_edit_detach_flag ]] ||
   2332       _ble_edit_detach_flag=reload
   2333   fi
   2334   ble/base/unload reload
   2335   return 0
   2336 }
   2337 ## @fn ble/base/unload [opts]
   2338 function ble/base/unload {
   2339   ble/util/is-running-in-subshell && return 1
   2340   local IFS=$_ble_term_IFS
   2341   ble/term/stty/TRAPEXIT "$1"
   2342   ble/term/leave
   2343   ble/util/buffer.flush >&2
   2344   blehook/invoke unload
   2345   ble/decode/keymap#unload
   2346   ble-edit/bind/clear-keymap-definition-loader
   2347   ble/builtin/trap/finalize "$1"
   2348   ble/util/import/finalize
   2349   ble/fd#finalize
   2350   ble/base/clean-up-runtime-directory finalize
   2351   builtin unset -v _ble_bash BLE_VERSION BLE_VERSINFO
   2352   return 0
   2353 }
   2354 
   2355 ## @var _ble_base_attach_from_prompt
   2356 ##   非空文字列の時、PROMPT_COMMAND 経由の ble-attach を現在試みている最中です。
   2357 ##
   2358 ## @arr _ble_base_attach_PROMPT_COMMAND
   2359 ##   PROMPT_COMMAND 経由の ble-attach をする時、元々の PROMPT_COMMAND の値を保
   2360 ##   持する配列です。複数回 ble.sh をロードした時に、各ロード時に待避した
   2361 ##   PROMPT_COMMAND の値を配列の各要素に保持します。
   2362 ##
   2363 ##   Note #D1851: 以前の ble.sh ロード時に設定された値を保持したいので、既に要
   2364 ##   素がある場合にはクリアしない。
   2365 _ble_base_attach_from_prompt=
   2366 ((${#_ble_base_attach_PROMPT_COMMAND[@]})) ||
   2367   _ble_base_attach_PROMPT_COMMAND=()
   2368 ## @fn ble/base/install-prompt-attach
   2369 function ble/base/install-prompt-attach {
   2370   [[ ! $_ble_base_attach_from_prompt ]] || return 0
   2371   _ble_base_attach_from_prompt=1
   2372   if ((_ble_bash>=50100)); then
   2373     ((${#PROMPT_COMMAND[@]})) || PROMPT_COMMAND[0]=
   2374     ble/array#push PROMPT_COMMAND ble/base/attach-from-PROMPT_COMMAND
   2375     if [[ $_ble_edit_detach_flag == reload ]]; then
   2376       _ble_edit_detach_flag=prompt-attach
   2377       blehook internal_PRECMD!=ble/base/attach-from-PROMPT_COMMAND
   2378     fi
   2379   else
   2380     local save_index=${#_ble_base_attach_PROMPT_COMMAND[@]}
   2381     _ble_base_attach_PROMPT_COMMAND[save_index]=${PROMPT_COMMAND-}
   2382     ble/function#lambda PROMPT_COMMAND \
   2383                         "ble/base/attach-from-PROMPT_COMMAND $save_index \"\$FUNCNAME\""
   2384     ble/function#trace "$PROMPT_COMMAND"
   2385     if [[ $_ble_edit_detach_flag == reload ]]; then
   2386       _ble_edit_detach_flag=prompt-attach
   2387       blehook internal_PRECMD!="$PROMPT_COMMAND"
   2388     fi
   2389   fi
   2390 }
   2391 _ble_base_attach_from_prompt_lastexit=
   2392 _ble_base_attach_from_prompt_lastarg=
   2393 _ble_base_attach_from_prompt_PIPESTATUS=()
   2394 ## @fn ble/base/attach-from-PROMPT_COMMAND prompt_command lambda
   2395 function ble/base/attach-from-PROMPT_COMMAND {
   2396   # 後続の設定によって PROMPT_COMMAND が置換された場合にはそれを保持する
   2397   {
   2398     # save $?, $_ and ${PIPE_STATUS[@]}
   2399     _ble_base_attach_from_prompt_lastexit=$? \
   2400       _ble_base_attach_from_prompt_lastarg=$_ \
   2401       _ble_base_attach_from_prompt_PIPESTATUS=("${PIPESTATUS[@]}")
   2402 #%if measure_load_time
   2403     ble/util/print "ble.sh: $EPOCHREALTIME start prompt-attach" >&2
   2404 #%end
   2405     if ((BASH_LINENO[${#BASH_LINENO[@]}-1]>=1)); then
   2406       # 既にコマンドを実行している時にはそのコマンドの結果を記録する
   2407       _ble_edit_exec_lastexit=$_ble_base_attach_from_prompt_lastexit
   2408       _ble_edit_exec_lastarg=$_ble_base_attach_from_prompt_lastarg
   2409       _ble_edit_exec_PIPESTATUS=("${_ble_base_attach_from_prompt_PIPESTATUS[@]}")
   2410       # Note: 本当は一つ前のコマンドを知りたいが確実な方法がないのでこの関数の名前を入れておく。
   2411       _ble_edit_exec_BASH_COMMAND=$FUNCNAME
   2412     fi
   2413 
   2414     local is_last_PROMPT_COMMAND=1
   2415     if (($#==0)); then
   2416       if local ret; ble/array#index PROMPT_COMMAND ble/base/attach-from-PROMPT_COMMAND; then
   2417         local keys; keys=("${!PROMPT_COMMAND[@]}")
   2418         ((ret==keys[${#keys[@]}-1])) || is_last_PROMPT_COMMAND=
   2419         ble/idict#replace PROMPT_COMMAND ble/base/attach-from-PROMPT_COMMAND
   2420       fi
   2421       blehook internal_PRECMD-=ble/base/attach-from-PROMPT_COMMAND || ((1)) # set -e 対策
   2422     else
   2423       local save_index=$1 lambda=$2
   2424 
   2425       # 待避していた内容を復元・実行
   2426       local PROMPT_COMMAND=${_ble_base_attach_PROMPT_COMMAND[save_index]}
   2427       local ble_base_attach_from_prompt_command=processing
   2428       ble/prompt/update/.eval-prompt_command 2>&3
   2429       ble/util/unlocal ble_base_attach_from_prompt_command
   2430       _ble_base_attach_PROMPT_COMMAND[save_index]=$PROMPT_COMMAND
   2431       ble/util/unlocal PROMPT_COMMAND
   2432 
   2433       # 可能なら自身を各 hook から除去
   2434       blehook internal_PRECMD-="$lambda" || ((1)) # set -e 対策
   2435       if [[ $PROMPT_COMMAND == "$lambda" ]]; then
   2436         PROMPT_COMMAND=${_ble_base_attach_PROMPT_COMMAND[save_index]}
   2437       else
   2438         is_last_PROMPT_COMMAND=
   2439       fi
   2440 
   2441       # #D1354: 入れ子の ble/base/attach-from-PROMPT_COMMAND の時は一番
   2442       #   外側で ble-attach を実行する様にする。3>&2 2>/dev/null のリダ
   2443       #   イレクトにより stdout.off の効果が巻き戻されるのを防ぐ為。
   2444       [[ ${ble_base_attach_from_prompt_command-} != processing ]] || return 0
   2445     fi
   2446 
   2447     # 既に attach 状態の時は処理はスキップ
   2448     [[ $_ble_base_attach_from_prompt ]] || return 0
   2449     _ble_base_attach_from_prompt=
   2450 
   2451     # Note #D1778: この attach-from-PROMPT_COMMAND が PROMPT_COMMAND
   2452     #   処理の最後と見做せる場合、この時点で PROMPT_COMMAND は一通り終
   2453     #   わったと見做せるので、ble-attach 内部で改めて PROMPT_COMMAND
   2454     #   を実行する必要はなくなる。それを伝える為に中間状態の
   2455     #   _ble_prompt_hash の値を設定する。
   2456     # Note #D1778: bash-preexec 経由でプロンプトを設定しようとしている
   2457     #   場合は、この時点で既に PRECMD に hook が移動している可能性があ
   2458     #   るので PRECMD も発火しておく (PROMPT_COMMAND と PRECMD の順序
   2459     #   が逆になるが仕方がない。問題になれば後で考える)。
   2460     if [[ $is_last_PROMPT_COMMAND ]]; then
   2461       ble-edit/exec:gexec/invoke-hook-with-setexit internal_PRECMD
   2462       ble-edit/exec:gexec/invoke-hook-with-setexit PRECMD
   2463       _ble_prompt_hash=$COLUMNS:$_ble_edit_lineno:prompt_attach
   2464     fi
   2465   } 3>&2 2>/dev/null # set -x 対策 #D0930
   2466 
   2467   ble-attach force
   2468 
   2469   # Note: 何故か分からないが PROMPT_COMMAND から ble-attach すると
   2470   # ble/bin/stty や ble/bin/mkfifo や tty 2>/dev/null などが
   2471   # ジョブとして表示されてしまう。joblist.flush しておくと平気。
   2472   # これで取り逃がすジョブもあるかもしれないが仕方ない。
   2473   ble/util/joblist.flush &>/dev/null
   2474   ble/util/joblist.check
   2475 #%if measure_load_time
   2476   ble/util/print "ble.sh: $EPOCHREALTIME end prompt-attach" >&2
   2477 #%end
   2478 }
   2479 
   2480 function ble/base/process-blesh-arguments {
   2481   local opts=$_ble_base_arguments_opts
   2482   local attach=$_ble_base_arguments_attach
   2483   local inputrc=$_ble_base_arguments_inputrc
   2484 
   2485   _ble_base_rcfile=$_ble_base_arguments_rcfile
   2486 
   2487   # reconstruction type of user-bindings
   2488   _ble_decode_initialize_inputrc=$inputrc
   2489 
   2490 #%if measure_load_time
   2491 time {
   2492 #%end
   2493   ble/base/load-rcfile # blerc
   2494 #%if measure_load_time
   2495 ble/debug/measure-set-timeformat "blerc: '$_ble_base_rcfile'"; }
   2496 #%end
   2497   ble/util/invoke-hook BLE_ONLOAD
   2498 
   2499   # attach
   2500   case $attach in
   2501   (attach) ble-attach ;;
   2502   (prompt) ble/base/install-prompt-attach ;;
   2503   (none) ;;
   2504   (*) ble/util/print "ble.sh: unrecognized attach method --attach='$attach'." ;;
   2505   esac
   2506 }
   2507 
   2508 function ble/base/sub:test {
   2509   local error= logfile=
   2510 
   2511   [[ ${LANG-} ]] || local LANG=en_US.UTF-8
   2512 
   2513   ble-import lib/core-test
   2514 
   2515   if (($#==0)); then
   2516     set -- bash main util canvas decode edit syntax complete
   2517     logfile=$_ble_base_cache/test.$(date +'%Y%m%d.%H%M%S').log
   2518     : >| "$logfile"
   2519     ble/test/log#open "$logfile"
   2520   fi
   2521 
   2522   if ((!_ble_make_command_check_count)); then
   2523     ble/test/log "MACHTYPE: $MACHTYPE"
   2524     ble/test/log "BLE_VERSION: $BLE_VERSION"
   2525   fi
   2526   ble/test/log "BASH_VERSION: $BASH_VERSION"
   2527   local line='locale:' var ret
   2528   for var in LANG "${!LC_@}"; do
   2529     ble/string#quote-word "${!var}"
   2530     line="$line $var=$ret"
   2531   done
   2532   ble/test/log "$line"
   2533 
   2534   local section
   2535   for section; do
   2536     local file=$_ble_base/lib/test-$section.sh
   2537     if [[ -f $file ]]; then
   2538       source "$file" || error=1
   2539     else
   2540       ble/test/log "ERROR: Test '$section' is not defined."
   2541       error=1
   2542     fi
   2543   done
   2544 
   2545   if [[ $logfile ]]; then
   2546     ble/test/log#close
   2547     ble/util/print "ble.sh: The test log was saved to '${_ble_term_setaf[4]}$logfile$_ble_term_sgr0'."
   2548   fi
   2549   [[ ! $error ]]
   2550 }
   2551 function ble/base/sub:update { ble-update; }
   2552 function ble/base/sub:clear-cache {
   2553   (shopt -u failglob; ble/bin/rm -rf "$_ble_base_cache"/*)
   2554 }
   2555 function ble/base/sub:lib { :; } # do nothing
   2556 
   2557 #%if measure_load_time
   2558 ble/debug/measure-set-timeformat ble.pp/epilogue; }
   2559 #%end
   2560 
   2561 # Note: ble-attach 及びそれを呼び出す可能性がある物には DEBUG trap を
   2562 #   継承させる。これはユーザーの設定した user trap を正しく抽出する為
   2563 #   に必要。現在は ble-attach から呼び出される ble-edit/attach で処理
   2564 #   している。
   2565 ble/function#trace ble-attach
   2566 ble/function#trace ble
   2567 ble/function#trace ble/dispatch
   2568 ble/function#trace ble/base/attach-from-PROMPT_COMMAND
   2569 
   2570 # Note #D1775: 以下は ble/base/unload 時に元の trap または ble.sh 有効時にユー
   2571 #   ザーが設定した trap を復元する為に用いる物。ble/base/unload は中で
   2572 #   ble/builtin/trap/finalize を呼び出す。ble/builtin/trap/finalize は別の箇所
   2573 #   で ble/function#trace されている。
   2574 ble/function#trace ble/base/unload
   2575 
   2576 ble-import -f lib/_package
   2577 if [[ $_ble_init_command ]]; then
   2578   ble/base/sub:"${_ble_init_command[@]}"; _ble_init_exit=$?
   2579   [[ $_ble_init_attached ]] && ble-attach
   2580   ble/util/setexit "$_ble_init_exit"
   2581 else
   2582   ble/base/process-blesh-arguments "$@"
   2583 fi
   2584 
   2585 #%if measure_load_time
   2586 ble/debug/measure-set-timeformat Total nofork; }
   2587 _ble_init_exit=$?
   2588 echo "ble.sh: $EPOCHREALTIME load end" >&2
   2589 ble/util/setexit "$_ble_init_exit"
   2590 #%end
   2591 
   2592 ble/init/clean-up check-attach 2>/dev/null # set -x 対策 #D0930
   2593 { builtin eval "return $? || exit $?"; } 2>/dev/null # set -x 対策 #D0930
   2594 ###############################################################################