xref: /freebsd-src/libexec/rc/debug.sh (revision 203027b2d5dc89fec3a0a7eee195a11cb394587f)
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#
34a4e7810fSSimon J. Gerraty#	Further; when we set "DEBUG_ON" if we find
35a4e7810fSSimon J. Gerraty#	"$DEBUG_ON:debug_add:tag" in "DEBUG_SH" we will
36a4e7810fSSimon J. Gerraty#	add the new "tag" to "DEBUG_SH" so it only has effect after that
37a4e7810fSSimon J. Gerraty#	point.
38a4e7810fSSimon 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*203027b2SSimon J. Gerraty#	$Id: debug.sh,v 1.46 2024/12/13 03:55:52 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*203027b2SSimon J. Gerraty# have is handy
111*203027b2SSimon J. Gerratyif test -z "$_HAVE_SH"; then
112*203027b2SSimon J. Gerraty	_HAVE_SH=:
113*203027b2SSimon J. Gerraty
114*203027b2SSimon J. Gerraty	##
115*203027b2SSimon J. Gerraty	# have that does not rely on return code of type
116*203027b2SSimon J. Gerraty	#
117*203027b2SSimon J. Gerraty	have() {
118*203027b2SSimon J. Gerraty		case `(type "$1") 2>&1` in
119*203027b2SSimon J. Gerraty		*" found") return 1;;
120*203027b2SSimon J. Gerraty		esac
121*203027b2SSimon J. Gerraty		return 0
122*203027b2SSimon J. Gerraty	}
123*203027b2SSimon J. Gerratyfi
124*203027b2SSimon J. Gerraty
125*203027b2SSimon J. Gerraty# does local *actually* work?
126*203027b2SSimon J. Gerratylocal_works() {
127*203027b2SSimon J. Gerraty    local _fu
128*203027b2SSimon J. Gerraty}
129*203027b2SSimon J. Gerraty
130*203027b2SSimon J. Gerratyif local_works > /dev/null 2>&1; then
131*203027b2SSimon J. Gerraty    _local=local
132*203027b2SSimon J. Gerratyelse
133*203027b2SSimon J. Gerraty    _local=:
134*203027b2SSimon J. Gerratyfi
135*203027b2SSimon J. Gerraty# for backwards compatability
136*203027b2SSimon J. Gerratylocal=$_local
137*203027b2SSimon J. Gerraty
138*203027b2SSimon J. Gerratyif test -z "$isPOSIX_SHELL"; then
139a4e7810fSSimon J. Gerraty	if (echo ${PATH%:*}) > /dev/null 2>&1; then
140a4e7810fSSimon J. Gerraty		# true should be a builtin, : certainly is
141a4e7810fSSimon J. Gerraty		isPOSIX_SHELL=:
142a4e7810fSSimon J. Gerraty	else
143a4e7810fSSimon J. Gerraty		isPOSIX_SHELL=false
144a4e7810fSSimon J. Gerraty		false() {
145a4e7810fSSimon J. Gerraty			return 1
146a4e7810fSSimon J. Gerraty		}
147a4e7810fSSimon J. Gerraty	fi
148*203027b2SSimon J. Gerratyfi
149a4e7810fSSimon J. Gerraty
150a4e7810fSSimon J. Gerratyis_posix_shell() {
151a4e7810fSSimon J. Gerraty	$isPOSIX_SHELL
152a4e7810fSSimon J. Gerraty	return
153a4e7810fSSimon J. Gerraty}
154a4e7810fSSimon J. Gerraty
155a4e7810fSSimon J. Gerraty
156a4e7810fSSimon J. Gerraty##
157a4e7810fSSimon J. Gerraty# _debugAdd match
158a4e7810fSSimon J. Gerraty#
159a4e7810fSSimon J. Gerraty# Called from _debugOn when $match also appears in $DEBUG_SH with
160a4e7810fSSimon J. Gerraty# a suffix of :debug_add:tag we will add tag to DEBUG_SH
161a4e7810fSSimon J. Gerraty#
162a4e7810fSSimon J. Gerraty_debugAdd() {
163*203027b2SSimon J. Gerraty	eval $_local tag
164a4e7810fSSimon J. Gerraty
165a4e7810fSSimon J. Gerraty	for tag in `IFS=,; echo $DEBUG_SH`
166a4e7810fSSimon J. Gerraty	do
167a4e7810fSSimon J. Gerraty		: tag=$tag
168a4e7810fSSimon J. Gerraty		case "$tag" in
169a4e7810fSSimon J. Gerraty		$1:debug_add:*)
170a4e7810fSSimon J. Gerraty			if is_posix_shell; then
171a4e7810fSSimon J. Gerraty				tag=${tag#$1:debug_add:}
172a4e7810fSSimon J. Gerraty			else
173a4e7810fSSimon J. Gerraty				tag=`expr $tag : '.*:debug_add:\(.*\)'`
174a4e7810fSSimon J. Gerraty			fi
175a4e7810fSSimon J. Gerraty			case ",$DEBUG_SH," in
176a4e7810fSSimon J. Gerraty			*,$tag,*) ;;
177a4e7810fSSimon J. Gerraty			*)	set -x
178a4e7810fSSimon J. Gerraty				: _debugAdd $1
179a4e7810fSSimon J. Gerraty				DEBUG_SH=$DEBUG_SH,$tag
180a4e7810fSSimon J. Gerraty				set +x
181a4e7810fSSimon J. Gerraty				;;
182a4e7810fSSimon J. Gerraty			esac
183a4e7810fSSimon J. Gerraty			;;
184a4e7810fSSimon J. Gerraty		esac
185a4e7810fSSimon J. Gerraty	done
186a4e7810fSSimon J. Gerraty	export DEBUG_SH
187a4e7810fSSimon J. Gerraty}
188a4e7810fSSimon J. Gerraty
189a4e7810fSSimon J. Gerraty
1907e1c014aSSimon J. Gerraty##
1917e1c014aSSimon J. Gerraty# _debugOn match first
1927e1c014aSSimon J. Gerraty#
1937e1c014aSSimon J. Gerraty# Actually turn on tracing, set $DEBUG_ON=$match
1947e1c014aSSimon J. Gerraty#
195a4e7810fSSimon J. Gerraty# Check if $DEBUG_SH contains $match:debug_add:* and call _debugAdd
196a4e7810fSSimon J. Gerraty# to add the suffix to DEBUG_SH.  This useful when we only want
197a4e7810fSSimon J. Gerraty# to trace some script when run under specific circumstances.
198a4e7810fSSimon J. Gerraty#
1997e1c014aSSimon J. Gerraty# If we have included hooks.sh $_HOOKS_SH will be set
2007e1c014aSSimon J. Gerraty# and if $first (the first arg to DebugOn) is suitable as a variable
2017e1c014aSSimon J. Gerraty# name we will run ${first}_debugOn_hooks.
2027e1c014aSSimon J. Gerraty#
2037e1c014aSSimon J. Gerraty# We disable tracing for hooks_run itself but functions can trace
2047e1c014aSSimon J. Gerraty# if they want based on DEBUG_DO
2057e1c014aSSimon J. Gerraty#
206aa3b7a2fSSimon J. Gerraty_debugOn() {
207aa3b7a2fSSimon J. Gerraty	DEBUG_OFF=
208aa3b7a2fSSimon J. Gerraty	DEBUG_DO=
209aa3b7a2fSSimon J. Gerraty	DEBUG_SKIP=:
210aa3b7a2fSSimon J. Gerraty	DEBUG_X=-x
211a4e7810fSSimon J. Gerraty	# do this firt to reduce noise
212a4e7810fSSimon J. Gerraty	case ",$DEBUG_SH," in
213a4e7810fSSimon J. Gerraty	*,$1:debug_add:*) _debugAdd $1;;
214a4e7810fSSimon J. Gerraty	*,$2:debug_add:*) _debugAdd $2;;
215a4e7810fSSimon J. Gerraty	esac
216aa3b7a2fSSimon J. Gerraty	set -x
217aa3b7a2fSSimon J. Gerraty	DEBUG_ON=$1
2187e1c014aSSimon J. Gerraty	case "$_HOOKS_SH,$2" in
2197e1c014aSSimon J. Gerraty	,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;;
2207e1c014aSSimon J. Gerraty	*)	# avoid noise from hooks_run
2217e1c014aSSimon J. Gerraty		set +x
2227e1c014aSSimon J. Gerraty		hooks_run ${2}_debugOn_hooks
2237e1c014aSSimon J. Gerraty		set -x
2247e1c014aSSimon J. Gerraty		;;
2257e1c014aSSimon J. Gerraty	esac
226aa3b7a2fSSimon J. Gerraty}
227aa3b7a2fSSimon J. Gerraty
2287e1c014aSSimon J. Gerraty##
2297e1c014aSSimon J. Gerraty# _debugOff match $DEBUG_ON $first
2307e1c014aSSimon J. Gerraty#
2317e1c014aSSimon J. Gerraty# Actually turn off tracing, set $DEBUG_OFF=$match
2327e1c014aSSimon J. Gerraty#
2337e1c014aSSimon J. Gerraty# If we have included hooks.sh $_HOOKS_SH will be set
2347e1c014aSSimon J. Gerraty# and if $first (the first arg to DebugOff) is suitable as a variable
2357e1c014aSSimon J. Gerraty# name we will run ${first}_debugOff_hooks.
2367e1c014aSSimon J. Gerraty#
2377e1c014aSSimon J. Gerraty# We do hooks_run after turning off tracing, but before resetting
2387e1c014aSSimon J. Gerraty# DEBUG_DO so functions can trace if they want
2397e1c014aSSimon J. Gerraty#
240aa3b7a2fSSimon J. Gerraty_debugOff() {
241aa3b7a2fSSimon J. Gerraty	DEBUG_OFF=$1
242aa3b7a2fSSimon J. Gerraty	set +x
2437e1c014aSSimon J. Gerraty	case "$_HOOKS_SH,$3" in
2447e1c014aSSimon J. Gerraty	,*|:,|:,*[${CASE_CLASS_NEG:-!}A-Za-z0-9_]*) ;;
2457e1c014aSSimon J. Gerraty	*)	hooks_run ${3}_debugOff_hooks;;
2467e1c014aSSimon J. Gerraty	esac
2477e1c014aSSimon J. Gerraty	set +x			# just to be sure
248aa3b7a2fSSimon J. Gerraty	DEBUG_ON=$2
249aa3b7a2fSSimon J. Gerraty	DEBUG_DO=:
250aa3b7a2fSSimon J. Gerraty	DEBUG_SKIP=
251aa3b7a2fSSimon J. Gerraty	DEBUG_X=
252aa3b7a2fSSimon J. Gerraty}
253aa3b7a2fSSimon J. Gerraty
25402653835SSimon J. Gerraty##
25502653835SSimon J. Gerraty# DebugAdd tag
25602653835SSimon J. Gerraty#
25702653835SSimon J. Gerraty# Add tag to DEBUG_SH
25802653835SSimon J. Gerraty#
25902653835SSimon J. GerratyDebugAdd() {
26002653835SSimon J. Gerraty        DEBUG_SH=${DEBUG_SH:+$DEBUG_SH,}$1
26102653835SSimon J. Gerraty        export DEBUG_SH
26202653835SSimon J. Gerraty}
26302653835SSimon J. Gerraty
26402653835SSimon J. Gerraty##
26502653835SSimon J. Gerraty# DebugEcho message
26602653835SSimon J. Gerraty#
26702653835SSimon J. Gerraty# Output message if we are debugging
26802653835SSimon J. Gerraty#
269aa3b7a2fSSimon J. GerratyDebugEcho() {
270aa3b7a2fSSimon J. Gerraty	$DEBUG_DO echo "$@"
271aa3b7a2fSSimon J. Gerraty}
272aa3b7a2fSSimon J. Gerraty
2737e1c014aSSimon J. Gerraty##
2747e1c014aSSimon J. Gerraty# Debugging
2757e1c014aSSimon J. Gerraty#
2767e1c014aSSimon J. Gerraty# return 0 if we are debugging.
2777e1c014aSSimon J. Gerraty#
278aa3b7a2fSSimon J. GerratyDebugging() {
279aa3b7a2fSSimon J. Gerraty	test "$DEBUG_SKIP"
280aa3b7a2fSSimon J. Gerraty}
281aa3b7a2fSSimon J. Gerraty
2827e1c014aSSimon J. Gerraty##
2837e1c014aSSimon J. Gerraty# DebugLog message
2847e1c014aSSimon J. Gerraty#
2857e1c014aSSimon J. Gerraty# Outout message with timestamp if we are debugging
2867e1c014aSSimon J. Gerraty#
287aa3b7a2fSSimon J. GerratyDebugLog() {
288aa3b7a2fSSimon J. Gerraty	$DEBUG_SKIP return 0
289aa3b7a2fSSimon J. Gerraty	echo `date '+@ %s [%Y-%m-%d %H:%M:%S %Z]'` "$@"
290aa3b7a2fSSimon J. Gerraty}
291aa3b7a2fSSimon J. Gerraty
2927e1c014aSSimon J. Gerraty##
2937e1c014aSSimon J. Gerraty# DebugTrace message
2947e1c014aSSimon J. Gerraty#
2957e1c014aSSimon J. Gerraty# Something hard to miss when wading through huge -x output
2967e1c014aSSimon J. Gerraty#
297aa3b7a2fSSimon J. GerratyDebugTrace() {
298aa3b7a2fSSimon J. Gerraty	$DEBUG_SKIP return 0
299aa3b7a2fSSimon J. Gerraty	set +x
300aa3b7a2fSSimon J. Gerraty	echo "@ ==================== [ $DEBUG_ON ] ===================="
301aa3b7a2fSSimon J. Gerraty	DebugLog "$@"
302aa3b7a2fSSimon J. Gerraty	echo "@ ==================== [ $DEBUG_ON ] ===================="
303aa3b7a2fSSimon J. Gerraty	set -x
304aa3b7a2fSSimon J. Gerraty}
305aa3b7a2fSSimon J. Gerraty
3067e1c014aSSimon J. Gerraty##
3077e1c014aSSimon J. Gerraty# DebugOn [-e] [-o] match ...
3087e1c014aSSimon J. Gerraty#
3097e1c014aSSimon J. Gerraty# Turn on debugging if any $match is found in $DEBUG_SH.
3107e1c014aSSimon J. Gerraty#
311aa3b7a2fSSimon J. GerratyDebugOn() {
3127e1c014aSSimon J. Gerraty	eval ${local:-:} _e _match _off _rc
313aa3b7a2fSSimon J. Gerraty	_rc=0			# avoid problems with set -e
314aa3b7a2fSSimon J. Gerraty	_off=:
315aa3b7a2fSSimon J. Gerraty	while :
316aa3b7a2fSSimon J. Gerraty	do
317aa3b7a2fSSimon J. Gerraty		case "$1" in
318aa3b7a2fSSimon J. Gerraty		-e) _rc=1; shift;; # caller ok with return 1
319aa3b7a2fSSimon J. Gerraty		-o) _off=; shift;; # off unless we have a match
320aa3b7a2fSSimon J. Gerraty		*) break;;
321aa3b7a2fSSimon J. Gerraty		esac
322aa3b7a2fSSimon J. Gerraty	done
323aa3b7a2fSSimon J. Gerraty	case ",${DEBUG_SH:-$DEBUG}," in
324aa3b7a2fSSimon J. Gerraty	,,)	return $_rc;;
325aa3b7a2fSSimon J. Gerraty	*,[Dd]ebug,*) ;;
326aa3b7a2fSSimon J. Gerraty	*) $DEBUG_DO set +x;;		# reduce the noise
327aa3b7a2fSSimon J. Gerraty	esac
328aa3b7a2fSSimon J. Gerraty	_match=
329aa3b7a2fSSimon J. Gerraty	# if debugging is off because of a !e
330aa3b7a2fSSimon J. Gerraty	# don't add 'all' to the On list.
331aa3b7a2fSSimon J. Gerraty	case "$_off$DEBUG_OFF" in
332aa3b7a2fSSimon J. Gerraty	:)	_e=all;;
333aa3b7a2fSSimon J. Gerraty	*)	_e=;;
334aa3b7a2fSSimon J. Gerraty	esac
335aa3b7a2fSSimon J. Gerraty	for _e in ${*:-$Myname} $_e
336aa3b7a2fSSimon J. Gerraty	do
337aa3b7a2fSSimon J. Gerraty		: $_e in ,${DEBUG_SH:-$DEBUG},
338aa3b7a2fSSimon J. Gerraty		case ",${DEBUG_SH:-$DEBUG}," in
339aa3b7a2fSSimon J. Gerraty		*,!$_e,*|*,!$Myname:$_e,*)
340aa3b7a2fSSimon J. Gerraty			# only turn it off if it was on
341aa3b7a2fSSimon J. Gerraty			_rc=0
3427e1c014aSSimon J. Gerraty			$DEBUG_DO _debugOff $_e $DEBUG_ON $1
343aa3b7a2fSSimon J. Gerraty			break
344aa3b7a2fSSimon J. Gerraty			;;
345aa3b7a2fSSimon J. Gerraty		*,$_e,*|*,$Myname:$_e,*)
346aa3b7a2fSSimon J. Gerraty			# only turn it on if it was off
347aa3b7a2fSSimon J. Gerraty			_rc=0
348aa3b7a2fSSimon J. Gerraty			_match=$_e
3497e1c014aSSimon J. Gerraty			$DEBUG_SKIP _debugOn $_e $1
350aa3b7a2fSSimon J. Gerraty			break
351aa3b7a2fSSimon J. Gerraty			;;
352aa3b7a2fSSimon J. Gerraty		esac
353aa3b7a2fSSimon J. Gerraty	done
354aa3b7a2fSSimon J. Gerraty	if test -z "$_off$_match"; then
355aa3b7a2fSSimon J. Gerraty		# off unless explicit match, but
356aa3b7a2fSSimon J. Gerraty		# only turn it off if it was on
3577e1c014aSSimon J. Gerraty		$DEBUG_DO _debugOff $_e $DEBUG_ON $1
358aa3b7a2fSSimon J. Gerraty	fi
359aa3b7a2fSSimon J. Gerraty	DEBUGGING=$DEBUG_SKIP	# backwards compatability
360aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# back on if needed
361aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# make sure we see it in trace
362aa3b7a2fSSimon J. Gerraty	return $_rc
363aa3b7a2fSSimon J. Gerraty}
364aa3b7a2fSSimon J. Gerraty
3657e1c014aSSimon J. Gerraty##
3667e1c014aSSimon J. Gerraty# DebugOff [-e] [-o] [rc=$?] match ...
3677e1c014aSSimon J. Gerraty#
368aa3b7a2fSSimon J. Gerraty# Only turn debugging off if one of our args was the reason it
369aa3b7a2fSSimon J. Gerraty# was turned on.
3707e1c014aSSimon J. Gerraty#
371aa3b7a2fSSimon J. Gerraty# We normally return 0, but caller can pass rc=$? as first arg
372aa3b7a2fSSimon J. Gerraty# so that we preserve the status of last statement.
3737e1c014aSSimon J. Gerraty#
3747e1c014aSSimon J. Gerraty# The options '-e' and '-o' are ignored, they just make it easier to
3757e1c014aSSimon J. Gerraty# keep DebugOn and DebugOff lines in sync.
3767e1c014aSSimon J. Gerraty#
377aa3b7a2fSSimon J. GerratyDebugOff() {
3787e1c014aSSimon J. Gerraty	eval ${local:-:} _e _rc
379aa3b7a2fSSimon J. Gerraty	case ",${DEBUG_SH:-$DEBUG}," in
380aa3b7a2fSSimon J. Gerraty	*,[Dd]ebug,*) ;;
381aa3b7a2fSSimon J. Gerraty	*) $DEBUG_DO set +x;;		# reduce the noise
382aa3b7a2fSSimon J. Gerraty	esac
383aa3b7a2fSSimon J. Gerraty	_rc=0			# always happy
384aa3b7a2fSSimon J. Gerraty	while :
385aa3b7a2fSSimon J. Gerraty	do
386aa3b7a2fSSimon J. Gerraty		case "$1" in
387aa3b7a2fSSimon J. Gerraty		-[eo]) shift;;	# ignore it
388aa3b7a2fSSimon J. Gerraty		rc=*) eval "_$1"; shift;;
389aa3b7a2fSSimon J. Gerraty		*) break;;
390aa3b7a2fSSimon J. Gerraty		esac
391aa3b7a2fSSimon J. Gerraty	done
392aa3b7a2fSSimon J. Gerraty	for _e in $*
393aa3b7a2fSSimon J. Gerraty	do
394aa3b7a2fSSimon J. Gerraty		: $_e==$DEBUG_OFF DEBUG_OFF
395aa3b7a2fSSimon J. Gerraty		case "$DEBUG_OFF" in
396aa3b7a2fSSimon J. Gerraty		"")	break;;
3977e1c014aSSimon J. Gerraty		$_e)	_debugOn $DEBUG_ON $1; return $_rc;;
398aa3b7a2fSSimon J. Gerraty		esac
399aa3b7a2fSSimon J. Gerraty	done
400aa3b7a2fSSimon J. Gerraty	for _e in $*
401aa3b7a2fSSimon J. Gerraty	do
402aa3b7a2fSSimon J. Gerraty		: $_e==$DEBUG_ON DEBUG_ON
403aa3b7a2fSSimon J. Gerraty		case "$DEBUG_ON" in
404aa3b7a2fSSimon J. Gerraty		"")	break;;
4057e1c014aSSimon J. Gerraty		$_e)	_debugOff "" "" $1; return $_rc;;
406aa3b7a2fSSimon J. Gerraty		esac
407aa3b7a2fSSimon J. Gerraty	done
408aa3b7a2fSSimon J. Gerraty	DEBUGGING=$DEBUG_SKIP	# backwards compatability
409aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# back on if needed
410aa3b7a2fSSimon J. Gerraty	$DEBUG_DO set -x	# make sure we see it in trace
411aa3b7a2fSSimon J. Gerraty	return $_rc
412aa3b7a2fSSimon J. Gerraty}
413aa3b7a2fSSimon J. Gerraty
414aa3b7a2fSSimon J. Gerraty_TTY=${_TTY:-`test -t 0 && tty`}; export _TTY
415aa3b7a2fSSimon J. Gerraty
416aa3b7a2fSSimon J. Gerraty# override this if you like
417aa3b7a2fSSimon J. Gerraty_debugShell() {
4187e1c014aSSimon J. Gerraty	test "x$_TTY" != x || return 0
419aa3b7a2fSSimon J. Gerraty	{
420aa3b7a2fSSimon J. Gerraty		echo DebugShell "$@"
421aa3b7a2fSSimon J. Gerraty		echo "Type 'exit' to continue..."
422aa3b7a2fSSimon J. Gerraty	} > $_TTY
423aa3b7a2fSSimon J. Gerraty	${DEBUG_SHELL:-${SHELL:-/bin/sh}} < $_TTY > $_TTY 2>&1
424aa3b7a2fSSimon J. Gerraty}
425aa3b7a2fSSimon J. Gerraty
426aa3b7a2fSSimon J. Gerraty# Run an interactive shell if appropriate
427aa3b7a2fSSimon J. Gerraty# Note: you can use $DEBUG_SKIP DebugShell ... to skip unless debugOn
428aa3b7a2fSSimon J. GerratyDebugShell() {
4297e1c014aSSimon J. Gerraty	eval ${local:-:} _e
430aa3b7a2fSSimon J. Gerraty	case "$_TTY%${DEBUG_INTERACTIVE}" in
431aa3b7a2fSSimon J. Gerraty	*%|%*) return 0;;	# no tty or no spec
432aa3b7a2fSSimon J. Gerraty	esac
433aa3b7a2fSSimon J. Gerraty	for _e in ${*:-$Myname} all
434aa3b7a2fSSimon J. Gerraty	do
435aa3b7a2fSSimon J. Gerraty		case ",${DEBUG_INTERACTIVE}," in
436aa3b7a2fSSimon J. Gerraty		*,!$_e,*|*,!$Myname:$_e,*)
437aa3b7a2fSSimon J. Gerraty			return 0
438aa3b7a2fSSimon J. Gerraty			;;
439aa3b7a2fSSimon J. Gerraty		*,$_e,*|*,$Myname:$_e,*)
440aa3b7a2fSSimon J. Gerraty			# Provide clues as to why/where
441aa3b7a2fSSimon J. Gerraty			_debugShell "$_e: $@"
442aa3b7a2fSSimon J. Gerraty			return $?
443aa3b7a2fSSimon J. Gerraty			;;
444aa3b7a2fSSimon J. Gerraty		esac
445aa3b7a2fSSimon J. Gerraty	done
446aa3b7a2fSSimon J. Gerraty	return 0
447aa3b7a2fSSimon J. Gerraty}
448aa3b7a2fSSimon J. Gerraty
449aa3b7a2fSSimon J. Gerraty# For backwards compatability
450aa3b7a2fSSimon J. GerratyDebug() {
451aa3b7a2fSSimon J. Gerraty	case "${DEBUG_SH:-$DEBUG}" in
452aa3b7a2fSSimon J. Gerraty	"")	;;
453aa3b7a2fSSimon J. Gerraty	*)	DEBUG_ON=${DEBUG_ON:-_Debug}
454aa3b7a2fSSimon J. Gerraty		DebugOn -e $* || DebugOff $DEBUG_LAST
455aa3b7a2fSSimon J. Gerraty		DEBUGGING=$DEBUG_SKIP
456aa3b7a2fSSimon J. Gerraty		;;
457aa3b7a2fSSimon J. Gerraty	esac
458aa3b7a2fSSimon J. Gerraty}
459