[comp.sources.amiga] debug routines

ain@j.cc.purdue.edu (Patrick White) (12/19/87)

Program Name:	debug source
Submitted By:	John G. Hardie <rutgers!cisunx.psu.edu!psuvax1!pitt!
		jgh2@uunet.uu.net>
Summary:	a set of rotines that aid in debugging programs.
Poster Boy:  Pat White  (ain@j.cc.purdue.edu)
Compiled, but not used.

NOTES:
   I had to change the void for go_away() to an int to get it to compile,
but that was probably because I was too brain dead at the time to figure out
what he was doing.


-- Pat White   (co-moderator comp.sources/binaries.amiga)
UUCP: j.cc.purdue.edu!ain  BITNET: PATWHITE@PURCCVM   PHONE: (317) 743-8421
U.S.  Mail:  320 Brown St. apt. 406,    West Lafayette, IN 47906

----------------------------------------


#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	README
#	debug.c
# This archive created: Fri Dec 18 15:59:15 1987
# By:	Patrick White (PUCC Land, USA)
cat << \SHAR_EOF > README
The following are two routines that I wrote to make tracing C programs
easier.  They aren't sophisticated, nor fancy but they are usually 
sufficient for the purpose, and they are easy to use.

USAGE:	1) compile debug.c -> debug.o
	2) call the debugging routines wherever desired in your
	   source code.
	3) compile and link with debug.o

	That's all folks.

I hope that you find these routines useful.  Let me know.

-- 
John G. Hardie			UUCP:	jgh2@cisunx.UUCP 
Dept. of Physics, 		-or-	jgh2@unix.cis.pittsburgh.edu@pitt
Univ. of Pittsburgh		BIX:	jhardie
Pittsburgh, PA 15260		BITNET:	JGH2@PITTVMS
SHAR_EOF
if test 600 -ne "`wc -c README`"
then
echo shar: error transmitting README '(should have been 600 characters)'
fi
cat << \SHAR_EOF > debug.c
/*************************************************************************
*	Debugging/Tracing routines.
*
*
*	DEBUGGING ROUTINE
*
*	void debug(level,str,int1,int2,doubl1,doubl2)
*	where:
*		level 		- integer  - level of debug call.
*		str   		- char *   - labelling string (may be NULL)
*		int1,2		- int *    - integer args (may be NULL)
*		doubl1,2 	- double * - double args (may be NULL)
*
*	if an argument is NULL, it will not be printed in the debug 
*	message.  The format of the debug message is:
*
*	'DEBUGGER called at level:<lev> with:'
*	'Str: <string>' 
*	'I1=<int1> I2=<int2>'
*	'F1=<doub1> F2=<doub2>'
*
*	The level of debugging can be controlled by setting the
*	appropriate bits in the debugging mask defined below.  The mask
*	globalmask controlls whether there is complete (at all levels)
*	debugging, selective debugging or no debugging.
*
*	The debugging mask works as follows,
*	The mask is a 32 bit unsigned integer, so there are 32 possible
*	debugging levels.  Each bit corresponds to a level.  If a 
*	bit is set, then that level is enabled and debugging info
*	is printed for that level.  If all the bits are set, then the
*	message is printed for all levels, if no bits are set, then
* 	no debugging info is printed.
*
*	In addition, if the flag 'trace' is set, the debug funcion will
*	stop the program after each message is printed and give the user
*	the option to a) continue the program - or -
*		      b) abort the program.
*	In the case of b, the debug funtion will call the function
*	*exitfunc().  The default exitfunc() is the ANSI function 
*	exit(), but it may be reassigned by the user in the debug_level()
*	call.  If any memory is allocated, files opened, libraries opened,
*	etc. it is recommended that you reassign the exit function so
*	that any allocated resources are closed before the program
*	exits.
*
*	Also, if the constant NODEBUGGER is defined, the debug function
*	will be #ifdef'ed out and simply become a Jump/Return pair.
*	(actually, the function will simply do a return, but the compiler
*	will still insert the parameter setup code, stack checking (if
*	enabled) and any other overhead...<sigh>
*
*	SET UP/ DEBUG LEVEL CHANGES
*
*	void debug_level(mask,trace,func)
*	where	mask	- int 	       - mask to be used in defining
*					 the debug level.
*		trace	- int	       - flag.  If set, then debug()
*					 will stop after each message
*					 and wait for the user to signal
*					 that it is OK to continue.
*		func    -(*function)() - pointer to the function that will
*					 be called on exit (if trace is set)
*					 if this field is NULL, the default
*					 function exit() will be called.
*
*	This function may be called to change the default debugging
*	level ( default - NO DEBUGGING ENABLED, TRACE OFF)
*	ie to turn debugging on/off.
*	The routine uses the first parameter to toggle the particular
*	debug level.  For example, if the first argument is 1, then 
*	debugging level 1 will be turned on if it is off, and off if it
*	is on.  If the value is negative, then one of three things can
*	happen.  If the param is -1, debugging will be turned off. If
*	it is -2, debugging will be turned on globally, and if it is
*	any other negative value, then the mask will be complemented,
*	ie, all levels that are on will be turned off, and all that are
*	off will be turned on.
*
*	Problems:  None that I know of.
*
*	Programmed by: John G. Hardie	
*		       UUCP: jgh2@unix.cis.pittsburgh.edu@pitt
*
**************************************************************************/

#include "stdio.h"
#include "string.h"
#include "math.h"
#include "ctype.h"

int (*exitfunc)();			/* pointer to exit function */

static int trace = 0;			/* trace flag */
static unsigned int globalmask = 0;	/* debug mask flags	*/
static reset_defaults = 0;		/* detects the first call and */
					/* allows exitfunc to be init'ld */


void debug(lev,str,int1,int2,dbl1,dbl2)
int lev;
char *str;
int *int1,*int2;
double *dbl1,*dbl2;
{
#ifndef NODEBUGGER

	void go_away();
	char resp;

	if (!reset_defaults)
	{
		exitfunc = go_away;
		reset_defaults++;
	}
	if (globalmask & (1<<lev))
	{
		printf("\n Debugger entered at level %d with:\n",lev);
		if (str)
			printf(" str: %s\n",str);
		if (int1)
			printf("  int 1= %d",*int1);
		if (int2)
			printf("  int 2= %d",*int2);
		putchar('\n');
		if (dbl1)
			printf("  dbl 1= %g",*dbl1);
		if (dbl2)
			printf("  dbl 2= %g",*dbl2);
		putchar('\n');
		if (trace)
		{
			printf("\nTrace: continue program execution? (y or n) ");
			while (!isalpha((resp = getchar())))
				;
			if (resp == 'n')
				(*exitfunc)();
		}
	}
#endif
}


void debug_level(mask,trflag,func)
int mask;
int trflag;
int (*func)();
{
#ifndef	NODEBUGGER
	void go_away();

	if (mask >= 0)
		globalmask |= (1<<mask);
	else if (mask == -1)
		globalmask = 0;
	else if (mask = -2 )
		globalmask = 0xffffffff;
	else 
		globalmask = ~globalmask;
	trace = trflag;
	if (func == NULL)
		exitfunc = go_away;
	else
		exitfunc = func;
#endif
}


void go_away()
{
#ifndef NODEBUGGER
	puts("DEBUGGER: KILLING PROGRAM - EXITING THROUGH DEFAULT HANDLER");
	exit(1999);
#endif
}
SHAR_EOF
if test 5114 -ne "`wc -c debug.c`"
then
echo shar: error transmitting debug.c '(should have been 5114 characters)'
fi
#	End of shell archive
exit 0