1919# (c) 2016-2019 solidity contributors.
2020# ------------------------------------------------------------------------------
2121
22+ # Save the initial working directory so that printStackTrace() can access it even if the sourcing
23+ # changes directory. The paths returned by `caller` are relative to it.
24+ _initial_work_dir=$( pwd)
25+
2226if [ " $CIRCLECI " ]
2327then
2428 export TERM=" ${TERM:- xterm} "
@@ -41,15 +45,31 @@ function printStackTrace
4145 local frame=1
4246 while caller " $frame " > /dev/null
4347 do
44- local lineNumber file function
48+ local lineNumber line file function
4549
4650 # `caller` returns something that could already be printed as a stacktrace but we can make
4751 # it more readable by rearranging the components.
4852 # NOTE: This assumes that paths do not contain spaces.
4953 lineNumber=$( caller " $frame " | cut --delimiter " " --field 1)
5054 function=$( caller " $frame " | cut --delimiter " " --field 2)
5155 file=$( caller " $frame " | cut --delimiter " " --field 3)
56+
57+ # Paths in the output from `caller` can be relative or absolute (depends on how the path
58+ # with which the script was invoked) and if they're relative, they're not necessarily
59+ # relative to the current working dir. This is a heuristic that will work if they're absolute,
60+ # relative to current dir, or relative to the dir that was current when the script started.
61+ # If neither works, it gives up.
62+ line=$(
63+ {
64+ tail " --lines=+${lineNumber} " " $file " ||
65+ tail " --lines=+${lineNumber} " " ${_initial_work_dir} /${file} "
66+ } 2> /dev/null |
67+ head --lines=1 |
68+ sed -e ' s/^[[:space:]]*//'
69+ ) || line=" <failed to find source line>"
70+
5271 >&2 printf " %s:%d in function %s()\n" " $file " " $lineNumber " " $function "
72+ >&2 printf " %s\n" " $line "
5373
5474 (( frame++ ))
5575 done
0 commit comments