From af58844636f51ca9c9350c66de3baf427d3e8646 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 9 Jul 2009 20:26:34 +0000 Subject: [PATCH] Add information about the log message generation location to wxLog. This means that wxLog::DoLogRecord() can now retrieve the file name, line number and the function where the message was logged. An unfortunate consequence of this change is that now if ( condition ) wxLogError("Whatever"); results in a warning from g++ 4.x with -Wparentehses, so extra parentheses had to be added in many places. Finally, also allow storing arbitrary attributes in wxLogRecordInfo. This had to be added to implement our own overloaded wxLogStatus() and wxLogSysError() and will probably be useful for the others as well. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61363 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/doxygen/overviews/log.h | 26 +- include/wx/hashmap.h | 3 + include/wx/log.h | 772 +++++++++++++++++++++++++------- include/wx/platform.h | 10 +- interface/wx/log.h | 49 +- samples/dialogs/dialogs.cpp | 5 +- src/common/file.cpp | 2 + src/common/hyperlnkcmn.cpp | 4 + src/common/imagbmp.cpp | 48 ++ src/common/imaggif.cpp | 2 + src/common/imagiff.cpp | 2 + src/common/imagjpeg.cpp | 4 + src/common/imagpcx.cpp | 2 + src/common/imagpng.cpp | 10 + src/common/imagpnm.cpp | 22 +- src/common/imagtga.cpp | 2 + src/common/imagtiff.cpp | 18 + src/common/intl.cpp | 2 + src/common/log.cpp | 432 +++--------------- src/common/msgout.cpp | 2 +- src/common/socket.cpp | 2 + src/common/tarstrm.cpp | 4 + src/common/zipstrm.cpp | 2 + src/common/zstream.cpp | 2 + src/generic/logg.cpp | 62 +-- src/gtk/dataview.cpp | 2 + src/richtext/richtextbuffer.cpp | 6 + 27 files changed, 875 insertions(+), 622 deletions(-) diff --git a/docs/doxygen/overviews/log.h b/docs/doxygen/overviews/log.h index f39f4cbcc3..d8cb23e9f7 100644 --- a/docs/doxygen/overviews/log.h +++ b/docs/doxygen/overviews/log.h @@ -71,10 +71,12 @@ argument list pointer. Here are all of them: as the first argument. @li wxLogDebug is @b the right function for debug output. It only does anything at all in the debug mode (when the preprocessor symbol __WXDEBUG__ is - defined) and expands to nothing in release mode (otherwise). @b Tip: under - Windows, you must either run the program under debugger or use a 3rd party - program such as DebugView to actually see the debug output. - - DebugView: http://www.microsoft.com/technet/sysinternals/Miscellaneous/DebugView.mspx + defined) and expands to nothing in release mode (otherwise). + + @b Tip: under Windows, you must either run the program under debugger or + use a 3rd party program such as DebugView + (http://www.microsoft.com/technet/sysinternals/Miscellaneous/DebugView.mspx) + to actually see the debug output. @li wxLogTrace as wxLogDebug only does something in debug build. The reason for making it a separate function from it is that usually there are a lot of trace messages, so it might make sense to separate them from other debug @@ -133,12 +135,16 @@ the active target with a call to @e SetActiveTarget() and it will be used automatically by all subsequent calls to @e wxLogXXX() functions. To create a new log target class you only need to derive it from wxLog and -implement one (or both) of @e DoLog() and @e DoLogString() in it. The second -one is enough if you're happy with the standard wxLog message formatting -(prepending "Error:" or "Warning:", timestamping @&c) but just want to send -the messages somewhere else. The first one may be overridden to do whatever -you want but you have to distinguish between the different message types -yourself. +override one or several of wxLog::DoLogRecord(), wxLog::DoLogTextAtLevel() and +wxLog::DoLogText() in it. The first one is the most flexible and allows you to +change the formatting of the messages, dynamically filter and redirect them and +so on -- all log messages, except for those generated by wxLogFatalError(), +pass by this function. wxLog::DoLogTextAtLevel() should be overridden if you +simply want to redirect the log messages somewhere else, without changing their +formatting. Finally, it is enough to override wxLog::DoLogText() if you only +want to redirect the log messages and the destination doesn't depend on the +message log level. + There are some predefined classes deriving from wxLog and which might be helpful to see how you can create a new log target class and, of course, may diff --git a/include/wx/hashmap.h b/include/wx/hashmap.h index 325c072196..252df7885d 100644 --- a/include/wx/hashmap.h +++ b/include/wx/hashmap.h @@ -748,5 +748,8 @@ WX_DECLARE_HASH_MAP_WITH_DECL( long, long, wxIntegerHash, wxIntegerEqual, WX_DECLARE_STRING_HASH_MAP_WITH_DECL( wxString, wxStringToStringHashMap, class WXDLLIMPEXP_BASE ); +WX_DECLARE_STRING_HASH_MAP_WITH_DECL( wxUIntPtr, wxStringToNumHashMap, + class WXDLLIMPEXP_BASE ); + #endif // _WX_HASHMAP_H_ diff --git a/include/wx/log.h b/include/wx/log.h index 29c404668b..60b6e8b620 100644 --- a/include/wx/log.h +++ b/include/wx/log.h @@ -54,6 +54,7 @@ typedef unsigned long wxLogLevel; #endif // ! __WXPALMOS5__ #include "wx/dynarray.h" +#include "wx/hashmap.h" #if wxUSE_THREADS #include "wx/thread.h" @@ -124,20 +125,67 @@ enum wxLogLevelValues // information about a log record, i.e. unit of log output // ---------------------------------------------------------------------------- -struct wxLogRecordInfo +class wxLogRecordInfo { +public: + // default ctor creates an uninitialized object wxLogRecordInfo() { - timestamp = 0; + memset(this, 0, sizeof(this)); + } + + // normal ctor, used by wxLogger specifies the location of the log + // statement; its time stamp and thread id are set up here + wxLogRecordInfo(const char *filename_, + int line_, + const char *func_) + { + filename = filename_; + func = func_; + line = line_; + + timestamp = time(NULL); #if wxUSE_THREADS - threadId = 0; + threadId = wxThread::GetCurrentId(); #endif // wxUSE_THREADS + + m_data = NULL; + } + + // we need to define copy ctor and assignment operator because of m_data + wxLogRecordInfo(const wxLogRecordInfo& other) + { + Copy(other); + } + + wxLogRecordInfo& operator=(const wxLogRecordInfo& other) + { + if ( &other != this ) + { + delete m_data; + Copy(other); + } + + return *this; } - // default copy ctor, assignment operator and dtor are ok + // dtor is non-virtual, this class is not meant to be derived from + ~wxLogRecordInfo() + { + delete m_data; + } + // the file name and line number of the file where the log record was + // generated, if available or NULL and 0 otherwise + const char *filename; + int line; + + // the name of the function where the log record was generated (may be NULL + // if the compiler doesn't support __FUNCTION__) + const char *func; + // time of record generation time_t timestamp; @@ -145,8 +193,81 @@ struct wxLogRecordInfo // id of the thread which logged this record wxThreadIdType threadId; #endif // wxUSE_THREADS + + + // store an arbitrary value in this record context + // + // wxWidgets always uses keys starting with "wx.", e.g. "wx.sys_error" + void StoreValue(const wxString& key, wxUIntPtr val) + { + if ( !m_data ) + m_data = new ExtraData; + + m_data->numValues[key] = val; + } + + void StoreValue(const wxString& key, const wxString& val) + { + if ( !m_data ) + m_data = new ExtraData; + + m_data->strValues[key] = val; + } + + + // these functions retrieve the value of either numeric or string key, + // return false if not found + bool GetNumValue(const wxString& key, wxUIntPtr *val) const + { + if ( !m_data ) + return false; + + wxStringToNumHashMap::const_iterator it = m_data->numValues.find(key); + if ( it == m_data->numValues.end() ) + return false; + + *val = it->second; + + return true; + } + + bool GetStrValue(const wxString& key, wxString *val) const + { + if ( !m_data ) + return false; + + wxStringToStringHashMap::const_iterator it = m_data->strValues.find(key); + if ( it == m_data->strValues.end() ) + return false; + + *val = it->second; + + return true; + } + +private: + void Copy(const wxLogRecordInfo& other) + { + memcpy(this, &other, sizeof(wxLogRecordInfo)); + if ( other.m_data ) + m_data = new ExtraData(*other.m_data); + } + + // extra data associated with the log record: this is completely optional + // and can be used to pass information from the log function to the log + // sink (e.g. wxLogSysError() uses this to pass the error code) + struct ExtraData + { + wxStringToNumHashMap numValues; + wxStringToStringHashMap strValues; + }; + + // NULL if not used + ExtraData *m_data; }; +#define wxLOG_KEY_TRACE_MASK "wx.trace_mask" + // ---------------------------------------------------------------------------- // 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 @@ -338,7 +459,7 @@ protected: // 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, @@ -599,15 +720,333 @@ private: #include "wx/generic/logg.h" #endif // wxUSE_GUI +// ---------------------------------------------------------------------------- +// wxLogger +// ---------------------------------------------------------------------------- + +// wxLogger is a helper class used by wxLogXXX() functions implementation, +// don't use it directly as it's experimental and subject to change (OTOH it +// might become public in the future if it's deemed to be useful enough) + +// contains information about the context from which a log message originates +// and provides Log() vararg method which forwards to wxLog::OnLog() and passes +// this context to it +class wxLogger +{ +public: + // ctor takes the basic information about the log record + wxLogger(wxLogLevel level, + const char *filename, + int line, + const char *func) + : m_level(level), + m_info(filename, line, func) + { + } + + // store extra data in our log record and return this object itself (so + // that further calls to its functions could be chained) + template + wxLogger& Store(const wxString& key, T val) + { + m_info.StoreValue(key, val); + return *this; + } + + // hack for "overloaded" wxLogXXX() functions: calling this method + // indicates that we may have an extra first argument preceding the format + // string and that if we do have it, we should store it in m_info using the + // given key (while by default 0 value will be used) + wxLogger& MaybeStore(const wxString& key) + { + wxASSERT_MSG( m_optKey.empty(), "can only have one optional value" ); + m_optKey = key; + + m_info.StoreValue(key, 0); + return *this; + } + + + // non-vararg function used by wxVLogXXX(): + + // log the message at the level specified in the ctor if this log message + // is enabled + void LogV(const wxString& format, va_list argptr) + { + // remember that fatal errors can't be disabled + if ( m_level == wxLOG_FatalError || wxLog::IsLevelEnabled(m_level) ) + DoCallOnLog(format, argptr); + } + + // overloads used by functions with optional leading arguments (whose + // values are stored in the key passed to MaybeStore()) + void LogV(long num, const wxString& format, va_list argptr) + { + Store(m_optKey, num); + + LogV(format, argptr); + } + + void LogV(void *ptr, const wxString& format, va_list argptr) + { + Store(m_optKey, wxPtrToUInt(ptr)); + + LogV(format, argptr); + } + + + // vararg functions used by wxLogXXX(): + + // will log the message at the level specified in the ctor + // + // notice that this function supposes that the caller already checked that + // the level was enabled and does no checks itself + WX_DEFINE_VARARG_FUNC_VOID + ( + Log, + 1, (const wxFormatString&), + DoLog, DoLogUtf8 + ) + + // same as Log() but with an extra numeric or pointer parameters: this is + // used to pass an optional value by storing it in m_info under the name + // passed to MaybeStore() and is required to support "overloaded" versions + // of wxLogStatus() and wxLogSysError() + WX_DEFINE_VARARG_FUNC_VOID + ( + Log, + 2, (long, const wxFormatString&), + DoLogWithNum, DoLogWithNumUtf8 + ) + + WX_DEFINE_VARARG_FUNC_VOID + ( + Log, + 2, (void *, const wxFormatString&), + DoLogWithPtr, DoLogWithPtrUtf8 + ) + + // log the message at the level specified as its first argument + // + // as the macros don't have access to the level argument in this case, this + // function does check that the level is enabled itself + WX_DEFINE_VARARG_FUNC_VOID + ( + LogAtLevel, + 2, (wxLogLevel, const wxFormatString&), + DoLogAtLevel, DoLogAtLevelUtf8 + ) + + // special versions for wxLogTrace() which is passed either string or + // integer (TODO) mask as first argument determining whether the message + // should be logged or not + WX_DEFINE_VARARG_FUNC_VOID + ( + LogTrace, + 2, (const wxString&, const wxFormatString&), + DoLogTrace, DoLogTraceUtf8 + ) + +#ifdef __WATCOMC__ + // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 1, (const wxString&), + (wxFormatString(f1))) + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 1, (const wxCStrData&), + (wxFormatString(f1))) + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 1, (const char*), + (wxFormatString(f1))) + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 1, (const wchar_t*), + (wxFormatString(f1))) + + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 2, (long, const wxString&), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 2, (long, const wxCStrData&), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 2, (long, const char *), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 2, (long, const wchar_t *), + (f1, wxFormatString(f2))) + + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 2, (void *, const wxString&), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 2, (void *, const wxCStrData&), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 2, (void *, const char *), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, Log, + 2, (void *, const wchar_t *), + (f1, wxFormatString(f2))) + + WX_VARARG_WATCOM_WORKAROUND(void, LogAtLevel, + 2, (wxLogLevel, const wxString&), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, LogAtLevel, + 2, (wxLogLevel, const wxCStrData&), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, LogAtLevel, + 2, (wxLogLevel, const char *), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, LogAtLevel, + 2, (wxLogLevel, const wchar_t *), + (f1, wxFormatString(f2))) + + WX_VARARG_WATCOM_WORKAROUND(void, LogTrace, + 2, (const wxString&, const wxString&), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, LogTrace, + 2, (const wxString&, const wxCStrData&), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, LogTrace, + 2, (const wxString&, const char *), + (f1, wxFormatString(f2))) + WX_VARARG_WATCOM_WORKAROUND(void, LogTrace, + 2, (const wxString&, const wchar_t *), + (f1, wxFormatString(f2))) +#endif // __WATCOMC__ + +private: +#if !wxUSE_UTF8_LOCALE_ONLY + void DoLog(const wxChar *format, ...) + { + va_list argptr; + va_start(argptr, format); + DoCallOnLog(format, argptr); + va_end(argptr); + } + + void DoLogWithNum(long num, const wxChar *format, ...) + { + Store(m_optKey, num); + + va_list argptr; + va_start(argptr, format); + DoCallOnLog(format, argptr); + va_end(argptr); + } + + void DoLogWithPtr(void *ptr, const wxChar *format, ...) + { + Store(m_optKey, wxPtrToUInt(ptr)); + + va_list argptr; + va_start(argptr, format); + DoCallOnLog(format, argptr); + va_end(argptr); + } + + void DoLogAtLevel(wxLogLevel level, const wxChar *format, ...) + { + if ( !wxLog::IsLevelEnabled(level) ) + return; + + va_list argptr; + va_start(argptr, format); + DoCallOnLog(level, format, argptr); + va_end(argptr); + } + + void DoLogTrace(const wxString& mask, const wxChar *format, ...) + { + if ( !wxLog::IsAllowedTraceMask(mask) ) + return; + + Store(wxLOG_KEY_TRACE_MASK, mask); + + va_list argptr; + va_start(argptr, format); + DoCallOnLog(format, argptr); + va_end(argptr); + } +#endif // !wxUSE_UTF8_LOCALE_ONLY + +#if wxUSE_UNICODE_UTF8 + void DoLogUtf8(const char *format, ...) + { + va_list argptr; + va_start(argptr, format); + DoCallOnLog(format, argptr); + va_end(argptr); + } + + void DoLogWithNumUtf8(long num, const char *format, ...) + { + Store(m_optKey, num); + + va_list argptr; + va_start(argptr, format); + DoCallOnLog(format, argptr); + va_end(argptr); + } + + void DoLogWithPtrUtf8(void *ptr, const char *format, ...) + { + Store(m_optKey, wxPtrToUInt(ptr)); + + va_list argptr; + va_start(argptr, format); + DoCallOnLog(format, argptr); + va_end(argptr); + } + + void DoLogAtLevelUtf8(wxLogLevel level, const char *format, ...) + { + if ( !wxLog::IsLevelEnabled(level) ) + return; + + va_list argptr; + va_start(argptr, format); + DoCallOnLog(level, format, argptr); + va_end(argptr); + } + + void DoLogTraceUtf8(const wxString& mask, const char *format, ...) + { + if ( !wxLog::IsAllowedTraceMask(mask) ) + return; + + Store(wxLOG_KEY_TRACE_MASK, mask); + + va_list argptr; + va_start(argptr, format); + DoCallOnLog(format, argptr); + va_end(argptr); + } +#endif // wxUSE_UNICODE_UTF8 + + void DoCallOnLog(wxLogLevel level, const wxString& format, va_list argptr) + { + wxLog::OnLog(level, wxString::FormatV(format, argptr), m_info); + } + + void DoCallOnLog(const wxString& format, va_list argptr) + { + wxLog::OnLog(m_level, wxString::FormatV(format, argptr), m_info); + } + + + const wxLogLevel m_level; + wxLogRecordInfo m_info; + + wxString m_optKey; + + wxDECLARE_NO_COPY_CLASS(wxLogger); +}; + // ============================================================================ // global functions // ============================================================================ -// ---------------------------------------------------------------------------- -// Log functions should be used by application instead of stdio, iostream &c -// for log messages for easy redirection -// ---------------------------------------------------------------------------- - // ---------------------------------------------------------------------------- // get error code/error message from system in a portable way // ---------------------------------------------------------------------------- @@ -619,76 +1058,152 @@ WXDLLIMPEXP_BASE unsigned long wxSysErrorCode(); WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0); // ---------------------------------------------------------------------------- -// define wxLog +// define wxLog() functions which can be used by application instead of +// stdio, iostream &c for log messages for easy redirection // ---------------------------------------------------------------------------- -#define DECLARE_LOG_FUNCTION(level) \ - extern void WXDLLIMPEXP_BASE \ - wxDoLog##level##Wchar(const wxChar *format, ...); \ - extern void WXDLLIMPEXP_BASE \ - wxDoLog##level##Utf8(const char *format, ...); \ - WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \ - 1, (const wxFormatString&), \ - wxDoLog##level##Wchar, wxDoLog##level##Utf8) \ - DECLARE_LOG_FUNCTION_WATCOM(level) \ - extern void WXDLLIMPEXP_BASE wxVLog##level(const wxString& format, \ - va_list argptr) +/* + The code below is unreadable because it (unfortunately unavoidably) + contains a lot of macro magic but all it does is to define wxLogXXX() such + that you can call them as vararg functions to log a message at the + corresponding level. + + More precisely, it defines: + + - wxLog{FatalError,Error,Warning,Message,Verbose,Debug}() functions + taking the format string and additional vararg arguments if needed. + - wxLogGeneric(wxLogLevel level, const wxString& format, ...) which + takes the log level explicitly. + - wxLogSysError(const wxString& format, ...) and wxLogSysError(long + err, const wxString& format, ...) which log a wxLOG_Error severity + message with the error message corresponding to the system error code + err or the last error. + - wxLogStatus(const wxString& format, ...) which logs the message into + the status bar of the main application window and its overload + wxLogStatus(wxFrame *frame, const wxString& format, ...) which logs it + into the status bar of the specified frame. + - wxLogTrace(Mask mask, const wxString& format, ...) which only logs + the message is the specified mask is enabled. This comes in two kinds: + Mask can be a wxString or a long. Both are deprecated. + + In addition, wxVLogXXX() versions of all the functions above are also + defined. They take a va_list argument instead of "...". + */ -#ifdef __WATCOMC__ - // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351; - // 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_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*), \ - (wxFormatString(f1))) \ - WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \ - 1, (const wchar_t*), \ - (wxFormatString(f1))) -#else - #define DECLARE_LOG_FUNCTION_WATCOM(level) -#endif +// creates wxLogger object for the current location +#define wxMAKE_LOGGER(level) \ + wxLogger(wxLOG_##level, __FILE__, __LINE__, __WXFUNCTION__) +// this macro generates the expression which logs whatever follows it in +// parentheses at the level specified as argument +#define wxDO_LOG(level) wxMAKE_LOGGER(level).Log -#define DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, expdecl) \ - extern void expdecl wxDoLog##level##Wchar(argclass arg, \ - const wxChar *format, ...); \ - extern void expdecl wxDoLog##level##Utf8(argclass arg, \ - const char *format, ...); \ - WX_DEFINE_VARARG_FUNC_VOID(wxLog##level, \ - 2, (argclass, const wxFormatString&), \ - wxDoLog##level##Wchar, wxDoLog##level##Utf8) \ - DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl) \ - extern void expdecl wxVLog##level(argclass arg, \ - const wxString& format, \ - va_list argptr) +// this is the non-vararg equivalent +#define wxDO_LOGV(level, format, argptr) \ + wxMAKE_LOGGER(level).LogV(format, argptr) -#ifdef __WATCOMC__ - // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351; - // 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_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*), \ - (f1, wxFormatString(f2))) \ - WX_VARARG_WATCOM_WORKAROUND(void, wxLog##level, \ - 2, (argclass, const wchar_t*), \ - (f1, wxFormatString(f2))) -#else - #define DECLARE_LOG_FUNCTION2_EXP_WATCOM(level, argclass, arg, expdecl) -#endif +// this macro declares wxLog() macro which logs whatever follows it if +// logging at specified level is enabled (notice that if it is false, the +// following arguments are not even evaluated which is good as it avoids +// unnecessary overhead) +// +// Note: the strange if/else construct is needed to make the following code +// +// if ( cond ) +// wxLogError("!!!"); +// else +// ... +// +// work as expected, without it the second "else" would match the "if" +// inside wxLogError(). Unfortunately code like +// +// if ( cond ) +// wxLogError("!!!"); +// +// now provokes "suggest explicit braces to avoid ambiguous 'else'" +// warnings from g++ 4.3 and later with -Wparentheses on but they can be +// easily fixed by adding curly braces around wxLogError() and at least +// the code still does do the right thing. +#define wxDO_LOG_IF_ENABLED(level) \ + if ( !wxLog::IsLevelEnabled(wxLOG_##level) ) \ + {} \ + else \ + wxDO_LOG(level) + +// wxLogFatalError() is special as it can't be disabled +#define wxLogFatalError wxDO_LOG(FatalError) +#define wxVLogFatalError(format, argptr) wxDO_LOGV(FatalError, format, argptr) + +#define wxLogError wxDO_LOG_IF_ENABLED(Error) +#define wxVLogError(format, argptr) wxDO_LOGV(Error, format, argptr) + +#define wxLogWarning wxDO_LOG_IF_ENABLED(Warning) +#define wxVLogWarning(format, argptr) wxDO_LOGV(Warning, format, argptr) + +#define wxLogMessage wxDO_LOG_IF_ENABLED(Message) +#define wxVLogMessage(format, argptr) wxDO_LOGV(Message, format, argptr) + +// this one is special as it only logs if we're in verbose mode +#define wxLogVerbose \ + if ( !(wxLog::IsLevelEnabled(wxLOG_Info) && wxLog::GetVerbose()) ) \ + {} \ + else \ + wxDO_LOG(Info) +#define wxVLogVerbose(format, argptr) \ + if ( !(wxLog::IsLevelEnabled(wxLOG_Info) && wxLog::GetVerbose()) ) \ + {} \ + else \ + wxDO_LOGV(Info, format, argptr) + +// deprecated synonyms for wxLogVerbose() and wxVLogVerbose() +#define wxLogInfo wxLogVerbose +#define wxVLogInfo wxVLogVerbose + + +// another special case: the level is passed as first argument of the function +// and so is not available to the macro +// +// notice that because of this, arguments of wxLogGeneric() are currently +// always evaluated, unlike for the other log functions +#define wxLogGeneric wxMAKE_LOGGER(Max).LogAtLevel +#define wxVLogGeneric(level, format, argptr) \ + if ( !wxLog::IsLevelEnabled(wxLOG_##level) ) \ + {} \ + else \ + wxDO_LOGV(level, format, argptr) + + +// wxLogSysError() needs to stash the error code value in the log record info +// so it needs special handling too; additional complications arise because the +// error code may or not be present as the first argument +#define wxLOG_KEY_SYS_ERROR_CODE "wx.sys_error" + +#define wxLogSysError \ + if ( !wxLog::IsLevelEnabled(wxLOG_Error) ) \ + {} \ + else \ + wxMAKE_LOGGER(Error).MaybeStore(wxLOG_KEY_SYS_ERROR_CODE).Log + +// unfortunately we can't have overloaded macros so we can't define versions +// both with and without error code argument and have to rely on LogV() +// overloads in wxLogger to select between them +#define wxVLogSysError \ + wxMAKE_LOGGER(Error).MaybeStore(wxLOG_KEY_SYS_ERROR_CODE).LogV + +#if wxUSE_GUI + // wxLogStatus() is similar to wxLogSysError() as it allows to optionally + // specify the frame to which the message should go + #define wxLOG_KEY_FRAME "wx.frame" + + #define wxLogStatus \ + if ( !wxLog::IsLevelEnabled(wxLOG_Status) ) \ + {} \ + else \ + wxMAKE_LOGGER(Status).MaybeStore(wxLOG_KEY_FRAME).Log + + #define wxVLogStatus(format, argptr) \ + wxMAKE_LOGGER(Status).MaybeStore(wxLOG_KEY_FRAME).LogV +#endif // wxUSE_GUI #else // !wxUSE_LOG @@ -699,13 +1214,6 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 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 -#else - #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 @@ -713,8 +1221,11 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0); #define WX_WATCOM_OR_MINGW_ONLY_CODE( x ) #endif -// log functions do nothing at all -#define DECLARE_LOG_FUNCTION(level) \ +// define macros for defining log functions which do nothing at all +// +// WX_WATCOM_ONLY_CODE is needed to work around +// http://bugzilla.openwatcom.org/show_bug.cgi?id=351 +#define wxDEFINE_EMPTY_LOG_FUNCTION(level) \ WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const wxString&)) \ WX_WATCOM_ONLY_CODE( \ WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 1, (const char*)) \ @@ -724,7 +1235,7 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0); inline void wxVLog##level(const wxString& WXUNUSED(format), \ va_list WXUNUSED(argptr)) { } \ -#define DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, expdecl) \ +#define wxDEFINE_EMPTY_LOG_FUNCTION2(level, argclass) \ WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const wxString&)) \ WX_WATCOM_OR_MINGW_ONLY_CODE( \ WX_DEFINE_VARARG_FUNC_NOP(wxLog##level, 2, (argclass, const char*)) \ @@ -735,6 +1246,22 @@ WXDLLIMPEXP_BASE const wxChar* wxSysErrorMsg(unsigned long nErrCode = 0); const wxString& WXUNUSED(format), \ va_list WXUNUSED(argptr)) {} +wxDEFINE_EMPTY_LOG_FUNCTION(FatalError); +wxDEFINE_EMPTY_LOG_FUNCTION(Error); +wxDEFINE_EMPTY_LOG_FUNCTION(SysError); +wxDEFINE_EMPTY_LOG_FUNCTION2(SysError, long); +wxDEFINE_EMPTY_LOG_FUNCTION(Warning); +wxDEFINE_EMPTY_LOG_FUNCTION(Message); +wxDEFINE_EMPTY_LOG_FUNCTION(Info); +wxDEFINE_EMPTY_LOG_FUNCTION(Verbose); + +wxDEFINE_EMPTY_LOG_FUNCTION2(Generic, wxLogLevel); + +#if wxUSE_GUI + wxDEFINE_EMPTY_LOG_FUNCTION(Status); + wxDEFINE_EMPTY_LOG_FUNCTION2(Status, wxFrame *); +#endif // wxUSE_GUI + // Empty Class to fake wxLogNull class WXDLLIMPEXP_BASE wxLogNull { @@ -751,51 +1278,6 @@ public: #endif // wxUSE_LOG/!wxUSE_LOG -#define DECLARE_LOG_FUNCTION2(level, argclass, arg) \ - DECLARE_LOG_FUNCTION2_EXP(level, argclass, arg, WXDLLIMPEXP_BASE) - -// 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 - -// a generic function for all levels (level is passes as parameter) -DECLARE_LOG_FUNCTION2(Generic, wxLogLevel, level); - -// one function per each level -DECLARE_LOG_FUNCTION(FatalError); -DECLARE_LOG_FUNCTION(Error); -DECLARE_LOG_FUNCTION(Warning); -DECLARE_LOG_FUNCTION(Message); -DECLARE_LOG_FUNCTION(Info); -DECLARE_LOG_FUNCTION(Verbose); - -// this function sends the log message to the status line of the top level -// application frame, if any -DECLARE_LOG_FUNCTION(Status); - -#if wxUSE_GUI - // this one is the same as previous except that it allows to explicitly - 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 - -// additional one: as wxLogError, but also logs last system call error code -// and the corresponding error message if available -DECLARE_LOG_FUNCTION(SysError); - -// and another one which also takes the error code (for those broken APIs -// that don't set the errno (like registry APIs in Win32)) -DECLARE_LOG_FUNCTION2(SysError, long, lErrCode); -#ifdef __WATCOMC__ -// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 -DECLARE_LOG_FUNCTION2(SysError, unsigned long, lErrCode); -#endif - // debug functions can be completely disabled in optimized builds @@ -820,7 +1302,8 @@ DECLARE_LOG_FUNCTION2(SysError, unsigned long, lErrCode); #endif #if wxUSE_LOG_DEBUG - DECLARE_LOG_FUNCTION(Debug); + #define wxLogDebug wxDO_LOG_IF_ENABLED(Debug) + #define wxVLogDebug(format, argptr) wxDO_LOGV(Debug, format, argptr) #else // !wxUSE_LOG_DEBUG #define wxVLogDebug(fmt, valist) wxLogNop() @@ -832,26 +1315,11 @@ DECLARE_LOG_FUNCTION2(SysError, unsigned long, lErrCode); #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); -#ifdef __WATCOMC__ - // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 - DECLARE_LOG_FUNCTION2(Trace, const char*, mask); - DECLARE_LOG_FUNCTION2(Trace, const wchar_t*, mask); -#endif - - // 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 -#endif // WXWIN_COMPATIBILITY_2_8 - + #define wxLogTrace \ + if ( !wxLog::IsLevelEnabled(wxLOG_Trace) ) \ + {} \ + else \ + wxMAKE_LOGGER(Trace).LogTrace #else // !wxUSE_LOG_TRACE #define wxVLogTrace(mask, fmt, valist) wxLogNop() @@ -870,10 +1338,6 @@ DECLARE_LOG_FUNCTION2(SysError, unsigned long, lErrCode); #endif // HAVE_VARIADIC_MACROS/!HAVE_VARIADIC_MACROS #endif // wxUSE_LOG_TRACE/!wxUSE_LOG_TRACE -#if defined(__VISUALC__) && __VISUALC__ < 1300 - #pragma warning(pop) -#endif - // 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 WXDLLIMPEXP_BASE diff --git a/include/wx/platform.h b/include/wx/platform.h index a1a2537981..6e07657e07 100644 --- a/include/wx/platform.h +++ b/include/wx/platform.h @@ -338,18 +338,22 @@ /* - This macro can be used to test the Open Watcom version. + Define Watcom-specific macros. */ #ifndef __WATCOMC__ # define wxWATCOM_VERSION(major,minor) 0 # define wxCHECK_WATCOM_VERSION(major,minor) 0 # define wxONLY_WATCOM_EARLIER_THAN(major,minor) 0 -#elif defined(__WATCOMC__) && __WATCOMC__ < 1200 -# error "Only Open Watcom is supported in this release" +# define WX_WATCOM_ONLY_CODE( x ) #else +# if __WATCOMC__ < 1200 +# error "Only Open Watcom is supported in this release" +# endif + # define wxWATCOM_VERSION(major,minor) ( major * 100 + minor * 10 + 1100 ) # define wxCHECK_WATCOM_VERSION(major,minor) ( __WATCOMC__ >= wxWATCOM_VERSION(major,minor) ) # define wxONLY_WATCOM_EARLIER_THAN(major,minor) ( __WATCOMC__ < wxWATCOM_VERSION(major,minor) ) +# define WX_WATCOM_ONLY_CODE( x ) x #endif /* diff --git a/interface/wx/log.h b/interface/wx/log.h index 4492e375fd..42ef240c14 100644 --- a/interface/wx/log.h +++ b/interface/wx/log.h @@ -37,8 +37,23 @@ typedef unsigned long wxLogLevel; /** Information about a log record (unit of the log output). */ -struct wxLogRecordInfo +class wxLogRecordInfo { +public: + /// The name of the file where this log message was generated. + const char *filename; + + /// The line number at which this log message was generated. + int line; + + /** + The name of the function where the log record was generated. + + This field may be @NULL if the compiler doesn't support @c __FUNCTION__ + (but most modern compilers do). + */ + const char *func; + /// Time when the log message was generated. time_t timestamp; @@ -587,19 +602,23 @@ public: @section log_derivingyours Deriving your own log target - There are two functions which must be implemented by any derived class to - actually process the log messages: DoLog() and DoLogString(). - The second function receives a string which just has to be output in some way - and the easiest way to write a new log target is to override just this function - in the derived class. + There are several methods which may be overridden in the derived class to + customize log messages handling: DoLogRecord(), DoLogTextAtLevel() and + DoLogText(). - If more control over the output format is needed, then the first function must - be overridden which allows to construct custom messages depending on the log level - or even do completely different things depending on the message severity - (for example, throw away all messages except warnings and errors, show warnings - on the screen and forward the error messages to the user's (or programmer's) cell - phone - maybe depending on whether the timestamp tells us if it is day or - night in the current time zone). + The last method is the simplest one: you should override it if you simply + want to redirect the log output elsewhere, without taking into account the + level of the message. If you do want to handle messages of different levels + differently, then you should override DoLogTextAtLevel(). + + Finally, if more control over the output format is needed, then the first + function must be overridden as it allows to construct custom messages + depending on the log level or even do completely different things depending + on the message severity (for example, throw away all messages except + warnings and errors, show warnings on the screen and forward the error + messages to the user's (or programmer's) cell phone -- maybe depending on + whether the timestamp tells us if it is day or night in the current time + zone). There also functions to support message buffering. Why are they needed? Some of wxLog implementations, most notably the standard wxLogGui class, @@ -609,9 +628,7 @@ public: Flush() shows them all and clears the buffer contents. This function doesn't do anything if the buffer is already empty. - See also: - @li Flush() - @li FlushActive() + @see FlushActive() @section log_tracemasks Using trace masks diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index b334211622..248f717fcc 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -1521,10 +1521,9 @@ void MyFrame::OnNotifMsgShow(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnNotifMsgHide(wxCommandEvent& WXUNUSED(event)) { - if ( m_notifMsg ) + if ( m_notifMsg && !m_notifMsg->Close() ) { - if ( !m_notifMsg->Close() ) - wxLogStatus("Failed to hide manual notification message"); + wxLogStatus("Failed to hide manual notification message"); } } diff --git a/src/common/file.cpp b/src/common/file.cpp index 58e36f2218..d4514c5693 100644 --- a/src/common/file.cpp +++ b/src/common/file.cpp @@ -560,7 +560,9 @@ void wxTempFile::Discard() { m_file.Close(); if ( wxRemove(m_strTemp) != 0 ) + { wxLogSysError(_("can't remove temporary file '%s'"), m_strTemp.c_str()); + } } #endif // wxUSE_FILE diff --git a/src/common/hyperlnkcmn.cpp b/src/common/hyperlnkcmn.cpp index 582147736d..7765e21d8b 100644 --- a/src/common/hyperlnkcmn.cpp +++ b/src/common/hyperlnkcmn.cpp @@ -77,8 +77,12 @@ void wxHyperlinkCtrlBase::SendEvent() wxString url = GetURL(); wxHyperlinkEvent linkEvent(this, GetId(), url); if (!GetEventHandler()->ProcessEvent(linkEvent)) // was the event skipped ? + { if (!wxLaunchDefaultBrowser(url)) + { wxLogWarning(wxT("Could not launch the default browser with url '%s' !"), url.c_str()); + } + } } #endif // wxUSE_HYPERLINKCTRL diff --git a/src/common/imagbmp.cpp b/src/common/imagbmp.cpp index 388a0c8224..93288ddab1 100644 --- a/src/common/imagbmp.cpp +++ b/src/common/imagbmp.cpp @@ -84,7 +84,9 @@ bool wxBMPHandler::SaveDib(wxImage *image, if ( !image->Ok() ) { if ( verbose ) + { wxLogError(_("BMP: Couldn't save invalid image.")); + } return false; } @@ -118,7 +120,9 @@ bool wxBMPHandler::SaveDib(wxImage *image, ) { if ( verbose ) + { wxLogError(_("BMP: wxImage doesn't have own wxPalette.")); + } return false; } bpp = 8; @@ -222,7 +226,9 @@ bool wxBMPHandler::SaveDib(wxImage *image, ) { if (verbose) + { wxLogError(_("BMP: Couldn't write the file (Bitmap) header.")); + } return false; } } @@ -243,7 +249,9 @@ bool wxBMPHandler::SaveDib(wxImage *image, ) { if (verbose) + { wxLogError(_("BMP: Couldn't write the file (BitmapInfo) header.")); + } return false; } } @@ -317,7 +325,9 @@ bool wxBMPHandler::SaveDib(wxImage *image, if ( !stream.Write(rgbquad, palette_size*4) ) { if (verbose) + { wxLogError(_("BMP: Couldn't write RGB color map.")); + } delete[] rgbquad; #if wxUSE_PALETTE delete palette; @@ -450,7 +460,9 @@ bool wxBMPHandler::SaveDib(wxImage *image, if ( !stream.Write(buffer, row_width) ) { if (verbose) + { wxLogError(_("BMP: Couldn't write data.")); + } delete[] buffer; #if wxUSE_PALETTE delete palette; @@ -498,7 +510,9 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, if ( !cmap ) { if (verbose) + { wxLogError(_("BMP: Couldn't allocate memory.")); + } return false; } } @@ -518,7 +532,9 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, if ( !ptr ) { if ( verbose ) + { wxLogError( _("BMP: Couldn't allocate memory.") ); + } return false; } @@ -531,7 +547,9 @@ bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height, if ( !alpha ) { if ( verbose ) + { wxLogError(_("BMP: Couldn't allocate memory.")); + } return false; } } @@ -924,13 +942,17 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream, if ( width > 32767 ) { if (verbose) + { wxLogError( _("DIB Header: Image width > 32767 pixels for file.") ); + } return false; } if ( height > 32767 ) { if (verbose) + { wxLogError( _("DIB Header: Image height > 32767 pixels for file.") ); + } return false; } @@ -944,7 +966,9 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream, if ( bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 && bpp != 32 ) { if (verbose) + { wxLogError( _("DIB Header: Unknown bitdepth in file.") ); + } return false; } @@ -954,7 +978,9 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream, comp != BI_BITFIELDS ) { if (verbose) + { wxLogError( _("DIB Header: Unknown encoding in file.") ); + } return false; } @@ -969,7 +995,9 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream, ((comp == BI_BITFIELDS) && (bpp != 16 && bpp != 32))) { if (verbose) + { wxLogError( _("DIB Header: Encoding doesn't match bitdepth.") ); + } return false; } @@ -978,7 +1006,9 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream, verbose, IsBmp, true) ) { if (verbose) + { wxLogError( _("Error in reading image DIB.") ); + } return false; } @@ -991,7 +1021,9 @@ bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream, verbose, IsBmp, false) ) { if (verbose) + { wxLogError( _("ICO: Error in reading mask DIB.") ); + } return false; } image->SetMaskFromImage(mask, 255, 255, 255); @@ -1069,13 +1101,17 @@ bool wxICOHandler::SaveFile(wxImage *image, if ( image->GetHeight () > 127 ) { if ( verbose ) + { wxLogError(_("ICO: Image too tall for an icon.")); + } return false; } if ( image->GetWidth () > 255 ) { if ( verbose ) + { wxLogError(_("ICO: Image too wide for an icon.")); + } return false; } @@ -1101,7 +1137,9 @@ bool wxICOHandler::SaveFile(wxImage *image, if ( !stream.IsOk() ) { if ( verbose ) + { wxLogError(_("ICO: Error writing the image file!")); + } return false; } @@ -1160,7 +1198,9 @@ bool wxICOHandler::SaveFile(wxImage *image, if ( !bResult ) { if ( verbose ) + { wxLogError(_("ICO: Error writing the image file!")); + } return false; } IsMask = true; @@ -1169,7 +1209,9 @@ bool wxICOHandler::SaveFile(wxImage *image, if ( !bResult ) { if ( verbose ) + { wxLogError(_("ICO: Error writing the image file!")); + } return false; } wxUint32 Size = cStream.GetSize(); @@ -1224,7 +1266,9 @@ bool wxICOHandler::SaveFile(wxImage *image, if ( !stream.IsOk() ) { if ( verbose ) + { wxLogError(_("ICO: Error writing the image file!")); + } return false; } @@ -1234,7 +1278,9 @@ bool wxICOHandler::SaveFile(wxImage *image, if ( !bResult ) { if ( verbose ) + { wxLogError(_("ICO: Error writing the image file!")); + } return false; } IsMask = true; @@ -1243,7 +1289,9 @@ bool wxICOHandler::SaveFile(wxImage *image, if ( !bResult ) { if ( verbose ) + { wxLogError(_("ICO: Error writing the image file!")); + } return false; } diff --git a/src/common/imaggif.cpp b/src/common/imaggif.cpp index cd81463b49..7c7ef7c8e3 100644 --- a/src/common/imaggif.cpp +++ b/src/common/imaggif.cpp @@ -89,7 +89,9 @@ bool wxGIFHandler::SaveFile( wxImage * WXUNUSED(image), wxOutputStream& WXUNUSED(stream), bool verbose ) { if (verbose) + { wxLogDebug(wxT("GIF: the handler is read-only!!")); + } return false; } diff --git a/src/common/imagiff.cpp b/src/common/imagiff.cpp index 2ea52b1403..2c7dd95454 100644 --- a/src/common/imagiff.cpp +++ b/src/common/imagiff.cpp @@ -777,7 +777,9 @@ bool wxIFFHandler::SaveFile(wxImage * WXUNUSED(image), wxOutputStream& WXUNUSED(stream), bool verbose) { if (verbose) + { wxLogDebug(wxT("IFF: the handler is read-only!!")); + } return false; } diff --git a/src/common/imagjpeg.cpp b/src/common/imagjpeg.cpp index a06f0dd8f2..3dbadbe1cf 100644 --- a/src/common/imagjpeg.cpp +++ b/src/common/imagjpeg.cpp @@ -251,7 +251,9 @@ bool wxJPEGHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos * We need to clean up the JPEG object, close the input file, and return. */ if (verbose) + { wxLogError(_("JPEG: Couldn't load - file is probably corrupted.")); + } (cinfo.src->term_source)(&cinfo); jpeg_destroy_decompress(&cinfo); if (image->Ok()) image->Destroy(); @@ -421,7 +423,9 @@ bool wxJPEGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo * We need to clean up the JPEG object, close the input file, and return. */ if (verbose) + { wxLogError(_("JPEG: Couldn't save image.")); + } jpeg_destroy_compress(&cinfo); return false; } diff --git a/src/common/imagpcx.cpp b/src/common/imagpcx.cpp index 71f3b1e7a5..09a4612cbf 100644 --- a/src/common/imagpcx.cpp +++ b/src/common/imagpcx.cpp @@ -439,7 +439,9 @@ bool wxPCXHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose if (!CanRead(stream)) { if (verbose) + { wxLogError(_("PCX: this is not a PCX file.")); + } return false; } diff --git a/src/common/imagpng.cpp b/src/common/imagpng.cpp index 83446867ad..abe155c880 100644 --- a/src/common/imagpng.cpp +++ b/src/common/imagpng.cpp @@ -165,7 +165,9 @@ PNGLINKAGEMODE wx_png_warning(png_structp png_ptr, png_const_charp message) { wxPNGInfoStruct *info = png_ptr ? WX_PNG_INFO(png_ptr) : NULL; if ( !info || info->verbose ) + { wxLogWarning( wxString::FromAscii(message) ); + } } // from pngerror.c @@ -608,7 +610,9 @@ wxPNGHandler::LoadFile(wxImage *image, error: if (verbose) + { wxLogError(_("Couldn't load a PNG image - file is corrupted or not enough memory.")); + } if ( image->Ok() ) { @@ -657,7 +661,9 @@ bool wxPNGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos if (!png_ptr) { if (verbose) + { wxLogError(_("Couldn't save PNG image.")); + } return false; } @@ -666,7 +672,9 @@ bool wxPNGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos { png_destroy_write_struct( &png_ptr, (png_infopp)NULL ); if (verbose) + { wxLogError(_("Couldn't save PNG image.")); + } return false; } @@ -674,7 +682,9 @@ bool wxPNGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos { png_destroy_write_struct( &png_ptr, (png_infopp)NULL ); if (verbose) + { wxLogError(_("Couldn't save PNG image.")); + } return false; } diff --git a/src/common/imagpnm.cpp b/src/common/imagpnm.cpp index 2b3e75f979..731220450b 100644 --- a/src/common/imagpnm.cpp +++ b/src/common/imagpnm.cpp @@ -69,7 +69,10 @@ bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose case wxT('5'): // RAW Grey case wxT('6'): break; default: - if (verbose) wxLogError(_("PNM: File format is not recognized.")); + if (verbose) + { + wxLogError(_("PNM: File format is not recognized.")); + } return false; } @@ -85,7 +88,9 @@ bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose if (!ptr) { if (verbose) + { wxLogError( _("PNM: Couldn't allocate memory.") ); + } return false; } @@ -103,7 +108,10 @@ bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose *ptr++=(unsigned char)value; // B if ( !buf_stream ) { - if (verbose) wxLogError(_("PNM: File seems truncated.")); + if (verbose) + { + wxLogError(_("PNM: File seems truncated.")); + } return false; } } @@ -122,7 +130,10 @@ bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose if ( !buf_stream ) { - if (verbose) wxLogError(_("PNM: File seems truncated.")); + if (verbose) + { + wxLogError(_("PNM: File seems truncated.")); + } return false; } } @@ -141,7 +152,10 @@ bool wxPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose *ptr++=value; // B if ( !buf_stream ) { - if (verbose) wxLogError(_("PNM: File seems truncated.")); + if (verbose) + { + wxLogError(_("PNM: File seems truncated.")); + } return false; } } diff --git a/src/common/imagtga.cpp b/src/common/imagtga.cpp index d98ff01800..62080d22c1 100644 --- a/src/common/imagtga.cpp +++ b/src/common/imagtga.cpp @@ -669,7 +669,9 @@ bool wxTGAHandler::LoadFile(wxImage* image, if ( !CanRead(stream) ) { if ( verbose ) + { wxLogError(wxT("TGA: this is not a TGA file.")); + } return false; } diff --git a/src/common/imagtiff.cpp b/src/common/imagtiff.cpp index 506000e034..13606aeffe 100644 --- a/src/common/imagtiff.cpp +++ b/src/common/imagtiff.cpp @@ -270,7 +270,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos if (!tif) { if (verbose) + { wxLogError( _("TIFF: Error loading image.") ); + } return false; } @@ -278,7 +280,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos if (!TIFFSetDirectory( tif, (tdir_t)index )) { if (verbose) + { wxLogError( _("Invalid TIFF image index.") ); + } TIFFClose( tif ); @@ -305,7 +309,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos if ( bytesNeeded >= wxUINT32_MAX ) { if ( verbose ) + { wxLogError( _("TIFF: Image size is abnormally big.") ); + } TIFFClose(tif); @@ -317,7 +323,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos if (!raster) { if (verbose) + { wxLogError( _("TIFF: Couldn't allocate memory.") ); + } TIFFClose( tif ); @@ -328,7 +336,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos if (!image->Ok()) { if (verbose) + { wxLogError( _("TIFF: Couldn't allocate memory.") ); + } _TIFFfree( raster ); TIFFClose( tif ); @@ -342,7 +352,9 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos if (!TIFFReadRGBAImage( tif, w, h, raster, 0 )) { if (verbose) + { wxLogError( _("TIFF: Error reading image.") ); + } _TIFFfree( raster ); image->Destroy(); @@ -450,7 +462,9 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo if (!tif) { if (verbose) + { wxLogError( _("TIFF: Error saving image.") ); + } return false; } @@ -530,7 +544,9 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo if (!buf) { if (verbose) + { wxLogError( _("TIFF: Couldn't allocate memory.") ); + } TIFFClose( tif ); @@ -576,7 +592,9 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo if ( TIFFWriteScanline(tif, buf ? buf : ptr, (uint32)row, 0) < 0 ) { if (verbose) + { wxLogError( _("TIFF: Error writing image.") ); + } TIFFClose( tif ); if (buf) diff --git a/src/common/intl.cpp b/src/common/intl.cpp index 978b4b41e5..f5fe1b49cd 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -1635,7 +1635,9 @@ bool wxLocale::Init(const wxString& name, m_pszOldLocale = NULL; if ( m_pszOldLocale == NULL ) + { wxLogError(_("locale '%s' can not be set."), szLocale); + } // the short name will be used to look for catalog files as well, // so we need something here diff --git a/src/common/log.cpp b/src/common/log.cpp index eea84cbf12..0afb906f28 100644 --- a/src/common/log.cpp +++ b/src/common/log.cpp @@ -137,82 +137,9 @@ PreviousLogInfo gs_prevLog; // ============================================================================ // ---------------------------------------------------------------------------- -// implementation of Log functions -// -// NB: unfortunately we need all these distinct functions, we can't make them -// macros and not all compilers inline vararg functions. +// helper global functions // ---------------------------------------------------------------------------- -// generic log function -void wxVLogGeneric(wxLogLevel level, const wxString& format, va_list argptr) -{ - if ( wxLog::IsEnabled() ) - { - wxLog::OnLog(level, wxString::FormatV(format, argptr)); - } -} - -#if !wxUSE_UTF8_LOCALE_ONLY -void wxDoLogGenericWchar(wxLogLevel level, const wxChar *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogGeneric(level, format, argptr); - va_end(argptr); -} -#endif // wxUSE_UTF8_LOCALE_ONLY - -#if wxUSE_UNICODE_UTF8 -void wxDoLogGenericUtf8(wxLogLevel level, const char *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogGeneric(level, format, argptr); - va_end(argptr); -} -#endif // wxUSE_UNICODE_UTF8 - -#if !wxUSE_UTF8_LOCALE_ONLY - #define IMPLEMENT_LOG_FUNCTION_WCHAR(level) \ - void wxDoLog##level##Wchar(const wxChar *format, ...) \ - { \ - va_list argptr; \ - va_start(argptr, format); \ - wxVLog##level(format, argptr); \ - va_end(argptr); \ - } -#else - #define IMPLEMENT_LOG_FUNCTION_WCHAR(level) -#endif - -#if wxUSE_UNICODE_UTF8 - #define IMPLEMENT_LOG_FUNCTION_UTF8(level) \ - void wxDoLog##level##Utf8(const char *format, ...) \ - { \ - va_list argptr; \ - va_start(argptr, format); \ - wxVLog##level(format, argptr); \ - va_end(argptr); \ - } -#else - #define IMPLEMENT_LOG_FUNCTION_UTF8(level) -#endif - -#define IMPLEMENT_LOG_FUNCTION(level) \ - void wxVLog##level(const wxString& format, va_list argptr) \ - { \ - if ( wxLog::IsEnabled() ) \ - wxLog::OnLog(wxLOG_##level, wxString::FormatV(format, argptr)); \ - } \ - IMPLEMENT_LOG_FUNCTION_WCHAR(level) \ - IMPLEMENT_LOG_FUNCTION_UTF8(level) - -IMPLEMENT_LOG_FUNCTION(Error) -IMPLEMENT_LOG_FUNCTION(Warning) -IMPLEMENT_LOG_FUNCTION(Message) -IMPLEMENT_LOG_FUNCTION(Info) -IMPLEMENT_LOG_FUNCTION(Status) - void wxSafeShowMessage(const wxString& title, const wxString& text) { #ifdef __WINDOWS__ @@ -223,291 +150,6 @@ void wxSafeShowMessage(const wxString& title, const wxString& text) #endif } -// fatal errors can't be suppressed nor handled by the custom log target and -// always terminate the program -void wxVLogFatalError(const wxString& format, va_list argptr) -{ - wxSafeShowMessage(wxS("Fatal Error"), wxString::FormatV(format, argptr)); - -#ifdef __WXWINCE__ - ExitThread(3); -#else - abort(); -#endif -} - -#if !wxUSE_UTF8_LOCALE_ONLY -void wxDoLogFatalErrorWchar(const wxChar *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogFatalError(format, argptr); - - // some compilers warn about unreachable code and it shouldn't matter - // for the others anyhow... - //va_end(argptr); -} -#endif // wxUSE_UTF8_LOCALE_ONLY - -#if wxUSE_UNICODE_UTF8 -void wxDoLogFatalErrorUtf8(const char *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogFatalError(format, argptr); - - // some compilers warn about unreachable code and it shouldn't matter - // for the others anyhow... - //va_end(argptr); -} -#endif // wxUSE_UNICODE_UTF8 - -// same as info, but only if 'verbose' mode is on -void wxVLogVerbose(const wxString& format, va_list argptr) -{ - if ( wxLog::IsEnabled() ) { - if ( wxLog::GetActiveTarget() != NULL && wxLog::GetVerbose() ) - wxLog::OnLog(wxLOG_Info, wxString::FormatV(format, argptr)); - } -} - -#if !wxUSE_UTF8_LOCALE_ONLY -void wxDoLogVerboseWchar(const wxChar *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogVerbose(format, argptr); - va_end(argptr); -} -#endif // !wxUSE_UTF8_LOCALE_ONLY - -#if wxUSE_UNICODE_UTF8 -void wxDoLogVerboseUtf8(const char *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogVerbose(format, argptr); - va_end(argptr); -} -#endif // wxUSE_UNICODE_UTF8 - -// ---------------------------------------------------------------------------- -// debug and trace functions -// ---------------------------------------------------------------------------- - -#if wxUSE_LOG_DEBUG - void wxVLogDebug(const wxString& format, va_list argptr) - { - if ( wxLog::IsEnabled() ) - { - wxLog::OnLog(wxLOG_Debug, wxString::FormatV(format, argptr)); - } - } - -#if !wxUSE_UTF8_LOCALE_ONLY - void wxDoLogDebugWchar(const wxChar *format, ...) - { - va_list argptr; - va_start(argptr, format); - wxVLogDebug(format, argptr); - va_end(argptr); - } -#endif // !wxUSE_UTF8_LOCALE_ONLY - -#if wxUSE_UNICODE_UTF8 - void wxDoLogDebugUtf8(const char *format, ...) - { - va_list argptr; - va_start(argptr, format); - wxVLogDebug(format, argptr); - va_end(argptr); - } -#endif // wxUSE_UNICODE_UTF8 -#endif // wxUSE_LOG_DEBUG - -#if wxUSE_LOG_TRACE - void wxVLogTrace(const wxString& mask, const wxString& format, va_list argptr) - { - if ( wxLog::IsEnabled() && wxLog::IsAllowedTraceMask(mask) ) { - wxString msg; - msg << wxS("(") << mask << wxS(") ") << wxString::FormatV(format, argptr); - - wxLog::OnLog(wxLOG_Trace, msg); - } - } - -#if !wxUSE_UTF8_LOCALE_ONLY - void wxDoLogTraceWchar(const wxString& mask, const wxChar *format, ...) - { - va_list argptr; - va_start(argptr, format); - wxVLogTrace(mask, format, argptr); - va_end(argptr); - } -#endif // !wxUSE_UTF8_LOCALE_ONLY - -#if wxUSE_UNICODE_UTF8 - void wxDoLogTraceUtf8(const wxString& mask, const char *format, ...) - { - va_list argptr; - va_start(argptr, format); - wxVLogTrace(mask, format, argptr); - va_end(argptr); - } -#endif // wxUSE_UNICODE_UTF8 - -// deprecated (but not declared as such because we don't want to complicate -// DECLARE_LOG_FUNCTION macros even more) overloads for wxTraceMask -#if WXWIN_COMPATIBILITY_2_8 - void wxVLogTrace(wxTraceMask mask, const wxString& format, va_list argptr) - { - // 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 ( wxLog::IsEnabled() && ((wxLog::GetTraceMask() & mask) == mask) ) { - wxLog::OnLog(wxLOG_Trace, wxString::FormatV(format, argptr)); - } - } - -#if !wxUSE_UTF8_LOCALE_ONLY - void wxDoLogTraceWchar(wxTraceMask mask, const wxChar *format, ...) - { - va_list argptr; - va_start(argptr, format); - wxVLogTrace(mask, format, argptr); - va_end(argptr); - } -#endif // !wxUSE_UTF8_LOCALE_ONLY - -#if wxUSE_UNICODE_UTF8 - void wxDoLogTraceUtf8(wxTraceMask mask, const char *format, ...) - { - va_list argptr; - va_start(argptr, format); - wxVLogTrace(mask, format, argptr); - va_end(argptr); - } -#endif // wxUSE_UNICODE_UTF8 - -#endif // WXWIN_COMPATIBILITY_2_8 - -#ifdef __WATCOMC__ -#if WXWIN_COMPATIBILITY_2_8 - // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 - void wxDoLogTraceWchar(int mask, const wxChar *format, ...) - { - va_list argptr; - va_start(argptr, format); - wxVLogTrace(mask, format, argptr); - va_end(argptr); - } -#endif // WXWIN_COMPATIBILITY_2_8 - - void wxDoLogTraceWchar(const char *mask, const wxChar *format, ...) - { - va_list argptr; - va_start(argptr, format); - wxVLogTrace(mask, format, argptr); - va_end(argptr); - } - - void wxDoLogTraceWchar(const wchar_t *mask, const wxChar *format, ...) - { - va_list argptr; - va_start(argptr, format); - wxVLogTrace(mask, format, argptr); - va_end(argptr); - } - -#if WXWIN_COMPATIBILITY_2_8 - void wxVLogTrace(int mask, const wxString& format, va_list argptr) - { wxVLogTrace((wxTraceMask)mask, format, argptr); } -#endif // WXWIN_COMPATIBILITY_2_8 - void wxVLogTrace(const char *mask, const wxString& format, va_list argptr) - { wxVLogTrace(wxString(mask), format, argptr); } - void wxVLogTrace(const wchar_t *mask, const wxString& format, va_list argptr) - { wxVLogTrace(wxString(mask), format, argptr); } -#endif // __WATCOMC__ -#endif // wxUSE_LOG_TRACE - - -// wxLogSysError: one uses the last error code, for other you must give it -// explicitly - -// return the system error message description -static inline wxString wxLogSysErrorHelper(long err) -{ - return wxString::Format(_(" (error %ld: %s)"), err, wxSysErrorMsg(err)); -} - -void WXDLLIMPEXP_BASE wxVLogSysError(const wxString& format, va_list argptr) -{ - wxVLogSysError(wxSysErrorCode(), format, argptr); -} - -#if !wxUSE_UTF8_LOCALE_ONLY -void WXDLLIMPEXP_BASE wxDoLogSysErrorWchar(const wxChar *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogSysError(format, argptr); - va_end(argptr); -} -#endif // !wxUSE_UTF8_LOCALE_ONLY - -#if wxUSE_UNICODE_UTF8 -void WXDLLIMPEXP_BASE wxDoLogSysErrorUtf8(const char *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogSysError(format, argptr); - va_end(argptr); -} -#endif // wxUSE_UNICODE_UTF8 - -void WXDLLIMPEXP_BASE wxVLogSysError(long err, const wxString& format, va_list argptr) -{ - if ( wxLog::IsEnabled() ) - { - wxLog::OnLog(wxLOG_Error, - wxString::FormatV(format, argptr) + wxLogSysErrorHelper(err)); - } -} - -#if !wxUSE_UTF8_LOCALE_ONLY -void WXDLLIMPEXP_BASE wxDoLogSysErrorWchar(long lErrCode, const wxChar *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogSysError(lErrCode, format, argptr); - va_end(argptr); -} -#endif // !wxUSE_UTF8_LOCALE_ONLY - -#if wxUSE_UNICODE_UTF8 -void WXDLLIMPEXP_BASE wxDoLogSysErrorUtf8(long lErrCode, const char *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogSysError(lErrCode, format, argptr); - va_end(argptr); -} -#endif // wxUSE_UNICODE_UTF8 - -#ifdef __WATCOMC__ -// workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351 -void WXDLLIMPEXP_BASE wxDoLogSysErrorWchar(unsigned long lErrCode, const wxChar *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogSysError(lErrCode, format, argptr); - va_end(argptr); -} - -void WXDLLIMPEXP_BASE wxVLogSysError(unsigned long err, const wxString& format, va_list argptr) - { wxVLogSysError((long)err, format, argptr); } -#endif // __WATCOMC__ - // ---------------------------------------------------------------------------- // wxLog class implementation // ---------------------------------------------------------------------------- @@ -581,35 +223,65 @@ wxLog::OnLog(wxLogLevel level, const wxString& msg, const wxLogRecordInfo& info) { - if ( IsEnabled() && ms_logLevel >= level ) + // fatal errors can't be suppressed nor handled by the custom log target + // and always terminate the program + if ( level == wxLOG_FatalError ) { - wxLog *pLogger = GetActiveTarget(); - if ( pLogger ) - { - if ( GetRepetitionCounting() ) - { - wxCRIT_SECT_LOCKER(lock, GetPreviousLogCS()); + wxSafeShowMessage(wxS("Fatal Error"), msg); - if ( msg == gs_prevLog.msg ) - { - gs_prevLog.numRepeated++; +#ifdef __WXWINCE__ + ExitThread(3); +#else + abort(); +#endif + } - // nothing else to do, in particular, don't log the - // repeated message - return; - } + wxLog *pLogger = GetActiveTarget(); + if ( !pLogger ) + return; - pLogger->LogLastRepeatIfNeededUnlocked(); + if ( GetRepetitionCounting() ) + { + wxCRIT_SECT_LOCKER(lock, GetPreviousLogCS()); - // reset repetition counter for a new message - gs_prevLog.msg = msg; - gs_prevLog.level = level; - gs_prevLog.info = info; - } + if ( msg == gs_prevLog.msg ) + { + gs_prevLog.numRepeated++; - pLogger->DoLogRecord(level, msg, info); + // nothing else to do, in particular, don't log the + // repeated message + return; } + + pLogger->LogLastRepeatIfNeededUnlocked(); + + // reset repetition counter for a new message + gs_prevLog.msg = msg; + gs_prevLog.level = level; + gs_prevLog.info = info; } + + // handle extra data which may be passed to us by wxLogXXX() + wxString prefix, suffix; + wxUIntPtr num; + if ( info.GetNumValue(wxLOG_KEY_SYS_ERROR_CODE, &num) ) + { + long err = static_cast(num); + if ( !err ) + err = wxSysErrorCode(); + + suffix.Printf(_(" (error %ld: %s)"), err, wxSysErrorMsg(err)); + } + +#if wxUSE_LOG_TRACE + wxString str; + if ( level == wxLOG_Trace && info.GetStrValue(wxLOG_KEY_TRACE_MASK, &str) ) + { + prefix = "(" + str + ") "; + } +#endif // wxUSE_LOG_TRACE + + pLogger->DoLogRecord(level, prefix + msg + suffix, info); } void wxLog::DoLogRecord(wxLogLevel level, diff --git a/src/common/msgout.cpp b/src/common/msgout.cpp index 6e9c57a558..0e663c40fc 100644 --- a/src/common/msgout.cpp +++ b/src/common/msgout.cpp @@ -176,7 +176,7 @@ void wxMessageOutputLog::Output(const wxString& str) out.Replace(wxT("\t"), wxT(" ")); - ::wxLogMessage(wxT("%s"), out.c_str()); + wxLogMessage(wxT("%s"), out.c_str()); } #endif // wxUSE_BASE diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 032b8f094e..000d89b464 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -819,7 +819,9 @@ void wxSocketBase::Init() // this Initialize() will be undone by wxSocketModule::OnExit(), all // the other calls to it should be matched by a call to Shutdown() if (!Initialize()) + { wxLogError("Cannot initialize wxSocketBase"); + } } } diff --git a/src/common/tarstrm.cpp b/src/common/tarstrm.cpp index 033c34cf09..0942b65236 100644 --- a/src/common/tarstrm.cpp +++ b/src/common/tarstrm.cpp @@ -793,7 +793,9 @@ wxStreamError wxTarInputStream::ReadHeaders() while (!done) { m_hdr->Read(*m_parent_i_stream); if (m_parent_i_stream->Eof()) + { wxLogError(_("incomplete header block in tar")); + } if (!*m_parent_i_stream) return wxSTREAM_READ_ERROR; m_offset += TAR_BLOCKSIZE; @@ -1040,7 +1042,9 @@ size_t wxTarInputStream::OnSysRead(void *buffer, size_t size) } else if (!m_parent_i_stream->IsOk()) { // any other error will have been reported by the underlying stream if (m_parent_i_stream->Eof()) + { wxLogError(_("unexpected end of file")); + } m_lasterror = wxSTREAM_READ_ERROR; } diff --git a/src/common/zipstrm.cpp b/src/common/zipstrm.cpp index e353d41986..17f698fb60 100644 --- a/src/common/zipstrm.cpp +++ b/src/common/zipstrm.cpp @@ -1269,7 +1269,9 @@ bool wxZipEndRec::Read(wxInputStream& stream, wxMBConv& conv) if (m_DiskNumber != 0 || m_StartDisk != 0 || m_EntriesHere != m_TotalEntries) + { wxLogWarning(_("assuming this is a multi-part zip concatenated")); + } return true; } diff --git a/src/common/zstream.cpp b/src/common/zstream.cpp index 57bed6a6a3..13b29c1782 100644 --- a/src/common/zstream.cpp +++ b/src/common/zstream.cpp @@ -224,7 +224,9 @@ size_t wxZlibInputStream::OnSysRead(void *buffer, size_t size) // by the parent strean, m_lasterror = wxSTREAM_READ_ERROR; if (m_parent_i_stream->Eof()) + { wxLogError(_("Can't read inflate stream: unexpected EOF in underlying stream.")); + } break; default: diff --git a/src/generic/logg.cpp b/src/generic/logg.cpp index 08f2808d7b..b4fe435373 100644 --- a/src/generic/logg.cpp +++ b/src/generic/logg.cpp @@ -201,60 +201,10 @@ static int OpenLogFile(wxFile& file, wxString *filename = NULL, wxWindow *parent #endif // CAN_SAVE_FILES -// ---------------------------------------------------------------------------- -// global variables -// ---------------------------------------------------------------------------- - -// we use a global variable to store the frame pointer for wxLogStatus - bad, -// but it's the easiest way -static wxFrame *gs_pFrame = NULL; // FIXME MT-unsafe - // ============================================================================ // implementation // ============================================================================ -// ---------------------------------------------------------------------------- -// global functions -// ---------------------------------------------------------------------------- - -// accepts an additional argument which tells to which frame the output should -// be directed -void wxVLogStatus(wxFrame *pFrame, const wxString& format, va_list argptr) -{ - wxString msg; - - wxLog *pLog = wxLog::GetActiveTarget(); - if ( pLog != NULL ) - { - msg.PrintfV(format, argptr); - - wxASSERT( gs_pFrame == NULL ); // should be reset! - gs_pFrame = pFrame; - wxLog::OnLog(wxLOG_Status, msg); - gs_pFrame = NULL; - } -} - -#if !wxUSE_UTF8_LOCALE_ONLY -void wxDoLogStatusWchar(wxFrame *pFrame, const wxChar *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogStatus(pFrame, format, argptr); - va_end(argptr); -} -#endif // !wxUSE_UTF8_LOCALE_ONLY - -#if wxUSE_UNICODE_UTF8 -void wxDoLogStatusUtf8(wxFrame *pFrame, const char *format, ...) -{ - va_list argptr; - va_start(argptr, format); - wxVLogStatus(pFrame, format, argptr); - va_end(argptr); -} -#endif // wxUSE_UNICODE_UTF8 - // ---------------------------------------------------------------------------- // wxLogGui implementation (FIXME MT-unsafe) // ---------------------------------------------------------------------------- @@ -420,8 +370,16 @@ void wxLogGui::DoLogRecord(wxLogLevel level, case wxLOG_Status: #if wxUSE_STATUSBAR { + wxFrame *pFrame = NULL; + + // check if the frame was passed to us explicitly + wxUIntPtr ptr; + if ( info.GetNumValue(wxLOG_KEY_FRAME, &ptr) ) + { + pFrame = static_cast(wxUIntToPtr(ptr)); + } + // find the top window and set it's status text if it has any - wxFrame *pFrame = gs_pFrame; if ( pFrame == NULL ) { wxWindow *pWin = wxTheApp->GetTopWindow(); if ( pWin != NULL && pWin->IsKindOf(CLASSINFO(wxFrame)) ) { @@ -1080,7 +1038,9 @@ void wxLogDialog::OnSave(wxCommandEvent& WXUNUSED(event)) } if ( !rc || !file.Write(GetLogMessages()) || !file.Close() ) + { wxLogError(_("Can't save log contents to file.")); + } } #endif // CAN_SAVE_FILES diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index 14b2bea6b7..60974b785a 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -2572,9 +2572,11 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *WXUNUSED(column), wx_model->GetValue( value, item, cell->GetOwner()->GetModelColumn() ); if (value.GetType() != cell->GetVariantType()) + { wxLogError( wxT("Wrong type, required: %s but: %s"), value.GetType().c_str(), cell->GetVariantType().c_str() ); + } cell->SetValue( value ); diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index 53853c6ef9..782856d81d 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -4671,7 +4671,9 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR int s1 = selectionRange.GetStart()-1; int fragmentLen = s1 - r1 + 1; if (fragmentLen < 0) + { wxLogDebug(wxT("Mid(%d, %d"), (int)(r1 - offset), (int)fragmentLen); + } wxString stringFragment = str.Mid(r1 - offset, fragmentLen); DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false); @@ -4702,7 +4704,9 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR int fragmentLen = s2 - s1 + 1; if (fragmentLen < 0) + { wxLogDebug(wxT("Mid(%d, %d"), (int)(s1 - offset), (int)fragmentLen); + } wxString stringFragment = str.Mid(s1 - offset, fragmentLen); DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, true); @@ -4733,7 +4737,9 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR int fragmentLen = r2 - s2 + 1; if (fragmentLen < 0) + { wxLogDebug(wxT("Mid(%d, %d"), (int)(s2 - offset), (int)fragmentLen); + } wxString stringFragment = str.Mid(s2 - offset, fragmentLen); DrawTabbedString(dc, textAttr, rect, stringFragment, x, y, false); -- 2.47.2