X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3f562374f11048ff0005b7229683b3804d2208d2..53eff2a282f306d3ae692001e7e7fee0461a0a40:/include/wx/log.h diff --git a/include/wx/log.h b/include/wx/log.h index d7d62303dc..193861f4bc 100644 --- a/include/wx/log.h +++ b/include/wx/log.h @@ -12,7 +12,7 @@ #ifndef _WX_LOG_H_ #define _WX_LOG_H_ -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(__APPLE__) #pragma interface "log.h" #endif @@ -40,10 +40,20 @@ typedef unsigned long wxLogLevel; #if wxUSE_LOG +#ifndef __WXWINCE__ #include // for time_t +#endif #include "wx/dynarray.h" +#ifndef wxUSE_LOG_DEBUG +# ifdef __WXDEBUG__ +# define wxUSE_LOG_DEBUG 1 +# else // !__WXDEBUG__ +# define wxUSE_LOG_DEBUG 0 +# endif +#endif + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -55,12 +65,13 @@ enum wxLOG_Error, // a serious error, user must be informed about it wxLOG_Warning, // user is normally informed about it but may be ignored wxLOG_Message, // normal message (i.e. normal output of a non GUI app) - wxLOG_Info, // informational message (a.k.a. 'Verbose') wxLOG_Status, // informational: might go to the status line of GUI app + wxLOG_Info, // informational message (a.k.a. 'Verbose') wxLOG_Debug, // never shown to the user, disabled in release mode wxLOG_Trace, // trace messages are also only enabled in debug mode wxLOG_Progress, // used for progress indicator (not yet) - wxLOG_User = 100 // user defined levels start here + wxLOG_User = 100, // user defined levels start here + wxLOG_Max = 10000 }; // symbolic trace masks - wxLogTrace("foo", "some trace message...") will be @@ -90,7 +101,7 @@ enum #define wxTraceOleCalls 0x0100 // OLE interface calls #endif -#include "wx/ioswrap.h" +#include "wx/iosfwrap.h" // ---------------------------------------------------------------------------- // derive from this class to redirect (or suppress, or ...) log messages @@ -103,6 +114,12 @@ public: // ctor wxLog(); + // Internal buffer. + // Allow replacement of the fixed size static buffer with + // a user allocated one. Pass in NULL to restore the + // built in static buffer. + static wxChar *SetLogBuffer( wxChar *buf, size_t size = 0 ); + // these functions allow to completely disable all log messages // is logging disabled now? static bool IsEnabled() { return ms_doLog; } @@ -114,7 +131,7 @@ public: // derived classes static void OnLog(wxLogLevel level, const wxChar *szString, time_t t) { - if ( IsEnabled() ) { + if ( IsEnabled() && ms_logLevel >= level ) { wxLog *pLogger = GetActiveTarget(); if ( pLogger ) pLogger->DoLog(level, szString, t); @@ -126,22 +143,19 @@ public: // and iostream logs don't need it, but wxGuiLog does to avoid showing // 17 modal dialogs one after another) virtual void Flush(); - // call to Flush() may be optimized: call it only if this function - // returns true (although Flush() also returns immediately if there is - // no messages, this functions is more efficient because inline) - bool HasPendingMessages() const { return m_bHasMessages; } - // only one sink is active at each moment // flush the active target if any static void FlushActive() { if ( !ms_suspendCount ) { wxLog *log = GetActiveTarget(); - if ( log && log->HasPendingMessages() ) + if ( log ) log->Flush(); } } + + // only one sink is active at each moment // get current log target, will call wxApp::CreateLogTarget() to // create one if none exists static wxLog *GetActiveTarget(); @@ -159,6 +173,10 @@ public: // verbose mode is activated by standard command-line '-verbose' // option static void SetVerbose(bool bVerbose = TRUE) { ms_bVerbose = bVerbose; } + + // Set log level. Log messages with level > logLevel will not be logged. + static void SetLogLevel(wxLogLevel logLevel) { ms_logLevel = logLevel; } + // should GetActiveTarget() try to create a new log object if the // current is NULL? static void DontCreateOnDemand(); @@ -171,12 +189,15 @@ public: static void RemoveTraceMask(const wxString& str); // remove all string trace masks static void ClearTraceMasks(); + // get string trace masks + static const wxArrayString &GetTraceMasks() { return ms_aTraceMasks; } // sets the timestamp string: this is used as strftime() format string // for the log targets which add time stamps to the messages - set it // to NULL to disable time stamping completely. static void SetTimestamp(const wxChar *ts) { ms_timestamp = ts; } + // accessors // gets the verbose status static bool GetVerbose() { return ms_bVerbose; } @@ -185,10 +206,13 @@ public: // is this trace mask in the list? static bool IsAllowedTraceMask(const wxChar *mask) { return ms_aTraceMasks.Index(mask) != wxNOT_FOUND; } + // return the current loglevel limit + static wxLogLevel GetLogLevel() { return ms_logLevel; } // get the current timestamp format string (may be NULL) static const wxChar *GetTimestamp() { return ms_timestamp; } + // helpers // put the time stamp into the string if ms_timestamp != NULL (don't // change it otherwise) @@ -197,9 +221,11 @@ public: // make dtor virtual for all derived classes virtual ~wxLog() { } -protected: - bool m_bHasMessages; // any messages in the queue? + // this method exists for backwards compatibility only, don't use + bool HasPendingMessages() const { return TRUE; } + +protected: // the logging functions that can be overriden // default DoLog() prepends the time stamp and a prefix corresponding // to the message to szString and then passes it to DoLogString() @@ -217,6 +243,8 @@ private: static bool ms_bAutoCreate; // create new log targets on demand? static bool ms_bVerbose; // FALSE => ignore LogInfo messages + static wxLogLevel ms_logLevel; // limit logging to levels <= ms_logLevel + static size_t ms_suspendCount; // if positive, logs are not flushed // format string for strftime(), if NULL, time stamping log messages is @@ -234,6 +262,8 @@ private: // log everything to a "FILE *", stderr by default class WXDLLEXPORT wxLogStderr : public wxLog { + DECLARE_NO_COPY_CLASS(wxLogStderr) + public: // redirect log output to a FILE wxLogStderr(FILE *fp = (FILE *) NULL); @@ -287,8 +317,8 @@ protected: class WXDLLEXPORT wxLogNull { public: - wxLogNull() { m_flagOld = wxLog::EnableLogging(FALSE); } - ~wxLogNull() { (void)wxLog::EnableLogging(m_flagOld); } + wxLogNull() : m_flagOld(wxLog::EnableLogging(FALSE)) { } + ~wxLogNull() { (void)wxLog::EnableLogging(m_flagOld); } private: bool m_flagOld; // the previous value of the wxLog::ms_doLog @@ -307,7 +337,7 @@ class WXDLLEXPORT wxLogChain : public wxLog { public: wxLogChain(wxLog *logger); - virtual ~wxLogChain() { delete m_logOld; } + virtual ~wxLogChain(); // change the new log target void SetLog(wxLog *logger); @@ -338,6 +368,8 @@ private: // do we pass the messages to the old logger? bool m_bPassMessages; + + DECLARE_NO_COPY_CLASS(wxLogChain) }; // a chain log target which uses itself as the new logger @@ -369,6 +401,8 @@ private: // the control we use wxTextCtrl *m_pTextCtrl; + + DECLARE_NO_COPY_CLASS(wxLogTextCtrl) }; #endif // wxUSE_TEXTCTRL @@ -398,7 +432,9 @@ protected: wxArrayInt m_aSeverity; // one of wxLOG_XXX values wxArrayLong m_aTimes; // the time of each message bool m_bErrors, // do we have any errors? - m_bWarnings; // any warnings? + m_bWarnings, // any warnings? + m_bHasMessages; // any messages at all? + }; #endif // wxUSE_LOGGUI @@ -447,6 +483,8 @@ protected: private: wxLogFrame *m_pLogFrame; // the log frame + + DECLARE_NO_COPY_CLASS(wxLogWindow) }; #endif // wxUSE_LOGWINDOW @@ -468,25 +506,51 @@ private: // return the last system error code WXDLLEXPORT unsigned long wxSysErrorCode(); + // return the error message for given (or last if 0) error code WXDLLEXPORT const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0); +// ---------------------------------------------------------------------------- // define wxLog -// ------------------- +// ---------------------------------------------------------------------------- #define DECLARE_LOG_FUNCTION(level) \ -extern void WXDLLEXPORT wxLog##level(const wxChar *szFormat, ...) +extern void WXDLLEXPORT wxVLog##level(const wxChar *szFormat, \ + va_list argptr); \ +extern void WXDLLEXPORT wxLog##level(const wxChar *szFormat, \ + ...) ATTRIBUTE_PRINTF_1 #define DECLARE_LOG_FUNCTION2(level, arg1) \ -extern void WXDLLEXPORT wxLog##level(arg1, const wxChar *szFormat, ...) +extern void WXDLLEXPORT wxVLog##level(arg1, const wxChar *szFormat, \ + va_list argptr); \ +extern void WXDLLEXPORT wxLog##level(arg1, const wxChar *szFormat, \ + ...) ATTRIBUTE_PRINTF_2 #else // !wxUSE_LOG // log functions do nothing at all #define DECLARE_LOG_FUNCTION(level) \ +inline void WXDLLEXPORT wxVLog##level(const wxChar *szFormat, \ + va_list argptr) {} \ inline void WXDLLEXPORT wxLog##level(const wxChar *szFormat, ...) {} #define DECLARE_LOG_FUNCTION2(level, arg1) \ +inline void WXDLLEXPORT wxVLog##level(arg1, const wxChar *szFormat, \ + va_list argptr) {} \ inline void WXDLLEXPORT wxLog##level(arg1, const wxChar *szFormat, ...) {} +// Empty Class to fake wxLogNull +class WXDLLEXPORT wxLogNull +{ +public: + wxLogNull() {} +}; + +// Dummy macros to replace some functions. +#define wxSysErrorCode() (unsigned long)0 +#define wxSysErrorMsg( X ) (const wxChar*)NULL + +// Fake symbolic trace masks... for those that are used frequently +#define wxTRACE_OleCalls wxT("") // OLE interface calls + #endif // wxUSE_LOG/!wxUSE_LOG // a generic function for all levels (level is passes as parameter) @@ -517,10 +581,10 @@ DECLARE_LOG_FUNCTION(SysError); DECLARE_LOG_FUNCTION2(SysError, long lErrCode); // debug functions do nothing in release mode -#ifdef __WXDEBUG__ +#if wxUSE_LOG_DEBUG DECLARE_LOG_FUNCTION(Debug); - // first king of LogTrace is uncoditional: it doesn't check the level, + // first kind of LogTrace is unconditional: it doesn't check the level, DECLARE_LOG_FUNCTION(Trace); // this second version will only log the message if the mask had been @@ -533,12 +597,20 @@ DECLARE_LOG_FUNCTION2(SysError, long lErrCode); DECLARE_LOG_FUNCTION2(Trace, wxTraceMask mask); #else //!debug // these functions do nothing in release builds + inline void wxVLogDebug(const wxChar *, va_list) { } inline void wxLogDebug(const wxChar *, ...) { } + inline void wxVLogTrace(const wxChar *, va_list) { } inline void wxLogTrace(const wxChar *, ...) { } + inline void wxVLogTrace(wxTraceMask, const wxChar *, va_list) { } inline void wxLogTrace(wxTraceMask, const wxChar *, ...) { } + inline void wxVLogTrace(const wxChar *, const wxChar *, va_list) { } inline void wxLogTrace(const wxChar *, const wxChar *, ...) { } #endif // debug/!debug +// wxLogFatalError helper: show the (fatal) error to the user in a safe way, +// i.e. without using wxMessageBox() for example because it could crash +void WXDLLEXPORT wxSafeShowMessage(const wxString& title, const wxString& text); + // ---------------------------------------------------------------------------- // debug only logging functions: use them with API name and error code // ---------------------------------------------------------------------------- @@ -549,14 +621,14 @@ DECLARE_LOG_FUNCTION2(SysError, long lErrCode); #ifdef __VISUALC__ #define wxLogApiError(api, rc) \ wxLogDebug(wxT("%s(%d): '%s' failed with error 0x%08lx (%s)."), \ - __TFILE__, __LINE__, api, \ - rc, wxSysErrorMsg(rc)) + __TFILE__, __LINE__, api, \ + (long)rc, wxSysErrorMsg(rc)) #else // !VC++ #define wxLogApiError(api, rc) \ wxLogDebug(wxT("In file %s at line %d: '%s' failed with " \ - "error 0x%08lx (%s)."), \ - __TFILE__, __LINE__, api, \ - rc, wxSysErrorMsg(rc)) + "error 0x%08lx (%s)."), \ + __TFILE__, __LINE__, api, \ + (long)rc, wxSysErrorMsg(rc)) #endif // VC++/!VC++ #define wxLogLastError(api) wxLogApiError(api, wxSysErrorCode()) @@ -567,3 +639,4 @@ DECLARE_LOG_FUNCTION2(SysError, long lErrCode); #endif //debug/!debug #endif // _WX_LOG_H_ +