#include "wx/fontmap.h"
#endif // wxUSE_FONTMAP
+#if defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
+ // For MacTypes.h for Debugger function
+ #include <CoreFoundation/CFBase.h>
+#endif
+
#if defined(__WXMAC__)
- // VZ: MacTypes.h is enough under Mac OS X (where I could test it) but
- // I don't know which headers are needed under earlier systems so
- // include everything when in doubt
#ifdef __DARWIN__
- #include "MacTypes.h"
+ #include <CoreServices/CoreServices.h>
#else
#include "wx/mac/private.h" // includes mac headers
#endif
#endif // __WXMAC__
+#ifdef __WXDEBUG__
+ #if wxUSE_STACKWALKER
+ #include "wx/stackwalk.h"
+ #ifdef __WXMSW__
+ #include "wx/msw/debughlp.h"
+ #endif
+ #endif // wxUSE_STACKWALKER
+#endif // __WXDEBUG__
+
+// wxABI_VERSION can be defined when compiling applications but it should be
+// left undefined when compiling the library itself, it is then set to its
+// default value in version.h
+#if wxABI_VERSION != wxMAJOR_VERSION * 10000 + wxMINOR_VERSION * 100 + 99
+#error "wxABI_VERSION should not be defined when compiling the library"
+#endif
+
// ----------------------------------------------------------------------------
// private functions prototypes
// ----------------------------------------------------------------------------
// initilization/cleanup
// ----------------------------------------------------------------------------
-bool wxAppConsole::Initialize(int& argc, wxChar **argv)
+bool wxAppConsole::Initialize(int& argcOrig, wxChar **argvOrig)
{
-#if wxUSE_LOG
- // If some code logged something before wxApp instance was created,
- // wxLogStderr was set as the target. Undo it here by destroying the
- // current target. It will be re-created next time logging is needed, but
- // this time wxAppTraits will be used:
- delete wxLog::SetActiveTarget(NULL);
-#endif // wxUSE_LOG
-
// remember the command line arguments
- this->argc = argc;
- this->argv = argv;
+ argc = argcOrig;
+ argv = argvOrig;
#ifndef __WXPALMOS__
if ( m_appName.empty() && argv )
delete wxConfigBase::Set((wxConfigBase *) NULL);
#endif // wxUSE_CONFIG
- // use Set(NULL) and not Get() to avoid creating a message output object on
- // demand when we just want to delete it
- delete wxMessageOutput::Set(NULL);
-
return 0;
}
void wxAppConsole::ProcessPendingEvents()
{
+#if wxUSE_THREADS
+ if ( !wxPendingEventsLocker )
+ return;
+#endif
+
// ensure that we're the only thread to modify the pending events list
wxENTER_CRIT_SECT( *wxPendingEventsLocker );
// In ProcessPendingEvents(), new handlers might be add
// and we can safely leave the critical section here.
wxLEAVE_CRIT_SECT( *wxPendingEventsLocker );
+
handler->ProcessPendingEvents();
+
wxENTER_CRIT_SECT( *wxPendingEventsLocker );
node = wxPendingEvents->GetFirst();
(handler->*func)(event);
}
-bool
-wxAppConsole::OnExceptionInMainLoop()
-{
- throw;
-
- // some compilers are too stupid to know that we never return after throw
-#if defined(__DMC__) || (defined(_MSC_VER) && _MSC_VER < 1200)
- return false;
-#endif
-}
-
#endif // wxUSE_EXCEPTIONS
// ----------------------------------------------------------------------------
#if wxUSE_LOG
{
wxCMD_LINE_SWITCH,
- _T(""),
+ wxEmptyString,
OPTION_VERBOSE,
gettext_noop("generate verbose log messages"),
wxCMD_LINE_VAL_NONE,
// terminator
{
wxCMD_LINE_NONE,
- _T(""),
- _T(""),
- _T(""),
+ wxEmptyString,
+ wxEmptyString,
+ wxEmptyString,
wxCMD_LINE_VAL_NONE,
0x0
}
#endif // __WXDEBUG__
+#if WXWIN_COMPATIBILITY_2_4
+
+bool wxAppConsole::CheckBuildOptions(const wxBuildOptions& buildOptions)
+{
+ return CheckBuildOptions(buildOptions.m_signature, "your program");
+}
+
+#endif
+
// ============================================================================
// other classes implementations
// ============================================================================
#else
SysBreak();
#endif
+#elif defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
+ Debugger();
#elif defined(__UNIX__)
raise(SIGTRAP);
#else
return false;
}
+#if wxUSE_STACKWALKER
+static wxString GetAssertStackTrace()
+{
+ wxString stackTrace;
+
+ class StackDump : public wxStackWalker
+ {
+ public:
+ StackDump() { }
+
+ const wxString& GetStackTrace() const { return m_stackTrace; }
+
+ protected:
+ virtual void OnStackFrame(const wxStackFrame& frame)
+ {
+ m_stackTrace << wxString::Format
+ (
+ _T("[%02d] "),
+ wx_truncate_cast(int, frame.GetLevel())
+ );
+
+ wxString name = frame.GetName();
+ if ( !name.empty() )
+ {
+ m_stackTrace << wxString::Format(_T("%-40s"), name.c_str());
+ }
+ else
+ {
+ m_stackTrace << wxString::Format(_T("%p"), frame.GetAddress());
+ }
+
+ if ( frame.HasSourceLocation() )
+ {
+ m_stackTrace << _T('\t')
+ << frame.GetFileName()
+ << _T(':')
+ << frame.GetLine();
+ }
+
+ m_stackTrace << _T('\n');
+ }
+
+ private:
+ wxString m_stackTrace;
+ };
+
+ StackDump dump;
+ dump.Walk(5); // don't show OnAssert() call itself
+ stackTrace = dump.GetStackTrace();
+
+ // don't show more than maxLines or we could get a dialog too tall to be
+ // shown on screen: 20 should be ok everywhere as even with 15 pixel high
+ // characters it is still only 300 pixels...
+ static const int maxLines = 20;
+ const int count = stackTrace.Freq(wxT('\n'));
+ for ( int i = 0; i < count - maxLines; i++ )
+ stackTrace = stackTrace.BeforeLast(wxT('\n'));
+
+ return stackTrace;
+}
+#endif // wxUSE_STACKWALKER
+
// show the assert modal dialog
static
void ShowAssertDialog(const wxChar *szFile,
msg << _T('.');
}
+#if wxUSE_STACKWALKER
+ const wxString stackTrace = GetAssertStackTrace();
+ if ( !stackTrace.empty() )
+ {
+ msg << _T("\n\nCall stack:\n") << stackTrace;
+ }
+#endif // wxUSE_STACKWALKER
+
#if wxUSE_THREADS
// if we are not in the main thread, output the assert directly and trap
// since dialogs cannot be displayed
// He-e-e-e-elp!! we're asserting in a child thread
wxTrap();
}
+ else
#endif // wxUSE_THREADS
if ( !s_bNoAsserts )