/* UCMS_VERSION_ID("@(#)pcpdbg.h 61EX:6 readonly 17/05/95 12:59(#)@") */ #ifndef PCPDBG_H /***************************************************************************** * * $Workfile:: PCPDBG.H $ * * $Logfile:: $ * * Library:: CLASSLIB.LIB * * Makefile:: MAKEFILE * * $Date:: $ * * $Revision:: 0.00 $ * * $Author:: Klaas van Ditzhuyzen $ * * Functions:: * * $Log:: $ * * NOTES: DEBUG_PRINTF should be defined as a standard printf routine * to a debug port or file. * DEBUG_ON() is a macro which returns the debug level. When * zero, all runtime debugging is turned off. * *****************************************************************************/ /***************************************************************************** * Definitions *****************************************************************************/ #ifndef EXTERN_C /* Allow usage of C++ compiler */ #ifdef __cplusplus /* Move this to "software.h" */ #define EXTERN_C extern "C" #define EXTERN_C_BEGIN EXTERN_C { #define EXTERN_C_END } #else #define EXTERN_C #define EXTERN_C_BEGIN #define EXTERN_C_END #endif /* C++ */ #endif /* EXTERN_C */ #ifndef NULL #define NULL ((void*) 0) #endif #if DEBUG #ifdef _MSC_VER #pragma message("DEBUG SHIT ENABLED") #endif #ifndef DEBUG_PRINTF_FUNCDEF #define DEBUG_PRINTF_FUNCDEF(file) \ EXTERN_C int DEBUG_PRINTF(const char *s, ...) \ { \ va_list array; \ char *p = file; \ int i; \ static FILE * fp; \ va_start(array,s); \ if (!fp) \ { \ if (!file) \ { \ char fbuf[100]; \ strcpy(fbuf, __FILE__); \ p = strchr(fbuf, '.'); \ strcpy(p, ".log"); \ p = fbuf; \ } \ fp = fopen(p, "w"); \ } \ i = vfprintf(fp, s, array); \ fflush(fp); \ return i; \ } #endif EXTERN_C void DEBUG_DUMPDATA(const char *name, const void *ptr, int nbytes, int flags); /* * Log current value of STACK in hex (consumes two words of stack space !). */ #ifndef DEBUG_LOGSTACK #define DEBUG_LOGSTACK() { int _stack, *STACK=&_stack; dsx(STACK); } #endif /* * Makes always an acceptable string */ #ifndef DEBUG_STR #define DEBUG_STR(x) (char*)(x) ? (*((char*)x) ? (char*)(x) : "\\0") : _nullname #endif /* * Opens the debug environment. Can be redefined. */ #ifndef DEBUG_OPEN #define DEBUG_OPEN(file) fopen(file, "w",stdout) #endif /* * Does a printf() to a debug file or port. */ #ifndef DEBUG_PRINTF #define DEBUG_PRINTF printf #endif #ifndef zprintf #define zprintf DEBUG_PRINTF #endif /* * Logs return value and return it. */ #ifndef DEBUG_RETURN #define DEBUG_RETURN(x) { ds(("Returning %s\n",#x)) return x; } #endif /* * Can be replaced by a variable which holds the debug level. */ #ifndef DEBUG_ON #if DEBUG==2 int _debug_on=1; #elif DEBUG==3 extern int _debug_on; #elif DEBUG==1 static int _debug_on=1; #endif #define DEBUG_ON() (_debug_on) #endif /* * Can be replaced by a variable which holds the debug level. * Used for tracing function entries. */ #ifndef DEBUG_ENTRYON #define DEBUG_ENTRYON() DEBUG_ON() #endif /* * Cleans up the debug environment. */ #ifndef DEBUG_CLOSE #define DEBUG_CLOSE() fclose(stdout) #endif /* * Log file name and line number */ #ifndef DEBUG_LOGFILELINE static char __fileline__[]="%-10s %4d :"; /* #define DEBUG_LOGFILELINE(file, line) DEBUG_PRINTF("%-10s %4d :",file,line) */ #define DEBUG_LOGFILELINE(file, line) DEBUG_PRINTF(__fileline__,file,line) #endif #ifndef DL #define DL() DEBUG_LOGFILELINE(__FILE__,__LINE__); #endif #ifndef DEBUG_ENTRY /* * Function entry and exit */ #define _DEBUG_STACKTAG 0xFEDCBA98 /* magic number */ #ifdef __cplusplus class debug_logentry { private: long stacktag; char *funcname; public: char *getfuncname() { return funcname; } // function name void * getstack() { int hello; return (void*) &hello; } // return current stack void * unwindstack(); // unwind stack debug_logentry(char *name) { funcname = name; stacktag = _DEBUG_STACKTAG; // magic number if (DEBUG_ENTRYON()) DEBUG_PRINTF("Entering [%s]\n", funcname); } ~debug_logentry() { if (DEBUG_ENTRYON()) DEBUG_PRINTF("Leaving [%s]\n", funcname); } } ; #define __FUNCENTRY__(a,b) debug_logentry __FUNC__(a); #else /* * Sets the name of a function in a local variable called __FUNC__. * Can be replaced by logging the name. */ typedef struct { long stacktag; char *funcname; } debug_logentry; #define __FUNCENTRY__(a,b) debug_logentry __FUNC__ = {_DEBUG_STACKTAG, a} ; #endif /* C++ */ #define DEBUG_ENTRY(a,b) __FUNCENTRY__(#a,b) #endif /* DEBUG_ENTRY */ #define D(x) x #define d(x) {if (DEBUG_ON()) {x} } #define dd(x) {if (DEBUG_ON()) {DL() x} } #define ds(x) dd(DEBUG_PRINTF x; ) #define dsx(x) ds(( #x "=0x%08lX\n", (long)(x))) #define dsd(x) ds(( #x "=%ld\n", (long)(x))) #define dsxd(x) ds(( #x "=0x%08lX %ld\n", (long)(x), (long)(x))) #define dsf(x) ds(( #x "=%16g\n", (double)(x))) #define dsm(s,n) DL() DEBUG_DUMPDATA(#s, s, n, 0) static const char _nullname[] = ""; #define dss(x) ds(( #x "=[%s]\n", (const char*)((char*)(x) ? (char*)(x) : _nullname))) #define dsxs(x) ds(( #x "=0x%08lX [%s]\n", (long)(x), (const char*)((char*)(x) ? (char*)(x) : _nullname))) #if __cplusplus #define dcp(x) { dd((x)->debug(#x);) } // class debug function /* * For debugging of existing structures: make a derived class of it. * NOTE: private members are not accessible by this class ! */ #define DEBUG_DCLASS(type, statements) \ class _DEBUG_##type : public type \ { \ public: \ inline operator type & () { return (type &) *this; } \ inline _DEBUG_##type & operator = (type & par) { *this = (_DEBUG_##type &) par; return *this; } \ DEBUG_LOGSTRUCT(statements) \ } ; \ DEBUG_LOGSTRUCTFUNC(type,var) #define ddcp(var) { dd(_debug_logstruct(var, #var); ) } /* * For debugging of nonstruct scalar types: make a class containing one data element * of the specified type named . */ #define DEBUG_VCLASS(type,statements) \ class _DEBUG_##type \ { \ protected: \ type var; \ public: \ _DEBUG_##type(const type init) { var = init; } \ inline operator type & () const { return (type&) var ; } \ DEBUG_LOGSTRUCT(statements) \ } ; \ DEBUG_LOGSTRUCTFUNC(type,var) #else /* Standard Regular C */ #define DEBUG_VCLASS(y,x) #define DEBUG_DCLASS(y,x) #define ddcp(x) /* not defined */ #define dcp(x) /* not defined */ #endif /* if C++ */ #else /* DEBUG off */ /* stub out DEBUG_PRINTF */ #define DEBUG_PRINTF_FUNCDEF(file) \ EXTERN_C int DEBUG_PRINTF(const char *s, ...) { return 0; } #define DEBUG_STR(s) s #define DEBUG_LOGSTACK() #define DEBUG_VCLASS(y,x) #define DEBUG_DCLASS(y,x) #define DEBUG_OPEN(file) #define DEBUG_CLOSE() #define DEBUG_ENTRY(a,b) #define DEBUG_LOGFILELINE(x,y) #define DEBUG_RETURN(x) return x #define __FUNCENTRY__(a,b) #define D(x) #define DL() #define d(x) #define dd(x) #define ds(x) #define dsx(x) #define dsd(x) #define dsxd(x) #define dsf(x) #define dsm(s,n) #define dss(x) #define dcp(x) #define ddcp(x) #define dsxs(x) #endif /* if DEBUG */ #ifndef assert #include #endif #if !DEBUG #define _assert(exp, file, line) _assert(NULL, file, line) #endif /* * DEBUG member function in a struct or class (C++ only) * To be put as last item in a struct or class definition. */ #if DEBUG && __cplusplus /* * This nonclass function allows type specific versions to allow * automatic invocation of the type specific debug function without * specifying the type in the macro. */ #define DEBUG_LOGSTRUCTFUNC(type, var) \ inline void _debug_logstruct(const type * var, char * str) \ { \ ((_DEBUG_##type*)var)->debug(str, #type); \ } #ifndef DEBUG_LOGSTRUCT #define DEBUG_LOGSTRUCT(x) \ public: void debug(const char *s, const char *typestr=NULL) { \ DEBUG_PRINTF("%s [%s]: ptr=%08lXh\n", typestr ? typestr : "?", s, this); \ if (this) { x ; } } #endif #else #define DEBUG_LOGSTRUCTFUNC(type, var) #define DEBUG_LOGSTRUCT(x) #endif /* if C++ */ #define PCPDBG_H #endif