diff --git a/src/gui/control/card_viewer.cpp b/src/gui/control/card_viewer.cpp index 12cbc6f5..34a2c8ca 100644 --- a/src/gui/control/card_viewer.cpp +++ b/src/gui/control/card_viewer.cpp @@ -72,7 +72,9 @@ void CardViewer::onChangeSize() { void CardViewer::onPaint(wxPaintEvent&) { #ifdef _DEBUG // we don't want recursion - assert(!inOnPaint()); + if (inOnPaint()) { + wxTrap(); + } WITH_DYNAMIC_ARG(inOnPaint, true); #endif wxSize cs = GetClientSize(); @@ -129,7 +131,9 @@ class CardViewer::OverdrawDC : private OverdrawDC_aux, public RotatedDC { shared_ptr CardViewer::overdrawDC() { #ifdef _DEBUG // don't call from onPaint - assert(!inOnPaint()); + if (inOnPaint()) { + wxTrap(); + } #endif return shared_ptr(new OverdrawDC(this)); } diff --git a/src/main.cpp b/src/main.cpp index c059bebc..fb68e1a2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,6 +46,10 @@ class MSE : public wxApp { int OnExit(); /// On exception: display error message bool OnExceptionInMainLoop(); + /// Fancier assert + #if defined(_MSC_VER) && defined(_DEBUG) + void OnAssert(const wxChar *file, int line, const wxChar *cond, const wxChar *msg); + #endif }; IMPLEMENT_APP(MSE) @@ -265,3 +269,18 @@ bool MSE::OnExceptionInMainLoop() { } CATCH_ALL_ERRORS(true); return true; } + +#if defined(_MSC_VER) && defined(_DEBUG) + // Print assert failures to debug output + void msvc_assert(const char*, const char*, const char*, unsigned); + void MSE::OnAssert(const wxChar *file, int line, const wxChar *cond, const wxChar *msg) { + #ifdef UNICODE + char file_[1024]; wcstombs(file_,file,1023); + char cond_[1024]; wcstombs(cond_,cond,1023); + char msg_ [1024]; wcstombs(msg_, msg, 1023); + msvc_assert(msg_, cond_, file_, line); + #else + msvc_assert(msg, cond, file, line); + #endif + } +#endif diff --git a/src/util/error.cpp b/src/util/error.cpp index db0e919e..e861b50a 100644 --- a/src/util/error.cpp +++ b/src/util/error.cpp @@ -12,6 +12,25 @@ DECLARE_TYPEOF_COLLECTION(ScriptParseError); +// ----------------------------------------------------------------------------- : Debug utilities + +#if defined(_MSC_VER) && defined(_DEBUG) + void msvc_assert(const char* msg, const char* expr, const char* file, unsigned line) { + if (IsDebuggerPresent()) { + char buffer[1024]; + if (msg) { + sprintf(buffer, "Assertion failed: %s: %s, file %s, line %d\n", msg, expr, file, line); + } else { + sprintf(buffer, "Assertion failed: %s, file %s, line %d\n", expr, file, line); + } + OutputDebugStringA(buffer); + DebugBreak(); + } else { + _assert(expr, file, line); + } + } +#endif + // ----------------------------------------------------------------------------- : Error types Error::Error(const String& message) diff --git a/src/util/prec.hpp b/src/util/prec.hpp index 737eafe4..53eb881d 100644 --- a/src/util/prec.hpp +++ b/src/util/prec.hpp @@ -80,12 +80,21 @@ class FileName : public wxString { #include "reflect.hpp" #include "regex.hpp" +// ----------------------------------------------------------------------------- : Debugging fixes + #ifdef _MSC_VER -//# pragma conform(forScope,on) // in "for(int x=..);" x goes out of scope after the for -// somehow forScope pragma doesn't work in precompiled headers, use this hack instead: -#ifdef _DEBUG - #define for if(false);else for -#endif + //# pragma conform(forScope,on) // in "for(int x=..);" x goes out of scope after the for + // somehow forScope pragma doesn't work in precompiled headers, use this hack instead: + #ifdef _DEBUG + #define for if(false);else for + #endif + + #ifdef _DEBUG + // Use OutputDebugString/DebugBreak for assertions if in debug mode + void msvc_assert(const char*, const char*, const char*, unsigned); + #undef assert + #define assert(exp) (void)( (exp) || (msvc_assert(nullptr, #exp, __FILE__, __LINE__), 0) ) + #endif #endif // ----------------------------------------------------------------------------- : EOF diff --git a/src/util/regex.hpp b/src/util/regex.hpp index 51cbe4d0..57da3a12 100644 --- a/src/util/regex.hpp +++ b/src/util/regex.hpp @@ -54,6 +54,9 @@ } }; + inline Regex() {} + inline Regex(const String& code) { assign(code); } + void assign(const String& code); inline bool matches(const String& str) const { return regex_search(str.begin(), str.end(), regex); @@ -126,6 +129,9 @@ friend class ScriptRegex; }; + inline Regex() {} + inline Regex(const String& code) { assign(code); } + void assign(const String& code); inline bool matches(const String& str) const { return regex.Matches(str);