|
1 | 1 | #!/usr/bin/env bash |
| 2 | +shopt -s extdebug |
2 | 3 | set -Eeuo pipefail |
3 | 4 | IFS=$'\n\t' |
4 | 5 |
|
@@ -204,24 +205,74 @@ fatal_notrace() { |
204 | 205 | exit 1 |
205 | 206 | } |
206 | 207 | fatal() { |
207 | | - local -a stack=("${C["Error"]}Stack trace:${NC}\n") |
208 | | - local stack_size=${#FUNCNAME[@]} |
209 | | - local -i i |
210 | | - local indent=" " |
211 | | - # to avoid noise we start with 1 to skip the stack function |
212 | | - for ((i = 1; i < stack_size; i++)); do |
213 | | - local func="${FUNCNAME[$i]:-(top level)}" |
214 | | - local -i line="${BASH_LINENO[$((i - 1))]}" |
215 | | - local src="${BASH_SOURCE[$i]:-(no file)}" |
216 | | - stack+=("${indent}└ ${C["File"]}$src${NC}:${C["RunningCommand"]}$line${NC} (${C["RunningCommand"]}$func${NC})\n") |
217 | | - indent="${indent} " |
| 208 | + local -i thisFuncLine=$((LINENO - 1)) |
| 209 | + local -a Stack=("${C["Error"]}Stack trace:${NC}\n") |
| 210 | + local StackSize=${#FUNCNAME[@]} |
| 211 | + local -i FrameNumberLength |
| 212 | + FrameNumberLength=$((${#StackSize} / 10)) |
| 213 | + local indent=" " |
| 214 | + local NoFile="<nofile>" |
| 215 | + local NoFunction="<nofunction>" |
| 216 | + |
| 217 | + local SourceFile="${BASH_SOURCE[0]:-$NoFile}" |
| 218 | + local -i line="${thisFuncLine}" |
| 219 | + local func="${FUNCNAME[0]:-$NoFunction}" |
| 220 | + local cmd |
| 221 | + local -i CurrentArg=0 |
| 222 | + local -i CmdArgCount=0 |
| 223 | + for ((Frame = 0; Frame <= StackSize; Frame++)); do |
| 224 | + local StackLineFormat=" ${C["RunningCommand"]}%${FrameNumberLength}d${NC}:${indent}└ ${C["File"]}%s${NC}:${C["RunningCommand"]}%d${NC} (${C["RunningCommand"]}%s${NC})\n" |
| 225 | + |
| 226 | + # shellcheck disable=SC2059 # Don't use variables in the printf format string. |
| 227 | + Stack+=( |
| 228 | + "$( |
| 229 | + printf "${StackLineFormat}" "${Frame}" "${SourceFile}" "${line}" "${func}" |
| 230 | + )\n" |
| 231 | + ) |
| 232 | + if [[ -n ${cmd-} ]]; then |
| 233 | + local -a cmdArgs=() |
| 234 | + local -i j |
| 235 | + for ((j = CurrentArg + CmdArgCount - 1; j >= CurrentArg; j--)); do |
| 236 | + cmdArgs+=("$(strip_ansi_colors "${BASH_ARGV[$j]}")") |
| 237 | + done |
| 238 | + cmdString="$( |
| 239 | + custom_quote_elements_with_spaces "${NC}'" "${C["RunningCommand"]}" "${cmd}" "${cmdArgs[@]}" |
| 240 | + )" |
| 241 | + local StackCmdFormat=" %${FrameNumberLength}s${indent} %s\n" |
| 242 | + # shellcheck disable=SC2059 # Don't use variables in the printf format string. |
| 243 | + Stack+=( |
| 244 | + "$( |
| 245 | + printf "${StackCmdFormat}" "" "${cmdString}" |
| 246 | + )\n" |
| 247 | + ) |
| 248 | + fi |
| 249 | + SourceFile="${BASH_SOURCE[Frame + 1]:-$NoFile}" |
| 250 | + line="${BASH_LINENO[Frame]:-0}" |
| 251 | + func="${FUNCNAME[Frame + 1]:-$NoFunction}" |
| 252 | + cmd="${FUNCNAME[Frame]:-$NoFunction}" |
| 253 | + CurrentArg+=${CmdArgCount} |
| 254 | + CmdArgCount=${BASH_ARGC[Frame]-} |
| 255 | + indent+=" " |
218 | 256 | done |
219 | 257 |
|
| 258 | + #local -a stack=("${C["Error"]}Stack trace:${NC}\n") |
| 259 | + #local stack_size=${#FUNCNAME[@]} |
| 260 | + #local -i i |
| 261 | + #local indent=" " |
| 262 | + ## to avoid noise we start with 1 to skip the stack function |
| 263 | + #for ((i = 1; i < stack_size; i++)); do |
| 264 | + # local func="${FUNCNAME[$i]:-(top level)}" |
| 265 | + # local -i line="${BASH_LINENO[$((i - 1))]}" |
| 266 | + # local src="${BASH_SOURCE[$i]:-(no file)}" |
| 267 | + # stack+=("${indent}└ ${C["File"]}$src${NC}:${C["RunningCommand"]}$line${NC} (${C["RunningCommand"]}$func${NC})\n") |
| 268 | + # indent="${indent} " |
| 269 | + #done |
| 270 | + |
220 | 271 | fatal_notrace \ |
221 | 272 | "$@" \ |
222 | 273 | "\n" \ |
223 | 274 | "\n" \ |
224 | | - "${stack[@]}" \ |
| 275 | + "${Stack[@]}" \ |
225 | 276 | "\n" \ |
226 | 277 | "${C["Error"]}Please let the dev know of this error.${NC}" |
227 | 278 | } |
|
0 commit comments