xref: /src/libexec/rc/debug.sh (revision d7922c3d2391c6db3dac77fa491d53e080162c79)
1aa3b7a2fSSimon J. Gerraty:
2aa3b7a2fSSimon J. Gerraty# NAME:
3aa3b7a2fSSimon J. Gerraty#	debug.sh - selectively debug scripts
4aa3b7a2fSSimon J. Gerraty#
5aa3b7a2fSSimon J. Gerraty# SYNOPSIS:
6aa3b7a2fSSimon J. Gerraty#	$_DEBUG_SH . debug.sh
7aa3b7a2fSSimon J. Gerraty#	DebugOn [-eo] "tag" ...
8aa3b7a2fSSimon J. Gerraty#	DebugOff [-eo] [rc="rc"] "tag" ...
9aa3b7a2fSSimon J. Gerraty#	Debugging
1002653835SSimon J. Gerraty#	DebugAdd "tag"
11aa3b7a2fSSimon J. Gerraty#	DebugEcho ...
12aa3b7a2fSSimon J. Gerraty#	DebugLog ...
13aa3b7a2fSSimon J. Gerraty#	DebugShell "tag" ...
14aa3b7a2fSSimon J. Gerraty#	DebugTrace ...
15aa3b7a2fSSimon J. Gerraty#	Debug "tag" ...
16aa3b7a2fSSimon J. Gerraty#
17aa3b7a2fSSimon J. Gerraty#	$DEBUG_SKIP echo skipped when Debug "tag" is true.
18aa3b7a2fSSimon J. Gerraty#	$DEBUG_DO echo only done when Debug "tag" is true.
19aa3b7a2fSSimon J. Gerraty#
20aa3b7a2fSSimon J. Gerraty# DESCRIPTION:
21aa3b7a2fSSimon J. Gerraty#	debug.sh provides the following functions to facilitate
22aa3b7a2fSSimon J. Gerraty#	flexible run-time tracing of complicated shell scripts.
23aa3b7a2fSSimon J. Gerraty#
24aa3b7a2fSSimon J. Gerraty#	DebugOn turns tracing on if any "tag" is found in "DEBUG_SH".
25aa3b7a2fSSimon J. Gerraty#	It turns tracing off if "!tag" is found in "DEBUG_SH".
26aa3b7a2fSSimon J. Gerraty#	It also sets "DEBUG_ON" to the "tag" that caused tracing to be
27aa3b7a2fSSimon J. Gerraty#	enabled, or "DEBUG_OFF" if we matched "!tag".
28aa3b7a2fSSimon J. Gerraty#	If '-e' option given returns 1 if no "tag" matched.
29aa3b7a2fSSimon J. Gerraty#	If the '-o' flag is given, tracing is turned off unless there
30aa3b7a2fSSimon J. Gerraty#	was a matched "tag", useful for functions too noisy to tace.
31aa3b7a2fSSimon J. Gerraty#
32a4e7810fSSimon J. Gerraty#	Further; when we set "DEBUG_ON" if we find
33a4e7810fSSimon J. Gerraty#	"$DEBUG_ON:debug_add:tag" in "DEBUG_SH" we will
34a4e7810fSSimon J. Gerraty#	add the new "tag" to "DEBUG_SH" so it only has effect after that
35a4e7810fSSimon J. Gerraty#	point.
36a4e7810fSSimon J. Gerraty#
37aa3b7a2fSSimon J. Gerraty#	DebugOff turns tracing on if any "tag" matches "DEBUG_OFF" or
38aa3b7a2fSSimon J. Gerraty#	off if any "tag" matches "DEBUG_ON". This allows nested
39aa3b7a2fSSimon J. Gerraty#	functions to not interfere with each other.
40aa3b7a2fSSimon J. Gerraty#
41aa3b7a2fSSimon J. Gerraty#	DebugOff accepts but ignores the '-e' and '-o' options.
42aa3b7a2fSSimon J. Gerraty#	The optional "rc" value will be returned rather than the
43aa3b7a2fSSimon J. Gerraty#	default of 0. Thus if DebugOff is the last operation in a
44aa3b7a2fSSimon J. Gerraty#	function, "rc" will be the return code of that function.
45aa3b7a2fSSimon J. Gerraty#
4602653835SSimon J. Gerraty#	DebugAdd allows adding a "tag" to "DEBUG_SH" to influence
4702653835SSimon J. Gerraty#	later events, possibly in a child process.
4802653835SSimon J. Gerraty#
49aa3b7a2fSSimon J. Gerraty#	DebugEcho is just shorthand for:
50aa3b7a2fSSimon J. Gerraty#.nf
51aa3b7a2fSSimon J. Gerraty#	$DEBUG_DO echo "$@"
52aa3b7a2fSSimon J. Gerraty#.fi
53aa3b7a2fSSimon J. Gerraty#
54aa3b7a2fSSimon J. Gerraty#	Debugging returns true if tracing is enabled.
55aa3b7a2fSSimon J. Gerraty#	It is useful for bounding complex debug actions, rather than
56aa3b7a2fSSimon J. Gerraty#	using lots of "DEBUG_DO" lines.
57aa3b7a2fSSimon J. Gerraty#
58aa3b7a2fSSimon J. Gerraty#	DebugShell runs an interactive shell if any "tag" is found in
59aa3b7a2fSSimon J. Gerraty#	"DEBUG_INTERACTIVE", and there is a tty available.
60aa3b7a2fSSimon J. Gerraty#	The shell used is defined by "DEBUG_SHELL" or "SHELL" and
61aa3b7a2fSSimon J. Gerraty#	defaults to '/bin/sh'.
62aa3b7a2fSSimon J. Gerraty#
63aa3b7a2fSSimon J. Gerraty#	Debug calls DebugOn and if that does not turn tracing on, it
64aa3b7a2fSSimon J. Gerraty#	calls DebugOff to turn it off.
65aa3b7a2fSSimon J. Gerraty#
66aa3b7a2fSSimon J. Gerraty#	The variables "DEBUG_SKIP" and "DEBUG_DO" are set so as to
67aa3b7a2fSSimon J. Gerraty#	enable/disable code that should be skipped/run when debugging
68aa3b7a2fSSimon J. Gerraty#	is turned on. "DEBUGGING" is the same as "DEBUG_SKIP" for
69aa3b7a2fSSimon J. Gerraty#	backwards compatability.
70aa3b7a2fSSimon J. Gerraty#
71aa3b7a2fSSimon J. Gerraty#	The use of $_DEBUG_SH is to prevent multiple inclusion, though
72aa3b7a2fSSimon J. Gerraty#	it does no harm in this case.
73aa3b7a2fSSimon J. Gerraty#
74aa3b7a2fSSimon J. Gerraty# BUGS:
75aa3b7a2fSSimon J. Gerraty#	Does not work with some versions of ksh.
76aa3b7a2fSSimon J. Gerraty#	If a function turns tracing on, ksh turns it off when the
77aa3b7a2fSSimon J. Gerraty#	function returns - useless.
78aa3b7a2fSSimon J. Gerraty#	PD ksh works ok ;-)
79aa3b7a2fSSimon J. Gerraty#
80aa3b7a2fSSimon J. Gerraty# AUTHOR:
81aa3b7a2fSSimon J. Gerraty#	Simon J. Gerraty <sjg@crufty.net>
82aa3b7a2fSSimon J. Gerraty
83aa3b7a2fSSimon J. Gerraty# RCSid:
845c4d1c85SSimon J. Gerraty#	$Id: debug.sh,v 1.47 2025/08/07 21:59:54 sjg Exp $
85aa3b7a2fSSimon J. Gerraty#
86aa3b7a2fSSimon J. Gerraty#	@(#) Copyright (c) 1994-2024 Simon J. Gerraty
87aa3b7a2fSSimon J. Gerraty#
885c4d1c85SSimon J. Gerraty#	SPDX-License-Identifier: BSD-2-Clause
89aa3b7a2fSSimon J. Gerraty#
90aa3b7a2fSSimon J. Gerraty#	Please send copies of changes and bug-fixes to:
91aa3b7a2fSSimon J. Gerraty#	sjg@crufty.net
92aa3b7a2fSSimon J. Gerraty#
93aa3b7a2fSSimon J. Gerraty
94aa3b7a2fSSimon J. Gerraty_DEBUG_SH=:
95aa3b7a2fSSimon J. Gerraty
96aa3b7a2fSSimon J. GerratyMyname=${Myname:-`basename $0 .sh`}
97aa3b7a2fSSimon J. Gerraty
98aa3b7a2fSSimon J. GerratyDEBUGGING=
99aa3b7a2fSSimon J. GerratyDEBUG_DO=:
100aa3b7a2fSSimon J. GerratyDEBUG_SKIP=
101aa3b7a2fSSimon J. Gerratyexport DEBUGGING DEBUG_DO DEBUG_SKIP
102aa3b7a2fSSimon J. Gerraty
103203027b2SSimon J. Gerraty# have is handy
104203027b2SSimon J. Gerratyif test -z "$_HAVE_SH"; then
105203027b2SSimon J. Gerraty	_HAVE_SH=:
106203027b2SSimon J. Gerraty
107203027b2SSimon J. Gerraty	##
108203027b2SSimon J. Gerraty	# have that does not rely on return code of type
109203027b2SSimon J. Gerraty	#
110203027b2SSimon J. Gerraty	have() {
111203027b2SSimon J. Gerraty		case `(type "$1") 2>&1` in
112203027b2SSimon J. Gerraty		*" found") return 1;;
113203027b2SSimon J. Gerraty		esac
114203027b2SSimon J. Gerraty		return 0
115203027b2SSimon J. Gerraty	}
116203027b2SSimon J. Gerratyfi
117203027b2SSimon J. Gerraty
118203027b2SSimon J. Gerraty# does local *actually* work?
119203027b2SSimon J. Gerratylocal_works() {
120203027b2SSimon J. Gerraty    local _fu
121203027b2SSimon J. Gerraty}
122203027b2SSimon J. Gerraty
123203027b2SSimon J. Gerratyif local_works > /dev/null 2>&1; then
124203027b2SSimon J. Gerraty    _local=local
125203027b2SSimon J. Gerratyelse
126203027b2SSimon J. Gerraty    _local=:
127203027b2SSimon J. Gerratyfi
128203027b2SSimon J. Gerraty# for backwards compatability
129203027b2SSimon J. Gerratylocal=$_local
130203027b2SSimon J. Gerraty
131203027b2SSimon J. Gerratyif test -z "$isPOSIX_SHELL"; then
132a4e7810fSSimon J. Gerraty	if (echo ${PATH%:*}) > /dev/null 2>&1; then
133a4e7810fSSimon J. Gerraty		# true should be a builtin, : certainly is
134a4e7810fSSimon J. Gerraty		isPOSIX_SHELL=:
135a4e7810fSSimon J. Gerraty	else
136a4e7810fSSimon J. Gerraty		isPOSIX_SHELL=false
137a4e7810fSSimon J. Gerraty		false() {
138a4e7810fSSimon J. Gerraty			return 1
139a4e7810fSSimon J. Gerraty		}
140a4e7810fSSimon J. Gerraty	fi
141203027b2SSimon J. Gerratyfi
142a4e7810fSSimon J. Gerraty
143a4e7810fSSimon J. Gerratyis_posix_shell() {
144a4e7810fSSimon J. Gerraty	$isPOSIX_SHELL
145a4e7810fSSimon J. Gerraty	return
146a4e7810fSSimon J. Gerraty}
147a4e7810fSSimon J. Gerraty
148a4e7810fSSimon J. Gerraty
149a4e7810fSSimon J. Gerraty##
150a4e7810fSSimon J. Gerraty# _debugAdd match
151a4e7810fSSimon J. Gerraty#
152a4e7810fSSimon J. Gerraty# Called from _debugOn when $match also appears in $DEBUG_SH with
153a4e7810fSSimon J. Gerraty# a suffix of :debug_add:tag we will add tag to DEBUG_SH
154a4e7810fSSimon J. Gerraty#
155a4e7810fSSimon J. Gerraty_debugAdd() {
156203027b2SSimon J. Gerraty	eval $_local tag
157a4e7810fSSimon J. Gerraty
158a4e7810fSSimon J. Gerraty	for tag in `IFS=,; echo $DEBUG_SH`
159a4e7810fSSimon J. Gerraty	do
160a4e7810fSSimon J. Gerraty		: tag=$tag
161a4e7810fSSimon J. Gerraty		case "$tag" in
162a4e7810fSSimon J. Gerraty		$1:debug_add:*)
163a4e7810fSSimon J. Gerraty			if is_posix_shell; then
164a4e7810fSSimon J. Gerraty				tag=${tag#$1:debug_add:}
165a4e7810fSSimon J. Gerraty			else
166a4e7810fSSimon J. Gerraty				tag=`expr $tag : '.*:debug_add:\(.*\)'`
167a4e7810fSSimon J. Gerraty			fi
168a4e7810fSSimon J. Gerraty			case ",$DEBUG_SH," in
169a4e7810fSSimon J. Gerraty			*,$tag,*) ;;
170a4e7810fSSimon J. Gerraty			*)	set -x
171a4e7810fSSimon J. Gerraty				: _debugAdd $1
172a4e7810fSSimon J. Gerraty				DEBUG_SH=$DEBUG_SH,$tag
173a4e7810fSSimon J. Gerraty				set +x
174a4e7810fSSimon J. Gerraty				;;
175a4e7810fSSimon J. Gerraty			esac
176a4e7810fSSimon J. Gerraty			;;
177a4e7810fSSimon J. Gerraty		esac
178a4e7810fSSimon J. Gerraty	done
179a4e7810fSSimon J. Gerraty	export DEBUG_SH
180a4e7810fSSimon J. Gerraty}
181a4e7810fSSimon J. Gerraty
182a4e7810fSSimon J. Gerraty
1837e1c014aSSimon J. Gerraty##
1847e1c014aSSimon J. Gerraty# _debugOn match first
1857e1c014aSSimon J. Gerraty#
1867e1c014aSSimon J. Gerraty# Actually turn on tracing, set $DEBUG_ON=$match
1877e1c014aSSimon J. Gerraty#
188a4e7810fSSimon J. Gerraty# Check if $DEBUG_SH contains $match:debug_add:* and call _debugAdd
189a4e7810fSSimon J. Gerraty# to add the suffix to DEBUG_SH.  This useful when we only want
190a4e7810fSSimon J. Gerraty# to trace some script when run under specific circumstances.
191a4e7810fSSimon J. Gerraty#
1927e1c014aSSimon J. Gerraty# If we have included hooks.sh $_HOOKS_SH will be set
1937e1c014aSSimon J. Gerraty# and if $first (the first arg to DebugOn) is suitable as a variable
1947e1c014aSSimon J. Gerraty# name we will run ${first}_debugOn_hooks.
1957e1c014aSSimon J. Gerraty#
1967e1c014aSSimon J. Gerraty# We disable tracing for hooks_run itself but functions can trace
1977e1c014aSSimon J. Gerraty# if they want based on DEBUG_DO
1987e1c014aSSimon J. Gerraty#
199aa3b7a2fSSimon J. Gerraty_debugOn() {
200aa3b7a2fSSimon J. Gerraty	DEBUG_OFF=
201aa3b7a2fSSimon J. Gerraty	DEBUG_DO=
202aa3b7a2fSSimon J. Gerraty	DEBUG_SKIP=:
203aa3b7a2fSSimon J. Gerraty	DEBUG_X=-x
204ab835b37SArtem Bunichev	# do this first to reduce noise
205a4e7810fSSimon J. Gerraty	case ",$DEBUG_SH," in
206a4e7810fSSimon J. Gerraty	*,$1:debug_add:*) _debugAdd $1;;
207a4e7810fSSimon J. Gerraty	*,$2:debug_add:*) _debugAdd $2;;
208a4e7810fSSimon J. Gerraty	esac
209aa3b7a2fSSimon J. Gerraty	set -x
210aa3b7a2fSSimon J. Gerraty	DEBUG_ON=$1
2117e1c014aSSimon J. Gerraty	case "$_HOOKS_SH,$2" in
2127e1c014aSSimon J. Gerraty	,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;;
2137e1c014aSSimon J. Gerraty	*)	# avoid noise from hooks_run
2147e1c014aSSimon J. Gerraty		set +x
2157e1c014aSSimon J. Gerraty		hooks_run ${2}_debugOn_hooks
2167e1c014aSSimon J. Gerraty		set -x
2177e1c014aSSimon J. Gerraty		;;
2187e1c014aSSimon J. Gerraty	esac
219aa3b7a2fSSimon J. Gerraty}
220aa3b7a2fSSimon J. Gerraty
2217e1c014aSSimon J. Gerraty##
2227e1c014aSSimon J. Gerraty# _debugOff match $DEBUG_ON $first
2237e1c014aSSimon J. Gerraty#
2247e1c014aSSimon J. Gerraty# Actually turn off tracing, set $DEBUG_OFF=$match
2257e1c014aSSimon J. Gerraty#
2267e1c014aSSimon J. Gerraty# If we have included hooks.sh $_HOOKS_SH will be set
2277e1c014aSSimon J. Gerraty# and if $first (the first arg to DebugOff) is suitable as a variable
2287e1c014aSSimon J. Gerraty# name we will run ${first}_debugOff_hooks.
2297e1c014aSSimon J. Gerraty#
2307e1c014aSSimon J. Gerraty# We do hooks_run after turning off tracing, but before resetting
2317e1c014aSSimon J. Gerraty# DEBUG_DO so functions can trace if they want
2327e1c014aSSimon J. Gerraty#
233aa3b7a2fSSimon J. Gerraty_debugOff() {
234aa3b7a2fSSimon J. Gerraty	DEBUG_OFF=$1
235aa3b7a2fSSimon J. Gerraty	set +x
2367e1c014aSSimon J. Gerraty	case "$_HOOKS_SH,$3" in
2377e1c014aSSimon J. Gerraty	,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;;
2387e1c014aSSimon J. Gerraty	*)	hooks_run ${3}_debugOff_hooks;;
2397e1c014aSSimon J. Gerraty	esac
2407e1c014aSSimon J. Gerraty	set +x			# just to be sure
241aa3b7a2fSSimon J. Gerraty	DEBUG_ON=$2
242aa3b7a2fSSimon J. Gerraty	DEBUG_DO=:
243aa3b7a2fSSimon J. Gerraty	DEBUG_SKIP=
244aa3b7a2fSSimon J. Gerraty	DEBUG_X=
245aa3b7a2fSSimon J. Gerraty}
246aa3b7a2fSSimon J. Gerraty
24702653835SSimon J. Gerraty##
24802653835SSimon J. Gerraty# DebugAdd tag
24902653835SSimon J. Gerraty#
25002653835SSimon J. Gerraty# Add tag to DEBUG_SH
25102653835SSimon J. Gerraty#
25202653835SSimon J. GerratyDebugAdd() {
25302653835SSimon J. Gerraty        DEBUG_SH=${DEBUG_SH:+$DEBUG_SH,}$1
25402653835SSimon J. Gerraty        export DEBUG_SH
25502653835SSimon J. Gerraty}
25602653835SSimon J. Gerraty
25702653835SSimon J. Gerraty##
25802653835SSimon J. Gerraty# DebugEcho message
25902653835SSimon J. Gerraty#
26002653835SSimon J. Gerraty# Output message if we are debugging
26102653835SSimon J. Gerraty#
262aa3b7a2fSSimon J. GerratyDebugEcho() {
263aa3b7a2fSSimon J. Gerraty	$DEBUG_DO echo "$@"
264aa3b7a2fSSimon J. Gerraty}
265aa3b7a2fSSimon J. Gerraty
2667e1c014aSSimon J. Gerraty##
2677e1c014aSSimon J. Gerraty# Debugging
2687e1c014aSSimon J. Gerraty#
2697e1c014aSSimon J. Gerraty# return 0 if we are debugging.
2707e1c014aSSimon J. Gerraty#
271aa3b7a2fSSimon J. GerratyDebugging() {
272aa3b7a2fSSimon J. Gerraty	test "$DEBUG_SKIP"
273aa3b7a2fSSimon J. Gerraty}
274aa3b7a2fSSimon J. Gerraty
2757e1c014aSSimon J. Gerraty##
2767e1c014aSSimon J. Gerraty# DebugLog message
2777e1c014aSSimon J. Gerraty#
2787e1c014aSSimon J. Gerraty# Outout message with timestamp if we are debugging
2797e1c014aSSimon J. Gerraty#
280aa3b7a2fSSimon J. GerratyDebugLog() {
281aa3b7a2fSSimon J. Gerraty	$DEBUG_SKIP return 0
282aa3b7a2fSSimon J. Gerraty	echo `date '+@ %s [%Y-%m-%d %H:%M:%S %Z]'` "$@"
283aa3b7a2fSSimon J. Gerraty}
284aa3b7a2fSSimon J. Gerraty
2857e1c014aSSimon J. Gerraty##
2867e1c014aSSimon J. Gerraty# DebugTrace message
2877e1c014aSSimon J. Gerraty#
2887e1c014aSSimon J. Gerraty# Something hard to miss when wading through huge -x output
2897e1c014aSSimon J. Gerraty#
290aa3b7a2fSSimon J. GerratyDebugTrace() {
291aa3b7a2fSSimon J. Gerraty	$DEBUG_SKIP return 0
292aa3b7a2fSSimon J. Gerraty	set +x
293aa3b7a2fSSimon J. Gerraty	echo "@ ==================== [ $DEBUG_ON ] ===================="
294aa3b7a2fSSimon J. Gerraty	DebugLog "$@"
295aa3b7a2fSSimon J. Gerraty	echo "@ ==================== [ $DEBUG_ON ] ===================="
296aa3b7a2fSSimon J. Gerraty	set -x
297aa3b7a2fSSimon J. Gerraty}
298aa3b7a2fSSimon J. Gerraty
2997e1c014aSSimon J. Gerraty##
3007e1c014aSSimon J. Gerraty# DebugOn [-e] [-o] match ...
3017e1c014aSSimon J. Gerraty#
3027e1c014aSSimon J. Gerraty# Turn on debugging if any $match is found in $DEBUG_SH.
3037e1c014aSSimon J. Gerraty#
304aa3b7a2fSSimon J. GerratyDebugOn() {
3057e1c014aSSimon J. Gerraty	eval ${local:-:} _e _match _off _rc
306aa3b7a2fSSimon J. Gerraty	_rc=0			# avoid problems with set -e
307aa3b7a2fSSimon J. Gerraty	_off=:
308aa3b7a2fSSimon J. Gerraty	while :
309aa3b7a2fSSimon J. Gerraty	do
310aa3b7a2fSSimon J. Gerraty		case "$1" in
311aa3b7a2fSSimon J. Gerraty		-e) _rc=1; shift;; # caller ok with return 1
312aa3b7a2fSSimon J. Gerraty		-o) _off=; shift;; # off unless we have a match
313aa3b7a2fSSimon J. Gerraty		*) break;;
314aa3b7a2fSSimon J. Gerraty		esac
315aa3b7a2fSSimon J. Gerraty	done
316aa3b7a2fSSimon J. Gerraty	case ",${DEBUG_SH:-$DEBUG}," in
317aa3b7a2fSSimon J. Gerraty	,,)	return $_rc;;
318aa3b7a2fSSimon J. Gerraty	*,[Dd]ebug,*) ;;
319aa3b7a2fSSimon J. Gerraty	*) $DEBUG_DO set +x;;		# reduce the noise
320aa3b7a2fSSimon J. Gerraty	esac
321aa3b7a2fSSimon J. Gerraty	_match=
322aa3b7a2fSSimon J. Gerraty	# if debugging is off because of a !e
323aa3b7a2fSSimon J. Gerraty	# don't add 'all' to the On list.
324aa3b7a2fSSimon J. Gerraty	case "$_off$DEBUG_OFF" in
325aa3b7a2fSSimon J. Gerraty	:)	_e=all;;
326aa3b7a2fSSimon J. Gerraty	*)	_e=;;
327aa3b7a2fSSimon J. Gerraty	esac
328aa3b7a2fSSimon J. Gerraty	for _e in ${*:-$Myname} $_e
329aa3b7a2fSSimon J. Gerraty	do
330aa3b7a2fSSimon J. Gerraty		: $_e in ,${DEBUG_SH:-$DEBUG},
331aa3b7a2fSSimon J. Gerraty		case ",${DEBUG_SH:-$DEBUG}," in
332aa3b7a2fSSimon J. Gerraty		*,!$_e,*|*,!$Myname:$_e,*)
333aa3b7a2fSSimon J. Gerraty			# only turn it off if it was on
334aa3b7a2fSSimon J. Gerraty			_rc=0
3357e1c014aSSimon J. Gerraty			$DEBUG_DO _debugOff $_e $DEBUG_ON $1
336aa3b7a2fSSimon J. Gerraty			break
337aa3b7a2fSSimon J. Gerraty			;;
338aa3b7a2fSSimon J. Gerraty		*,$_e,*|*,$Myname:$_e,*)
339aa3b7a2fSSimon J. Gerraty			# only turn it on if it was off
340aa3b7a2fSSimon J. Gerraty			_rc=0
341aa3b7a2fSSimon J. Gerraty			_match=$_e
3427e1c014aSSimon J. Gerraty			$DEBUG_SKIP _debugOn $_e $1
343aa3b7a2fSSimon J. Gerraty			break
344aa3b7a2fSSimon J. Gerraty			;;
345aa3b7a2fSSimon J. Gerraty		esac
346aa3b7a2fSSimon J. Gerraty	done
347aa3b7a2fSSimon J. Gerraty	if test -z "$_off$_match"; then
348aa3b7a2fSSimon J. Gerraty		# off unless explicit match, but
349aa3b7a2fSSimon J. Gerraty		# only turn it off if it was on
3507e1c014aSSimon J. Gerraty		$DEBUG_DO _debugOff $_e $DEBUG_ON $1
351aa3b7a2fSSimon J. Gerraty	fi
352aa3b7a2fSSimon J. Gerraty	DEBUGGING=$DEBUG_SKIP	# backwards compatability
353aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# back on if needed
354aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# make sure we see it in trace
355aa3b7a2fSSimon J. Gerraty	return $_rc
356aa3b7a2fSSimon J. Gerraty}
357aa3b7a2fSSimon J. Gerraty
3587e1c014aSSimon J. Gerraty##
3597e1c014aSSimon J. Gerraty# DebugOff [-e] [-o] [rc=$?] match ...
3607e1c014aSSimon J. Gerraty#
361aa3b7a2fSSimon J. Gerraty# Only turn debugging off if one of our args was the reason it
362aa3b7a2fSSimon J. Gerraty# was turned on.
3637e1c014aSSimon J. Gerraty#
364aa3b7a2fSSimon J. Gerraty# We normally return 0, but caller can pass rc=$? as first arg
365aa3b7a2fSSimon J. Gerraty# so that we preserve the status of last statement.
3667e1c014aSSimon J. Gerraty#
3677e1c014aSSimon J. Gerraty# The options '-e' and '-o' are ignored, they just make it easier to
3687e1c014aSSimon J. Gerraty# keep DebugOn and DebugOff lines in sync.
3697e1c014aSSimon J. Gerraty#
370aa3b7a2fSSimon J. GerratyDebugOff() {
3717e1c014aSSimon J. Gerraty	eval ${local:-:} _e _rc
372aa3b7a2fSSimon J. Gerraty	case ",${DEBUG_SH:-$DEBUG}," in
373aa3b7a2fSSimon J. Gerraty	*,[Dd]ebug,*) ;;
374aa3b7a2fSSimon J. Gerraty	*) $DEBUG_DO set +x;;		# reduce the noise
375aa3b7a2fSSimon J. Gerraty	esac
376aa3b7a2fSSimon J. Gerraty	_rc=0			# always happy
377aa3b7a2fSSimon J. Gerraty	while :
378aa3b7a2fSSimon J. Gerraty	do
379aa3b7a2fSSimon J. Gerraty		case "$1" in
380aa3b7a2fSSimon J. Gerraty		-[eo]) shift;;	# ignore it
381aa3b7a2fSSimon J. Gerraty		rc=*) eval "_$1"; shift;;
382aa3b7a2fSSimon J. Gerraty		*) break;;
383aa3b7a2fSSimon J. Gerraty		esac
384aa3b7a2fSSimon J. Gerraty	done
385aa3b7a2fSSimon J. Gerraty	for _e in $*
386aa3b7a2fSSimon J. Gerraty	do
387aa3b7a2fSSimon J. Gerraty		: $_e==$DEBUG_OFF DEBUG_OFF
388aa3b7a2fSSimon J. Gerraty		case "$DEBUG_OFF" in
389aa3b7a2fSSimon J. Gerraty		"")	break;;
3907e1c014aSSimon J. Gerraty		$_e)	_debugOn $DEBUG_ON $1; return $_rc;;
391aa3b7a2fSSimon J. Gerraty		esac
392aa3b7a2fSSimon J. Gerraty	done
393aa3b7a2fSSimon J. Gerraty	for _e in $*
394aa3b7a2fSSimon J. Gerraty	do
395aa3b7a2fSSimon J. Gerraty		: $_e==$DEBUG_ON DEBUG_ON
396aa3b7a2fSSimon J. Gerraty		case "$DEBUG_ON" in
397aa3b7a2fSSimon J. Gerraty		"")	break;;
3987e1c014aSSimon J. Gerraty		$_e)	_debugOff "" "" $1; return $_rc;;
399aa3b7a2fSSimon J. Gerraty		esac
400aa3b7a2fSSimon J. Gerraty	done
401aa3b7a2fSSimon J. Gerraty	DEBUGGING=$DEBUG_SKIP	# backwards compatability
402aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# back on if needed
403aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# make sure we see it in trace
404aa3b7a2fSSimon J. Gerraty	return $_rc
405aa3b7a2fSSimon J. Gerraty}
406aa3b7a2fSSimon J. Gerraty
407aa3b7a2fSSimon J. Gerraty_TTY=${_TTY:-`test -t 0 && tty`}; export _TTY
408aa3b7a2fSSimon J. Gerraty
409aa3b7a2fSSimon J. Gerraty# override this if you like
410aa3b7a2fSSimon J. Gerraty_debugShell() {
4117e1c014aSSimon J. Gerraty	test "x$_TTY" != x || return 0
412aa3b7a2fSSimon J. Gerraty	{
413aa3b7a2fSSimon J. Gerraty		echo DebugShell "$@"
414aa3b7a2fSSimon J. Gerraty		echo "Type 'exit' to continue..."
415aa3b7a2fSSimon J. Gerraty	} > $_TTY
416aa3b7a2fSSimon J. Gerraty	${DEBUG_SHELL:-${SHELL:-/bin/sh}} < $_TTY > $_TTY 2>&1
417aa3b7a2fSSimon J. Gerraty}
418aa3b7a2fSSimon J. Gerraty
419aa3b7a2fSSimon J. Gerraty# Run an interactive shell if appropriate
420aa3b7a2fSSimon J. Gerraty# Note: you can use $DEBUG_SKIP DebugShell ... to skip unless debugOn
421aa3b7a2fSSimon J. GerratyDebugShell() {
4227e1c014aSSimon J. Gerraty	eval ${local:-:} _e
423aa3b7a2fSSimon J. Gerraty	case "$_TTY%${DEBUG_INTERACTIVE}" in
424aa3b7a2fSSimon J. Gerraty	*%|%*) return 0;;	# no tty or no spec
425aa3b7a2fSSimon J. Gerraty	esac
426aa3b7a2fSSimon J. Gerraty	for _e in ${*:-$Myname} all
427aa3b7a2fSSimon J. Gerraty	do
428aa3b7a2fSSimon J. Gerraty		case ",${DEBUG_INTERACTIVE}," in
429aa3b7a2fSSimon J. Gerraty		*,!$_e,*|*,!$Myname:$_e,*)
430aa3b7a2fSSimon J. Gerraty			return 0
431aa3b7a2fSSimon J. Gerraty			;;
432aa3b7a2fSSimon J. Gerraty		*,$_e,*|*,$Myname:$_e,*)
433aa3b7a2fSSimon J. Gerraty			# Provide clues as to why/where
434aa3b7a2fSSimon J. Gerraty			_debugShell "$_e: $@"
435aa3b7a2fSSimon J. Gerraty			return $?
436aa3b7a2fSSimon J. Gerraty			;;
437aa3b7a2fSSimon J. Gerraty		esac
438aa3b7a2fSSimon J. Gerraty	done
439aa3b7a2fSSimon J. Gerraty	return 0
440aa3b7a2fSSimon J. Gerraty}
441aa3b7a2fSSimon J. Gerraty
442*d7922c3dSKalevi Kolttonen# For backwards compatibility
443aa3b7a2fSSimon J. GerratyDebug() {
444aa3b7a2fSSimon J. Gerraty	case "${DEBUG_SH:-$DEBUG}" in
445aa3b7a2fSSimon J. Gerraty	"")	;;
446aa3b7a2fSSimon J. Gerraty	*)	DEBUG_ON=${DEBUG_ON:-_Debug}
447aa3b7a2fSSimon J. Gerraty		DebugOn -e $* || DebugOff $DEBUG_LAST
448aa3b7a2fSSimon J. Gerraty		DEBUGGING=$DEBUG_SKIP
449aa3b7a2fSSimon J. Gerraty		;;
450aa3b7a2fSSimon J. Gerraty	esac
451aa3b7a2fSSimon J. Gerraty}
452