#include "wx/defs.h"
// ----------------------------------------------------------------------------
-// common constants for use in wxUSE_LOG/!wxUSE_LOG
+// types
// ----------------------------------------------------------------------------
-// the trace masks have been superceded by symbolic trace constants, they're
-// for compatibility only andwill be removed soon - do NOT use them
-
-// meaning of different bits of the trace mask (which allows selectively
-// enable/disable some trace messages)
-#define wxTraceMemAlloc 0x0001 // trace memory allocation (new/delete)
-#define wxTraceMessages 0x0002 // trace window messages/X callbacks
-#define wxTraceResAlloc 0x0004 // trace GDI resource allocation
-#define wxTraceRefCount 0x0008 // trace various ref counting operations
+// NB: this is needed even if wxUSE_LOG == 0
+typedef unsigned long wxLogLevel;
-#ifdef __WXMSW__
- #define wxTraceOleCalls 0x0100 // OLE interface calls
-#endif
+// the trace masks have been superseded by symbolic trace constants, they're
+// for compatibility only and will be removed soon - do NOT use them
+#if WXWIN_COMPATIBILITY_2_8
+ #define wxTraceMemAlloc 0x0001 // trace memory allocation (new/delete)
+ #define wxTraceMessages 0x0002 // trace window messages/X callbacks
+ #define wxTraceResAlloc 0x0004 // trace GDI resource allocation
+ #define wxTraceRefCount 0x0008 // trace various ref counting operations
-// ----------------------------------------------------------------------------
-// types
-// ----------------------------------------------------------------------------
+ #ifdef __WXMSW__
+ #define wxTraceOleCalls 0x0100 // OLE interface calls
+ #endif
-// NB: these types are needed even if wxUSE_LOG == 0
-typedef unsigned long wxTraceMask;
-typedef unsigned long wxLogLevel;
+ typedef unsigned long wxTraceMask;
+#endif // WXWIN_COMPATIBILITY_2_8
// ----------------------------------------------------------------------------
// headers
#include "wx/arrstr.h"
+#ifndef __WXPALMOS5__
#ifndef __WXWINCE__
#include <time.h> // for time_t
#endif
+#endif // ! __WXPALMOS5__
#include "wx/dynarray.h"
+#if wxUSE_THREADS
+ #include "wx/thread.h"
+#endif // wxUSE_THREADS
+
+// wxUSE_LOG_DEBUG enables the debug log messages
#ifndef wxUSE_LOG_DEBUG
-# ifdef __WXDEBUG__
-# define wxUSE_LOG_DEBUG 1
-# else // !__WXDEBUG__
-# define wxUSE_LOG_DEBUG 0
-# endif
+ #if wxDEBUG_LEVEL
+ #define wxUSE_LOG_DEBUG 1
+ #else // !wxDEBUG_LEVEL
+ #define wxUSE_LOG_DEBUG 0
+ #endif
#endif
+// wxUSE_LOG_TRACE enables the trace messages, they are disabled by default
+#ifndef wxUSE_LOG_TRACE
+ #if wxDEBUG_LEVEL
+ #define wxUSE_LOG_TRACE 1
+ #else // !wxDEBUG_LEVEL
+ #define wxUSE_LOG_TRACE 0
+ #endif
+#endif // wxUSE_LOG_TRACE
+
// ----------------------------------------------------------------------------
// forward declarations
// ----------------------------------------------------------------------------
#if wxUSE_GUI
- class WXDLLIMPEXP_CORE wxTextCtrl;
- class WXDLLIMPEXP_CORE wxLogFrame;
- class WXDLLIMPEXP_CORE wxFrame;
- class WXDLLIMPEXP_CORE wxWindow;
+ class WXDLLIMPEXP_FWD_CORE wxFrame;
#endif // wxUSE_GUI
// ----------------------------------------------------------------------------
#include "wx/iosfwrap.h"
+// ----------------------------------------------------------------------------
+// information about a log record, i.e. unit of log output
+// ----------------------------------------------------------------------------
+
+struct wxLogRecordInfo
+{
+ wxLogRecordInfo()
+ {
+ timestamp = 0;
+
+#if wxUSE_THREADS
+ threadId = 0;
+#endif // wxUSE_THREADS
+ }
+
+ // default copy ctor, assignment operator and dtor are ok
+
+
+ // time of record generation
+ time_t timestamp;
+
+#if wxUSE_THREADS
+ // id of the thread which logged this record
+ wxThreadIdType threadId;
+#endif // wxUSE_THREADS
+};
+
// ----------------------------------------------------------------------------
// derive from this class to redirect (or suppress, or ...) log messages
// normally, only a single instance of this class exists but it's not enforced
{
public:
// ctor
- wxLog(){}
+ wxLog() { }
+
+ // make dtor virtual for all derived classes
+ virtual ~wxLog();
+
// these functions allow to completely disable all log messages
- // is logging disabled now?
+ // is logging enabled at all now?
static bool IsEnabled() { return ms_doLog; }
+ // is logging at this level enabled?
+ static bool IsLevelEnabled(wxLogLevel level)
+ { return IsEnabled() && level <= ms_logLevel; }
+
// change the flag state, return the previous one
static bool EnableLogging(bool doIt = true)
{ bool doLogOld = ms_doLog; ms_doLog = doIt; return doLogOld; }
- // static sink function - see DoLog() for function to overload in the
- // derived classes
- static void OnLog(wxLogLevel level, const wxChar *szString, time_t t);
-
// message buffering
// flush shows all messages if they're not logged immediately (FILE
static void Resume() { ms_suspendCount--; }
// functions controlling the default wxLog behaviour
- // verbose mode is activated by standard command-line '-verbose'
+ // verbose mode is activated by standard command-line '--verbose'
// option
static void SetVerbose(bool bVerbose = true) { ms_bVerbose = bVerbose; }
// current is NULL?
static void DontCreateOnDemand();
+ // Make GetActiveTarget() create a new log object again.
+ static void DoCreateOnDemand();
+
// log the count of repeating messages instead of logging the messages
// multiple times
static void SetRepetitionCounting(bool bRepetCounting = true)
// gets duplicate counting status
static bool GetRepetitionCounting() { return ms_bRepetCounting; }
- // trace mask (see wxTraceXXX constants for details)
- static void SetTraceMask(wxTraceMask ulMask) { ms_ulTraceMask = ulMask; }
-
// add string trace mask
- static void AddTraceMask(const wxString& str)
- { ms_aTraceMasks.push_back(str); }
+ static void AddTraceMask(const wxString& str);
// add string trace mask
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; }
+ // get string trace masks: note that this is MT-unsafe if other threads can
+ // call AddTraceMask() concurrently
+ static const wxArrayString& GetTraceMasks() { return ms_aTraceMasks; }
+
+ // sets the time stamp string format: this is used as strftime() format
+ // string for the log targets which add time stamps to the messages; set
+ // it to empty string to disable time stamping completely.
+ static void SetTimestamp(const wxString& ts) { ms_timestamp = ts; }
- // 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; }
+ // disable time stamping of log messages
+ static void DisableTimestamp() { SetTimestamp(wxEmptyString); }
// accessors
// gets the verbose status
static bool GetVerbose() { return ms_bVerbose; }
- // get trace mask
- static wxTraceMask GetTraceMask() { return ms_ulTraceMask; }
-
// is this trace mask in the list?
- static bool IsAllowedTraceMask(const wxChar *mask);
+ static bool IsAllowedTraceMask(const wxString& mask);
// 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; }
+ // get the current timestamp format string (maybe empty)
+ static const wxString& GetTimestamp() { return ms_timestamp; }
+
- // helpers
+ // helpers: all functions in this section are mostly for internal use only,
+ // don't call them from your code even if they are not formally deprecated
// put the time stamp into the string if ms_timestamp != NULL (don't
// change it otherwise)
static void TimeStamp(wxString *str);
- // make dtor virtual for all derived classes
- virtual ~wxLog();
+ // these methods should only be called from derived classes DoLogRecord(),
+ // DoLogTextAtLevel() and DoLogText() implementations respectively and
+ // shouldn't be called directly, use logging functions instead
+ void LogRecord(wxLogLevel level,
+ const wxString& msg,
+ const wxLogRecordInfo& info)
+ {
+ DoLogRecord(level, msg, info);
+ }
+
+ void LogTextAtLevel(wxLogLevel level, const wxString& msg)
+ {
+ DoLogTextAtLevel(level, msg);
+ }
+
+ void LogText(const wxString& msg)
+ {
+ DoLogText(msg);
+ }
+
+ // this is a helper used by wxLogXXX() functions, don't call it directly
+ // and see DoLog() for function to overload in the derived classes
+ static void OnLog(wxLogLevel level,
+ const wxString& msg,
+ const wxLogRecordInfo& info);
+
+ // version called when no information about the location of the log record
+ // generation is available (but the time stamp is), it mainly exists for
+ // backwards compatibility, don't use it in new code
+ static void OnLog(wxLogLevel level, const wxString& msg, time_t t);
+
+ // a helper calling the above overload with current time
+ static void OnLog(wxLogLevel level, const wxString& msg)
+ {
+ OnLog(level, msg, time(NULL));
+ }
// this method exists for backwards compatibility only, don't use
#if WXWIN_COMPATIBILITY_2_6
// this function doesn't do anything any more, don't call it
- wxDEPRECATED( static wxChar *SetLogBuffer(wxChar *buf, size_t size = 0) );
-#endif
+ wxDEPRECATED_INLINE(
+ static wxChar *SetLogBuffer(wxChar *, size_t = 0), return NULL;
+ );
+#endif // WXWIN_COMPATIBILITY_2_6
+
+ // don't use integer masks any more, use string trace masks instead
+#if WXWIN_COMPATIBILITY_2_8
+ wxDEPRECATED_INLINE( static void SetTraceMask(wxTraceMask ulMask),
+ ms_ulTraceMask = ulMask; )
+ wxDEPRECATED_BUT_USED_INTERNALLY_INLINE( static wxTraceMask GetTraceMask(),
+ return ms_ulTraceMask; )
+#endif // WXWIN_COMPATIBILITY_2_8
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()
- virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
-
- // default DoLogString does nothing but is not pure virtual because if
- // you override DoLog() you might not need it at all
- virtual void DoLogString(const wxChar *szString, time_t t);
-
- // log a line containing the number of times the previous message was
- // repeated
- // returns: the number
- static unsigned DoLogNumberOfRepeats();
+ // the logging functions that can be overridden: DoLogRecord() is called
+ // for every "record", i.e. a unit of log output, to be logged and by
+ // default formats the message and passes it to DoLogTextAtLevel() which in
+ // turn passes it to DoLogText() by default
+
+ // override this method if you want to change message formatting or do
+ // dynamic filtering
+ virtual void DoLogRecord(wxLogLevel level,
+ const wxString& msg,
+ const wxLogRecordInfo& info);
+
+ // override this method to redirect output to different channels depending
+ // on its level only; if even the level doesn't matter, override
+ // DoLogText() instead
+ virtual void DoLogTextAtLevel(wxLogLevel level, const wxString& msg);
+
+ // this function is not pure virtual as it might not be needed if you do
+ // the logging in overridden DoLogRecord() or DoLogTextAtLevel() directly
+ // but if you do not override them in your derived class you must override
+ // this one as the default implementation of it simply asserts
+ virtual void DoLogText(const wxString& msg);
+
+
+ // the rest of the functions are for backwards compatibility only, don't
+ // use them in new code; if you're updating your existing code you need to
+ // switch to overriding DoLogRecord/Text() above (although as long as these
+ // functions exist, log classes using them will continue to work)
+#if WXWIN_COMPATIBILITY_2_8
+ wxDEPRECATED_BUT_USED_INTERNALLY(
+ virtual void DoLog(wxLogLevel level, const char *szString, time_t t)
+ );
+
+ wxDEPRECATED_BUT_USED_INTERNALLY(
+ virtual void DoLog(wxLogLevel level, const wchar_t *wzString, time_t t)
+ );
+
+ // these shouldn't be used by new code
+ wxDEPRECATED_BUT_USED_INTERNALLY_INLINE(
+ virtual void DoLogString(const char *WXUNUSED(szString),
+ time_t WXUNUSED(t)),
+ )
+
+ wxDEPRECATED_BUT_USED_INTERNALLY_INLINE(
+ virtual void DoLogString(const wchar_t *WXUNUSED(wzString),
+ time_t WXUNUSED(t)),
+ )
+#endif // WXWIN_COMPATIBILITY_2_8
+
+
+ // log a message indicating the number of times the previous message was
+ // repeated if previous repetition counter is strictly positive, does
+ // nothing otherwise; return the old value of repetition counter
+ unsigned LogLastRepeatIfNeeded();
private:
+ // implement of LogLastRepeatIfNeeded(): it assumes that the
+ // caller had already locked GetPreviousLogCS()
+ unsigned LogLastRepeatIfNeededUnlocked();
+
// static variables
// ----------------
- // traditional behaviour or counting repetitions
+ // if true, don't log the same message multiple times, only log it once
+ // with the number of times it was repeated
static bool ms_bRepetCounting;
- static wxString ms_prevString; // previous message that was logged
- // how many times the previous message was logged
- static unsigned ms_prevCounter;
- static time_t ms_prevTimeStamp;// timestamp of the previous message
- static wxLogLevel ms_prevLevel; // level of the previous message
static wxLog *ms_pLogger; // currently active log sink
static bool ms_doLog; // false => all logging disabled
static size_t ms_suspendCount; // if positive, logs are not flushed
- // format string for strftime(), if NULL, time stamping log messages is
+ // format string for strftime(), if empty, time stamping log messages is
// disabled
- static const wxChar *ms_timestamp;
+ static wxString ms_timestamp;
+#if WXWIN_COMPATIBILITY_2_8
static wxTraceMask ms_ulTraceMask; // controls wxLogTrace behaviour
- static wxArrayString ms_aTraceMasks; // more powerful filter for wxLogTrace
+#endif // WXWIN_COMPATIBILITY_2_8
+
+ // currently enabled trace masks
+ static wxArrayString ms_aTraceMasks;
};
// ----------------------------------------------------------------------------
// "trivial" derivations of wxLog
// ----------------------------------------------------------------------------
-// log everything to a buffer
+// log everything except for the debug/trace messages (which are passed to
+// wxMessageOutputDebug) to a buffer
class WXDLLIMPEXP_BASE wxLogBuffer : public wxLog
{
public:
virtual void Flush();
protected:
- virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
- virtual void DoLogString(const wxChar *szString, time_t t);
+ virtual void DoLogTextAtLevel(wxLogLevel level, const wxString& msg);
private:
wxString m_str;
- DECLARE_NO_COPY_CLASS(wxLogBuffer)
+ wxDECLARE_NO_COPY_CLASS(wxLogBuffer);
};
{
public:
// redirect log output to a FILE
- wxLogStderr(FILE *fp = (FILE *) NULL);
+ wxLogStderr(FILE *fp = NULL);
protected:
// implement sink function
- virtual void DoLogString(const wxChar *szString, time_t t);
+ virtual void DoLogText(const wxString& msg);
FILE *m_fp;
- DECLARE_NO_COPY_CLASS(wxLogStderr)
+ wxDECLARE_NO_COPY_CLASS(wxLogStderr);
};
#if wxUSE_STD_IOSTREAM
protected:
// implement sink function
- virtual void DoLogString(const wxChar *szString, time_t t);
+ virtual void DoLogText(const wxString& msg);
// using ptr here to avoid including <iostream.h> from this file
wxSTD ostream *m_ostr;
// override base class version to flush the old logger as well
virtual void Flush();
+ // call to avoid destroying the old log target
+ void DetachOldLog() { m_logOld = NULL; }
+
protected:
- // pass the chain to the old logger if needed
- virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t);
+ // pass the record to the old logger if needed
+ virtual void DoLogRecord(wxLogLevel level,
+ const wxString& msg,
+ const wxLogRecordInfo& info);
private:
// the current log target
// do we pass the messages to the old logger?
bool m_bPassMessages;
- DECLARE_NO_COPY_CLASS(wxLogChain)
+ wxDECLARE_NO_COPY_CLASS(wxLogChain);
};
// a chain log target which uses itself as the new logger
-class WXDLLIMPEXP_BASE wxLogPassThrough : public wxLogChain
+
+#define wxLogPassThrough wxLogInterposer
+
+class WXDLLIMPEXP_BASE wxLogInterposer : public wxLogChain
{
public:
- wxLogPassThrough();
+ wxLogInterposer();
private:
- DECLARE_NO_COPY_CLASS(wxLogPassThrough)
+ wxDECLARE_NO_COPY_CLASS(wxLogInterposer);
+};
+
+// a temporary interposer which doesn't destroy the old log target
+// (calls DetachOldLog)
+
+class WXDLLIMPEXP_BASE wxLogInterposerTemp : public wxLogChain
+{
+public:
+ wxLogInterposerTemp();
+
+private:
+ wxDECLARE_NO_COPY_CLASS(wxLogInterposerTemp);
};
#if wxUSE_GUI
// can't use WX_WATCOM_ONLY_CODE here because the macro would expand to
// something too big for Borland C++ to handle
#define DECLARE_LOG_FUNCTION_WATCOM(level) \
- WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
+ WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \
+ 1, (const wxString&), \
+ (wxFormatString(f1))) \
+ WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \
+ 1, (const wxCStrData&), \
+ (wxFormatString(f1))) \
+ WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \
1, (const char*), \
- wxDoLog##level##Wchar, \
- wxDoLog##level##Utf8) \
- WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
+ (wxFormatString(f1))) \
+ WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \
1, (const wchar_t*), \
- wxDoLog##level##Wchar, \
- wxDoLog##level##Utf8) \
- WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
- 1, (const wxCStrData&), \
- wxDoLog##level##Wchar, \
- wxDoLog##level##Utf8)
+ (wxFormatString(f1)))
#else
#define DECLARE_LOG_FUNCTION_WATCOM(level)
#endif
// can't use WX_WATCOM_ONLY_CODE here because the macro would expand to
// something too big for Borland C++ to handle
#define DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl) \
- WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
+ WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \
+ 2, (argclass, const wxString&), \
+ (f1, wxFormatString(f2))) \
+ WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \
+ 2, (argclass, const wxCStrData&), \
+ (f1, wxFormatString(f2))) \
+ WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \
2, (argclass, const char*), \
- wxDoLog##level##Wchar, \
- wxDoLog##level##Utf8) \
- WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
+ (f1, wxFormatString(f2))) \
+ WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \
2, (argclass, const wchar_t*), \
- wxDoLog##level##Wchar, \
- wxDoLog##level##Utf8) \
- WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \
- 2, (argclass, const wxCStrData&), \
- wxDoLog##level##Wchar, \
- wxDoLog##level##Utf8)
+ (f1, wxFormatString(f2)))
#else
#define DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl)
#endif
#else // !wxUSE_LOG
+#undef wxUSE_LOG_DEBUG
+#define wxUSE_LOG_DEBUG 0
+
+#undef wxUSE_LOG_TRACE
+#define wxUSE_LOG_TRACE 0
+
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
#define WX_WATCOM_ONLY_CODE( x ) x
#define WX_WATCOM_ONLY_CODE( x )
#endif
+#if defined(__WATCOMC__) || defined(__MINGW32__)
+ // Mingw has similar problem with wxLogSysError:
+ #define WX_WATCOM_OR_MINGW_ONLY_CODE( x ) x
+#else
+ #define WX_WATCOM_OR_MINGW_ONLY_CODE( x )
+#endif
+
// log functions do nothing at all
#define DECLARE_LOG_FUNCTION(level) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const wxString&)) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const wxCStrData&)) \
) \
inline void wxVLog##level(const wxString& WXUNUSED(format), \
- va_list WXUNUSED(argptr)) { } \
+ va_list WXUNUSED(argptr)) { } \
#define DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, expdecl) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const wxString&)) \
- WX_WATCOM_ONLY_CODE( \
+ WX_WATCOM_OR_MINGW_ONLY_CODE( \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const char*)) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const wchar_t*)) \
WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const wxCStrData&)) \
) \
inline void wxVLog##level(argclass WXUNUSED(arg), \
- const wxString& WXUNUSED(format), \
- va_list WXUNUSED(argptr)) {}
+ const wxString& WXUNUSED(format), \
+ va_list WXUNUSED(argptr)) {}
// Empty Class to fake wxLogNull
class WXDLLIMPEXP_BASE wxLogNull
// VC6 produces a warning if we a macro expanding to nothing to
// DECLARE_LOG_FUNCTION2:
#if defined(__VISUALC__) && __VISUALC__ < 1300
+ #pragma warning(push)
// "not enough actual parameters for macro 'DECLARE_LOG_FUNCTION2_EXP'"
#pragma warning(disable:4003)
#endif
#if wxUSE_GUI
// this one is the same as previous except that it allows to explicitly
- class WXDLLEXPORT wxFrame;
+ class WXDLLIMPEXP_FWD_CORE wxFrame;
// specify the frame to which the output should go
DECLARE_LOG_FUNCTION2_EXP(Status, wxFrame *, pFrame, WXDLLIMPEXP_CORE);
#endif // wxUSE_GUI
DECLARE_LOG_FUNCTION2(SysError, unsigned long, lErrCode);
#endif
-// debug functions do nothing in release mode
-#if wxUSE_LOG && wxUSE_LOG_DEBUG
+
+// debug functions can be completely disabled in optimized builds
+
+// if these log functions are disabled, we prefer to define them as (empty)
+// variadic macros as this completely removes them and their argument
+// evaluation from the object code but if this is not supported by compiler we
+// use empty inline functions instead (defining them as nothing would result in
+// compiler warnings)
+//
+// note that making wxVLogDebug/Trace() themselves (empty inline) functions is
+// a bad idea as some compilers are stupid enough to not inline even empty
+// functions if their parameters are complicated enough, but by defining them
+// as an empty inline function we ensure that even dumbest compilers optimise
+// them away
+#ifdef __BORLANDC__
+ // but Borland gives "W8019: Code has no effect" for wxLogNop() so we need
+ // to define it differently for it to avoid these warnings (same problem as
+ // with wxUnusedVar())
+ #define wxLogNop() { }
+#else
+ inline void wxLogNop() { }
+#endif
+
+#if wxUSE_LOG_DEBUG
DECLARE_LOG_FUNCTION(Debug);
+#else // !wxUSE_LOG_DEBUG
+ #define wxVLogDebug(fmt, valist) wxLogNop()
- // there is no more unconditional LogTrace: it is not different from
- // LogDebug and it creates overload ambiguities
- //DECLARE_LOG_FUNCTION(Trace);
+ #ifdef HAVE_VARIADIC_MACROS
+ #define wxLogDebug(fmt, ...) wxLogNop()
+ #else // !HAVE_VARIADIC_MACROS
+ WX_DEFINE_VARARG_FUNC_NOP(wxLogDebug, 1, (const wxString&))
+ #endif
+#endif // wxUSE_LOG_DEBUG/!wxUSE_LOG_DEBUG
+#if wxUSE_LOG_TRACE
// this version only logs the message if the mask had been added to the
// list of masks with AddTraceMask()
DECLARE_LOG_FUNCTION2(Trace, const wxString&, mask);
// and this one does nothing if all of level bits are not set in
// wxLog::GetActive()->GetTraceMask() -- it's deprecated in favour of
// string identifiers
+#if WXWIN_COMPATIBILITY_2_8
DECLARE_LOG_FUNCTION2(Trace, wxTraceMask, mask);
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
DECLARE_LOG_FUNCTION2(Trace, int, mask);
#endif
-#else //!debug || !wxUSE_LOG
- // these functions do nothing in release builds, but don't define them as
- // nothing as it could result in different code structure in debug and
- // release and this could result in trouble when these macros are used
- // inside if/else
- //
- // note that making wxVLogDebug/Trace() themselves (empty inline) functions
- // is a bad idea as some compilers are stupid enough to not inline even
- // empty functions if their parameters are complicated enough, but by
- // defining them as an empty inline function we ensure that even dumbest
- // compilers optimise them away
- inline void wxLogNop() { }
+#endif // WXWIN_COMPATIBILITY_2_8
- #define wxVLogDebug(fmt, valist) wxLogNop()
+#else // !wxUSE_LOG_TRACE
#define wxVLogTrace(mask, fmt, valist) wxLogNop()
#ifdef HAVE_VARIADIC_MACROS
- // unlike the inline functions below, this completely removes the
- // wxLogXXX calls from the object file:
- #define wxLogDebug(fmt, ...) wxLogNop()
#define wxLogTrace(mask, fmt, ...) wxLogNop()
#else // !HAVE_VARIADIC_MACROS
- //inline void wxLogDebug(const wxString& fmt, ...) {}
- WX_DEFINE_VARARG_FUNC_NOP(wxLogDebug, 1, (const wxString&))
- //inline void wxLogTrace(wxTraceMask, const wxString& fmt, ...) {}
- //inline void wxLogTrace(const wxString&, const wxString& fmt, ...) {}
+ #if WXWIN_COMPATIBILITY_2_8
WX_DEFINE_VARARG_FUNC_NOP(wxLogTrace, 2, (wxTraceMask, const wxString&))
+ #endif
WX_DEFINE_VARARG_FUNC_NOP(wxLogTrace, 2, (const wxString&, const wxString&))
#ifdef __WATCOMC__
// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
WX_DEFINE_VARARG_FUNC_NOP(wxLogTrace, 2, (const wchar_t*, const wchar_t*))
#endif
#endif // HAVE_VARIADIC_MACROS/!HAVE_VARIADIC_MACROS
-#endif // debug/!debug
+#endif // wxUSE_LOG_TRACE/!wxUSE_LOG_TRACE
#if defined(__VISUALC__) && __VISUALC__ < 1300
- #pragma warning(default:4003)
+ #pragma warning(pop)
#endif
// wxLogFatalError helper: show the (fatal) error to the user in a safe way,
// debug only logging functions: use them with API name and error code
// ----------------------------------------------------------------------------
-#ifdef __WXDEBUG__
+#if wxUSE_LOG_DEBUG
// make life easier for people using VC++ IDE: clicking on the message
// will take us immediately to the place of the failed API
#ifdef __VISUALC__
#define wxLogApiError(api, rc) \
wxLogDebug(wxT("%s(%d): '%s' failed with error 0x%08lx (%s)."), \
- __TFILE__, __LINE__, api, \
+ __FILE__, __LINE__, api, \
(long)rc, wxSysErrorMsg(rc))
#else // !VC++
#define wxLogApiError(api, rc) \
wxLogDebug(wxT("In file %s at line %d: '%s' failed with ") \
wxT("error 0x%08lx (%s)."), \
- __TFILE__, __LINE__, api, \
+ __FILE__, __LINE__, api, \
(long)rc, wxSysErrorMsg(rc))
#endif // VC++/!VC++
#define wxLogLastError(api) wxLogApiError(api, wxSysErrorCode())
-#else //!debug
+#else // !wxUSE_LOG_DEBUG
#define wxLogApiError(api, err) wxLogNop()
#define wxLogLastError(api) wxLogNop()
-#endif //debug/!debug
+#endif // wxUSE_LOG_DEBUG/!wxUSE_LOG_DEBUG
// wxCocoa has additiional trace masks
#if defined(__WXCOCOA__)