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! *)