#include "wx/app.h"
#include "wx/intl.h"
#include "wx/list.h"
- #if wxUSE_LOG
- #include "wx/log.h"
- #endif // wxUSE_LOG
+ #include "wx/log.h"
#endif //WX_PRECOMP
#include "wx/utils.h"
#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
#endif
#endif // __WXMAC__
+#ifdef __WXDEBUG__
+ #ifdef wxUSE_STACKWALKER
+ #include "wx/stackwalk.h"
+ #endif // wxUSE_STACKWALKER
+#endif // __WXDEBUG__
+
// ----------------------------------------------------------------------------
// private functions prototypes
// ----------------------------------------------------------------------------
#ifdef __WXDEBUG__
SetTraceMasks();
+#if wxUSE_UNICODE
+ // In unicode mode the SetTraceMasks call can cause an apptraits to be
+ // created, but since we are still in the constructor the wrong kind will
+ // be created for GUI apps. Destroy it so it can be created again later.
+ delete m_traits;
+ m_traits = NULL;
+#endif
#endif
}
bool wxAppConsole::Initialize(int& argc, wxChar **argv)
{
+#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;
+#ifndef __WXPALMOS__
if ( m_appName.empty() && argv )
{
// the application name is, by default, the name of its executable file
wxFileName::SplitPath(argv[0], NULL, &m_appName, NULL);
}
+#endif
return true;
}
OnInitCmdLine(parser);
bool cont;
- switch ( parser.Parse(FALSE /* don't show usage */) )
+ switch ( parser.Parse(false /* don't show usage */) )
{
case -1:
cont = OnCmdLineHelp(parser);
}
if ( !cont )
- return FALSE;
+ return false;
#endif // wxUSE_CMDLINE_PARSER
- return TRUE;
+ return true;
}
int wxAppConsole::OnExit()
return -1;
}
+// ----------------------------------------------------------------------------
+// exception handling
+// ----------------------------------------------------------------------------
+
#if wxUSE_EXCEPTIONS
void
(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
}
#if wxUSE_LOG
if ( parser.Found(OPTION_VERBOSE) )
{
- wxLog::SetVerbose(TRUE);
+ wxLog::SetVerbose(true);
}
+#else
+ wxUnusedVar(parser);
#endif // wxUSE_LOG
- return TRUE;
+ return true;
}
bool wxAppConsole::OnCmdLineHelp(wxCmdLineParser& parser)
{
parser.Usage();
- return FALSE;
+ return false;
}
bool wxAppConsole::OnCmdLineError(wxCmdLineParser& parser)
{
parser.Usage();
- return FALSE;
+ return false;
}
#endif // wxUSE_CMDLINE_PARSER
msg.Printf(_T("Mismatch between the program and library build versions detected.\nThe library used %s,\nand %s used %s."),
lib.c_str(), progName.c_str(), prog.c_str());
- wxLogFatalError(msg);
+ wxLogFatalError(msg.c_str());
// normally wxLogFatalError doesn't return
- return FALSE;
+ return false;
}
#undef wxCMP
- return TRUE;
+ return true;
}
#ifdef __WXDEBUG__
#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
const wxChar *szMsg)
{
// FIXME MT-unsafe
- static bool s_bInAssert = FALSE;
+ static bool s_bInAssert = false;
if ( s_bInAssert )
{
// He-e-e-e-elp!! we're trapped in endless loop
wxTrap();
- s_bInAssert = FALSE;
+ s_bInAssert = false;
return;
}
- s_bInAssert = TRUE;
+ s_bInAssert = true;
if ( !wxTheApp )
{
wxTheApp->OnAssert(szFile, nLine, szCond, szMsg);
}
- s_bInAssert = FALSE;
+ s_bInAssert = false;
}
#endif // __WXDEBUG__
wxT("You can also choose [Cancel] to suppress ")
wxT("further warnings.");
- switch ( ::MessageBox(NULL, msgDlg, _T("wxWindows Debug Alert"),
+ switch ( ::MessageBox(NULL, msgDlg, _T("wxWidgets Debug Alert"),
MB_YESNOCANCEL | MB_ICONSTOP ) )
{
case IDYES:
wxAppTraits *traits)
{
// this variable can be set to true to suppress "assert failure" messages
- static bool s_bNoAsserts = FALSE;
+ static bool s_bNoAsserts = false;
wxString msg;
msg.reserve(2048);
msg << _T('.');
}
+#if wxUSE_STACKWALKER
+ 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] "), frame.GetLevel());
+
+ wxString name = frame.GetName();
+ if ( !name.empty() )
+ {
+ m_stackTrace << wxString::Format(_T("%-40s"), name.c_str());
+ }
+ else
+ {
+ m_stackTrace << wxString::Format
+ (
+ _T("0x%08lx"),
+ (unsigned long)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
+ wxString 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...
+ const int maxLines = 20;
+ int count = stackTrace.Freq(wxT('\n'));
+ if (count > maxLines)
+ {
+ int i;
+ for (i = 0; i < count - maxLines; i++)
+ stackTrace = stackTrace.BeforeLast(wxT('\n'));
+ }
+ 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 )