/* * * Copyright (c) 1995 * Knowledge Science Institute, University of Calgary * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. The Knowledge Science Institute makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ #ifndef MDEBUG_H #define MDEBUG_H 1 /******************************** debug macros ********************************* these SET_x macros control the settings of the active macros: MTRACE(ID,ID),MTRACEOUT(ID,ID) is used at the start (end) of a member function: MTRACE(class,member_function) MDEBUG(EXP) is used anyware, typlically: MDEBUG(error(-1,'D',"result is '%x',res)) the NDEBUG macro controls the expansion of other debugging facilities The outline of a class using these facilities is as follows: class C [: public P] { MDEBUG_DECL[_VIRTUAL](C); [ C() | MCONSTRUCTOR_IMP[_VIRTUAL](C) ]; [ ~C() | MDESTRUCTOR_IMP[_VIRTUAL](C) ]; void x(); } void C::classInvarient(char* file, int line) const { MCLASSINVTEST(); ... [P::classInvarient(file,line);] } C::C() { MTRACE(C,C); //can't check class invarient because object isn't valid yet MPRECONDITION(); ... MCONSTRUCTOR_IMP_CODE[_VIRTUAL](C) POSTCONDITION(); ... MEXIT_CODE(C,C); } C::~C() { MTRACE(C,~C); MPRECONDITION(); ... MDESTRUCTOR_IMP_CODE[_VIRTUAL](C) POSTCONDITION(); ... MTRACEOUT(C,~C); //can't check class invarient because object isn't valid anymore } void C::x() { MENTRY_CODE(C,x); MPRECONDITION(); ... POSTCONDITION(); ... MEXIT_CODE(C,x); } */ //#ifndef __TOOLHELP_H //#include //#endif #ifndef MERROR_H #include #endif #ifndef __STDDEF_H #include #endif #ifndef NDEBUG #ifndef __TYPEINFO_H #include #endif #endif #ifdef SET_TRACE # define MTRACE(CLASS,MEMBER) error((HWND)-1,'T',#CLASS"::"#MEMBER); # define MTRACEOUT(CLASS,MEMBER) error((HWND)-1,'t',#CLASS"::"#MEMBER": done"); #else # define MTRACE(CLASS,MEMBER) # define MTRACEOUT(CLASS,MEMBER) #endif #ifdef SET_DEBUG # define MDEBUG(STATEMENT) STATEMENT #else # define MDEBUG(STATEMENT) #endif # define CLASS_DECL(CLASS) \ public:\ virtual void classInvarient (char* file, int line) const; #ifdef NDEBUG # define MDEBUG_DECL(CLASS) CLASS_DECL(CLASS) # define MDEBUG_DECL_VIRTUAL(CLASS) CLASS_DECL(CLASS) # define MCONSTRUCTOR_IMP_CODE(CLASS) # define MCONSTRUCTOR_IMP_CODE_VIRTUAL(CLASS) # define MCONSTRUCTOR_IMP(CLASS) # define MCONSTRUCTOR_IMP_VIRTUAL(CLASS) # define MDESTRUCTOR_IMP_CODE(CLASS) # define MDESTRUCTOR_IMP_CODE_VIRTUAL(CLASS) # define MDESTRUCTOR_IMP(CLASS) # define MDESTRUCTOR_IMP_VIRTUAL(CLASS) # define MPRECONDITION(p) ((void)0) # define MPOSTCONDITION(p) ((void)0) # define MCLASSINVTEST(p) ((void)0) # define MASSERT(p) ((void)0) # define MCLASSINVARIENT # define MVERIFYOBJECT # define MENTRY_CODE(CLASS,MEMBER) MTRACE(CLASS,MEMBER) # define MEXIT_CODE(CLASS,MEMBER) MTRACEOUT(CLASS,MEMBER) # define MSAFETY(STATEMENT) #else # define MDEBUG_DECL_VIRTUAL(CLASS) \ CLASS_DECL(CLASS)\ public:\ virtual int verifyObject() const = 0;\ virtual const char* debugClassName() /*= 0;*/{return typeid(*this).name();} # define MDEBUG_DECL(CLASS) \ CLASS_DECL(CLASS)\ private:\ short CLASS##VerifyObject;\ public:\ virtual int verifyObject() const {return CLASS##VerifyObject == CLASS##Class;}\ virtual const char* debugClassName() {return typeid(*this).name();} # define MCONSTRUCTOR_IMP_CODE(CLASS) \ CLASS##VerifyObject = CLASS##Class; //incObjectCount(); # define MCONSTRUCTOR_IMP_CODE_VIRTUAL(CLASS) # define MCONSTRUCTOR_IMP(CLASS) \ CLASS() {CONSTUCTOR_IMP_CODE(CLASS)}; # define MCONSTRUCTOR_IMP_VIRTUAL(CLASS) # define MDESTRUCTOR_IMP_CODE(CLASS) \ CLASS##VerifyObject = 0; //decObjectCount(); # define MDESTRUCTOR_IMP_CODE_VIRTUAL(CLASS) # define MDESTRUCTOR_IMP(CLASS) \ ~CLASS() {DESTUCTOR_IMP_CODE(CLASS)}; # define MDESTRUCTOR_IMP_VIRTUAL(CLASS) # define MPRECONDITION(p) ((p) ? (void)0 : (void) error(0,'F',\ "Precondition violated: <%s>, file \"%s\", line %d\n", \ #p, __FILE__, __LINE__ ) ) # define MPOSTCONDITION(p) ((p) ? (void)0 : (void) error(0,'F',\ "Postcondition violated: <%s>, file \"%s\", line %d\n", \ #p, __FILE__, __LINE__ ) ) # define MCLASSINVTEST(p) ((p) ? (void)0 : (void) error(0,'F',\ "Class Invarient failed: <%s>, file \"%s\", line %d\n", \ #p, file, line ) ) # define MASSERT(p) ((p) ? (void)0 : (void) error(0,'F',\ "Assertion failed: <%s>, file \"%s\", line %d\n", \ #p, __FILE__, __LINE__ ) ) # define MCLASSINVARIENT classInvarient(__FILE__,__LINE__) # define MVERIFYOBJECT MASSERT(verifyObject()); # define MENTRY_CODE(CLASS,MEMBER) \ MTRACE(CLASS,MEMBER)\ MPRECONDITION(verifyObject());\ MCLASSINVARIENT; # define MEXIT_CODE(CLASS,MEMBER) \ MCLASSINVARIENT;\ MTRACEOUT(CLASS,MEMBER) # define MSAFETY(STATEMENT) STATEMENT #endif #endif