emu48-mirror/PCPDBG.H
Gwenhael Le Moine c3ab4004ad
1996-02-01: Historic version 0.37
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
2024-03-19 22:11:59 +01:00

354 lines
9.5 KiB
C++

/* 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[] = "<NULL>";
#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 <var>.
*/
#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 <assert.h>
#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