X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dfa0b52f4ac947d5e7566dabb81c39bbf881fac5..50fae378f2cad3ba80dcdc024ee8fbb620e79045:/include/wx/debug.h diff --git a/include/wx/debug.h b/include/wx/debug.h index e783d5efac..936755e71b 100644 --- a/include/wx/debug.h +++ b/include/wx/debug.h @@ -19,7 +19,7 @@ #endif #include /* for CHAR_BIT used below */ -#include "wx/wxchar.h" /* for __TFILE__ and wxChar */ +#include "wx/chartype.h" /* for __TFILE__ and wxChar */ /* ---------------------------------------------------------------------------- */ /* Defines controlling the debugging macros */ @@ -47,17 +47,28 @@ #endif /* !WXDEBUG */ #endif /* __WXDEBUG__ */ -/* TODO: add more compilers supporting __FUNCTION__ */ -#if defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1300) - #define __TFUNC__ wxAPPLY_T(__FUNCTION__) -#else /* old compilers without __FUNCTION__ support */ - #define __TFUNC__ _T("") -#endif +#ifndef __WXFUNCTION__ + /* TODO: add more compilers supporting __FUNCTION__ */ + #if defined(__DMC__) + /* + __FUNCTION__ happens to be not defined within class members + http://www.digitalmars.com/drn-bin/wwwnews?c%2B%2B.beta/485 + */ + #define __WXFUNCTION__ (NULL) + #elif defined(__GNUC__) || \ + (defined(_MSC_VER) && _MSC_VER >= 1300) || \ + defined(__FUNCTION__) + #define __WXFUNCTION__ __FUNCTION__ + #else + /* still define __WXFUNCTION__ to avoid #ifdefs elsewhere */ + #define __WXFUNCTION__ (NULL) + #endif +#endif /* __WXFUNCTION__ already defined */ /* ---------------------------------------------------------------------------- */ /* Debugging macros */ /* */ -/* All debugging macros rely on ASSERT() which in turn calls user-defined */ +/* All debugging macros rely on ASSERT() which in turn calls the user-defined */ /* OnAssert() function. To keep things simple, it's called even when the */ /* expression is true (i.e. everything is ok) and by default does nothing: just */ /* returns the same value back. But if you redefine it to do something more sexy */ @@ -81,58 +92,128 @@ /* This function is called whenever one of debugging macros fails (i.e. condition is false in an assertion). To customize its behaviour, override - wxApp::OnAssert(). + wxApp::OnAssertFailure(). Parameters: szFile and nLine - file name and line number of the ASSERT - szFunc - function name of the ASSERT, may be empty + szFunc - function name of the ASSERT, may be NULL (NB: ASCII) szCond - text form of the condition which failed szMsg - optional message explaining the reason */ + + /* this version is for compatibility with wx 2.8 Unicode build only: */ extern void WXDLLIMPEXP_BASE wxOnAssert(const wxChar *szFile, int nLine, - const wxChar *szFunc, + const char *szFunc, const wxChar *szCond, const wxChar *szMsg = NULL); +#if wxUSE_UNICODE + /* char versions are used by debugging macros; we have to provide + wxChar* szMsg version because it's common to use _T() in the macros + and finally, we can't use const wx(char)* szMsg = NULL, because that + would be ambiguous: */ + extern void WXDLLIMPEXP_BASE wxOnAssert(const char *szFile, + int nLine, + const char *szFunc, + const char *szCond); + + extern void WXDLLIMPEXP_BASE wxOnAssert(const char *szFile, + int nLine, + const char *szFunc, + const char *szCond, + const char *szMsg); + + extern void WXDLLIMPEXP_BASE wxOnAssert(const char *szFile, + int nLine, + const char *szFunc, + const char *szCond, + const wxChar *szMsg); +#endif /* wxUSE_UNICODE */ + + class WXDLLIMPEXP_FWD_BASE wxString; + class WXDLLIMPEXP_FWD_BASE wxCStrData; + + /* these two work when szMsg passed to debug macro is a string, + we also have to provide wxCStrData overload to resolve ambiguity + which would otherwise arise from wxASSERT( s.c_str() ): */ + extern void WXDLLIMPEXP_BASE wxOnAssert(const wxString& szFile, + int nLine, + const wxString& szFunc, + const wxString& szCond, + const wxString& szMsg); + + extern void WXDLLIMPEXP_BASE wxOnAssert(const wxString& szFile, + int nLine, + const wxString& szFunc, + const wxString& szCond); + + extern void WXDLLIMPEXP_BASE wxOnAssert(const char *szFile, + int nLine, + const char *szFunc, + const char *szCond, + const wxCStrData& msg); + + extern void WXDLLIMPEXP_BASE wxOnAssert(const char *szFile, + int nLine, + const char *szFunc, + const char *szCond, + const wxString& szMsg); + /* call this function to break into the debugger unconditionally (assuming */ /* the program is running under debugger, of course) */ extern void WXDLLIMPEXP_BASE wxTrap(); /* generic assert macro */ - #define wxASSERT(cond) wxASSERT_MSG(cond, NULL) - - /* assert with additional message explaining it's cause */ - #define wxASSERT_MSG(cond, msg) \ - if ( cond ) \ - ; \ - else \ - wxOnAssert(__TFILE__, __LINE__, __TFUNC__, _T(#cond), msg) + #define wxASSERT(cond) wxASSERT_MSG(cond, (const char*)NULL) + + + /* assert with additional message explaining its cause */ + + /* compilers can give a warning (such as "possible unwanted ;") when using */ + /* the default definition of wxASSERT_MSG so we provide an alternative */ + #if defined(__MWERKS__) + #define wxASSERT_MSG(cond, msg) \ + if ( cond ) \ + {} \ + else \ + wxOnAssert(__FILE__, __LINE__, __WXFUNCTION__, #cond, msg) + #else + #define wxASSERT_MSG(cond, msg) \ + if ( cond ) \ + ; \ + else \ + wxOnAssert(__FILE__, __LINE__, __WXFUNCTION__, #cond, msg) + #endif /* special form of assert: always triggers it (in debug mode) */ - #define wxFAIL wxFAIL_MSG(NULL) + #define wxFAIL wxFAIL_MSG((const char*)NULL) /* FAIL with some message */ - #define wxFAIL_MSG(msg) \ - wxOnAssert(__TFILE__, __LINE__, __TFUNC__, _T("wxAssertFailure"), msg) + #define wxFAIL_MSG(msg) wxFAIL_COND_MSG("wxAssertFailure", msg) + + /* FAIL with some message and a condition */ + #define wxFAIL_COND_MSG(cond, msg) \ + wxOnAssert(__FILE__, __LINE__, __WXFUNCTION__, cond, msg) - /* an assert helper used to avoid warning when testing constant expressions, */ + /* An assert helper used to avoid warning when testing constant expressions, */ /* i.e. wxASSERT( sizeof(int) == 4 ) can generate a compiler warning about */ /* expression being always true, but not using */ /* wxASSERT( wxAssertIsEqual(sizeof(int), 4) ) */ /* */ - /* NB: this is made obsolete by wxCOMPILE_TIME_ASSERT() and shouldn't be */ - /* used any longer */ + /* NB: this is made obsolete by wxCOMPILE_TIME_ASSERT() and should no */ + /* longer be used. */ extern bool WXDLLIMPEXP_BASE wxAssertIsEqual(int x, int y); #else #define wxTrap() - /* nothing to do in release modes (hopefully at this moment there are */ + /* nothing to do in release mode (hopefully at this moment there are */ /* no more bugs ;-) */ #define wxASSERT(cond) #define wxASSERT_MSG(cond, msg) #define wxFAIL #define wxFAIL_MSG(msg) + #define wxFAIL_COND_MSG(cond, msg) #endif /* __WXDEBUG__ */ #ifdef __cplusplus @@ -143,34 +224,48 @@ #define wxAssertFailure wxFalse -/* NB: the following macros work also in release mode! */ +/* NB: the following macros also work in release mode! */ /* These macros must be used only in invalid situation: for example, an - invalid parameter (NULL pointer) is passed to a function. Instead of + invalid parameter (e.g. a NULL pointer) is passed to a function. Instead of dereferencing it and causing core dump the function might try using CHECK( p != NULL ) or CHECK( p != NULL, return LogError("p is NULL!!") ) */ /* check that expression is true, "return" if not (also FAILs in debug mode) */ -#define wxCHECK(cond, rc) wxCHECK_MSG(cond, rc, NULL) +#define wxCHECK(cond, rc) wxCHECK_MSG(cond, rc, (const char*)NULL) /* as wxCHECK but with a message explaining why we fail */ #define wxCHECK_MSG(cond, rc, msg) wxCHECK2_MSG(cond, return rc, msg) /* check that expression is true, perform op if not */ -#define wxCHECK2(cond, op) wxCHECK2_MSG(cond, op, NULL) +#define wxCHECK2(cond, op) wxCHECK2_MSG(cond, op, (const char*)NULL) /* as wxCHECK2 but with a message explaining why we fail */ -#define wxCHECK2_MSG(cond, op, msg) \ - if ( cond ) \ - ; \ - else \ - do \ + +/* see comment near the definition of wxASSERT_MSG for the # if/else reason */ +#if defined(__MWERKS__) + #define wxCHECK2_MSG(cond, op, msg) \ + if ( cond ) \ + {} \ + else \ { \ - wxOnAssert(__TFILE__, __LINE__, __TFUNC__, _T(#cond), msg); \ + wxFAIL_COND_MSG(#cond, msg); \ op; \ - } while ( 0 ) + } \ + struct wxDummyCheckStruct /* just to force a semicolon */ +#else + #define wxCHECK2_MSG(cond, op, msg) \ + if ( cond ) \ + ; \ + else \ + { \ + wxFAIL_COND_MSG(#cond, msg); \ + op; \ + } \ + struct wxDummyCheckStruct /* just to force a semicolon */ +#endif /* special form of wxCHECK2: as wxCHECK, but for use in void functions */ /* */