X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7d610b90ffb5c212b429c717ebae5f605fc5fac7..f3ecfad1923022f59dca6fe065e5f278e2802faf:/src/common/log.cpp diff --git a/src/common/log.cpp b/src/common/log.cpp index 837956d26a..03838b73d7 100644 --- a/src/common/log.cpp +++ b/src/common/log.cpp @@ -50,14 +50,18 @@ #include "wx/log.h" #include "wx/thread.h" +#if wxUSE_LOG + // other standard headers #include #include #include -#ifdef __WXMSW__ +#if defined(__WXMSW__) #include "wx/msw/private.h" // includes windows.h for OutputDebugString -#else //Unix +#endif + +#if !defined(__WXMSW__) || defined(__WXMICROWIN__) #include #endif //Win/Unix @@ -94,6 +98,12 @@ static wxCriticalSection gs_csLogBuf; #endif // wxUSE_THREADS +// return true if we have a non NULL non disabled log target +static inline bool IsLoggingEnabled() +{ + return wxLog::IsEnabled() && (wxLog::GetActiveTarget() != NULL); +} + // ---------------------------------------------------------------------------- // implementation of Log functions // @@ -104,31 +114,31 @@ static wxCriticalSection gs_csLogBuf; // generic log function void wxLogGeneric(wxLogLevel level, const wxChar *szFormat, ...) { - if ( wxLog::GetActiveTarget() != NULL ) { - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); + if ( IsLoggingEnabled() ) { + wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); - va_list argptr; - va_start(argptr, szFormat); - wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); - va_end(argptr); + va_list argptr; + va_start(argptr, szFormat); + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + va_end(argptr); - wxLog::OnLog(level, s_szBuf, time(NULL)); - } + wxLog::OnLog(level, s_szBuf, time(NULL)); + } } -#define IMPLEMENT_LOG_FUNCTION(level) \ - void wxLog##level(const wxChar *szFormat, ...) \ - { \ - if ( wxLog::GetActiveTarget() != NULL ) { \ - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); \ - \ - va_list argptr; \ - va_start(argptr, szFormat); \ - wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); \ - va_end(argptr); \ - \ - wxLog::OnLog(wxLOG_##level, s_szBuf, time(NULL)); \ - } \ +#define IMPLEMENT_LOG_FUNCTION(level) \ + void wxLog##level(const wxChar *szFormat, ...) \ + { \ + if ( IsLoggingEnabled() ) { \ + wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); \ + \ + va_list argptr; \ + va_start(argptr, szFormat); \ + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); \ + va_end(argptr); \ + \ + wxLog::OnLog(wxLOG_##level, s_szBuf, time(NULL)); \ + } \ } IMPLEMENT_LOG_FUNCTION(FatalError) @@ -141,41 +151,41 @@ IMPLEMENT_LOG_FUNCTION(Status) // same as info, but only if 'verbose' mode is on void wxLogVerbose(const wxChar *szFormat, ...) { - wxLog *pLog = wxLog::GetActiveTarget(); - if ( pLog != NULL && pLog->GetVerbose() ) { - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); + if ( IsLoggingEnabled() ) { + wxLog *pLog = wxLog::GetActiveTarget(); + if ( pLog != NULL && pLog->GetVerbose() ) { + wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); - va_list argptr; - va_start(argptr, szFormat); - wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); - va_end(argptr); + va_list argptr; + va_start(argptr, szFormat); + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + va_end(argptr); - wxLog::OnLog(wxLOG_Info, s_szBuf, time(NULL)); - } + wxLog::OnLog(wxLOG_Info, s_szBuf, time(NULL)); + } + } } // debug functions #ifdef __WXDEBUG__ -#define IMPLEMENT_LOG_DEBUG_FUNCTION(level) \ - void wxLog##level(const wxChar *szFormat, ...) \ - { \ - if ( wxLog::GetActiveTarget() != NULL ) { \ - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); \ - \ - va_list argptr; \ - va_start(argptr, szFormat); \ - wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); \ - va_end(argptr); \ - \ - wxLog::OnLog(wxLOG_##level, s_szBuf, time(NULL)); \ - } \ +#define IMPLEMENT_LOG_DEBUG_FUNCTION(level) \ + void wxLog##level(const wxChar *szFormat, ...) \ + { \ + if ( IsLoggingEnabled() ) { \ + wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); \ + \ + va_list argptr; \ + va_start(argptr, szFormat); \ + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); \ + va_end(argptr); \ + \ + wxLog::OnLog(wxLOG_##level, s_szBuf, time(NULL)); \ + } \ } void wxLogTrace(const wxChar *mask, const wxChar *szFormat, ...) { - wxLog *pLog = wxLog::GetActiveTarget(); - - if ( pLog != NULL && wxLog::IsAllowedTraceMask(mask) ) { + if ( IsLoggingEnabled() && wxLog::IsAllowedTraceMask(mask) ) { wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); wxChar *p = s_szBuf; @@ -203,12 +213,10 @@ void wxLogVerbose(const wxChar *szFormat, ...) void wxLogTrace(wxTraceMask mask, const wxChar *szFormat, ...) { - wxLog *pLog = wxLog::GetActiveTarget(); - // we check that all of mask bits are set in the current mask, so // that wxLogTrace(wxTraceRefCount | wxTraceOle) will only do something // if both bits are set. - if ( pLog != NULL && ((pLog->GetTraceMask() & mask) == mask) ) { + if ( IsLoggingEnabled() && ((wxLog::GetTraceMask() & mask) == mask) ) { wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); va_list argptr; @@ -243,26 +251,30 @@ void wxLogSysErrorHelper(long lErrCode) void WXDLLEXPORT wxLogSysError(const wxChar *szFormat, ...) { - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); + if ( IsLoggingEnabled() ) { + wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); - va_list argptr; - va_start(argptr, szFormat); - wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); - va_end(argptr); + va_list argptr; + va_start(argptr, szFormat); + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + va_end(argptr); - wxLogSysErrorHelper(wxSysErrorCode()); + wxLogSysErrorHelper(wxSysErrorCode()); + } } void WXDLLEXPORT wxLogSysError(long lErrCode, const wxChar *szFormat, ...) { - wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); + if ( IsLoggingEnabled() ) { + wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); - va_list argptr; - va_start(argptr, szFormat); - wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); - va_end(argptr); + va_list argptr; + va_start(argptr, szFormat); + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + va_end(argptr); - wxLogSysErrorHelper(lErrCode); + wxLogSysErrorHelper(lErrCode); + } } // ---------------------------------------------------------------------------- @@ -272,13 +284,7 @@ void WXDLLEXPORT wxLogSysError(long lErrCode, const wxChar *szFormat, ...) wxLog::wxLog() { m_bHasMessages = FALSE; - - // enable verbose messages by default in the debug builds -#ifdef __WXDEBUG__ - m_bVerbose = TRUE; -#else // release m_bVerbose = FALSE; -#endif // debug/release } wxLog *wxLog::GetActiveTarget() @@ -319,6 +325,16 @@ wxLog *wxLog::SetActiveTarget(wxLog *pLogger) return pOldLogger; } +void wxLog::DontCreateOnDemand() +{ + ms_bAutoCreate = FALSE; + + // this is usually called at the end of the program and we assume that it + // is *always* called at the end - so we free memory here to avoid false + // memory leak reports from wxWin memory tracking code + ClearTraceMasks(); +} + void wxLog::RemoveTraceMask(const wxString& str) { int index = ms_aTraceMasks.Index(str); @@ -326,6 +342,11 @@ void wxLog::RemoveTraceMask(const wxString& str) ms_aTraceMasks.Remove((size_t)index); } +void wxLog::ClearTraceMasks() +{ + ms_aTraceMasks.Clear(); +} + void wxLog::TimeStamp(wxString *str) { if ( ms_timestamp ) @@ -402,7 +423,7 @@ wxLogStderr::wxLogStderr(FILE *fp) m_fp = fp; } -#if defined(__WXMAC__) +#if defined(__WXMAC__) && !defined(__UNIX__) #define kDebuggerSignature 'MWDB' static Boolean FindProcessBySignature(OSType signature, ProcessInfoRec* info) @@ -494,11 +515,11 @@ 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__) && wxUSE_GUI +#if defined(__WXMAC__) && !defined(__WXMAC_X__) && wxUSE_GUI Str255 pstr ; strcpy( (char*) pstr , str.c_str() ) ; strcat( (char*) pstr , ";g" ) ; @@ -529,7 +550,7 @@ void wxLogStderr::DoLogString(const wxChar *szString, time_t WXUNUSED(t)) DebugStr(pstr); #endif } -#endif // MSW +#endif // Mac } // ---------------------------------------------------------------------------- @@ -537,17 +558,19 @@ void wxLogStderr::DoLogString(const wxChar *szString, time_t WXUNUSED(t)) // ---------------------------------------------------------------------------- #if wxUSE_STD_IOSTREAM -wxLogStream::wxLogStream(ostream *ostr) +wxLogStream::wxLogStream(wxSTD ostream *ostr) { if ( ostr == NULL ) - m_ostr = &cerr; + m_ostr = &wxSTD cerr; else m_ostr = ostr; } void wxLogStream::DoLogString(const wxChar *szString, time_t WXUNUSED(t)) { - (*m_ostr) << wxConvertWX2MB(szString) << endl; + wxString str; + TimeStamp(&str); + (*m_ostr) << str << wxConvertWX2MB(szString) << wxSTD endl; } #endif // wxUSE_STD_IOSTREAM @@ -618,7 +641,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 @@ -636,7 +659,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]; @@ -684,10 +707,16 @@ const wxChar *wxSysErrorMsg(unsigned long nErrCode) #ifdef __WXDEBUG__ +// wxASSERT() helper +bool wxAssertIsEqual(int x, int y) +{ + return x == y; +} + // break into the debugger -void Trap() +void wxTrap() { -#ifdef __WXMSW__ +#if defined(__WXMSW__) && !defined(__WXMICROWIN__) DebugBreak(); #elif defined(__WXMAC__) #if __powerc @@ -711,7 +740,7 @@ void wxOnAssert(const wxChar *szFile, int nLine, const wxChar *szMsg) if ( s_bInAssert ) { // He-e-e-e-elp!! we're trapped in endless loop - Trap(); + wxTrap(); s_bInAssert = FALSE; @@ -745,41 +774,43 @@ void wxOnAssert(const wxChar *szFile, int nLine, const wxChar *szMsg) // send it to the normal log destination wxLogDebug(szBuf); -#if wxUSE_GUI || defined(__WXMSW__) +#if (wxUSE_GUI && wxUSE_MSGDLG) || 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.")); -#if wxUSE_GUI - switch ( wxMessageBox(szBuf, wxT("Debug"), - wxYES_NO | wxCANCEL | wxICON_STOP ) ) { - case wxYES: - Trap(); + // use the native message box if available: this is more robust than + // using our own +#if defined(__WXMSW__) && !defined(__WXMICROWIN__) + switch ( ::MessageBox(NULL, szBuf, _T("Debug"), + MB_YESNOCANCEL | MB_ICONSTOP ) ) { + case IDYES: + wxTrap(); break; - case wxCANCEL: + case IDCANCEL: s_bNoAsserts = TRUE; break; - //case wxNO: nothing to do + //case IDNO: nothing to do } -#else // !GUI, but MSW - switch ( ::MessageBox(NULL, szBuf, _T("Debug"), - MB_YESNOCANCEL | MB_ICONSTOP ) ) { - case IDYES: - Trap(); +#else // !MSW + switch ( wxMessageBox(szBuf, wxT("Debug"), + wxYES_NO | wxCANCEL | wxICON_STOP ) ) { + case wxYES: + wxTrap(); break; - case IDCANCEL: + case wxCANCEL: s_bNoAsserts = TRUE; break; - //case IDNO: nothing to do + //case wxNO: nothing to do } #endif // GUI or MSW #else // !GUI - Trap(); + wxTrap(); #endif // GUI/!GUI } @@ -788,3 +819,4 @@ void wxOnAssert(const wxChar *szFile, int nLine, const wxChar *szMsg) #endif //WXDEBUG +#endif //wxUSE_LOG