[net.sources] debugger repost...sorry

mc68020@gilbbs.UUCP (Thomas J Keller) (09/29/86)

   Oops.  I discovered after posting my debugging macro package that it was
an older version that didn't quite work correctly, so I am posting the
correct (and fully tested) version.

   I also decided that perhaps some documentation was in order, over and above
the comments in the file, so I wrote a documentation file.  It is included
here as well.

   Happy debugging!

   This is *NOT* a shell archive!

--------------------------------  cut here  ----------------------------------

/*----------------------------------------------------------------------*\
 |
 |	debug.h
 |
 |	this file contains the defines necessary to implement the 
 |	conditional compilation of debugging macros.
 |
 |	86/01/25		tjk & gsm
 |
 |	XENIX 3.01.00		Tandy 6000
 |
 |	USAGE:  to utilize this debugging tool, simply include instances
 |	of the type specific debug macros liberally throughout your code.
 |	If you are using types not included, create a debug macro for the
 |	type you wish to include by following the format of the existing
 |	macros.  Then simply use a -DDEBUG in your cc call to enable the
 |	debugging macros.  It is necessary that debug.h be included in 
 |	your source AFTER stdio.h.
 |
 |	Copyright 1986 Thomas J Keller, Gregory S. Melancon
 |
 |	NOTE:  the macros in this package are based on material published
 |	by Thomas D. Webb in Vol 3, No 2 of Computer Language Magazine.
 |
 |	Permission is hereby granted for the use of this software for
 |	any use, with the stipulation that the copyright and attribution
 |	notices remain intact, and that the authors and Thomas D. Webb 
 |	are credited if used in commercial software.
 |
\*----------------------------------------------------------------------*/


#ifdef DEBUG

/*	in DEBUG mode, PASSTHRU translates debug macros to fprintf statements
 *	by macro substitution.
 */

#    define	PASSTHRU(statements) statements
#    ifdef OCTAL
#        define	SPEC	'%03o'
#    else
#	define	SPEC	0x%02x
#    endif

#else

/*	in normal mode, PASSTHRU translates debug macros into null strings
 *	by macro substitution.
 */

#    define	PASSTHRU(statements)	/* empty */
#endif

/*	debug macro definitions      */


/* print a char variable */

# define	DCHAR(userText, charVar) \
		PASSTHRU(if (charVar == '\040') \
			    fprintf(stderr, "DEBUG: %s: BLANK char\n", \
				    userText); \
			else if (charVar == '\000') \
			    fprintf(stderr, "DEBUG: %s: NULL char\n", \
			    	    userText); \
			else \
			    fprintf(stderr, "DEBUG: %s: SPEC\n", \
				    userText, charVar))


/* print a short integer variable */
# define	DSHORT(userText, shortVar) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s: %d\n", userText, shortVar))


/* print an integer variable */
# define	DINT(userText, intVar) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s: %d\n", userText, intVar))


/* print a long integer variable */
# define	DLONG(userText, longVar) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s: %ld\n", userText, longVar))


/* print an unsigned char variable */
# define	DUCHAR(userText, ucharVar) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s: %u\n", userText, ucharVar))


/* print an unsigned short integer variable */
# define	DUSHORT(userText, ushortVar) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s: %u\n", \
			 userText, ushortVar))


/* print an unsigned integer variable */
# define	DUINT(userText, uintVar) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s: %u\n", userText, uintVar))


/* print an unsigned long integer variable */
# define	DULONG(userText, ulongVar) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s: %ul\n", \
			 userText, ulongVar))


/* print a float variable */
# define	DFLOAT(userText, floatVar) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s: %f\n", userText, floatVar))


/* print a double float variable /*
# define	DDOUBLE(userText, doubleVar) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s: %fl\n", \
			 userText, doubleVar))


/* print a string variable */
# define	DSTRING(userText, stringVar) \
		PASSTHRU(if (stringVar[0] == NULL) \
			     fprintf(stderr, "DEBUG: %s: NULL string\n", \
				     userText); \
			 else \
			     fprintf(stderr, "DEBUG: %s: \"%s\"\n", \
				     userText, stringVar))


