Skip to content

Instantly share code, notes, and snippets.

@ormaaj
Last active October 13, 2015 07:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ormaaj/4159235 to your computer and use it in GitHub Desktop.
Save ormaaj/4159235 to your computer and use it in GitHub Desktop.
# Adjacent function depth.
# Search up the stack for the first non-FUNCNAME[1] and count how deep we are.
# Result goes to stdout, or is optionally assigned to the given variable name.
function callDepth {
if [[ $FUNCNAME == "${FUNCNAME[1]}" ]]; then
unset -v n
printf "$@"
else
# If callee is empty then we're definitely being called from global scope.
# If there is exactly one callee named main, and len(BASH_SOURCE) == 2, then this is also definitely global scope.
if [[ -z ${FUNCNAME[1]} || ( ${FUNCNAME[-1]} == main && ( ${#FUNCNAME[@]} -eq 2 && ${#BASH_SOURCE[@]} -eq 2 ) ) ]]; then
typeset n=0
else
typeset -i n=1
while [[ ${FUNCNAME[1]} == "${FUNCNAME[n+1]}" && ${BASH_SOURCE[1]} == "${BASH_SOURCE[n+2]}" ]]; do
(( n++ ))
done
fi
${1:+"$FUNCNAME" -v} "${1:-printf}" %d "$n"
fi
}
# Set local options
function localopt {
typeset -a unsetopts setopts
typeset opt depth
if [[ $1 == -n ]]; then
# if [[ $2 != +([[:digit:]]) || callDepth depth ]]
# then :
# fi
:
fi
typeset -f +t "${FUNCNAME[@]::2}"
for opt; do
case $opt in
+*)
unsetopts+=("${opt#-}")
set +o "$opt"
;;
*)
setopts+=("$opt")
set -o "$opt"
esac
if [[ $SHELLOPTS != *${opt}* ]]; then
set -o "$opt"
unsetopts+=("$opt")
fi
done
}
typeset -ft localopt
{ eval function\ {f,main,source}" $(</dev/fd/0) ;"; } <<\EOF
{
local depth=
if callDepth depth && (( depth < $1 )); then
printf '%-2d' "$depth"
"$FUNCNAME" "$1"
printf '%-2d' "$depth"
fi
}
EOF
g() {
local depth=$(callDepth)
if (( depth < $1 )); then
printf '%-2d' "$depth"
"$FUNCNAME" "$1"
printf '%-2d' "$depth"
else
f 10
fi
}
f 10; echo
main 10; echo
callDepth; echo
typeset -xf callDepth f g main
bash -c 'f 10; echo; main 10; echo; g 10; echo; callDepth; echo'
g 10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment