X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e4db172a3b318df9aff178eb6c5da149d56e0859..613992479a1b3d1dfc57d19c90786a114f44cf49:/src/common/log.cpp diff --git a/src/common/log.cpp b/src/common/log.cpp index d7a7e7e895..73e6d1a58a 100644 --- a/src/common/log.cpp +++ b/src/common/log.cpp @@ -33,6 +33,7 @@ #include "wx/arrstr.h" #include "wx/intl.h" #include "wx/string.h" + #include "wx/utils.h" #endif //WX_PRECOMP #include "wx/apptrait.h" @@ -40,7 +41,6 @@ #include "wx/msgout.h" #include "wx/textfile.h" #include "wx/thread.h" -#include "wx/utils.h" #include "wx/wxchar.h" // other standard headers @@ -96,12 +96,6 @@ 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 // @@ -110,7 +104,7 @@ static inline bool IsLoggingEnabled() // ---------------------------------------------------------------------------- // wrapper for wxVsnprintf(s_szBuf) which always NULL-terminates it -static inline void PrintfInLogBug(const wxChar *szFormat, va_list argptr) +static inline void PrintfInLogBuf(const wxChar *szFormat, va_list argptr) { if ( wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr) < 0 ) { @@ -123,10 +117,10 @@ static inline void PrintfInLogBug(const wxChar *szFormat, va_list argptr) // generic log function void wxVLogGeneric(wxLogLevel level, const wxChar *szFormat, va_list argptr) { - if ( IsLoggingEnabled() ) { + if ( wxLog::IsEnabled() ) { wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); - PrintfInLogBug(szFormat, argptr); + PrintfInLogBuf(szFormat, argptr); wxLog::OnLog(level, s_szBuf, time(NULL)); } @@ -143,10 +137,10 @@ void wxLogGeneric(wxLogLevel level, const wxChar *szFormat, ...) #define IMPLEMENT_LOG_FUNCTION(level) \ void wxVLog##level(const wxChar *szFormat, va_list argptr) \ { \ - if ( IsLoggingEnabled() ) { \ + if ( wxLog::IsEnabled() ) { \ wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); \ \ - PrintfInLogBug(szFormat, argptr); \ + PrintfInLogBuf(szFormat, argptr); \ \ wxLog::OnLog(wxLOG_##level, s_szBuf, time(NULL)); \ } \ @@ -172,6 +166,7 @@ void wxSafeShowMessage(const wxString& title, const wxString& text) ::MessageBox(NULL, text, title, MB_OK | MB_ICONSTOP); #else wxFprintf(stderr, _T("%s: %s\n"), title.c_str(), text.c_str()); + fflush(stderr); #endif } @@ -204,7 +199,7 @@ void wxLogFatalError(const wxChar *szFormat, ...) // same as info, but only if 'verbose' mode is on void wxVLogVerbose(const wxChar *szFormat, va_list argptr) { - if ( IsLoggingEnabled() ) { + if ( wxLog::IsEnabled() ) { if ( wxLog::GetActiveTarget() != NULL && wxLog::GetVerbose() ) { wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); @@ -228,7 +223,7 @@ void wxLogVerbose(const wxChar *szFormat, ...) #define IMPLEMENT_LOG_DEBUG_FUNCTION(level) \ void wxVLog##level(const wxChar *szFormat, va_list argptr) \ { \ - if ( IsLoggingEnabled() ) { \ + if ( wxLog::IsEnabled() ) { \ wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); \ \ wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr); \ @@ -246,7 +241,7 @@ void wxLogVerbose(const wxChar *szFormat, ...) void wxVLogTrace(const wxChar *mask, const wxChar *szFormat, va_list argptr) { - if ( IsLoggingEnabled() && wxLog::IsAllowedTraceMask(mask) ) { + if ( wxLog::IsEnabled() && wxLog::IsAllowedTraceMask(mask) ) { wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); wxChar *p = s_szBuf; @@ -282,7 +277,7 @@ void wxLogVerbose(const wxChar *szFormat, ...) // 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 ( IsLoggingEnabled() && ((wxLog::GetTraceMask() & mask) == mask) ) { + if ( wxLog::IsEnabled() && ((wxLog::GetTraceMask() & mask) == mask) ) { wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr); @@ -322,7 +317,7 @@ void wxLogSysErrorHelper(long lErrCode) void WXDLLEXPORT wxVLogSysError(const wxChar *szFormat, va_list argptr) { - if ( IsLoggingEnabled() ) { + if ( wxLog::IsEnabled() ) { wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr); @@ -341,7 +336,7 @@ void WXDLLEXPORT wxLogSysError(const wxChar *szFormat, ...) void WXDLLEXPORT wxVLogSysError(long lErrCode, const wxChar *szFormat, va_list argptr) { - if ( IsLoggingEnabled() ) { + if ( wxLog::IsEnabled() ) { wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); wxVsnprintf(s_szBuf, s_szBufSize, szFormat, argptr); @@ -362,6 +357,62 @@ void WXDLLEXPORT wxLogSysError(long lErrCode, const wxChar *szFormat, ...) // wxLog class implementation // ---------------------------------------------------------------------------- +/* static */ +unsigned wxLog::DoLogNumberOfRepeats() +{ + long retval = ms_prevCounter; + wxLog *pLogger = GetActiveTarget(); + if ( pLogger && ms_prevCounter > 0 ) + { + wxString msg; + msg.Printf(wxPLURAL("The previous message repeated once.", + "The previous message repeated %lu times.", + ms_prevCounter), + ms_prevCounter); + ms_prevCounter = 0; + ms_prevString.clear(); + pLogger->DoLog(ms_prevLevel, msg.c_str(), ms_prevTimeStamp); + } + return retval; +} + +wxLog::~wxLog() +{ + if ( ms_prevCounter > 0 ) + { + // looks like the repeat count has not been logged yet, + // so let's do it now + wxLog::DoLogNumberOfRepeats(); + } +} + +/* static */ +void wxLog::OnLog(wxLogLevel level, const wxChar *szString, time_t t) +{ + if ( IsEnabled() && ms_logLevel >= level ) + { + wxLog *pLogger = GetActiveTarget(); + if ( pLogger ) + { + if ( GetRepetitionCounting() && ms_prevString == szString ) + { + ms_prevCounter++; + } + else + { + if ( GetRepetitionCounting() ) + { + pLogger->DoLogNumberOfRepeats(); + } + ms_prevString = szString; + ms_prevLevel = level; + ms_prevTimeStamp = t; + pLogger->DoLog(level, szString, t); + } + } + } +} + wxChar *wxLog::SetLogBuffer( wxChar *buf, size_t size) { wxChar *oldbuf = s_szBuf; @@ -701,6 +752,12 @@ wxLogPassThrough::wxLogPassThrough() // static variables // ---------------------------------------------------------------------------- +bool wxLog::ms_bRepetCounting = false; +wxString wxLog::ms_prevString; +unsigned int wxLog::ms_prevCounter = 0; +time_t wxLog::ms_prevTimeStamp= 0; +wxLogLevel wxLog::ms_prevLevel; + wxLog *wxLog::ms_pLogger = (wxLog *)NULL; bool wxLog::ms_doLog = true; bool wxLog::ms_bAutoCreate = true;