/* print a debug message, no variables */
# define	DMSG(userText) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s\n", userText))


/* print a function entry message */
# define	DENTER(funcName)\
		PASSTHRU(fprintf(stderr, "DEBUG: %s >>>>>>>>\n", \
				 funcName))


/* print a function exit message */
# define	DEXIT(funcName) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s <<<<<<<<\n", \
			 funcName))


/* print a function failure stop message */
# define	DSTOP(funcName) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s FAILURE #########\n",\
			 funcName))


/* print an errno error message */
#define		DERROR(userText, funcName) \
		PASSTHRU(fprintf(stderr, "DEBUG: %s: ", \
		funcName);\
		perror(userText))


        /*-------------- end of debug.h	--------------*/

------------------------------  cut here  ------------------------------------

/*---------------------------------------------------------------------------*\
 |
 |	FILENAME:	debug.doc
 |
 |	DATE:		86/09/28
 |
 |	AUTHOR:		thomas j keller
 |
 |	PROJECT:	Public Access UNIX(tm) Conferencing System (PAUCS)
 |
 |	SYSTEM:		XENIX 3.01.00 / Tandy 6000
 |
 |	DESCRIPTION:	this file documents the use of the debugging macros
 |			found in debug.h.  it also provides some pointers
 |			on how to add addtional debugging macros to the
 |			package.
 |
 |	COPYRIGHT:	(C) Thomas J Keller, Consequently Computers
 |
 |	PERMISSION:	permission is hereby granted for the non-commerical
 |			use of this software, provided that this copyright
 |			notice remains intact.  All commercial rights to the
 |			use of this software are reserved by the author.
 |
\*---------------------------------------------------------------------------*/

   The macros documented here provide a flexible and powerful debugging tool
for C programmers.  All macros are enabled by defining DEBUG at compile time.
A nice feature of this implementation is that if DEBUG is not defined, the
debug macros translate to null strings, and debugging code is not generated.
This is accomplished without the need to explicitly test for #ifdef DEBUG on
each macro instantiation.

   Each macro, when enabled, prints out a debug flag (DEBUG: ), followed by
a user specified string, followed by the value of the variable passed.  Some
of the macros also permit have a function name argument, allowing programmers
to identify which function is issuing the debug message.

   Suggested usage is to liberally include debugging calls throughout your
code while writing it.  This saves much editting later, and considerable speeds
the development cycle.

   Note that there is a separate macro for each identifier type.  Not all 
possible identifier types have been covered.  The user is free to follow the
guidelines for adding additional macros to the package to meet their needs.

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

Name:		DCHAR

Syntax:		DCHAR(text, char)

Type:		CPP macro

Synopsis:	DCHAR prints the flag, the contents of the string pointed to
		by (text), and one of the following:

		BLANK char	if the char passed in is a blank (0x20)
		NULL char	if the char passed in is a null  (0x00)
		numeric char value otherwise

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		char		char identifier name to view value of

Notes:		By defining OCTAL in debug.h, it is possible to alter the
		numerical char value output from hex to octal representation



Name:		DSHORT

Syntax:		DSHORT(text, var)

Type:		CPP macro

Synopsis:	DSHORT prints the debug flag, a user message pointed to by
		(text), and the value of the short int (var)

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		var		short int identifier to view value of



Name:		DINT

Syntax:		DINT(text, var)

Type:		CPP macro

Synopsis:	DINT prints the debug flag, a user message pointed to by
		(text), and the value of the integer (var)

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		var		integer identifier to view value of



Name:		DLONG


Type:		CPP macro

Syntax:		DLONG(text, var)	

Synopsis:	DLONG prints the debug flag, a user message pointed to by
		(text), and the value of the long integer (var)

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		var		integer identifier to view value of



Name:		DUCHAR


