Changeset View
Changeset View
Standalone View
Standalone View
libexec/rc/debug.sh
Show First 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
# If a function turns tracing on, ksh turns it off when the | # If a function turns tracing on, ksh turns it off when the | ||||
# function returns - useless. | # function returns - useless. | ||||
# PD ksh works ok ;-) | # PD ksh works ok ;-) | ||||
# | # | ||||
# AUTHOR: | # AUTHOR: | ||||
# Simon J. Gerraty <sjg@crufty.net> | # Simon J. Gerraty <sjg@crufty.net> | ||||
# RCSid: | # RCSid: | ||||
# $Id: debug.sh,v 1.35 2024/02/03 19:04:47 sjg Exp $ | # $Id: debug.sh,v 1.40 2024/09/09 20:06:00 sjg Exp $ | ||||
# | # | ||||
# @(#) Copyright (c) 1994-2024 Simon J. Gerraty | # @(#) Copyright (c) 1994-2024 Simon J. Gerraty | ||||
# | # | ||||
# This file is provided in the hope that it will | # This file is provided in the hope that it will | ||||
# be of use. There is absolutely NO WARRANTY. | # be of use. There is absolutely NO WARRANTY. | ||||
# Permission to copy, redistribute or otherwise | # Permission to copy, redistribute or otherwise | ||||
# use this file is hereby granted provided that | # use this file is hereby granted provided that | ||||
# the above copyright notice and this notice are | # the above copyright notice and this notice are | ||||
# left intact. | # left intact. | ||||
# | # | ||||
# Please send copies of changes and bug-fixes to: | # Please send copies of changes and bug-fixes to: | ||||
# sjg@crufty.net | # sjg@crufty.net | ||||
# | # | ||||
_DEBUG_SH=: | _DEBUG_SH=: | ||||
Myname=${Myname:-`basename $0 .sh`} | Myname=${Myname:-`basename $0 .sh`} | ||||
# We want to use local if we can | |||||
# if isposix-shell.sh has been sourced isPOSIX_SHELL will be set | |||||
# as will local | |||||
case "$local" in | |||||
local|:) ;; | |||||
*) | |||||
if (echo ${PATH%:*}) > /dev/null 2>&1; then | |||||
local=local | |||||
else | |||||
local=: | |||||
fi | |||||
;; | |||||
esac | |||||
DEBUGGING= | DEBUGGING= | ||||
DEBUG_DO=: | DEBUG_DO=: | ||||
DEBUG_SKIP= | DEBUG_SKIP= | ||||
export DEBUGGING DEBUG_DO DEBUG_SKIP | export DEBUGGING DEBUG_DO DEBUG_SKIP | ||||
## | |||||
# _debugOn match first | |||||
# | |||||
# Actually turn on tracing, set $DEBUG_ON=$match | |||||
# | |||||
# If we have included hooks.sh $_HOOKS_SH will be set | |||||
# and if $first (the first arg to DebugOn) is suitable as a variable | |||||
# name we will run ${first}_debugOn_hooks. | |||||
# | |||||
# We disable tracing for hooks_run itself but functions can trace | |||||
# if they want based on DEBUG_DO | |||||
# | |||||
_debugOn() { | _debugOn() { | ||||
DEBUG_OFF= | DEBUG_OFF= | ||||
DEBUG_DO= | DEBUG_DO= | ||||
DEBUG_SKIP=: | DEBUG_SKIP=: | ||||
DEBUG_X=-x | DEBUG_X=-x | ||||
set -x | set -x | ||||
DEBUG_ON=$1 | DEBUG_ON=$1 | ||||
case "$_HOOKS_SH,$2" in | |||||
,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;; | |||||
*) # avoid noise from hooks_run | |||||
set +x | |||||
hooks_run ${2}_debugOn_hooks | |||||
stevek: Don't you need a dummy "hooks_run" somewhere in the case where dot hooks.sh was not done? | |||||
Done Inline ActionsThat what checking for $_HOOKS_SH does, I was trying to keep the overhead down, as you know this stuff gets called a *lot* sjg: That what checking for $_HOOKS_SH does, I was trying to keep the overhead down, as you know… | |||||
set -x | |||||
;; | |||||
esac | |||||
} | } | ||||
## | |||||
# _debugOff match $DEBUG_ON $first | |||||
# | |||||
# Actually turn off tracing, set $DEBUG_OFF=$match | |||||
# | |||||
# If we have included hooks.sh $_HOOKS_SH will be set | |||||
# and if $first (the first arg to DebugOff) is suitable as a variable | |||||
# name we will run ${first}_debugOff_hooks. | |||||
# | |||||
# We do hooks_run after turning off tracing, but before resetting | |||||
# DEBUG_DO so functions can trace if they want | |||||
# | |||||
_debugOff() { | _debugOff() { | ||||
DEBUG_OFF=$1 | DEBUG_OFF=$1 | ||||
set +x | set +x | ||||
case "$_HOOKS_SH,$3" in | |||||
,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;; | |||||
*) hooks_run ${3}_debugOff_hooks;; | |||||
esac | |||||
set +x # just to be sure | |||||
DEBUG_ON=$2 | DEBUG_ON=$2 | ||||
DEBUG_DO=: | DEBUG_DO=: | ||||
DEBUG_SKIP= | DEBUG_SKIP= | ||||
DEBUG_X= | DEBUG_X= | ||||
} | } | ||||
DebugEcho() { | DebugEcho() { | ||||
$DEBUG_DO echo "$@" | $DEBUG_DO echo "$@" | ||||
} | } | ||||
## | |||||
# Debugging | |||||
# | |||||
# return 0 if we are debugging. | |||||
# | |||||
Debugging() { | Debugging() { | ||||
test "$DEBUG_SKIP" | test "$DEBUG_SKIP" | ||||
} | } | ||||
## | |||||
# DebugLog message | |||||
# | |||||
# Outout message with timestamp if we are debugging | |||||
# | |||||
DebugLog() { | DebugLog() { | ||||
$DEBUG_SKIP return 0 | $DEBUG_SKIP return 0 | ||||
echo `date '+@ %s [%Y-%m-%d %H:%M:%S %Z]'` "$@" | echo `date '+@ %s [%Y-%m-%d %H:%M:%S %Z]'` "$@" | ||||
} | } | ||||
# something hard to miss when wading through huge -x output | ## | ||||
# DebugTrace message | |||||
# | |||||
# Something hard to miss when wading through huge -x output | |||||
# | |||||
DebugTrace() { | DebugTrace() { | ||||
$DEBUG_SKIP return 0 | $DEBUG_SKIP return 0 | ||||
set +x | set +x | ||||
echo "@ ==================== [ $DEBUG_ON ] ====================" | echo "@ ==================== [ $DEBUG_ON ] ====================" | ||||
DebugLog "$@" | DebugLog "$@" | ||||
echo "@ ==================== [ $DEBUG_ON ] ====================" | echo "@ ==================== [ $DEBUG_ON ] ====================" | ||||
set -x | set -x | ||||
} | } | ||||
# Turn on debugging if appropriate | ## | ||||
# DebugOn [-e] [-o] match ... | |||||
# | |||||
# Turn on debugging if any $match is found in $DEBUG_SH. | |||||
# | |||||
DebugOn() { | DebugOn() { | ||||
eval ${local:-:} _e _match _off _rc | |||||
Done Inline ActionsSince you're using $local, should this script not sanity check $local somewhere? Something similar to the following perhaps? case "$local" in stevek: Since you're using $local, should this script not sanity check $local somewhere? Something… | |||||
Done Inline ActionsYes that's probably a good idea sjg: Yes that's probably a good idea | |||||
_rc=0 # avoid problems with set -e | _rc=0 # avoid problems with set -e | ||||
_off=: | _off=: | ||||
while : | while : | ||||
do | do | ||||
case "$1" in | case "$1" in | ||||
-e) _rc=1; shift;; # caller ok with return 1 | -e) _rc=1; shift;; # caller ok with return 1 | ||||
-o) _off=; shift;; # off unless we have a match | -o) _off=; shift;; # off unless we have a match | ||||
*) break;; | *) break;; | ||||
Show All 13 Lines | DebugOn() { | ||||
esac | esac | ||||
for _e in ${*:-$Myname} $_e | for _e in ${*:-$Myname} $_e | ||||
do | do | ||||
: $_e in ,${DEBUG_SH:-$DEBUG}, | : $_e in ,${DEBUG_SH:-$DEBUG}, | ||||
case ",${DEBUG_SH:-$DEBUG}," in | case ",${DEBUG_SH:-$DEBUG}," in | ||||
*,!$_e,*|*,!$Myname:$_e,*) | *,!$_e,*|*,!$Myname:$_e,*) | ||||
# only turn it off if it was on | # only turn it off if it was on | ||||
_rc=0 | _rc=0 | ||||
$DEBUG_DO _debugOff $_e $DEBUG_ON | $DEBUG_DO _debugOff $_e $DEBUG_ON $1 | ||||
break | break | ||||
;; | ;; | ||||
*,$_e,*|*,$Myname:$_e,*) | *,$_e,*|*,$Myname:$_e,*) | ||||
# only turn it on if it was off | # only turn it on if it was off | ||||
_rc=0 | _rc=0 | ||||
_match=$_e | _match=$_e | ||||
$DEBUG_SKIP _debugOn $_e | $DEBUG_SKIP _debugOn $_e $1 | ||||
break | break | ||||
;; | ;; | ||||
esac | esac | ||||
done | done | ||||
if test -z "$_off$_match"; then | if test -z "$_off$_match"; then | ||||
# off unless explicit match, but | # off unless explicit match, but | ||||
# only turn it off if it was on | # only turn it off if it was on | ||||
$DEBUG_DO _debugOff $_e $DEBUG_ON | $DEBUG_DO _debugOff $_e $DEBUG_ON $1 | ||||
fi | fi | ||||
DEBUGGING=$DEBUG_SKIP # backwards compatability | DEBUGGING=$DEBUG_SKIP # backwards compatability | ||||
$DEBUG_DO set -x # back on if needed | $DEBUG_DO set -x # back on if needed | ||||
$DEBUG_DO set -x # make sure we see it in trace | $DEBUG_DO set -x # make sure we see it in trace | ||||
return $_rc | return $_rc | ||||
} | } | ||||
## | |||||
# DebugOff [-e] [-o] [rc=$?] match ... | |||||
# | |||||
# Only turn debugging off if one of our args was the reason it | # Only turn debugging off if one of our args was the reason it | ||||
# was turned on. | # was turned on. | ||||
# | |||||
# We normally return 0, but caller can pass rc=$? as first arg | # We normally return 0, but caller can pass rc=$? as first arg | ||||
# so that we preserve the status of last statement. | # so that we preserve the status of last statement. | ||||
# | |||||
# The options '-e' and '-o' are ignored, they just make it easier to | |||||
# keep DebugOn and DebugOff lines in sync. | |||||
# | |||||
DebugOff() { | DebugOff() { | ||||
eval ${local:-:} _e _rc | |||||
case ",${DEBUG_SH:-$DEBUG}," in | case ",${DEBUG_SH:-$DEBUG}," in | ||||
*,[Dd]ebug,*) ;; | *,[Dd]ebug,*) ;; | ||||
*) $DEBUG_DO set +x;; # reduce the noise | *) $DEBUG_DO set +x;; # reduce the noise | ||||
esac | esac | ||||
_rc=0 # always happy | _rc=0 # always happy | ||||
while : | while : | ||||
do | do | ||||
case "$1" in | case "$1" in | ||||
-[eo]) shift;; # ignore it | -[eo]) shift;; # ignore it | ||||
rc=*) eval "_$1"; shift;; | rc=*) eval "_$1"; shift;; | ||||
*) break;; | *) break;; | ||||
esac | esac | ||||
done | done | ||||
for _e in $* | for _e in $* | ||||
do | do | ||||
: $_e==$DEBUG_OFF DEBUG_OFF | : $_e==$DEBUG_OFF DEBUG_OFF | ||||
case "$DEBUG_OFF" in | case "$DEBUG_OFF" in | ||||
"") break;; | "") break;; | ||||
$_e) _debugOn $DEBUG_ON; return $_rc;; | $_e) _debugOn $DEBUG_ON $1; return $_rc;; | ||||
esac | esac | ||||
done | done | ||||
for _e in $* | for _e in $* | ||||
do | do | ||||
: $_e==$DEBUG_ON DEBUG_ON | : $_e==$DEBUG_ON DEBUG_ON | ||||
case "$DEBUG_ON" in | case "$DEBUG_ON" in | ||||
"") break;; | "") break;; | ||||
$_e) _debugOff; return $_rc;; | $_e) _debugOff "" "" $1; return $_rc;; | ||||
esac | esac | ||||
done | done | ||||
DEBUGGING=$DEBUG_SKIP # backwards compatability | DEBUGGING=$DEBUG_SKIP # backwards compatability | ||||
$DEBUG_DO set -x # back on if needed | $DEBUG_DO set -x # back on if needed | ||||
$DEBUG_DO set -x # make sure we see it in trace | $DEBUG_DO set -x # make sure we see it in trace | ||||
return $_rc | return $_rc | ||||
} | } | ||||
_TTY=${_TTY:-`test -t 0 && tty`}; export _TTY | _TTY=${_TTY:-`test -t 0 && tty`}; export _TTY | ||||
# override this if you like | # override this if you like | ||||
_debugShell() { | _debugShell() { | ||||
test "x$_TTY" != x || return 0 | |||||
{ | { | ||||
echo DebugShell "$@" | echo DebugShell "$@" | ||||
echo "Type 'exit' to continue..." | echo "Type 'exit' to continue..." | ||||
} > $_TTY | } > $_TTY | ||||
${DEBUG_SHELL:-${SHELL:-/bin/sh}} < $_TTY > $_TTY 2>&1 | ${DEBUG_SHELL:-${SHELL:-/bin/sh}} < $_TTY > $_TTY 2>&1 | ||||
} | } | ||||
# Run an interactive shell if appropriate | # Run an interactive shell if appropriate | ||||
# Note: you can use $DEBUG_SKIP DebugShell ... to skip unless debugOn | # Note: you can use $DEBUG_SKIP DebugShell ... to skip unless debugOn | ||||
DebugShell() { | DebugShell() { | ||||
eval ${local:-:} _e | |||||
case "$_TTY%${DEBUG_INTERACTIVE}" in | case "$_TTY%${DEBUG_INTERACTIVE}" in | ||||
*%|%*) return 0;; # no tty or no spec | *%|%*) return 0;; # no tty or no spec | ||||
esac | esac | ||||
for _e in ${*:-$Myname} all | for _e in ${*:-$Myname} all | ||||
do | do | ||||
case ",${DEBUG_INTERACTIVE}," in | case ",${DEBUG_INTERACTIVE}," in | ||||
*,!$_e,*|*,!$Myname:$_e,*) | *,!$_e,*|*,!$Myname:$_e,*) | ||||
return 0 | return 0 | ||||
Show All 21 Lines |
Don't you need a dummy "hooks_run" somewhere in the case where dot hooks.sh was not done?