xref: /freebsd/libexec/rc/debug.sh (revision a4e7810f71376ee43c47b6b092d11e582c80fe9d)
1aa3b7a2fSSimon J. Gerraty:
2aa3b7a2fSSimon J. Gerraty# SPDX-License-Identifier: BSD-2-Clause
3aa3b7a2fSSimon J. Gerraty
4aa3b7a2fSSimon J. Gerraty# NAME:
5aa3b7a2fSSimon J. Gerraty#	debug.sh - selectively debug scripts
6aa3b7a2fSSimon J. Gerraty#
7aa3b7a2fSSimon J. Gerraty# SYNOPSIS:
8aa3b7a2fSSimon J. Gerraty#	$_DEBUG_SH . debug.sh
9aa3b7a2fSSimon J. Gerraty#	DebugOn [-eo] "tag" ...
10aa3b7a2fSSimon J. Gerraty#	DebugOff [-eo] [rc="rc"] "tag" ...
11aa3b7a2fSSimon J. Gerraty#	Debugging
1202653835SSimon J. Gerraty#	DebugAdd "tag"
13aa3b7a2fSSimon J. Gerraty#	DebugEcho ...
14aa3b7a2fSSimon J. Gerraty#	DebugLog ...
15aa3b7a2fSSimon J. Gerraty#	DebugShell "tag" ...
16aa3b7a2fSSimon J. Gerraty#	DebugTrace ...
17aa3b7a2fSSimon J. Gerraty#	Debug "tag" ...
18aa3b7a2fSSimon J. Gerraty#
19aa3b7a2fSSimon J. Gerraty#	$DEBUG_SKIP echo skipped when Debug "tag" is true.
20aa3b7a2fSSimon J. Gerraty#	$DEBUG_DO echo only done when Debug "tag" is true.
21aa3b7a2fSSimon J. Gerraty#
22aa3b7a2fSSimon J. Gerraty# DESCRIPTION:
23aa3b7a2fSSimon J. Gerraty#	debug.sh provides the following functions to facilitate
24aa3b7a2fSSimon J. Gerraty#	flexible run-time tracing of complicated shell scripts.
25aa3b7a2fSSimon J. Gerraty#
26aa3b7a2fSSimon J. Gerraty#	DebugOn turns tracing on if any "tag" is found in "DEBUG_SH".
27aa3b7a2fSSimon J. Gerraty#	It turns tracing off if "!tag" is found in "DEBUG_SH".
28aa3b7a2fSSimon J. Gerraty#	It also sets "DEBUG_ON" to the "tag" that caused tracing to be
29aa3b7a2fSSimon J. Gerraty#	enabled, or "DEBUG_OFF" if we matched "!tag".
30aa3b7a2fSSimon J. Gerraty#	If '-e' option given returns 1 if no "tag" matched.
31aa3b7a2fSSimon J. Gerraty#	If the '-o' flag is given, tracing is turned off unless there
32aa3b7a2fSSimon J. Gerraty#	was a matched "tag", useful for functions too noisy to tace.
33aa3b7a2fSSimon J. Gerraty#
34*a4e7810fSSimon J. Gerraty#	Further; when we set "DEBUG_ON" if we find
35*a4e7810fSSimon J. Gerraty#	"$DEBUG_ON:debug_add:tag" in "DEBUG_SH" we will
36*a4e7810fSSimon J. Gerraty#	add the new "tag" to "DEBUG_SH" so it only has effect after that
37*a4e7810fSSimon J. Gerraty#	point.
38*a4e7810fSSimon J. Gerraty#
39aa3b7a2fSSimon J. Gerraty#	DebugOff turns tracing on if any "tag" matches "DEBUG_OFF" or
40aa3b7a2fSSimon J. Gerraty#	off if any "tag" matches "DEBUG_ON". This allows nested
41aa3b7a2fSSimon J. Gerraty#	functions to not interfere with each other.
42aa3b7a2fSSimon J. Gerraty#
43aa3b7a2fSSimon J. Gerraty#	DebugOff accepts but ignores the '-e' and '-o' options.
44aa3b7a2fSSimon J. Gerraty#	The optional "rc" value will be returned rather than the
45aa3b7a2fSSimon J. Gerraty#	default of 0. Thus if DebugOff is the last operation in a
46aa3b7a2fSSimon J. Gerraty#	function, "rc" will be the return code of that function.
47aa3b7a2fSSimon J. Gerraty#
4802653835SSimon J. Gerraty#	DebugAdd allows adding a "tag" to "DEBUG_SH" to influence
4902653835SSimon J. Gerraty#	later events, possibly in a child process.
5002653835SSimon J. Gerraty#
51aa3b7a2fSSimon J. Gerraty#	DebugEcho is just shorthand for:
52aa3b7a2fSSimon J. Gerraty#.nf
53aa3b7a2fSSimon J. Gerraty#	$DEBUG_DO echo "$@"
54aa3b7a2fSSimon J. Gerraty#.fi
55aa3b7a2fSSimon J. Gerraty#
56aa3b7a2fSSimon J. Gerraty#	Debugging returns true if tracing is enabled.
57aa3b7a2fSSimon J. Gerraty#	It is useful for bounding complex debug actions, rather than
58aa3b7a2fSSimon J. Gerraty#	using lots of "DEBUG_DO" lines.
59aa3b7a2fSSimon J. Gerraty#
60aa3b7a2fSSimon J. Gerraty#	DebugShell runs an interactive shell if any "tag" is found in
61aa3b7a2fSSimon J. Gerraty#	"DEBUG_INTERACTIVE", and there is a tty available.
62aa3b7a2fSSimon J. Gerraty#	The shell used is defined by "DEBUG_SHELL" or "SHELL" and
63aa3b7a2fSSimon J. Gerraty#	defaults to '/bin/sh'.
64aa3b7a2fSSimon J. Gerraty#
65aa3b7a2fSSimon J. Gerraty#	Debug calls DebugOn and if that does not turn tracing on, it
66aa3b7a2fSSimon J. Gerraty#	calls DebugOff to turn it off.
67aa3b7a2fSSimon J. Gerraty#
68aa3b7a2fSSimon J. Gerraty#	The variables "DEBUG_SKIP" and "DEBUG_DO" are set so as to
69aa3b7a2fSSimon J. Gerraty#	enable/disable code that should be skipped/run when debugging
70aa3b7a2fSSimon J. Gerraty#	is turned on. "DEBUGGING" is the same as "DEBUG_SKIP" for
71aa3b7a2fSSimon J. Gerraty#	backwards compatability.
72aa3b7a2fSSimon J. Gerraty#
73aa3b7a2fSSimon J. Gerraty#	The use of $_DEBUG_SH is to prevent multiple inclusion, though
74aa3b7a2fSSimon J. Gerraty#	it does no harm in this case.
75aa3b7a2fSSimon J. Gerraty#
76aa3b7a2fSSimon J. Gerraty# BUGS:
77aa3b7a2fSSimon J. Gerraty#	Does not work with some versions of ksh.
78aa3b7a2fSSimon J. Gerraty#	If a function turns tracing on, ksh turns it off when the
79aa3b7a2fSSimon J. Gerraty#	function returns - useless.
80aa3b7a2fSSimon J. Gerraty#	PD ksh works ok ;-)
81aa3b7a2fSSimon J. Gerraty#
82aa3b7a2fSSimon J. Gerraty# AUTHOR:
83aa3b7a2fSSimon J. Gerraty#	Simon J. Gerraty <sjg@crufty.net>
84aa3b7a2fSSimon J. Gerraty
85aa3b7a2fSSimon J. Gerraty# RCSid:
86*a4e7810fSSimon J. Gerraty#	$Id: debug.sh,v 1.42 2024/10/30 18:23:19 sjg Exp $
87aa3b7a2fSSimon J. Gerraty#
88aa3b7a2fSSimon J. Gerraty#	@(#) Copyright (c) 1994-2024 Simon J. Gerraty
89aa3b7a2fSSimon J. Gerraty#
90aa3b7a2fSSimon J. Gerraty#	This file is provided in the hope that it will
91aa3b7a2fSSimon J. Gerraty#	be of use.  There is absolutely NO WARRANTY.
92aa3b7a2fSSimon J. Gerraty#	Permission to copy, redistribute or otherwise
93aa3b7a2fSSimon J. Gerraty#	use this file is hereby granted provided that
94aa3b7a2fSSimon J. Gerraty#	the above copyright notice and this notice are
95aa3b7a2fSSimon J. Gerraty#	left intact.
96aa3b7a2fSSimon J. Gerraty#
97aa3b7a2fSSimon J. Gerraty#	Please send copies of changes and bug-fixes to:
98aa3b7a2fSSimon J. Gerraty#	sjg@crufty.net
99aa3b7a2fSSimon J. Gerraty#
100aa3b7a2fSSimon J. Gerraty
101aa3b7a2fSSimon J. Gerraty_DEBUG_SH=:
102aa3b7a2fSSimon J. Gerraty
103aa3b7a2fSSimon J. GerratyMyname=${Myname:-`basename $0 .sh`}
104aa3b7a2fSSimon J. Gerraty
105aa3b7a2fSSimon J. GerratyDEBUGGING=
106aa3b7a2fSSimon J. GerratyDEBUG_DO=:
107aa3b7a2fSSimon J. GerratyDEBUG_SKIP=
108aa3b7a2fSSimon J. Gerratyexport DEBUGGING DEBUG_DO DEBUG_SKIP
109aa3b7a2fSSimon J. Gerraty
110*a4e7810fSSimon J. Gerratycase "$isPOSIX_SHELL,$local" in
111*a4e7810fSSimon J. Gerraty:,:|:,local|false,:) ;;		# sane
112*a4e7810fSSimon J. Gerraty*)	# this is the bulk of isposix-shell.sh
113*a4e7810fSSimon J. Gerraty	if (echo ${PATH%:*}) > /dev/null 2>&1; then
114*a4e7810fSSimon J. Gerraty		# true should be a builtin, : certainly is
115*a4e7810fSSimon J. Gerraty		isPOSIX_SHELL=:
116*a4e7810fSSimon J. Gerraty		# you need to eval $local var
117*a4e7810fSSimon J. Gerraty		local=local
118*a4e7810fSSimon J. Gerraty		: KSH_VERSION=$KSH_VERSION
119*a4e7810fSSimon J. Gerraty		case "$KSH_VERSION" in
120*a4e7810fSSimon J. Gerraty		Version*) local=: ;; # broken
121*a4e7810fSSimon J. Gerraty		esac
122*a4e7810fSSimon J. Gerraty	else
123*a4e7810fSSimon J. Gerraty		isPOSIX_SHELL=false
124*a4e7810fSSimon J. Gerraty		local=:
125*a4e7810fSSimon J. Gerraty		false() {
126*a4e7810fSSimon J. Gerraty			return 1
127*a4e7810fSSimon J. Gerraty		}
128*a4e7810fSSimon J. Gerraty	fi
129*a4e7810fSSimon J. Gerraty	;;
130*a4e7810fSSimon J. Gerratyesac
131*a4e7810fSSimon J. Gerraty
132*a4e7810fSSimon J. Gerratyis_posix_shell() {
133*a4e7810fSSimon J. Gerraty	$isPOSIX_SHELL
134*a4e7810fSSimon J. Gerraty	return
135*a4e7810fSSimon J. Gerraty}
136*a4e7810fSSimon J. Gerraty
137*a4e7810fSSimon J. Gerraty
138*a4e7810fSSimon J. Gerraty##
139*a4e7810fSSimon J. Gerraty# _debugAdd match
140*a4e7810fSSimon J. Gerraty#
141*a4e7810fSSimon J. Gerraty# Called from _debugOn when $match also appears in $DEBUG_SH with
142*a4e7810fSSimon J. Gerraty# a suffix of :debug_add:tag we will add tag to DEBUG_SH
143*a4e7810fSSimon J. Gerraty#
144*a4e7810fSSimon J. Gerraty_debugAdd() {
145*a4e7810fSSimon J. Gerraty	eval $local tag
146*a4e7810fSSimon J. Gerraty
147*a4e7810fSSimon J. Gerraty	for tag in `IFS=,; echo $DEBUG_SH`
148*a4e7810fSSimon J. Gerraty	do
149*a4e7810fSSimon J. Gerraty		: tag=$tag
150*a4e7810fSSimon J. Gerraty		case "$tag" in
151*a4e7810fSSimon J. Gerraty		$1:debug_add:*)
152*a4e7810fSSimon J. Gerraty			if is_posix_shell; then
153*a4e7810fSSimon J. Gerraty				tag=${tag#$1:debug_add:}
154*a4e7810fSSimon J. Gerraty			else
155*a4e7810fSSimon J. Gerraty				tag=`expr $tag : '.*:debug_add:\(.*\)'`
156*a4e7810fSSimon J. Gerraty			fi
157*a4e7810fSSimon J. Gerraty			case ",$DEBUG_SH," in
158*a4e7810fSSimon J. Gerraty			*,$tag,*) ;;
159*a4e7810fSSimon J. Gerraty			*)	set -x
160*a4e7810fSSimon J. Gerraty				: _debugAdd $1
161*a4e7810fSSimon J. Gerraty				DEBUG_SH=$DEBUG_SH,$tag
162*a4e7810fSSimon J. Gerraty				set +x
163*a4e7810fSSimon J. Gerraty				;;
164*a4e7810fSSimon J. Gerraty			esac
165*a4e7810fSSimon J. Gerraty			;;
166*a4e7810fSSimon J. Gerraty		esac
167*a4e7810fSSimon J. Gerraty	done
168*a4e7810fSSimon J. Gerraty	export DEBUG_SH
169*a4e7810fSSimon J. Gerraty}
170*a4e7810fSSimon J. Gerraty
171*a4e7810fSSimon J. Gerraty
1727e1c014aSSimon J. Gerraty##
1737e1c014aSSimon J. Gerraty# _debugOn match first
1747e1c014aSSimon J. Gerraty#
1757e1c014aSSimon J. Gerraty# Actually turn on tracing, set $DEBUG_ON=$match
1767e1c014aSSimon J. Gerraty#
177*a4e7810fSSimon J. Gerraty# Check if $DEBUG_SH contains $match:debug_add:* and call _debugAdd
178*a4e7810fSSimon J. Gerraty# to add the suffix to DEBUG_SH.  This useful when we only want
179*a4e7810fSSimon J. Gerraty# to trace some script when run under specific circumstances.
180*a4e7810fSSimon J. Gerraty#
1817e1c014aSSimon J. Gerraty# If we have included hooks.sh $_HOOKS_SH will be set
1827e1c014aSSimon J. Gerraty# and if $first (the first arg to DebugOn) is suitable as a variable
1837e1c014aSSimon J. Gerraty# name we will run ${first}_debugOn_hooks.
1847e1c014aSSimon J. Gerraty#
1857e1c014aSSimon J. Gerraty# We disable tracing for hooks_run itself but functions can trace
1867e1c014aSSimon J. Gerraty# if they want based on DEBUG_DO
1877e1c014aSSimon J. Gerraty#
188aa3b7a2fSSimon J. Gerraty_debugOn() {
189aa3b7a2fSSimon J. Gerraty	DEBUG_OFF=
190aa3b7a2fSSimon J. Gerraty	DEBUG_DO=
191aa3b7a2fSSimon J. Gerraty	DEBUG_SKIP=:
192aa3b7a2fSSimon J. Gerraty	DEBUG_X=-x
193*a4e7810fSSimon J. Gerraty	# do this firt to reduce noise
194*a4e7810fSSimon J. Gerraty	case ",$DEBUG_SH," in
195*a4e7810fSSimon J. Gerraty	*,$1:debug_add:*) _debugAdd $1;;
196*a4e7810fSSimon J. Gerraty	*,$2:debug_add:*) _debugAdd $2;;
197*a4e7810fSSimon J. Gerraty	esac
198aa3b7a2fSSimon J. Gerraty	set -x
199aa3b7a2fSSimon J. Gerraty	DEBUG_ON=$1
2007e1c014aSSimon J. Gerraty	case "$_HOOKS_SH,$2" in
2017e1c014aSSimon J. Gerraty	,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;;
2027e1c014aSSimon J. Gerraty	*)	# avoid noise from hooks_run
2037e1c014aSSimon J. Gerraty		set +x
2047e1c014aSSimon J. Gerraty		hooks_run ${2}_debugOn_hooks
2057e1c014aSSimon J. Gerraty		set -x
2067e1c014aSSimon J. Gerraty		;;
2077e1c014aSSimon J. Gerraty	esac
208aa3b7a2fSSimon J. Gerraty}
209aa3b7a2fSSimon J. Gerraty
2107e1c014aSSimon J. Gerraty##
2117e1c014aSSimon J. Gerraty# _debugOff match $DEBUG_ON $first
2127e1c014aSSimon J. Gerraty#
2137e1c014aSSimon J. Gerraty# Actually turn off tracing, set $DEBUG_OFF=$match
2147e1c014aSSimon J. Gerraty#
2157e1c014aSSimon J. Gerraty# If we have included hooks.sh $_HOOKS_SH will be set
2167e1c014aSSimon J. Gerraty# and if $first (the first arg to DebugOff) is suitable as a variable
2177e1c014aSSimon J. Gerraty# name we will run ${first}_debugOff_hooks.
2187e1c014aSSimon J. Gerraty#
2197e1c014aSSimon J. Gerraty# We do hooks_run after turning off tracing, but before resetting
2207e1c014aSSimon J. Gerraty# DEBUG_DO so functions can trace if they want
2217e1c014aSSimon J. Gerraty#
222aa3b7a2fSSimon J. Gerraty_debugOff() {
223aa3b7a2fSSimon J. Gerraty	DEBUG_OFF=$1
224aa3b7a2fSSimon J. Gerraty	set +x
2257e1c014aSSimon J. Gerraty	case "$_HOOKS_SH,$3" in
2267e1c014aSSimon J. Gerraty	,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;;
2277e1c014aSSimon J. Gerraty	*)	hooks_run ${3}_debugOff_hooks;;
2287e1c014aSSimon J. Gerraty	esac
2297e1c014aSSimon J. Gerraty	set +x			# just to be sure
230aa3b7a2fSSimon J. Gerraty	DEBUG_ON=$2
231aa3b7a2fSSimon J. Gerraty	DEBUG_DO=:
232aa3b7a2fSSimon J. Gerraty	DEBUG_SKIP=
233aa3b7a2fSSimon J. Gerraty	DEBUG_X=
234aa3b7a2fSSimon J. Gerraty}
235aa3b7a2fSSimon J. Gerraty
23602653835SSimon J. Gerraty##
23702653835SSimon J. Gerraty# DebugAdd tag
23802653835SSimon J. Gerraty#
23902653835SSimon J. Gerraty# Add tag to DEBUG_SH
24002653835SSimon J. Gerraty#
24102653835SSimon J. GerratyDebugAdd() {
24202653835SSimon J. Gerraty        DEBUG_SH=${DEBUG_SH:+$DEBUG_SH,}$1
24302653835SSimon J. Gerraty        export DEBUG_SH
24402653835SSimon J. Gerraty}
24502653835SSimon J. Gerraty
24602653835SSimon J. Gerraty##
24702653835SSimon J. Gerraty# DebugEcho message
24802653835SSimon J. Gerraty#
24902653835SSimon J. Gerraty# Output message if we are debugging
25002653835SSimon J. Gerraty#
251aa3b7a2fSSimon J. GerratyDebugEcho() {
252aa3b7a2fSSimon J. Gerraty	$DEBUG_DO echo "$@"
253aa3b7a2fSSimon J. Gerraty}
254aa3b7a2fSSimon J. Gerraty
2557e1c014aSSimon J. Gerraty##
2567e1c014aSSimon J. Gerraty# Debugging
2577e1c014aSSimon J. Gerraty#
2587e1c014aSSimon J. Gerraty# return 0 if we are debugging.
2597e1c014aSSimon J. Gerraty#
260aa3b7a2fSSimon J. GerratyDebugging() {
261aa3b7a2fSSimon J. Gerraty	test "$DEBUG_SKIP"
262aa3b7a2fSSimon J. Gerraty}
263aa3b7a2fSSimon J. Gerraty
2647e1c014aSSimon J. Gerraty##
2657e1c014aSSimon J. Gerraty# DebugLog message
2667e1c014aSSimon J. Gerraty#
2677e1c014aSSimon J. Gerraty# Outout message with timestamp if we are debugging
2687e1c014aSSimon J. Gerraty#
269aa3b7a2fSSimon J. GerratyDebugLog() {
270aa3b7a2fSSimon J. Gerraty	$DEBUG_SKIP return 0
271aa3b7a2fSSimon J. Gerraty	echo `date '+@ %s [%Y-%m-%d %H:%M:%S %Z]'` "$@"
272aa3b7a2fSSimon J. Gerraty}
273aa3b7a2fSSimon J. Gerraty
2747e1c014aSSimon J. Gerraty##
2757e1c014aSSimon J. Gerraty# DebugTrace message
2767e1c014aSSimon J. Gerraty#
2777e1c014aSSimon J. Gerraty# Something hard to miss when wading through huge -x output
2787e1c014aSSimon J. Gerraty#
279aa3b7a2fSSimon J. GerratyDebugTrace() {
280aa3b7a2fSSimon J. Gerraty	$DEBUG_SKIP return 0
281aa3b7a2fSSimon J. Gerraty	set +x
282aa3b7a2fSSimon J. Gerraty	echo "@ ==================== [ $DEBUG_ON ] ===================="
283aa3b7a2fSSimon J. Gerraty	DebugLog "$@"
284aa3b7a2fSSimon J. Gerraty	echo "@ ==================== [ $DEBUG_ON ] ===================="
285aa3b7a2fSSimon J. Gerraty	set -x
286aa3b7a2fSSimon J. Gerraty}
287aa3b7a2fSSimon J. Gerraty
2887e1c014aSSimon J. Gerraty##
2897e1c014aSSimon J. Gerraty# DebugOn [-e] [-o] match ...
2907e1c014aSSimon J. Gerraty#
2917e1c014aSSimon J. Gerraty# Turn on debugging if any $match is found in $DEBUG_SH.
2927e1c014aSSimon J. Gerraty#
293aa3b7a2fSSimon J. GerratyDebugOn() {
2947e1c014aSSimon J. Gerraty	eval ${local:-:} _e _match _off _rc
295aa3b7a2fSSimon J. Gerraty	_rc=0			# avoid problems with set -e
296aa3b7a2fSSimon J. Gerraty	_off=:
297aa3b7a2fSSimon J. Gerraty	while :
298aa3b7a2fSSimon J. Gerraty	do
299aa3b7a2fSSimon J. Gerraty		case "$1" in
300aa3b7a2fSSimon J. Gerraty		-e) _rc=1; shift;; # caller ok with return 1
301aa3b7a2fSSimon J. Gerraty		-o) _off=; shift;; # off unless we have a match
302aa3b7a2fSSimon J. Gerraty		*) break;;
303aa3b7a2fSSimon J. Gerraty		esac
304aa3b7a2fSSimon J. Gerraty	done
305aa3b7a2fSSimon J. Gerraty	case ",${DEBUG_SH:-$DEBUG}," in
306aa3b7a2fSSimon J. Gerraty	,,)	return $_rc;;
307aa3b7a2fSSimon J. Gerraty	*,[Dd]ebug,*) ;;
308aa3b7a2fSSimon J. Gerraty	*) $DEBUG_DO set +x;;		# reduce the noise
309aa3b7a2fSSimon J. Gerraty	esac
310aa3b7a2fSSimon J. Gerraty	_match=
311aa3b7a2fSSimon J. Gerraty	# if debugging is off because of a !e
312aa3b7a2fSSimon J. Gerraty	# don't add 'all' to the On list.
313aa3b7a2fSSimon J. Gerraty	case "$_off$DEBUG_OFF" in
314aa3b7a2fSSimon J. Gerraty	:)	_e=all;;
315aa3b7a2fSSimon J. Gerraty	*)	_e=;;
316aa3b7a2fSSimon J. Gerraty	esac
317aa3b7a2fSSimon J. Gerraty	for _e in ${*:-$Myname} $_e
318aa3b7a2fSSimon J. Gerraty	do
319aa3b7a2fSSimon J. Gerraty		: $_e in ,${DEBUG_SH:-$DEBUG},
320aa3b7a2fSSimon J. Gerraty		case ",${DEBUG_SH:-$DEBUG}," in
321aa3b7a2fSSimon J. Gerraty		*,!$_e,*|*,!$Myname:$_e,*)
322aa3b7a2fSSimon J. Gerraty			# only turn it off if it was on
323aa3b7a2fSSimon J. Gerraty			_rc=0
3247e1c014aSSimon J. Gerraty			$DEBUG_DO _debugOff $_e $DEBUG_ON $1
325aa3b7a2fSSimon J. Gerraty			break
326aa3b7a2fSSimon J. Gerraty			;;
327aa3b7a2fSSimon J. Gerraty		*,$_e,*|*,$Myname:$_e,*)
328aa3b7a2fSSimon J. Gerraty			# only turn it on if it was off
329aa3b7a2fSSimon J. Gerraty			_rc=0
330aa3b7a2fSSimon J. Gerraty			_match=$_e
3317e1c014aSSimon J. Gerraty			$DEBUG_SKIP _debugOn $_e $1
332aa3b7a2fSSimon J. Gerraty			break
333aa3b7a2fSSimon J. Gerraty			;;
334aa3b7a2fSSimon J. Gerraty		esac
335aa3b7a2fSSimon J. Gerraty	done
336aa3b7a2fSSimon J. Gerraty	if test -z "$_off$_match"; then
337aa3b7a2fSSimon J. Gerraty		# off unless explicit match, but
338aa3b7a2fSSimon J. Gerraty		# only turn it off if it was on
3397e1c014aSSimon J. Gerraty		$DEBUG_DO _debugOff $_e $DEBUG_ON $1
340aa3b7a2fSSimon J. Gerraty	fi
341aa3b7a2fSSimon J. Gerraty	DEBUGGING=$DEBUG_SKIP	# backwards compatability
342aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# back on if needed
343aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# make sure we see it in trace
344aa3b7a2fSSimon J. Gerraty	return $_rc
345aa3b7a2fSSimon J. Gerraty}
346aa3b7a2fSSimon J. Gerraty
3477e1c014aSSimon J. Gerraty##
3487e1c014aSSimon J. Gerraty# DebugOff [-e] [-o] [rc=$?] match ...
3497e1c014aSSimon J. Gerraty#
350aa3b7a2fSSimon J. Gerraty# Only turn debugging off if one of our args was the reason it
351aa3b7a2fSSimon J. Gerraty# was turned on.
3527e1c014aSSimon J. Gerraty#
353aa3b7a2fSSimon J. Gerraty# We normally return 0, but caller can pass rc=$? as first arg
354aa3b7a2fSSimon J. Gerraty# so that we preserve the status of last statement.
3557e1c014aSSimon J. Gerraty#
3567e1c014aSSimon J. Gerraty# The options '-e' and '-o' are ignored, they just make it easier to
3577e1c014aSSimon J. Gerraty# keep DebugOn and DebugOff lines in sync.
3587e1c014aSSimon J. Gerraty#
359aa3b7a2fSSimon J. GerratyDebugOff() {
3607e1c014aSSimon J. Gerraty	eval ${local:-:} _e _rc
361aa3b7a2fSSimon J. Gerraty	case ",${DEBUG_SH:-$DEBUG}," in
362aa3b7a2fSSimon J. Gerraty	*,[Dd]ebug,*) ;;
363aa3b7a2fSSimon J. Gerraty	*) $DEBUG_DO set +x;;		# reduce the noise
364aa3b7a2fSSimon J. Gerraty	esac
365aa3b7a2fSSimon J. Gerraty	_rc=0			# always happy
366aa3b7a2fSSimon J. Gerraty	while :
367aa3b7a2fSSimon J. Gerraty	do
368aa3b7a2fSSimon J. Gerraty		case "$1" in
369aa3b7a2fSSimon J. Gerraty		-[eo]) shift;;	# ignore it
370aa3b7a2fSSimon J. Gerraty		rc=*) eval "_$1"; shift;;
371aa3b7a2fSSimon J. Gerraty		*) break;;
372aa3b7a2fSSimon J. Gerraty		esac
373aa3b7a2fSSimon J. Gerraty	done
374aa3b7a2fSSimon J. Gerraty	for _e in $*
375aa3b7a2fSSimon J. Gerraty	do
376aa3b7a2fSSimon J. Gerraty		: $_e==$DEBUG_OFF DEBUG_OFF
377aa3b7a2fSSimon J. Gerraty		case "$DEBUG_OFF" in
378aa3b7a2fSSimon J. Gerraty		"")	break;;
3797e1c014aSSimon J. Gerraty		$_e)	_debugOn $DEBUG_ON $1; return $_rc;;
380aa3b7a2fSSimon J. Gerraty		esac
381aa3b7a2fSSimon J. Gerraty	done
382aa3b7a2fSSimon J. Gerraty	for _e in $*
383aa3b7a2fSSimon J. Gerraty	do
384aa3b7a2fSSimon J. Gerraty		: $_e==$DEBUG_ON DEBUG_ON
385aa3b7a2fSSimon J. Gerraty		case "$DEBUG_ON" in
386aa3b7a2fSSimon J. Gerraty		"")	break;;
3877e1c014aSSimon J. Gerraty		$_e)	_debugOff "" "" $1; return $_rc;;
388aa3b7a2fSSimon J. Gerraty		esac
389aa3b7a2fSSimon J. Gerraty	done
390aa3b7a2fSSimon J. Gerraty	DEBUGGING=$DEBUG_SKIP	# backwards compatability
391aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# back on if needed
392aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# make sure we see it in trace
393aa3b7a2fSSimon J. Gerraty	return $_rc
394aa3b7a2fSSimon J. Gerraty}
395aa3b7a2fSSimon J. Gerraty
396aa3b7a2fSSimon J. Gerraty_TTY=${_TTY:-`test -t 0 && tty`}; export _TTY
397aa3b7a2fSSimon J. Gerraty
398aa3b7a2fSSimon J. Gerraty# override this if you like
399aa3b7a2fSSimon J. Gerraty_debugShell() {
4007e1c014aSSimon J. Gerraty	test "x$_TTY" != x || return 0
401aa3b7a2fSSimon J. Gerraty	{
402aa3b7a2fSSimon J. Gerraty		echo DebugShell "$@"
403aa3b7a2fSSimon J. Gerraty		echo "Type 'exit' to continue..."
404aa3b7a2fSSimon J. Gerraty	} > $_TTY
405aa3b7a2fSSimon J. Gerraty	${DEBUG_SHELL:-${SHELL:-/bin/sh}} < $_TTY > $_TTY 2>&1
406aa3b7a2fSSimon J. Gerraty}
407aa3b7a2fSSimon J. Gerraty
408aa3b7a2fSSimon J. Gerraty# Run an interactive shell if appropriate
409aa3b7a2fSSimon J. Gerraty# Note: you can use $DEBUG_SKIP DebugShell ... to skip unless debugOn
410aa3b7a2fSSimon J. GerratyDebugShell() {
4117e1c014aSSimon J. Gerraty	eval ${local:-:} _e
412aa3b7a2fSSimon J. Gerraty	case "$_TTY%${DEBUG_INTERACTIVE}" in
413aa3b7a2fSSimon J. Gerraty	*%|%*) return 0;;	# no tty or no spec
414aa3b7a2fSSimon J. Gerraty	esac
415aa3b7a2fSSimon J. Gerraty	for _e in ${*:-$Myname} all
416aa3b7a2fSSimon J. Gerraty	do
417aa3b7a2fSSimon J. Gerraty		case ",${DEBUG_INTERACTIVE}," in
418aa3b7a2fSSimon J. Gerraty		*,!$_e,*|*,!$Myname:$_e,*)
419aa3b7a2fSSimon J. Gerraty			return 0
420aa3b7a2fSSimon J. Gerraty			;;
421aa3b7a2fSSimon J. Gerraty		*,$_e,*|*,$Myname:$_e,*)
422aa3b7a2fSSimon J. Gerraty			# Provide clues as to why/where
423aa3b7a2fSSimon J. Gerraty			_debugShell "$_e: $@"
424aa3b7a2fSSimon J. Gerraty			return $?
425aa3b7a2fSSimon J. Gerraty			;;
426aa3b7a2fSSimon J. Gerraty		esac
427aa3b7a2fSSimon J. Gerraty	done
428aa3b7a2fSSimon J. Gerraty	return 0
429aa3b7a2fSSimon J. Gerraty}
430aa3b7a2fSSimon J. Gerraty
431aa3b7a2fSSimon J. Gerraty# For backwards compatability
432aa3b7a2fSSimon J. GerratyDebug() {
433aa3b7a2fSSimon J. Gerraty	case "${DEBUG_SH:-$DEBUG}" in
434aa3b7a2fSSimon J. Gerraty	"")	;;
435aa3b7a2fSSimon J. Gerraty	*)	DEBUG_ON=${DEBUG_ON:-_Debug}
436aa3b7a2fSSimon J. Gerraty		DebugOn -e $* || DebugOff $DEBUG_LAST
437aa3b7a2fSSimon J. Gerraty		DEBUGGING=$DEBUG_SKIP
438aa3b7a2fSSimon J. Gerraty		;;
439aa3b7a2fSSimon J. Gerraty	esac
440aa3b7a2fSSimon J. Gerraty}
441