41#if !defined(_GSDEBUG_DLL_)
42 #define _GSDEBUG_DLL_ 0
53#if !defined(_GSDEBUG_LIB_)
54 #define _GSDEBUG_LIB_ 0
65#if !defined(GS_USE_ONLY_MODERN)
66 #define GS_USE_ONLY_MODERN 1
76#if !defined(GS_HWND_CHECK)
77 #if defined(_INC_WINDOWS) || defined(_GSWIN_)
78 #define GS_HWND_CHECK 1
80 #define GS_HWND_CHECK 0
90#if !defined(GS_USE_OBSOLETE)
91 #if !_MINICAD_EXTERNAL_ && !_GSWINSDK_ && !_MAGICFOLDER_ && !_GSESDK_ && !GS_SHELL_BUILD && !GS_COMP_BUILD && !GS_PROTECTION_BUILD && !GS_GSDEBUG_BUILD
92 #define GS_USE_OBSOLETE 1
94 #define GS_USE_OBSOLETE 0
104#if !defined(GS_USE_CLASS_DEBUGGING)
105 #if !_MINICAD_EXTERNAL_
106 #define GS_USE_CLASS_DEBUGGING 1
108 #define GS_USE_CLASS_DEBUGGING 0
119#if _GSDEBUG_ && !_GSDEBUG_DLL_ && !_GSDEBUG_LIB_
120 #error if _GSDEBUG_ is defined, _GSDEBUG_DLL_ or _GSDEBUG_LIB_ must also be defined
127#if _GSDEBUG_DLL_ && _GSDEBUG_LIB_
128 #error Not allowed to define both _GSDEBUG_DLL_ and _GSDEBUG_LIB_
130#if !_GSDEBUG_DLL_ && !_GSDEBUG_LIB_
131 #define _GSDEBUG_OBJ_ 1
138 #define GS_DSTOP_ALWAYS SteveJ
175#if _WINDOWS && _GSDEBUG_DLL_
178 #define GSDEBUG_EXPORT __declspec(dllexport)
182 #define GSDEBUG_EXPORT __declspec(dllimport)
186 #define GSDEBUG_EXPORT
203 #define Boolean Bool8
211#if GS_GSDEBUG_BUILD || (APPBUILD && !GS_INTERFACE_FACTORING)
212extern char gDebugAppName[32];
228 class GSDEBUG_EXPORT TProgrammer;
229 class GSDEBUG_EXPORT TDebugTimer
233 void Stop(
const TProgrammer &who, ConstGSCStrPtr name,
bool bWindow);
242 #define START_TIMER(name) TDebugTimer timer_##name
243 #define END_TIMER(who, name) timer_##name##.Stop(who, #name, false)
246 #define START_TIMER(name)
247 #define END_TIMER(who, name)
250#if _WINDOWS && _MAGICFOLDER_
251 #define START_TIMER_RELEASE(name) const Uint32 timer_##name = ::GetTickCount()
252 #define END_TIMER_RELEASE(name) do { \
253 const Uint32 elapsed = ::GetTickCount() - timer_##name; \
254 Uint32 seconds = elapsed / 1000; \
255 Uint32 tenths = (elapsed - seconds*1000 + 50) / 100; \
256 if (tenths > 9) { tenths = 0; ++seconds; } \
257 char szMessage[60]; \
258 ::sprintf(szMessage, "Timer '" #name "' took %d.%d seconds.", seconds, tenths); \
259 ::AfxMessageBox(szMessage); \
262 #define START_TIMER_RELEASE(name)
263 #define END_TIMER_RELEASE(name)
273#define CMSG_makeString1(x) #x
274#define CMSG_makeString(x) CMSG_makeString1(x)
275#define CMSG(who, desc) message(__FILE__ "(" CMSG_makeString(__LINE__) ") : " #who ": " desc)
286#define PRINTDEFINE(who, what) message(__FILE__ "(" CMSG_makeString(__LINE__) ") : " #who ": " #what " = " CMSG_makeString(what))
299#define NOT_IMPLEMENTED(who, func) DSTOP((who, "Not implemented: " #func))
304#if (_WINDOWS && _MINICAD_ && !defined(_INC_WINDOWS)) || !_WINDOWS
314 __declspec(dllimport)
316 Sint32 stricmp(
const char *a,
const char *b);
320 #define strcmpi stricmp
328 #if defined(_MINICAD_EXTERNAL_)
329 #define OutputDebugString Debug
331 #define OutputDebugString(msg) printf("%s", msg)
334 extern "C" __declspec(dllimport)
void _stdcall DebugBreak(
void);
344 #define DECLARE_THIS_FILE static const char THIS_FILE[] = __FILE__;
346 #define DECLARE_THIS_FILE
349 #define THIS_FILE __FILE__
361#define PASCALPRINT(pascal_string) \
362 ((ConstGSStringPtr)(pascal_string))[0], &((ConstGSStringPtr)(pascal_string))[1]
364#define RECTPRINT(r) \
365 (r).Left(), (r).Top(), (r).Right(), (r).Bottom()
367#define TXSTRINGPRINT(txstring) \
368 (const char*)txstring
379#define DEBUG_DO_NOTHING ((void) 0)
383enum EDebugLevel { dlAlways, brief, verbose, mongo, dlNever };
391 #if !defined(__MACTYPES__)
392 extern "C" void Debugger(
void);
395 #define Int13BreakMacro { __asm__("int $3\n" : : ); }
396 #define GSBreakToLowLevelDebugger_() Int13BreakMacro
397 #define GSBreakStrToLowLevelDebugger_(s) ::DebugStr(s)
398 #define GSBreakToSourceDebugger_() ::SysBreak()
399 #define GSBreakStrToSourceDebugger_(s) ::SysBreakStr(s)
408 #define ASSERTNOFPEXCEPTION() DEBUG_DO_NOTHING
409 #define ASSERTFPSTACKVALID() DEBUG_DO_NOTHING
422 const short kKludgeSendAssert = 2001;
423 const short kKludgeSendLog = 2002;
424 const short kKludgeValidatePointer = 2003;
425 const short kKludgeValidateHandle = 2004;
426 const short kKludgeCheckHeap = 2005;
427 const short kKludgeCheckPorts = 2006;
428 const short kKludgeValidateString = 2007;
429 const short kKludgeValidatePString = 2008;
444 const void*
const kCrashTrapConstant = (
void*) 0x50ff8001;
450 struct AssertParameters {
455 struct ValidateParameters {
461 void* thePointerOrHandle;
467 const Sint32 kAllowWMgrPort = 1L;
469 struct ValidatePortParameters {
489 #include <QuickDraw.h>
490 #define DO_PORT_CHECKING 1
492 #define DO_PORT_CHECKING 0
497 Bool8 IsValidMacPort(GrafPtr port);
498 #define __ASSERTPORT(toWhom, msg, port) DSTOP((!::IsValidMacPort((GrafPtr)(port)), toWhom, "%s: Invalid port (0x%08x)", (const char*)(msg), (GrafPtr)(port)))
500 #define __ASSERTCURRENTPORT(toWhom, msg) do { GrafPtr curPort; ::GetPort(&curPort); __ASSERTPORT(toWhom, msg, curPort); } while (0)
502 #define __ASSERTCURRENTPORT(toWhom, msg) ASSERTLEGALPORTM(msg)
510 #define ASSERTLEGALPORTM(message) __ASSERTCURRENTPORT(kGrafPortCheck, (message) ? (message) : "ASSERTLEGALPORTM")
511 #define LLASSERTLEGALPORTM(message) __ASSERTCURRENTPORT(kGrafPortCheck, (message) ? (message) : "LLASSERTLEGALPORTM")
513 Sint32 _AssertLegalPort(
char *message,
const char* file,
Sint32 line,
Bool8 allowWMgrPort);
515 #define ASSERTLEGALPORTM(message) ((void)_AssertLegalPort(message, THIS_FILE, __LINE__, false))
516 #define LLASSERTLEGALPORTM(message) ((void)_AssertLegalPort(message, THIS_FILE, __LINE__, true))
520 #define __ASSERTPORT(toWhom, msg, port) DEBUG_DO_NOTHING
521 #define __ASSERTCURRENTPORT(toWhom, msg) DEBUG_DO_NOTHING
522 #define ASSERTLEGALPORTM(message) DEBUG_DO_NOTHING
523 #define LLASSERTLEGALPORTM(message) DEBUG_DO_NOTHING
529 #define ASSERTPORT(toWhom, port) __ASSERTPORT(toWhom, "ASSERTPORT", port)
530 #define ASSERTCURRENTPORT(toWhom) __ASSERTCURRENTPORT(toWhom, "ASSERTCURRENTPORT")
533 #define ASSERTLEGALPORT() ASSERTLEGALPORTM(NULL)
534 #define LLASSERTLEGALPORT() LLASSERTLEGALPORTM(NULL)
544 #define DO_STOP() __debugbreak()
546 #define DO_STOP() GSBreakToLowLevelDebugger_()
548 #define STOP() do { if (GSDebug::WantToBreak()) DO_STOP(); } while(0)
550 #define STOP() DEBUG_DO_NOTHING
560 extern "C" Bool8 GSDebug_IsInDebugMessage();
572 bool GSDEBUG_EXPORT WantToDebug();
573 bool GSDEBUG_EXPORT WantToDebug(
bool bWantToDebug);
576 EDebugLevel GSDEBUG_EXPORT DebugLevel();
577 EDebugLevel GSDEBUG_EXPORT DebugLevel(EDebugLevel newDebuglevel);
580 bool GSDEBUG_EXPORT UseSourceDebugger();
581 bool GSDEBUG_EXPORT UseSourceDebugger(
bool bUseSourceDebugger);
585 bool GSDEBUG_EXPORT DrawToScreen();
586 bool GSDEBUG_EXPORT DrawToScreen(
bool bDrawToScreen);
590 bool GSDEBUG_EXPORT WantToBreak();
591 bool GSDEBUG_EXPORT WantToBreak(
bool bWantToBreak);
594 Uint32 GSDEBUG_EXPORT Flags();
599 const Uint64 kNoNetDebugFlag = 0x8000000000000000ULL;
600 const Uint64 kNoDebuggerBreakFlag = 0x4000000000000000ULL;
601 const Uint64 kNoDebugWindowFlag = 0x2000000000000000ULL;
602 const Uint64 kNoStackCrawlFlag = 0x1000000000000000ULL;
603 const Uint64 kOnlyIfActiveUserFlag = 0x0800000000000000ULL;
606 const Uint32 kNoFlags = 0x00000000UL;
607 const Uint32 kNeverUseDebugWindows = 0x00000001UL;
618 void GSDEBUG_EXPORT SetDStopFileName(ConstGSCStrPtr szFileName);
619 void GSDEBUG_EXPORT SetDStopLineNumber(
Sint32 nLineNumber);
625 #if !_MINICAD_EXTERNAL_
626 void InitRemoteDebug(
void);
627 void KillRemoteDebug(
void);
628 void LogVersionStamp(
void);
630 class GSDEBUG_EXPORT TProgrammer;
631 void GSDEBUG_EXPORT RemoteDebug(
const TProgrammer& toWhom,
const char *description);
632 void GSDEBUG_EXPORT RemoteDebug(
const char *toWhom,
const char *description,
Bool8 doStackCrawl=
true);
633 void GSDEBUG_EXPORT RemoteLog(
Uint16 level,
const char *description);
634 Sint32 GSDEBUG_EXPORT _Log(
Uint16 level,
const char *format, ...);
642const short kDebugStringLength = 50;
644#define kEveryoneConst 0x0FFFFFFFFFFFFFFFULL
645#define kEveryoneConstLSB 0xFFFFFFFFFFFFFFFFULL
646#define kProgrammerMask 0x0FFFFFFFFFFFFFFFULL
647#define kProgrammerMask 0x0FFFFFFFFFFFFFFFULL
648#define kProgrammerMaskLSB 0xFFFFFFFFFFFFFFFFULL
649#define kOptionBitsMask (~kProgrammerMask)
651class GSDEBUG_EXPORT TProgrammer
654 TProgrammer() { Set(
"Unnamed", 0, 0,
true); }
656 TProgrammer(
const char *name,
Uint64 id2,
Uint64 id1,
bool sendOwn=
true) { Register(name, id2, id1); Set(name, id2, id1, sendOwn); }
657 TProgrammer(
const TProgrammer& a) { Set(a.fName, a.fID2, a.fID1, a.fSendOnOwn); }
659 const char *GetName()
const {
return fName; }
660 Uint64 GetID2(
bool filter=
false)
const {
return filter ? (fID2 & kEveryoneConst) : fID2; }
661 Uint64 GetID1()
const {
return fID1; }
663 bool IsEveryone()
const {
return (fID1 & kEveryoneConstLSB) == kEveryoneConstLSB && (fID2 & kEveryoneConst) == kEveryoneConst; }
664 bool IsActLikeRelease()
const {
return (fID1 & kProgrammerMaskLSB) == 0 && (fID2 & kProgrammerMask) == 0;}
666 bool LogOnOwn()
const;
667 bool ShouldBreak()
const {
return !IsActLikeRelease() && !IsNoBreakBitSet(); }
668 bool ShouldNetDebug()
const {
return !IsActLikeRelease() && !IsNoNetDebugBitSet(); }
669 bool ShouldShowWindow()
const {
return !IsActLikeRelease() && !IsNoWindowBitSet(); }
670 bool ShouldDoStackCrawl()
const {
return !IsNoStackCrawlBitSet(); }
672 TProgrammer operator &(
const TProgrammer& a)
const;
673 TProgrammer operator |(
const TProgrammer& a)
const {
return this->operator &(a); }
675 operator const char *()
const {
return GetName(); }
677 bool operator ==(
const TProgrammer& a)
const {
return MatchExact(a); }
678 bool operator !=(
const TProgrammer& a)
const {
return !MatchExact(a); }
679 bool operator ==(
const char *sz)
const {
return _strcmpi(sz, fName)!=0; }
680 bool MatchExact(
const TProgrammer& a)
const {
return fID2 == a.fID2 && fID1 == a.fID1; }
681 bool IsIn(
const TProgrammer& a)
const {
return IsIn(a.fID2, a.fID1); }
686 bool ContainsCurrentUser()
const;
688 static bool GetProgrammerName(
Uint64 id2,
Uint64 id1,
char *name);
689 static bool ExtractProgrammer(TProgrammer &who, TProgrammer &one);
691 bool IsNoNetDebugBitSet()
const {
return (fID2 & GSDebug::kNoNetDebugFlag) != 0; }
692 bool IsNoBreakBitSet()
const {
return (fID2 & GSDebug::kNoDebuggerBreakFlag) != 0; }
693 bool IsNoWindowBitSet()
const {
return (fID2 & GSDebug::kNoDebugWindowFlag) != 0; }
694 bool IsNoStackCrawlBitSet()
const {
return (fID2 & GSDebug::kNoStackCrawlFlag) != 0; }
695 bool IsOnlyIfActiveUserBitSet()
const {
return (fID2 & GSDebug::kOnlyIfActiveUserFlag) != 0; }
698 void Set(
const char *name,
Uint64 id2,
Uint64 id1,
bool sendOwn) { strncpy(fName, name, kDebugStringLength-1); fID2 = id2; fID1 = id1; fSendOnOwn = sendOwn; }
702 class GSDEBUG_EXPORT TRegistered
705 TRegistered() { fID2 = 0; fID1 = 0; fName[0] = 0; }
706 char fName[kDebugStringLength];
709 static void Register(
const char *name,
Uint64 id2,
Uint64 id1);
710 static const Sint32 fMaxProgrammers;
711 static TRegistered fRegistered[];
713 char fName[kDebugStringLength];
720 #define TProgrammer Sint32
725#if BUG && !defined(_MINICAD_EXTERNAL_)
731#if TEST && !defined(_MINICAD_EXTERNAL_)
733 GSDEBUG_EXPORT
void GDB_DebugInit (
const char* appName,
Uint32 flags);
734 GSDEBUG_EXPORT
void GDB_DebugTerminate();
735 #if defined(_INC_WINDOWS)
736 extern "C" GSDEBUG_EXPORT
void GDB_DebugSetExeHandle(HINSTANCE hInst);
737 extern "C" GSDEBUG_EXPORT
void GDB_SetDebugMessageParentWindow(HWND hParentWnd);
740 void PerformLaunchAsserts(
void);
743 #define DEBUG_INIT(appName, flags) ::GDB_DebugInit(appName, flags)
745 #if defined(_INC_WINDOWS)
747 #define DEBUG_SETEXE(hInst) ::GDB_DebugSetExeHandle(hInst)
750 #define DEBUG_SETPARENTWINDOW(hParentWnd) ::GDB_SetDebugMessageParentWindow(hParentWnd)
752 #define DEBUG_SETEXE(hInst) DEBUG_DO_NOTHING
756 #define DEBUG_TERMINATE() ::GDB_DebugTerminate()
763 #define MAKEWHO(name) TProgrammer(name, kEveryoneConst, kEveryoneConstLSB, true)
764 #define DECLAREWHO(var, name) TProgrammer var(name, kEveryoneConst, kEveryoneConstLSB, true)
765 #define TEST_ONLY(x) x
767 #define MAKEWHO(name) 0
768 #define DECLAREWHO(var, name) TProgrammer var
773 #define BUG_ONLY(x) x
781 #if 1 || _MINICAD_EXTERNAL_ || _MAGICFOLDER_ || _GSESDK_ || _GSWINSDK_
782 inline void LIMITMESSAGES(
const TProgrammer &) { }
783 inline void LIMITMESSAGES(
const EDebugLevel &) { }
784 inline void LIMITMESSAGES(
const TProgrammer &,
const EDebugLevel &) { }
785 inline void LIMITMESSAGES(
const EDebugLevel &,
const TProgrammer &) { }
786 inline void LIMITMESSAGES() { }
788 extern TProgrammer gProgrammerFilter;
790 inline void LIMITMESSAGES(
const TProgrammer &who) { gProgrammerFilter = who; }
791 inline void LIMITMESSAGES(
const EDebugLevel &level) { debugLevel = level; }
792 inline void LIMITMESSAGES(
const TProgrammer &who,
const EDebugLevel &level) { LIMITMESSAGES(who); LIMITMESSAGES(level); }
793 inline void LIMITMESSAGES(
const EDebugLevel &level,
const TProgrammer &who) { LIMITMESSAGES(who, level); }
794 inline void LIMITMESSAGES() { LIMITMESSAGES(
kEveryone, brief); }
804Sint32 GSDEBUG_EXPORT _FileDebugMessage(
const TProgrammer& toWhom,
const char *file,
Sint32 line,
const char *message);
805Sint32 GSDEBUG_EXPORT _Assert(
const TProgrammer& toWhom,
const char *file,
Sint32 line,
const char *expr);
806Sint32 GSDEBUG_EXPORT _AssertEx(
const TProgrammer & inProgrammer,
const char * inAssertFile,
Sint32 inAssertLine,
const char * inMessage, ...);
819 short _FindContainingBlock(
const TProgrammer& toWhom,
void* ptr,
Sint32& result);
821 Sint32 _AssertNotVolatile(
const TProgrammer& toWhom,
const char* file,
Sint32 line,
const char* ptrName,
void* ptr);
826void GSDEBUG_EXPORT CheckHeap(
const TProgrammer &toWhom =
kEveryone);
833Sint32 GSDEBUG_EXPORT _AssertValidPointer(
const TProgrammer& toWhom,
const char* file,
Sint32 line,
const char* itemName,
const void *ptr,
size_t lByteCount=1,
Bool8 bReadOnly=
false);
834Bool8 GSDEBUG_EXPORT _VerifyValidPointer(
const TProgrammer& toWhom,
const char* file,
Sint32 line,
const char* itemName,
const void *ptr,
size_t lCount=1,
Bool8 bReadOnly=
false);
835Sint32 GSDEBUG_EXPORT _AssertValidString(
Bool8 isAssert,
const TProgrammer& toWhom,
const char* file,
Sint32 line,
const char* itemName,
const char *psz,
Sint32 cbMin=0,
Sint32 cbMax=0);
836Sint32 GSDEBUG_EXPORT _AssertValidHandle(
const TProgrammer& toWhom,
const char* file,
Sint32 line,
const char* itemName, GSHandle h,
size_t lCount=1);
837Sint32 GSDEBUG_EXPORT _AssertValidMenuHandle(
const TProgrammer& toWhom,
const char* file,
Sint32 line,
const char* itemName, GSHandle h);
838Bool8 GSDEBUG_EXPORT _VerifyValidHandle(
const TProgrammer& toWhom,
const char* file,
Sint32 line,
const char* itemName, GSHandle h,
size_t lCount=1);
839Sint32 GSDEBUG_EXPORT _AssertValidPString(
Bool8 isAssert,
const TProgrammer& toWhom,
const char* file,
Sint32 line,
const char* itemName, ConstGSStringPtr ps,
Sint32 cbMin=0,
Sint32 cbMax=0);
843#if defined(_INC_WINDOWS) || defined(_GSWIN_) || GS_HWND_CHECK
845 bool GSDEBUG_EXPORT _ValidateHWND(
const TProgrammer& toWhom,
bool bAssert,
const char* file,
Sint32 line,
const char* itemName,
void *hWnd);
846 bool GSDEBUG_EXPORT _ValidateHDC(
const TProgrammer& toWhom,
bool bAssert,
const char* file,
Sint32 line,
const char* itemName,
void *hdc);
861inline Bool8 VerifyStop(
Bool8 b) { STOP();
return b; }
864 #define ASSERTN(toWhom, exp) \
866 if (!(exp) && _Assert(toWhom, THIS_FILE, __LINE__, #exp)) STOP(); \
869 #define ASSERTLOCKED(toWhom, h) do {;} while (0)
870 #define ASSERTUNLOCKED(toWhom, h) do {;} while (0)
871 #define ASSERTNOTVOLATILE(toWhom, p) do {;} while (0)
872 #define ASSERTHANDLE(toWhom, h, bytes) do {;} while (0)
873 #define ASSERTPSTRING(toWhom, ps, min, max) do {;} while (0)
874 #define VERIFYN(toWhom, exp) \
875 ((Bool8)( (exp) ? true : (_Assert(toWhom, THIS_FILE, __LINE__, #exp) ? VerifyStop(false) : false ) ))
877 #define VERIFYMSG(toWhom, exp, failMsg, ...) \
878 ((Bool8)( (exp) ? true : (_AssertEx(toWhom, THIS_FILE, __LINE__, failMsg, __VA_ARGS__) ? VerifyStop(false) : false ) ))
880 #define ASSERTPOINTER_READONLY(toWhom, ptr, bytes) do {;} while (0)
881 #define ASSERTPOINTER(toWhom, ptr, bytes) do {;} while (0)
882 #define ASSERTSTRING(toWhom, psz, min, max) \
884 if (_AssertValidString(true,toWhom,THIS_FILE,__LINE__,#psz,(const char *)psz,min,max)) STOP(); \
889 #define ASSERTHWND(toWhom, hWnd) \
891 if (!_ValidateHWND(toWhom,true,THIS_FILE,__LINE__,#hWnd,hWnd)) STOP(); \
893 #define VERIFYHWND(toWhom, hWnd) \
894 ( _ValidateHWND(toWhom,FALSE,THIS_FILE,__LINE__,#hWnd,hWnd) ? true : false )
895 #define ASSERTHDC(toWhom, hdc) \
897 if (!_ValidateHDC(toWhom,true,THIS_FILE,__LINE__,#hdc,hdc)) STOP(); \
899 #define VERIFYHDC(toWhom, hdc) \
900 ( _ValidateHDC(toWhom,FALSE,THIS_FILE,__LINE__,#hdc,hdc) ? true : false )
905 #define ASSERTNOFPEXCEPTION() \
913 #define ASSERTN(toWhom, expression) \
915 if (!(expression) && _Assert(toWhom, THIS_FILE, __LINE__, #expression)) STOP(); \
919 #define VERIFYN(toWhom, exp) \
920 ((Bool8)( (exp) ? true : (_Assert(toWhom, THIS_FILE, __LINE__, #exp) ? VerifyStop(false) : false ) ))
922 #define VERIFYMSG(toWhom, exp, failMsg, ...) \
923 ((Bool8)( (exp) ? true : (_AssertEx(toWhom, THIS_FILE, __LINE__, failMsg, ##__VA_ARGS__) ? VerifyStop(false) : false ) ))
925 #define ASSERTSTRING(toWhom, psz, min, max) \
926 ((void)_AssertValidString(true,toWhom,THIS_FILE,__LINE__,#psz,(const char *)psz,min,max))
928 #define ASSERTPOINTER(toWhom, ptr, bytes) \
929 ((void)_AssertValidPointer(toWhom,THIS_FILE,__LINE__,#ptr,ptr,bytes))
931 #define ASSERTPOINTER_READONLY(toWhom, ptr, bytes) ASSERTPOINTER(toWhom, ptr, bytes)
933 Bool8 __IsHandleLocked(GSHandle h);
941 #define ASSERTLOCKED(toWhom,h) ((void) 0)
942 #define ASSERTUNLOCKED(toWhom,h) ((void) 0)
944 #define ASSERTNOTVOLATILE(toWhom, p) \
945 ( ((void)_AssertNotVolatile(toWhom, THIS_FILE, __LINE__, #p, p)) )
946 #define ASSERTHANDLE(toWhom, h, bytes) \
947 ((void)_AssertValidHandle(toWhom,THIS_FILE,__LINE__,#h,(GSHandle)h,bytes))
949 #define ASSERTPSTRING(toWhom, ps, min, max) \
950 ((void)_AssertValidPString(true,toWhom,THIS_FILE,__LINE__,#ps,(const BugStringPtr)ps,min,max))
953 #define ASSERTHWND(toWho, hWnd) \
955 #define VERIFYHWND(toWho, hWnd) \
960 #define ASSERTNOFPEXCEPTION() \
970#define VERIFYHANDLE(toWhom, h, bytes) \
971 ::_VerifyValidHandle(toWhom,THIS_FILE,__LINE__,#h,(GSHandle)h,bytes)
973#define ASSERTHEAP(toWhom) \
976#define VERIFYPOINTER(toWhom, ptr, bytes) \
977 ::_VerifyValidPointer(toWhom,THIS_FILE,__LINE__,#ptr,ptr,bytes,false)
979#define VERIFYPOINTER_READONLY(toWhom, ptr, bytes) \
980 ::_VerifyValidPointer(toWhom,THIS_FILE,__LINE__,#ptr,ptr,bytes,true)
982#define VERIFYSTRING(toWhom, psz, min, max) \
983 ::_AssertValidString(false,toWhom,THIS_FILE,__LINE__,#psz,(const char*)psz,min,max)
985#define VERIFYPSTRING(toWhom, ps, min, max) \
986 ::_AssertValidPString(false,toWhom,THIS_FILE,__LINE__,#ps,(const BugStringPtr)ps,min,max)
988#define ASSERTMENUHANDLE(toWhom, menu) \
989 ::_AssertValidMenuHandle(toWhom,THIS_FILE,__LINE__,#menu,(GSHandle)menu)
994extern std::atomic_flag gDSTOPLock;
996#define DSTOP(params) do { \
997 if ( ! gDSTOPLock.test_and_set()) { \
998 GSDebug::SetDStopFileName(THIS_FILE); \
999 GSDebug::SetDStopLineNumber(__LINE__); \
1000 if (::__DebugMessageStop params) STOP(); \
1001 GSDebug::SetDStopLineNumber(-1); \
1002 gDSTOPLock.clear(); \
1008#define GS_REMOVE_CONDITIONAL_DebugMessageStop 1
1010#if GS_REMOVE_CONDITIONAL_DebugMessageStop
1011#define DSTOPIF(condition, params) if (condition) DSTOP(params);
1013#define DSTOPIF(condition, params) DEBUG_DO_NOTHING
1017Bool8 GSDEBUG_EXPORT __DebugMessageStop(
const TProgrammer& toWhom, EDebugLevel level,
const char *szFmt, ...);
1018Bool8 GSDEBUG_EXPORT __DebugMessageStop(EDebugLevel level,
const TProgrammer& toWhom,
const char *szFmt, ...);
1019Bool8 GSDEBUG_EXPORT __DebugMessageStop(EDebugLevel level,
const char *szFmt, ...);
1020Bool8 GSDEBUG_EXPORT __DebugMessageStop(
const TProgrammer& toWhom,
const char *szFmt, ...);
1022#if ! GS_REMOVE_CONDITIONAL_DebugMessageStop
1023Bool8 GSDEBUG_EXPORT __DebugMessageStop(
Bool8 exp,
const TProgrammer& toWhom, EDebugLevel level,
const char *szFmt, ...);
1024Bool8 GSDEBUG_EXPORT __DebugMessageStop(
Bool8 exp, EDebugLevel level,
const TProgrammer& toWhom,
const char *szFmt, ...);
1025Bool8 GSDEBUG_EXPORT __DebugMessageStop(
Bool8 exp, EDebugLevel level,
const char *szFmt, ...);
1026Bool8 GSDEBUG_EXPORT __DebugMessageStop(
Bool8 exp,
const TProgrammer& toWhom,
const char *szFmt, ...);
1027Bool8 GSDEBUG_EXPORT __DebugMessageStop(
Bool8 exp,
const char *szFmt, ...);
1042#define DMSG(params) ::__DebugMessage params
1046#define DMSGIF(condition, params) if (condition) DMSG(params);
1049#if !GS_USE_ONLY_MODERN || GS_GSDEBUG_BUILD
1050void GSDEBUG_EXPORT __DebugMessage(EDebugLevel level,
const char *szFmt, ...);
1051void GSDEBUG_EXPORT __DebugMessage(
const char *szFmt, ...);
1052#if ! GS_REMOVE_CONDITIONAL_DebugMessageStop
1053void GSDEBUG_EXPORT __DebugMessage(
Bool8 exp, EDebugLevel level,
const char *szFmt, ...);
1054void GSDEBUG_EXPORT __DebugMessage(
Bool8 exp,
const char *szFmt, ...);
1057void GSDEBUG_EXPORT __DebugMessage(
const TProgrammer& toWhom, EDebugLevel level,
const char *szFmt, ...);
1058void GSDEBUG_EXPORT __DebugMessage(EDebugLevel level,
const TProgrammer& toWhom,
const char *szFmt, ...);
1059void GSDEBUG_EXPORT __DebugMessage(
const TProgrammer& toWhom,
const char *szFmt, ...);
1060#if ! GS_REMOVE_CONDITIONAL_DebugMessageStop
1061void GSDEBUG_EXPORT __DebugMessage(
Bool8 exp,
const TProgrammer& toWhom, EDebugLevel level,
const char *szFmt, ...);
1062void GSDEBUG_EXPORT __DebugMessage(
Bool8 exp, EDebugLevel level,
const TProgrammer& toWhom,
const char *szFmt, ...);
1063void GSDEBUG_EXPORT __DebugMessage(
Bool8 exp,
const TProgrammer& toWhom,
const char *szFmt, ...);
1069#if GS_USE_CLASS_DEBUGGING
1071 class GSDEBUG_EXPORT TDumpDevice
1077 virtual ~TDumpDevice() {}
1079 Sint32 printf(
const TProgrammer &toWhom,
Sint32 indent,
const char *fmt, ...)
const;
1080 Sint32 printf(
const char *fmt, ...)
const;
1082 void SetIndent(
Sint32 indent) { fIndent = indent; }
1083 void SetWho(
const TProgrammer &toWhom) { fWho = toWhom; }
1086 virtual Sint32 vprintf(
const TProgrammer &toWhom,
Sint32 indent,
const char *fmt, va_list ¶ms)
const = 0;
1092 class GSDEBUG_EXPORT TTextDumpDevice :
public TDumpDevice
1095 virtual ~TTextDumpDevice() {}
1097 Sint32 vprintf(
const TProgrammer &toWhom,
Sint32 indent,
const char *fmt, va_list ¶ms)
const;
1100 extern TTextDumpDevice gl_stdDumpDevice;
1102 #define DUMPCLASS(toWhom, ptr) (ptr)->Dump(toWhom, gl_stdDumpDevice, 0)
1104 #define DUMPCLASS(toWhom, ptr) DEBUG_DO_NOTHING
1106#define DUMPCLASSH(toWhom, hType, h) DUMPCLASS(toWhom, *(hType)(h))
1107#define DUMPCLASSHANDLE(toWhom, h) DUMPCLASS(toWhom, *(h))
1108#define DUMPTHISCLASS(toWhom) DUMPCLASS(toWhom, this)
1111 #define ASSERTCLASS(toWhom, ptr) (ptr)->AssertValid(toWhom, true)
1112 #define VERIFYCLASS(toWhom, ptr) ( (ptr) ? ((ptr)->AssertValid(toWhom, true), true) : VerifyStop(false))
1114 #define ASSERTCLASS(toWhom, ptr) DEBUG_DO_NOTHING
1115 #define VERIFYCLASS(toWhom, ptr) ((ptr) != nil)
1117#define ASSERTCLASSH(toWhom, type, h) ASSERTCLASSHANDLE(toWhom, (type)(h))
1118#define ASSERTCLASSHANDLE(toWhom, h) do { if (VERIFYHANDLE(toWhom, h, 0)) ASSERTCLASS(toWhom, *(h)); } while (0)
1119#define ASSERTTHISCLASS(toWhom) ASSERTCLASS(toWhom, this)
1120#define VERIFYCLASSH(toWhom, type, h) VERIFYCLASSHANDLE(toWhom, (type)(h))
1121#define VERIFYCLASSHANDLE(toWhom, h) (VERIFYHANDLE(toWhom, h, 0) ? VERIFYCLASS(toWhom, *(h)) : 0)
1122#define VERIFYTHISCLASS(toWhom) VERIFYCLASS(toWhom, this)
1125 #define DECLARE_ASSERTVALID \
1126 void AssertValid(const TProgrammer &toWhom, Bool8 bCheckMem) const;
1127 #define DECLARE_VIRTUAL_ASSERTVALID \
1128 virtual DECLARE_ASSERTVALID
1129 #define IMPLEMENT_ASSERTVALID(av_classname, av_parentclass, av_checks) \
1130 void av_classname::AssertValid(const TProgrammer &toWhom, Bool8 bCheckMem) const \
1132 if (bCheckMem) ASSERTPOINTER(toWhom, this, sizeof(av_classname)); \
1133 av_parentclass::AssertValid(toWhom, false); \
1137 #define DECLARE_ASSERTVALID
1138 #define DECLARE_VIRTUAL_ASSERTVALID
1139 #define IMPLEMENT_ASSERTVALID(av_classname, av_parentclass, av_checks)
1143 #define DECLARE_DUMP \
1144 void Dump(const TProgrammer &toWhom, TDumpDevice &dd, Sint32 indent) const;
1145 #define DECLARE_VIRTUAL_DUMP \
1146 virtual DECLARE_DUMP
1147 #define IMPLEMENT_DUMP(d_classname, d_parentclass, d_checks) \
1148 void d_classname::Dump(const TProgrammer &toWhom, TDumpDevice &dd, Sint32 indent) const \
1150 if (_IsUser(toWhom)) { \
1151 d_parentclass::Dump(toWhom, dd, indent); \
1152 dd.printf(toWhom, indent, #d_classname " class:\n"); \
1158 #define DECLARE_DUMP
1159 #define DECLARE_VIRTUAL_DUMP
1160 #define IMPLEMENT_DUMP(d_classname, d_parentclass, d_checks)
1165#define DUMP_BOOL(dp) \
1166 dd.printf(toWhom, indent, #dp " = %s (%d)\n", (dp) ? "true" : "false", (Sint32)(dp))
1167#define DUMP_CHAR(dp) \
1169#define DUMP_CLASS(dp) \
1171 dd.printf(toWhom, indent, #dp " =\n"); \
1172 (dp).Dump(toWhom, dd, indent+1); \
1174#define DUMP_CLASSHANDLE(dp) \
1176 if (dp) DUMP_CLASSPTR(*dp); \
1177 else DUMP_NULL(dp); \
1179#define DUMP_CLASSPTR(dp) \
1181 if (dp) DUMP_CLASS(*dp); \
1182 else DUMP_NULL(dp); \
1184#define DUMP_DOUBLE(dp) \
1186#define DUMP_HANDLE(dp) \
1188 if (dp && *dp) dd.printf(toWhom, indent, #dp " = 0x%p, *" #dp " = 0x%p\n", dp, *dp); \
1189 else if (dp) dd.printf(toWhom, indent, #dp " = 0x%p, *" #dp " = NULL\n", dp); \
1190 else DUMP_NULL(dp); \
1192#define DUMP_INT(dp) \
1194#define DUMP_ITEM(fmt, dp) \
1195 dd.printf(toWhom, indent, #dp " = " fmt "\n", dp)
1196#define DUMP_MSG(msg) \
1198 dd.SetIndent(indent); \
1199 dd.SetWho(toWhom); \
1202#define DUMP_NULL(dp) \
1203 dd.printf(toWhom, indent, #dp " = NULL\n")
1204#define DUMP_PSTR(dp) \
1206 if ((const unsigned char*)(dp)) dd.printf(toWhom, indent, #dp " = len:%d, \"%s\"\n", strlen(dp), TXSTRINGPRINT(dp)); \
1207 else DUMP_NULL(dp); \
1209#define DUMP_PTR(dp) \
1211 if (dp) DUMP_ITEM("0x%p", dp); \
1212 else DUMP_NULL(dp); \
1214#define DUMP_RECT(dp) \
1215 dd.printf(toWhom, indent, #dp " = (%d,%d)-(%d,%d)\n", RECTPRINT(dp))
1216#define DUMP_STR(dp) \
1218 if ((const char*)(dp)) dd.printf(toWhom, indent, #dp " = len:%d, \"%s\"\n", strlen(dp), TXSTRINGPRINT(dp)); \
1219 else DUMP_NULL(dp); \
1224#define DECLARE_SIZEOF \
1225 size_t SizeOf() const;
1226#define IMPLEMENT_SIZEOF(classname) \
1227 size_t classname::SizeOf() const
1228#define DECLIMP_SIZEOF(classname) \
1229 size_t SizeOf() const { return sizeof(classname); }
1234#define DECLARE_ASSERTVALID
1235#define DECLARE_VIRTUAL_ASSERTVALID
1236#define IMPLEMENT_ASSERTVALID(av_classname, av_parentclass, av_checks)
1239#define DECLARE_VIRTUAL_DUMP
1240#define IMPLEMENT_DUMP(d_classname, d_parentclass, d_checks)
1246#define DECLARE_CLASS_DEBUGGING \
1247 DECLARE_ASSERTVALID \
1250#define DECLARE_VIRTUAL_CLASS_DEBUGGING \
1251 DECLARE_VIRTUAL_ASSERTVALID \
1252 DECLARE_VIRTUAL_DUMP
1255class GSDEBUG_EXPORT TDebugObject
1260 void AssertValid(
const TProgrammer &toWhom,
Bool8 bCheckMem)
const;
1266class GSDEBUG_EXPORT TVirtualDebugObject
1269 virtual ~TVirtualDebugObject() {}
1270 DECLARE_VIRTUAL_CLASS_DEBUGGING
1279class GSDEBUG_EXPORT TWinErrorCode
1285 operator const char *()
const {
return (
const char *)fMessageBuffer; }
1288 void *fMessageBuffer;
1296 Sint32 GSDEBUG_EXPORT _AssertValidFilePath(
Bool8 isAssert,
const TProgrammer& toWhom,
const char* file,
Sint32 line,
const char* itemName,
const char* fullPath);
1298 #define ASSERTPATH(who, fullPath) \
1300 if (::_AssertValidFilePath(true, who, THIS_FILE, __LINE__, #fullPath, fullPath)) STOP(); \
1303 #define VERIFYPATH(who, fullPath) \
1304 ::_AssertValidFilePath(false, who, THIS_FILE, __LINE__, #fullPath, fullPath)
1308 #define ASSERTPATH(who, fullPath) DEBUG_DO_NOTHING
1309 #define VERIFYPATH(who, fullPath) ((BOOL)( (fullPath) != 0 ))
1318 #define DMSG(params) DEBUG_DO_NOTHING
1320 inline void LIMITMESSAGES(
const TProgrammer &) {}
1321 inline void LIMITMESSAGES(
const EDebugLevel &) {}
1322 inline void LIMITMESSAGES(
const TProgrammer &,
const EDebugLevel &) {}
1323 inline void LIMITMESSAGES(
const EDebugLevel &,
const TProgrammer &) {}
1324 inline void LIMITMESSAGES() {}
1329#define for_i(size) for( size_t i=0; i<size; i++ )
1330#define for_j(size) for( size_t j=0; j<size; j++ )
1331#define for_k(size) for( size_t k=0; k<size; k++ )
1332#define for_m(size) for( size_t m=0; m<size; m++ )
1334#define for_it( container ) for( auto it = (container).begin(); it != (container).end(); ++it )
1335#define for_jt( container ) for( auto jt = (container).begin(); jt != (container).end(); ++jt )
1336#define for_kt( container ) for( auto kt = (container).begin(); kt != (container).end(); ++kt )
1337#define for_mt( container ) for( auto mt = (container).begin(); mt != (container).end(); ++mt )
1370 static std::string GetString(
const std::string & inKey)
1372 TDebugFile & db = GetInstance();
1375 return db.fData[inKey];
1378 static int GetInt(
const std::string & inKey)
1380 TDebugFile & db = GetInstance();
1385 auto it = db.fData.find(inKey);
1386 if( it != db.fData.end() )
1387 return std::stoi(it->second);
1396 static float GetFloat(
const std::string & inKey)
1398 TDebugFile & db = GetInstance();
1403 auto it = db.fData.find(inKey);
1404 if( it != db.fData.end() )
1405 return std::stof(it->second);
1414 static double GetDouble(
const std::string & inKey)
1416 TDebugFile & db = GetInstance();
1421 auto it = db.fData.find(inKey);
1422 if( it != db.fData.end() )
1423 return std::stod(it->second);
1432 static bool GetBool(
const std::string & inKey)
1434 TDebugFile & db = GetInstance();
1441#pragma warning(disable:4996)
1443 auto it = db.fData.find(inKey);
1444 if( it != db.fData.end() )
1446 if( stricmp(it->second.c_str(),
"true") == 0 )
1448 else if( stricmp(it->second.c_str(),
"false") == 0 )
1462 static std::ostream & GetOutputStream()
1464 std::ofstream & outStream = GetInstance().fOutputStream;
1466 if( !outStream.is_open() )
1467 outStream.open(
"c:\\a\\debugOutput.txt");
1478 static bool first =
true;
1479 static auto lastTick = std::chrono::high_resolution_clock::now();
1480 auto tick = std::chrono::high_resolution_clock::now();
1482 if( first || std::chrono::duration_cast<std::chrono::milliseconds>(tick-lastTick).count() > 1000 )
1488 std::ifstream dbgFile(
"c:\\a\\debug.txt");
1490 std::ifstream dbgFile(
"/a/debug.txt");
1492 if( dbgFile.is_open() )
1496 dbgFile.seekg(0, std::ios::end);
1497 size_t size = size_t(dbgFile.tellg());
1498 dbgFile.seekg(0, std::ios::beg);
1500 std::string contents;
1501 contents.resize(size+1);
1502 dbgFile.read(&contents[0], size);
1509#define CheckEOF(index) if( index >= contents.size() ) break
1511 while( offset < contents.size() )
1517 offset = contents.find_first_not_of(
" \t\n\r", offset);
1520 size_t endOffset = offset;
1522 if( contents[offset] ==
'"' )
1523 endOffset = contents.find_first_of(
"\"", ++offset);
1525 endOffset = contents.find_first_of(
" \t\n\r=", offset);
1527 if( offset == endOffset )
1529 CheckEOF(endOffset);
1531 key = contents.substr(offset, endOffset-offset);
1534 offset = contents.find_first_of(
"=", offset);
1538 offset = contents.find_first_not_of(
" \t\n\r", offset);
1544 if( contents[endOffset] ==
'"' )
1545 endOffset = contents.find_first_of(
"\"", ++offset);
1547 endOffset = contents.find_first_of(
" \t\n\r", endOffset);
1549 CheckEOF(endOffset);
1551 value = contents.substr(offset, endOffset-offset);
1556 offset = contents.find_first_of(
"\n\r", offset);
1558 CheckEOF(endOffset);
1567 static TDebugFile & GetInstance()
1569 static TDebugFile gDebugFile;
1573 std::map<std::string, std::string> fData;
1574 std::ofstream fOutputStream;
unsigned char Bool8
Definition GSTypes.h:79
uint16_t Uint16
Definition GSTypes.h:26
int32_t Sint32
Definition GSTypes.h:36
uint64_t Uint64
Definition GSTypes.h:28
uint32_t Uint32
Definition GSTypes.h:27
#define kEveryone
Definition StdAfx.h:43