|
|
|
@ -7,11 +7,14 @@ SCRIPT=$1 |
|
|
|
|
|
|
|
# FUNCTIONS |
|
|
|
|
|
|
|
# overridden function which permits stacktracing of original `return` statement |
|
|
|
function return { |
|
|
|
code=${1:-0} |
|
|
|
[[ $code -gt 0 ]] && >&2 echo "${BASH_SOURCE[2]}: line ${BASH_LINENO[0]}: return $@" |
|
|
|
builtin return $code |
|
|
|
function on_return { |
|
|
|
if [[ "${BASH_COMMAND}" == return* ]]; then |
|
|
|
code=$(echo "${BASH_COMMAND}" | cut -d' ' -f2) # regex does not work here! |
|
|
|
if [[ -n "$code" ]] && [[ $code -ne 0 ]]; then |
|
|
|
trap - DEBUG |
|
|
|
>&2 echo "${BASH_SOURCE[2]}: line ${BASH_LINENO[0]}: return $code from ${FUNCNAME[1]}" |
|
|
|
fi |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
# overridden function which permits stacktracing of original `return` statement |
|
|
|
@ -28,6 +31,7 @@ function on_exit { |
|
|
|
stack_lines=("${BASH_LINENO[@]}") |
|
|
|
stack_functions=("${FUNCNAME[@]}") |
|
|
|
stack_sources=("${BASH_SOURCE[@]}") |
|
|
|
|
|
|
|
unset stack_lines[-1] |
|
|
|
unset stack_lines[-1] |
|
|
|
unset stack_functions[0] |
|
|
|
@ -35,6 +39,14 @@ function on_exit { |
|
|
|
stack_functions[-1]='<main>' |
|
|
|
unset stack_sources[0] |
|
|
|
unset stack_sources[-1] |
|
|
|
|
|
|
|
if [[ "${stack_functions[1]}" == exit && "${stack_sources[1]}" == "${BASH_SOURCE[0]}" ]]; then |
|
|
|
# the exit case scenario |
|
|
|
unset stack_functions[1] |
|
|
|
unset stack_sources[1] |
|
|
|
unset stack_lines[0] |
|
|
|
fi |
|
|
|
|
|
|
|
stack_lines=("${stack_lines[@]}") |
|
|
|
stack_functions=("${stack_functions[@]}") |
|
|
|
stack_sources=("${stack_sources[@]}") |
|
|
|
@ -44,15 +56,25 @@ function on_exit { |
|
|
|
last_error=$(tail -n1 $TMP_ERROR) |
|
|
|
last_source=${stack_sources[0]} |
|
|
|
last_source=${last_source//./"\."} # replace . by \. |
|
|
|
regex="^$last_source: line ([0-9]+): (.*)$" |
|
|
|
regex="^$last_source: line ([0-9]+): (.*)\$" |
|
|
|
if [[ "$last_error" =~ $regex ]]; then |
|
|
|
line=${BASH_REMATCH[1]} |
|
|
|
message=${BASH_REMATCH[2]} |
|
|
|
regex=': unbound variable$' |
|
|
|
[[ $code == 1 ]] && [[ "$message" =~ $regex ]] && stack_lines[0]=$line |
|
|
|
|
|
|
|
regex="^return [0-9]* from (.*)\$" |
|
|
|
if [[ "$message" =~ $regex ]]; then |
|
|
|
funcname="${BASH_REMATCH[1]}" |
|
|
|
# >&4 echo "RETURN DETECTED line ${stack_sources[0]} $line $funcname" |
|
|
|
stack_sources=("${stack_sources[0]}" "${stack_sources[@]}") |
|
|
|
stack_lines=("$line" "${stack_lines[@]}") |
|
|
|
stack_functions=("$funcname" "${stack_functions[@]}") |
|
|
|
fi |
|
|
|
|
|
|
|
>&4 echo -e "ERROR $code: [$message]" |
|
|
|
else |
|
|
|
>&4 echo "ERROR $code: <undefined>" |
|
|
|
>&4 echo "ERROR $code: <return>" |
|
|
|
fi |
|
|
|
|
|
|
|
for i in "${!stack_functions[@]}"; do |
|
|
|
@ -60,10 +82,6 @@ function on_exit { |
|
|
|
done |
|
|
|
fi |
|
|
|
|
|
|
|
# echo "${stack_lines[@]}" |
|
|
|
# echo "${stack_functions[@]}" |
|
|
|
# echo "${stack_sources[@]}" |
|
|
|
|
|
|
|
cleanup |
|
|
|
builtin exit $code |
|
|
|
} |
|
|
|
@ -90,6 +108,7 @@ function cleanup { |
|
|
|
|
|
|
|
set -TEue -o pipefail |
|
|
|
trap 'on_exit $?' ERR TERM INT EXIT |
|
|
|
trap 'on_return' DEBUG |
|
|
|
|
|
|
|
# magic FD |
|
|
|
exec 3>$TMP_ERROR 4>/dev/stderr |
|
|
|
|