+#######################################
+# Print stack trace
+#
+# usage: err-bash-trace [FRAME_START]
+#
+# This function is called by the other functions which print stack
+# traces.
+#
+# It does not show function args unless you first run:
+# shopt -s extdebug
+# which err-catch does for you.
+#
+# FRAME_START Optional variable to set before calling. The frame to
+# start printing on. default=1. If ${#FUNCNAME[@]} <=
+# FRAME_START + 1, don't print anything because we are at
+# the top level of the script and better off printing a
+# general message, for example see what our callers print.
+#
+#######################################
+err-bash-trace() {
+ local -i argc_index=0 frame i frame_start=${1:-1}
+ local source_loc
+ if (( ${#FUNCNAME[@]} <= frame_start + 1 )); then
+ return 0
+ fi
+ for ((frame=0; frame < ${#FUNCNAME[@]}; frame++)); do
+ argc=${BASH_ARGC[frame]}
+ argc_index+=$argc
+ if ((frame < frame_start)); then continue; fi
+ if (( ${#BASH_SOURCE[@]} > 1 )); then
+ source_loc="${BASH_SOURCE[frame]}:${BASH_LINENO[frame-1]}:"
+ fi
+ printf " from %sin \`%s" "$source_loc" "${FUNCNAME[frame]}" >&2
+ if shopt extdebug >/dev/null; then
+ for ((i=argc_index-1; i >= argc_index-argc; i--)); do
+ printf " %s" "${BASH_ARGV[i]}" >&2
+ done
+ fi
+ echo \' >&2
+ done
+ return 0
+}
+
+#######################################
+# Internal function for err-catch. Prints stack trace from interactive
+# shell trap.
+#
+# Usage: see err-catch-interactive
+#######################################
+_err-bash-trace-interactive() {
+ if (( ${#FUNCNAME[@]} <= 1 )); then
+ return 0
+ fi