Type:		CPP macro

Syntax:		DUCHAR(text, var)	

Synopsis:	DUCHAR prints the debug flag, a user message pointed to by
		(text), and the value of the usigned char (var)

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		var		integer identifier to view value of



Name:		DUSHORT


Type:		CPP macro

Syntax:		DUSHORT(text, var)	

Synopsis:	DUSHORT prints the debug flag, a user message pointed to by
		(text), and the value of the  unsigned short int (var)

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		var		integer identifier to view value of



Name:		DUINT


Type:		CPP macro

Syntax:		DUINT(text, var)	

Synopsis:	DUINT prints the debug flag, a user message pointed to by
		(text), and the value of the unsigned integer (var)

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		var		integer identifier to view value of



Name:		DULONG


Type:		CPP macro

Syntax:		DULONG(text, var)	

Synopsis:	DULONG prints the debug flag, a user message pointed to by
		(text), and the value of the unsigned long (var)

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		var		integer identifier to view value of



Name:		DFLOAT


Type:		CPP macro

Syntax:		DFLOAT(text, var)	

Synopsis:	DFLOAT prints the debug flag, a user message pointed to by
		(text), and the value of the float (var)

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		var		integer identifier to view value of



Name:		DDOUBLE


Type:		CPP macro

Syntax:		DDOUBLE(text, var)	

Synopsis:	XXXX prints the debug flag, a user message pointed to by
		(text), and the value of the double float (var)

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		var		integer identifier to view value of



Name:		DSTRING


Type:		CPP macro

Syntax:		DSTRING(text, var)	

Synopsis:	DSTRING prints the debug flag, a user message pointed to by
		(text), and the value of the string (var) in quotes

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		var		integer identifier to view value of



Name:		DMSG


Type:		CPP macro

Syntax:		DMSG(text)	

Synopsis:	DMSG prints the debug flag, and a user message pointed to by
		(text)

Input:		text		string pointer (usually a literal string)
				containing a descriptive message



Name:		DENTER

Type:		CPP macro

Syntax:		DENTER(funcname)	

Synopsis:	DENTER prints the debug flag and the name of the function 
		being entered (funcname).  This is placed as the first line
		of code in each function

Input:		funcname	string pointer (usually a literal string)
				containing name of function entered


Name:		DEXIT


Type:		CPP macro

Syntax:		DEXIT(funcname)	

Synopsis:	DEXIT prints the debug flag, and the name of the function
		being exitted (funcname).  This is placed as the last line
		of code in each function (excepting return())

Input:		funcname	string pointer (usually a literal string)
				containing name of function exitting


Name:		DSTOP


Type:		CPP macro

Syntax:		DSTOP(funcname)	

Synopsis:	DSTOP prints the debug flag, a name of function halting 
		(funcname)

Input:		funcname	string pointer (usually a literal string)
				containing name of function exitting


Name:		DERROR


Type:		CPP macro

Syntax:		DERROR(text, var)	

Synopsis:	DERROR prints the debug flag, a user message pointed to by
		(text), the function name where error occurred, and the
		perror() message associated with errno.

Input:		text		string pointer (usually a literal string)
				containing a descriptive message
		funcname	name of function where DERROR is called


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

Adding new macros:

   simply edit an entry into the debug.h file of the following format:

   #define D<macname>(arg[, arg]) \
	   PASSTHROUGH(code to perform desired debug action)


   Use the existing macros as a guide.  Be sure that the last statement in
your new macro has no semicolong after it, as the semicolon is supplied on
invocation (though it won't break things to have a closing semicolon in 
you macro).  Remember the rules to follow about multiline macro definitions.

-----------------------------  cut here  -------------------------------------

-- 

Disclaimer:  Disclaimer?  DISCLAIMER!? I don't need no stinking DISCLAIMER!!!

tom keller					"She's alive, ALIVE!"
{ihnp4, dual}!ptsfa!gilbbs!mc68020

(* we may not be big, but we're small! *)