Skip to content

Commit

Permalink
edit (TRAPDEBUG): preserve original DEBUG trap and enabled it in PROM…
Browse files Browse the repository at this point in the history
…PT_COMMAND
  • Loading branch information
akinomyoga committed Feb 16, 2022
1 parent e61dbaa commit ec2a67a
Show file tree
Hide file tree
Showing 7 changed files with 1,417 additions and 61 deletions.
23 changes: 20 additions & 3 deletions ble.pp
Expand Up @@ -323,7 +323,7 @@ function ble/variable#copy-state {

function ble/base/.adjust-bash-options {
builtin eval -- "$1=\$-"
set +exvuk -B
set +exvukT -B

[[ $2 == shopt ]] || local shopt
if ((_ble_bash>=40100)); then
Expand All @@ -343,6 +343,7 @@ function ble/base/.restore-bash-options {
local set=${!1} shopt=${!2}
[[ :$shopt: == *:nocasematch:* ]] && shopt -s nocasematch
[[ $set == *B* ]] || set +B
[[ $set == *T* ]] && set -T
[[ $set == *k* ]] && set -k
[[ $set == *u* ]] && set -u
[[ $set == *v* ]] && set -v
Expand Down Expand Up @@ -933,6 +934,8 @@ function ble/base/.create-user-directory {

##
## @var _ble_base
## @var _ble_base_blesh
## @var _ble_base_blesh_raw
##
## ble.sh のインストール先ディレクトリ。
## 読み込んだ ble.sh の実体があるディレクトリとして解決される。
Expand All @@ -942,9 +945,11 @@ function ble/base/initialize-base-directory {
local defaultDir=${2-}

# resolve symlink
if [[ -h $src ]] && type -t readlink &>/dev/null; then
_ble_base_blesh_raw=$src
if [[ -h $src ]]; then
local ret; ble/util/readlink "$src"; src=$ret
fi
_ble_base_blesh=$src

if [[ -s $src && $src != */* ]]; then
_ble_base=$PWD
Expand Down Expand Up @@ -1587,6 +1592,7 @@ function ble/base/install-prompt-attach {
_ble_base_attach_PROMPT_COMMAND[save_index]=${PROMPT_COMMAND-}
ble/function#lambda PROMPT_COMMAND \
"ble/base/attach-from-PROMPT_COMMAND $save_index \"\$FUNCNAME\""
ble/function#trace "$PROMPT_COMMAND"
if [[ $_ble_edit_detach_flag == reload ]]; then
_ble_edit_detach_flag=prompt-attach
blehook PRECMD+="$PROMPT_COMMAND"
Expand All @@ -1607,12 +1613,14 @@ function ble/base/attach-from-PROMPT_COMMAND {
local save_index=$1 lambda=$2

# 待避していた内容を復元・実行
[[ $PROMPT_COMMAND == "$lambda" ]] || local PROMPT_COMMAND
local PROMPT_COMMAND_local=
[[ $PROMPT_COMMAND == "$lambda" ]] || local PROMPT_COMMAND PROMPT_COMMAND_local=1
PROMPT_COMMAND=${_ble_base_attach_PROMPT_COMMAND[save_index]}
local ble_base_attach_from_prompt_command=processing
ble/prompt/update/.eval-prompt_command 2>&3
ble/util/unlocal ble_base_attach_from_prompt_command
_ble_base_attach_PROMPT_COMMAND[save_index]=$PROMPT_COMMAND
[[ ! $PROMPT_COMMAND_local ]] || ble/util/unlocal PROMPT_COMMAND
blehook PRECMD-="$lambda" || ((1)) # set -e 対策

# #D1354: 入れ子の ble/base/attach-from-PROMPT_COMMAND の時は一番
Expand Down Expand Up @@ -1748,6 +1756,15 @@ function ble/base/sub:clear-cache {
ble/debug/measure-set-timeformat ble.pp/epilogue; }
#%end

# Note: ble-attach 及びそれを呼び出す可能性がある物には DEBUG trap を
# 継承させる。これはユーザーの設定した user trap を正しく抽出する為
# に必要。現在は ble-attach から呼び出される ble-edit/attach で処理
# している。
ble/function#trace ble-attach
ble/function#trace ble
ble/function#trace ble/dispatch
ble/function#trace ble/base/attach-from-PROMPT_COMMAND

ble-import -f lib/_package
if [[ $_ble_init_command ]]; then
ble/base/sub:"$_ble_init_command"; _ble_init_exit=$?
Expand Down
1 change: 1 addition & 0 deletions docs/ChangeLog.md
Expand Up @@ -318,6 +318,7 @@
- main: check `/dev/tty` on startup (reported by andychu) `#D1749` 711c69f
- util: add identification of Windows Terminal `wt` `#D1758` e332dc5
- complete: evaluate words for `noquote` (motivated by SuperSandro2000) `#D1767` 0a42299
- edit (TRAPDEBUG): preserve original `DEBUG` trap and enabled it in `PROMPT_COMMAND` (motivated by ammarooo) `#D1772` `#D1773` 0000000

## Internal changes and fixes

Expand Down
1 change: 1 addition & 0 deletions make_command.sh
Expand Up @@ -1319,6 +1319,7 @@ function sub:scan {
\Zline = "bind"Zd
\Zlocal trap_command="trap -- Zd
\Zlocal trap$Zd
\Z\$\{content#"trap -- '\''"\}Zd
g'

sub:scan/a.txt
Expand Down
229 changes: 229 additions & 0 deletions memo/D1772.bashrc
@@ -0,0 +1,229 @@
#! bash config

shopt -s extglob
#opts=builtin-elapsed
#opts=no-timer

#type=none
type=initial
#type=initial-prompt
#type=final
#type=final-prompt

#type=check-DEBUG-behavior
#type=unset-self-func
#type=check-bashbug-tmpenv
#type=check-unset-trap-DEBUG

#set -T

if [[ $type == initial ]]; then
source out/ble.sh --attach=none
elif [[ $type == initial-prompt ]]; then
source out/ble.sh
fi

if [[ ${BLE_VERSION-} && :$opts: == *:builtin-elapsed:* ]]; then
ble-import contrib/prompt-elapsed
_ps1_time='\q{contrib/elapsed}'
elif [[ :$opts: != *:no-timer:* ]]; then
function timer_start {
#echo $FUNCNAME >/dev/tty
timer=${timer:-$SECONDS}
}

function timer_stop {
#echo $FUNCNAME >/dev/tty
timer_show=$(($SECONDS - $timer))
#timer_show=$(($SECONDS - timer))
unset timer
}

trap 'timer_start "$BASH_COMMAND"' DEBUG

if [ "$PROMPT_COMMAND" == "" ]; then
PROMPT_COMMAND="timer_stop"
else
PROMPT_COMMAND="$PROMPT_COMMAND; timer_stop"
fi

_ps1_time='${timer_show}s'
fi

case $type in
(check-DEBUG-behavior)
echo "direct:1"
builtin trap -p DEBUG
echo "direct:2"

# Q サブシェルの中でも DEBUG trap の定義を参照できるか?
# A 参照できる。
echo "subshell:1"
echo "[$(builtin trap -p DEBUG)]"
echo "subshell:2"

# Q 関数の中でも DEBUG trap の定義を参照できるか?
# A 参照できない。-t を付加していれば見られる。
function inside-function {
echo "$FUNCNAME:1"
builtin trap -p DEBUG
echo "$FUNCNAME:2"
} >/dev/tty
declare -ft inside-function
inside-function

# Q 関数内サブシェルでも DEBUG trap の定義を参照できるか?
# A できない。-t を付加していれば見られる。
function inside-func-subshell {
echo "$FUNCNAME[$(builtin trap -p DEBUG)]"
} >/dev/tty
declare -ft inside-func-subshell
inside-func-subshell

# Q 関数内 eval でも DEBUG trap の定義を参照できるか?
# A できない。-t を付加していれば見られる。
function inside-func-eval {
echo "$FUNCNAME:1"
eval 'builtin trap -p DEBUG'
echo "$FUNCNAME:2"
} >/dev/tty
declare -ft inside-func-eval
inside-func-eval

# Q 関数の更に内側の関数で DEBUG trap の定義を参照できるか?
# A できない。外側と内側の両方に -t を指定して初めて見られる。
function inside-func-nest/1 {
builtin trap -p DEBUG
}
function inside-func-nest {
echo "$FUNCNAME:1"
inside-func-nest/1
echo "$FUNCNAME:2"
} >/dev/tty
declare -ft inside-func-nest/1
declare -ft inside-func-nest
inside-func-nest

# Q 関数の中でリダイレクトした時に DEBUG trap の定義を参照できるか。
# A できない。-t を付加していれば見られる。
function inside-func-redir {
builtin trap -p DEBUG > a.tmp
echo "$FUNCNAME[$(<a.tmp)]"
} >/dev/tty
declare -ft inside-func-redir
inside-func-redir

# Q 内側の関数から呼び出された後で外側の関数に対して -t 属性を付加して参照できる様になるだろうか。
# A ならない。
function nest-afterward-trace/1 {
declare -ft "${FUNCNAME[1]}"
builtin trap -p DEBUG
}
function nest-afterward-trace {
echo "$FUNCNAME:1"
nest-afterward-trace/1
echo "$FUNCNAME:2"
}
declare -ft nest-afterward-trace/1
nest-afterward-trace

# Q 内側の関数で set -o functrace を設定して見られる様になるだろうか。
# A ならない。
function nest-afterward-functrace/1 {
set -o functrace
builtin trap -p DEBUG
set +o functrace
}
function nest-afterward-functrace {
echo "$FUNCNAME:1"
nest-afterward-functrace/1
echo "$FUNCNAME:2"
}
nest-afterward-functrace

# Q source xxx の中から DEBUG trap は見えるだろうか。
# A 見えない。但し set -T (-o functrace) が設定されていれば見える。
#set -T
{
echo echo inside-source:1
echo builtin trap -p DEBUG
echo echo inside-source:2
} >| a.tmp
source ./a.tmp

exit ;;

(unset-self-func)
function test-unset-self-function {
unset -f "$FUNCNAME"
echo hello
echo world
}
test-unset-self-function

if declare -f test-unset-self-function; then
echo $'test-unset-self-function: \e[1;31mfound\e[m (unexpected)'
else
echo $'test-unset-self-function: \e[1;32mnot found\e[m (expected)'
fi

exit ;;

(check-bashbug-tmpenv)
set +T

function hello {
echo "result1:$a"
echo "result2:$a"
}
a=value hello
a=value eval hello
a=value builtin eval hello

function print { echo "v=${v:-(not found)}"; }
function trapdebug { echo "$FUNCNAME:1:v=($v)"; }
builtin trap 'trapdebug' DEBUG
v=xxxx builtin eval 'echo v=${v:-(not found)}'
v=xxxx eval 'echo v=${v:-(not found)}'
echo "[print with debugtrap]"
v=xxxx print
v=xxxx eval print
v=xxxx builtin eval print

exit ;;

(check-unset-trap-DEBUG)
# Q trace 属性のついた関数内から DEBUG trap を削除する事は可能か?
# A 削除できる。
function unset-trap {
builtin trap - DEBUG
}
declare -ft unset-trap

echo check-unset-trap-DEBUG:1
builtin trap -p DEBUG
echo check-unset-trap-DEBUG:2
unset-trap
echo check-unset-trap-DEBUG:3
builtin trap -p DEBUG
echo check-unset-trap-DEBUG:4

exit ;;
esac

if [[ $type == final ]]; then
source out/ble.sh --attach=none
elif [[ $type == final-prompt ]]; then
source out/ble.sh
fi
PS1='[last: '$_ps1_time'][\w]$ '

if [[ ${BLE_VERSION-} && $type == @(final|initial) ]]; then
ble-attach
# { echo A
# builtin trap -p DEBUG
# echo B
# trap -p DEBUG
# echo C
# } >/dev/tty
fi

0 comments on commit ec2a67a

Please sign in to comment.