diff --git a/docs/changes.txt b/docs/changes.txt index 499cd9c0bb..f1d54ad02f 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -53,6 +53,7 @@ All: - Allow recursive calls to wxYield(). - Add wxART_FULL_SCREEN standard bitmap (Igor Korot). - Fix wxStringTokenizer copy ctor and assignment operator. +- Added wxASSERT_MSG_AT() and wxFAIL_MSG_AT() macros. Unix: diff --git a/include/wx/debug.h b/include/wx/debug.h index 539a892575..6a7b491d1f 100644 --- a/include/wx/debug.h +++ b/include/wx/debug.h @@ -282,34 +282,44 @@ extern WXDLLIMPEXP_BASE void wxOnAssert(const char *file, // reasons (if we changed its return type, we'd need to change wxApp:: // OnAssertFailure() too which would break user code overriding it), hence // the need for the ugly global flag. - #define wxASSERT_MSG(cond, msg) \ + #define wxASSERT_MSG_AT(cond, msg, file, line, func) \ wxSTATEMENT_MACRO_BEGIN \ if ( wxTheAssertHandler && !(cond) && \ - (wxOnAssert(__FILE__, __LINE__, __WXFUNCTION__, \ - #cond, msg), wxTrapInAssert) ) \ + (wxOnAssert(file, line, func, #cond, msg), \ + wxTrapInAssert) ) \ { \ wxTrapInAssert = false; \ wxTrap(); \ } \ wxSTATEMENT_MACRO_END + // A version asserting at the current location. + #define wxASSERT_MSG(cond, msg) \ + wxASSERT_MSG_AT(cond, msg, __FILE__, __LINE__, __WXFUNCTION__) + // a version without any additional message, don't use unless condition // itself is fully self-explanatory #define wxASSERT(cond) wxASSERT_MSG(cond, (const char*)NULL) // wxFAIL is a special form of assert: it always triggers (and so is // usually used in normally unreachable code) - #define wxFAIL_COND_MSG(cond, msg) \ + #define wxFAIL_COND_MSG_AT(cond, msg, file, line, func) \ wxSTATEMENT_MACRO_BEGIN \ if ( wxTheAssertHandler && \ - (wxOnAssert(__FILE__, __LINE__, __WXFUNCTION__, \ - cond, msg), wxTrapInAssert) ) \ + (wxOnAssert(file, line, func, #cond, msg), \ + wxTrapInAssert) ) \ { \ wxTrapInAssert = false; \ wxTrap(); \ } \ wxSTATEMENT_MACRO_END + #define wxFAIL_MSG_AT(msg, file, line, func) \ + wxFAIL_COND_MSG_AT("Assert failure", msg, file, line, func) + + #define wxFAIL_COND_MSG(cond, msg) \ + wxFAIL_COND_MSG_AT(cond, msg, __FILE__, __LINE__, __WXFUNCTION__) + #define wxFAIL_MSG(msg) wxFAIL_COND_MSG("Assert failure", msg) #define wxFAIL wxFAIL_MSG((const char*)NULL) #else // !wxDEBUG_LEVEL diff --git a/interface/wx/debug.h b/interface/wx/debug.h index 72db9d8238..90e52d734a 100644 --- a/interface/wx/debug.h +++ b/interface/wx/debug.h @@ -140,6 +140,27 @@ typedef void (*wxAssertHandler_t)(const wxString& file, */ #define wxASSERT_MSG( condition, message ) +/** + Assert macro pretending to assert at the specified location. + + This macro is the same as wxASSERT_MSG(), but the assert message will use + the specified source file, line number and function name instead of the + values corresponding to the current location as done by wxASSERT_MSG() by + default. + + It is mostly useful for asserting inside functions called from macros, as + by passing the usual @c __FILE__, @c __LINE__ and @c __FUNCTION__ values to + a function, it's possible to pretend that the assert happens at the + location of the macro in the source code (which can be useful) instead of + inside the function itself (which is never useful as these values are + always the same for the given assertion). + + @since 3.1.0 + + @header{wx/debug.h} + */ +#define wxASSERT_MSG_AT( condition, message, file, line, func ) + /** Checks that the condition is @true, returns with the given return value if not (stops execution in debug mode). This check is done even in release mode. @@ -312,6 +333,18 @@ void wxDisableAsserts(); */ #define wxFAIL_MSG( message ) +/** + Assert failure macro pretending to assert at the specified location. + + This is a cross between wxASSERT_MSG_AT() and wxFAIL_MSG(), see their + documentation for more details. + + @since 3.1.0 + + @header{wx/debug.h} + */ +#define wxFAIL_MSG_AT( message, file, line, func ) + /** Returns @true if the program is running under debugger, @false otherwise.