X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dd107c50be43e8d4dbdba20df162faf119a3781c..481fcc780da6b3ddbee3bd9f1eca5aafeef0a58b:/src/common/log.cpp diff --git a/src/common/log.cpp b/src/common/log.cpp index a73e2cdefa..be03d3c4c8 100644 --- a/src/common/log.cpp +++ b/src/common/log.cpp @@ -39,7 +39,6 @@ #ifdef __WXMSW__ #include "wx/msw/private.h" #endif - #include "wx/msgdlg.h" #endif #endif //WX_PRECOMP @@ -57,11 +56,9 @@ #include #include -#ifdef __WXMSW__ +#if defined(__WXMSW__) #include "wx/msw/private.h" // includes windows.h for OutputDebugString -#else //Unix - #include -#endif //Win/Unix +#endif // ---------------------------------------------------------------------------- // non member functions @@ -282,7 +279,6 @@ void WXDLLEXPORT wxLogSysError(long lErrCode, const wxChar *szFormat, ...) wxLog::wxLog() { m_bHasMessages = FALSE; - m_bVerbose = FALSE; } wxLog *wxLog::GetActiveTarget() @@ -406,7 +402,8 @@ void wxLog::DoLogString(const wxChar *WXUNUSED(szString), time_t WXUNUSED(t)) void wxLog::Flush() { - // do nothing + // remember that we don't have any more messages to show + m_bHasMessages = FALSE; } // ---------------------------------------------------------------------------- @@ -421,83 +418,83 @@ wxLogStderr::wxLogStderr(FILE *fp) m_fp = fp; } -#if defined(__WXMAC__) && !defined(__UNIX__) -#define kDebuggerSignature 'MWDB' +#if defined(__WXMAC__) && !defined(__DARWIN__) +#define kDebuggerSignature 'MWDB' static Boolean FindProcessBySignature(OSType signature, ProcessInfoRec* info) -{ - OSErr err; - ProcessSerialNumber psn; - Boolean found = false; - psn.highLongOfPSN = 0; - psn.lowLongOfPSN = kNoProcess; - - if (!info) return false; - - info->processInfoLength = sizeof(ProcessInfoRec); - info->processName = NULL; - info->processAppSpec = NULL; - - err = noErr; - while (!found && err == noErr) - { - err = GetNextProcess(&psn); - if (err == noErr) - { - err = GetProcessInformation(&psn, info); - found = err == noErr && info->processSignature == signature; - } - } - return found; +{ + OSErr err; + ProcessSerialNumber psn; + Boolean found = false; + psn.highLongOfPSN = 0; + psn.lowLongOfPSN = kNoProcess; + + if (!info) return false; + + info->processInfoLength = sizeof(ProcessInfoRec); + info->processName = NULL; + info->processAppSpec = NULL; + + err = noErr; + while (!found && err == noErr) + { + err = GetNextProcess(&psn); + if (err == noErr) + { + err = GetProcessInformation(&psn, info); + found = err == noErr && info->processSignature == signature; + } + } + return found; } pascal Boolean MWDebuggerIsRunning(void) { - ProcessInfoRec info; - return FindProcessBySignature(kDebuggerSignature, &info); + ProcessInfoRec info; + return FindProcessBySignature(kDebuggerSignature, &info); } pascal OSErr AmIBeingMWDebugged(Boolean* result) { - OSErr err; - ProcessSerialNumber psn; - OSType sig = kDebuggerSignature; - AppleEvent theAE = {typeNull, NULL}; - AppleEvent theReply = {typeNull, NULL}; - AEAddressDesc addr = {typeNull, NULL}; - DescType actualType; - Size actualSize; - - if (!result) return paramErr; - - err = AECreateDesc(typeApplSignature, &sig, sizeof(sig), &addr); - if (err != noErr) goto exit; - - err = AECreateAppleEvent('MWDB', 'Dbg?', &addr, - kAutoGenerateReturnID, kAnyTransactionID, &theAE); - if (err != noErr) goto exit; - - GetCurrentProcess(&psn); - err = AEPutParamPtr(&theAE, keyDirectObject, typeProcessSerialNumber, - &psn, sizeof(psn)); - if (err != noErr) goto exit; - - err = AESend(&theAE, &theReply, kAEWaitReply, kAENormalPriority, - kAEDefaultTimeout, NULL, NULL); - if (err != noErr) goto exit; - - err = AEGetParamPtr(&theReply, keyAEResult, typeBoolean, &actualType, result, - sizeof(Boolean), &actualSize); + OSErr err; + ProcessSerialNumber psn; + OSType sig = kDebuggerSignature; + AppleEvent theAE = {typeNull, NULL}; + AppleEvent theReply = {typeNull, NULL}; + AEAddressDesc addr = {typeNull, NULL}; + DescType actualType; + Size actualSize; + + if (!result) return paramErr; + + err = AECreateDesc(typeApplSignature, &sig, sizeof(sig), &addr); + if (err != noErr) goto exit; + + err = AECreateAppleEvent(kDebuggerSignature, 'Dbg?', &addr, + kAutoGenerateReturnID, kAnyTransactionID, &theAE); + if (err != noErr) goto exit; + + GetCurrentProcess(&psn); + err = AEPutParamPtr(&theAE, keyDirectObject, typeProcessSerialNumber, + &psn, sizeof(psn)); + if (err != noErr) goto exit; + + err = AESend(&theAE, &theReply, kAEWaitReply, kAENormalPriority, + kAEDefaultTimeout, NULL, NULL); + if (err != noErr) goto exit; + + err = AEGetParamPtr(&theReply, keyAEResult, typeBoolean, &actualType, result, + sizeof(Boolean), &actualSize); exit: - if (addr.dataHandle) - AEDisposeDesc(&addr); - if (theAE.dataHandle) - AEDisposeDesc(&theAE); - if (theReply.dataHandle) - AEDisposeDesc(&theReply); - - return err; + if (addr.dataHandle) + AEDisposeDesc(&addr); + if (theAE.dataHandle) + AEDisposeDesc(&theAE); + if (theReply.dataHandle) + AEDisposeDesc(&theReply); + + return err; } #endif @@ -513,41 +510,41 @@ void wxLogStderr::DoLogString(const wxChar *szString, time_t WXUNUSED(t)) // under Windows, programs usually don't have stderr at all, so show the // messages also under debugger - unless it's a console program -#if defined(__WXMSW__) && wxUSE_GUI +#if defined(__WXMSW__) && wxUSE_GUI && !defined(__WXMICROWIN__) str += wxT("\r\n") ; OutputDebugString(str.c_str()); #endif // MSW -#if defined(__WXMAC__) && !defined(__WXMAC_X__) && wxUSE_GUI - Str255 pstr ; - strcpy( (char*) pstr , str.c_str() ) ; - strcat( (char*) pstr , ";g" ) ; - c2pstr( (char*) pstr ) ; +#if defined(__WXMAC__) && !defined(__DARWIN__) && wxUSE_GUI + Str255 pstr ; + strcpy( (char*) pstr , str.c_str() ) ; + strcat( (char*) pstr , ";g" ) ; + c2pstr( (char*) pstr ) ; #if __WXDEBUG__ - Boolean running = false ; - + Boolean running = false ; + /* - if ( MWDebuggerIsRunning() ) - { - AmIBeingMWDebugged( &running ) ; - } + if ( MWDebuggerIsRunning() ) + { + AmIBeingMWDebugged( &running ) ; + } */ - if (running) - { - #ifdef __powerc - DebugStr(pstr); - #else - SysBreakStr(pstr); - #endif - } - else + if (running) + { +#ifdef __powerc + DebugStr(pstr); +#else + SysBreakStr(pstr); #endif - { - #ifdef __powerc - DebugStr(pstr); - #else - DebugStr(pstr); - #endif - } + } + else +#endif + { +#ifdef __powerc + DebugStr(pstr); +#else + DebugStr(pstr); +#endif + } #endif // Mac } @@ -572,6 +569,70 @@ void wxLogStream::DoLogString(const wxChar *szString, time_t WXUNUSED(t)) } #endif // wxUSE_STD_IOSTREAM +// ---------------------------------------------------------------------------- +// wxLogChain +// ---------------------------------------------------------------------------- + +wxLogChain::wxLogChain(wxLog *logger) +{ + m_logNew = logger; + m_logOld = wxLog::SetActiveTarget(this); +} + +void wxLogChain::SetLog(wxLog *logger) +{ + if ( m_logNew != this ) + delete m_logNew; + + wxLog::SetActiveTarget(logger); + + m_logNew = logger; +} + +void wxLogChain::Flush() +{ + if ( m_logOld ) + m_logOld->Flush(); + + // be careful to avoid inifinite recursion + if ( m_logNew && m_logNew != this ) + m_logNew->Flush(); +} + +void wxLogChain::DoLog(wxLogLevel level, const wxChar *szString, time_t t) +{ + // let the previous logger show it + if ( m_logOld && IsPassingMessages() ) + { + // bogus cast just to access protected DoLog + ((wxLogChain *)m_logOld)->DoLog(level, szString, t); + } + + if ( m_logNew && m_logNew != this ) + { + // as above... + ((wxLogChain *)m_logNew)->DoLog(level, szString, t); + } +} + +// ---------------------------------------------------------------------------- +// wxLogPassThrough +// ---------------------------------------------------------------------------- + +#ifdef __VISUALC__ + // "'this' : used in base member initializer list" - so what? + #pragma warning(disable:4355) +#endif // VC++ + +wxLogPassThrough::wxLogPassThrough() + : wxLogChain(this) +{ +} + +#ifdef __VISUALC__ + #pragma warning(default:4355) +#endif // VC++ + // ============================================================================ // Global functions/variables // ============================================================================ @@ -583,6 +644,7 @@ void wxLogStream::DoLogString(const wxChar *szString, time_t WXUNUSED(t)) wxLog *wxLog::ms_pLogger = (wxLog *)NULL; bool wxLog::ms_doLog = TRUE; bool wxLog::ms_bAutoCreate = TRUE; +bool wxLog::ms_bVerbose = FALSE; size_t wxLog::ms_suspendCount = 0; @@ -639,7 +701,7 @@ static void wxLogWrap(FILE *f, const char *pszPrefix, const char *psz) // get error code from syste unsigned long wxSysErrorCode() { -#ifdef __WXMSW__ +#if defined(__WXMSW__) && !defined(__WXMICROWIN__) #ifdef __WIN32__ return ::GetLastError(); #else //WIN16 @@ -657,7 +719,7 @@ const wxChar *wxSysErrorMsg(unsigned long nErrCode) if ( nErrCode == 0 ) nErrCode = wxSysErrorCode(); -#ifdef __WXMSW__ +#if defined(__WXMSW__) && !defined(__WXMICROWIN__) #ifdef __WIN32__ static wxChar s_szBuf[LOG_BUFFER_SIZE / 2]; @@ -670,7 +732,10 @@ const wxChar *wxSysErrorMsg(unsigned long nErrCode) 0, NULL); // copy it to our buffer and free memory - wxStrncpy(s_szBuf, (const wxChar *)lpMsgBuf, WXSIZEOF(s_szBuf) - 1); + if( lpMsgBuf != 0 ) + wxStrncpy(s_szBuf, (const wxChar *)lpMsgBuf, WXSIZEOF(s_szBuf) - 1); + else + s_szBuf[0] = wxT('\0'); s_szBuf[WXSIZEOF(s_szBuf) - 1] = wxT('\0'); LocalFree(lpMsgBuf); @@ -699,116 +764,4 @@ const wxChar *wxSysErrorMsg(unsigned long nErrCode) #endif // Win/Unix } -// ---------------------------------------------------------------------------- -// debug helper -// ---------------------------------------------------------------------------- - -#ifdef __WXDEBUG__ - -// break into the debugger -void Trap() -{ -#ifdef __WXMSW__ - DebugBreak(); -#elif defined(__WXMAC__) -#if __powerc - Debugger(); -#else - SysBreak(); -#endif -#elif defined(__UNIX__) - raise(SIGTRAP); -#else - // TODO -#endif // Win/Unix -} - -// this function is called when an assert fails -void wxOnAssert(const wxChar *szFile, int nLine, const wxChar *szMsg) -{ - // this variable can be set to true to suppress "assert failure" messages - static bool s_bNoAsserts = FALSE; - static bool s_bInAssert = FALSE; // FIXME MT-unsafe - - if ( s_bInAssert ) { - // He-e-e-e-elp!! we're trapped in endless loop - Trap(); - - s_bInAssert = FALSE; - - return; - } - - s_bInAssert = TRUE; - - wxChar szBuf[LOG_BUFFER_SIZE]; - - // make life easier for people using VC++ IDE: clicking on the message - // will take us immediately to the place of the failed assert - wxSnprintf(szBuf, WXSIZEOF(szBuf), -#ifdef __VISUALC__ - wxT("%s(%d): assert failed"), -#else // !VC++ - // make the error message more clear for all the others - wxT("Assert failed in file %s at line %d"), -#endif // VC/!VC - szFile, nLine); - - if ( szMsg != NULL ) { - wxStrcat(szBuf, wxT(": ")); - wxStrcat(szBuf, szMsg); - } - else { - wxStrcat(szBuf, wxT(".")); - } - - if ( !s_bNoAsserts ) { - // send it to the normal log destination - wxLogDebug(szBuf); - -#if wxUSE_GUI || defined(__WXMSW__) - // this message is intentionally not translated - it is for - // developpers only - wxStrcat(szBuf, wxT("\nDo you want to stop the program?\nYou can also choose [Cancel] to suppress further warnings.")); - - // use the native message box if available: this is more robust than - // using our own -#ifdef __WXMSW__ - switch ( ::MessageBox(NULL, szBuf, _T("Debug"), - MB_YESNOCANCEL | MB_ICONSTOP ) ) { - case IDYES: - Trap(); - break; - - case IDCANCEL: - s_bNoAsserts = TRUE; - break; - - //case IDNO: nothing to do - } -#else // !MSW - switch ( wxMessageBox(szBuf, wxT("Debug"), - wxYES_NO | wxCANCEL | wxICON_STOP ) ) { - case wxYES: - Trap(); - break; - - case wxCANCEL: - s_bNoAsserts = TRUE; - break; - - //case wxNO: nothing to do - } -#endif // GUI or MSW - -#else // !GUI - Trap(); -#endif // GUI/!GUI - } - - s_bInAssert = FALSE; -} - -#endif //WXDEBUG - #endif //wxUSE_LOG