]>
Commit | Line | Data |
---|---|---|
c801d85f KB |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: log.h | |
3 | // Purpose: Assorted wxLogXXX functions, and wxLog (sink for logs) | |
4 | // Author: Vadim Zeitlin | |
5 | // Modified by: | |
6 | // Created: 29/01/98 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> | |
9 | // Licence: wxWindows license | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | #ifndef __LOGH__ | |
13 | #define __LOGH__ | |
14 | ||
15 | #ifdef __GNUG__ | |
16 | #pragma interface "log.h" | |
17 | #endif //GNU C++ | |
18 | ||
19 | // ---------------------------------------------------------------------------- | |
20 | // derive from this class to redirect (or suppress, or ...) log messages | |
21 | // normally, only a single instance of this class exists but it's not enforced | |
22 | // | |
23 | // ## would ne nice to add a time stamp to log messages | |
24 | // ---------------------------------------------------------------------------- | |
25 | class WXDLLEXPORT wxLog | |
26 | { | |
27 | public: | |
28 | enum Level | |
29 | { | |
30 | FatalError, // program can't continue, abort immediately | |
31 | Error, // a serious error, user must be informed about it | |
32 | Warning, // warning: user is normally informed about but may ignore it | |
33 | Message, // normal message (i.e. normal output of a non GUI app) | |
34 | Info, // informational message (a.k.a. 'Verbose') | |
35 | Status, // informational: might go to the status line of GUI app | |
36 | Debug, // never shown to the user, disabled in release mode | |
37 | Trace, // trace messages are also only enabled in debug mode | |
38 | Progress, // used for progress indicator (not yet) | |
39 | User1, // user defined levels (use with wxLogGeneric(wxLog::User1,...) | |
40 | User2, // | |
41 | User3, // | |
42 | }; | |
43 | ||
44 | // ctor | |
45 | wxLog(); | |
46 | ||
47 | // sink function | |
48 | static void OnLog(Level level, const char *szString) | |
49 | { if ( ms_pLogger != 0 ) ms_pLogger->DoLog(level, szString); } | |
50 | ||
51 | // message buffering | |
52 | // flush shows all messages if they're not logged immediately | |
53 | // (FILE and iostream logs don't need it, but wxGuiLog does to avoid | |
54 | // showing 17 modal dialogs one after another) | |
55 | virtual void Flush(); | |
56 | // call Flush() only if this function returns true | |
57 | bool HasPendingMessages() const { return m_bHasMessages; } | |
58 | ||
59 | // only one sink is active at each moment | |
60 | // get current log target | |
61 | static wxLog *GetActiveTarget(); | |
62 | // change log target, pLogger = NULL disables logging, | |
63 | // returns the previous log target | |
64 | static wxLog *SetActiveTarget(wxLog *pLogger); | |
65 | ||
66 | // functions controlling the default wxLog behaviour | |
67 | // verbose mode is activated by standard command-line '-verbose' option | |
68 | static void SetVerbose(bool bVerbose = TRUE) { ms_bVerbose = bVerbose; } | |
69 | // sets the format for timestamp prepended by wxLog::DoLog(): it's | |
70 | // passed to strftime() function, see it's documentation for details. | |
71 | // the string is not copied! | |
72 | static void SetTimeStampFormat(const char *szTimeFormat) | |
73 | { ms_szTimeFormat = szTimeFormat; } | |
74 | ||
75 | // accessors | |
76 | // gets the verbose status | |
77 | static bool GetVerbose() { return ms_bVerbose; } | |
78 | ||
79 | // make dtor virtual for all derived classes | |
80 | virtual ~wxLog() { } | |
81 | ||
82 | protected: | |
83 | bool m_bHasMessages; | |
84 | ||
85 | // static variables | |
86 | // ---------------- | |
87 | static bool ms_bVerbose; // FALSE => ignore LogInfo messages | |
88 | static const char *ms_szTimeFormat; // format for strftime() | |
89 | ||
90 | private: | |
91 | // the logging functions that can be overriden | |
92 | // default DoLog() prepends the time stamp and a prefix corresponding | |
93 | // to the message to szString and then passes it to DoLogString() | |
94 | virtual void DoLog(Level level, const char *szString); | |
95 | // default DoLogString does nothing but is not pure virtual because if | |
96 | // you override DoLog() you might not need it at all | |
97 | virtual void DoLogString(const char *szString); | |
98 | ||
99 | static wxLog *ms_pLogger; // currently active log sink | |
100 | static bool ms_bInitialized; // any log targets created? | |
101 | }; | |
102 | ||
103 | // ---------------------------------------------------------------------------- | |
104 | // "trivial" derivations of wxLog | |
105 | // ---------------------------------------------------------------------------- | |
106 | ||
107 | // log everything to a "FILE *", stderr by default | |
108 | class WXDLLEXPORT wxLogStderr : public wxLog | |
109 | { | |
110 | public: | |
111 | // redirect log output to a FILE | |
112 | wxLogStderr(FILE *fp = NULL); | |
113 | ||
114 | private: | |
115 | // implement sink function | |
116 | virtual void DoLogString(const char *szString); | |
117 | ||
118 | FILE *m_fp; | |
119 | }; | |
120 | ||
121 | // log everything to an "ostream", cerr by default | |
122 | class WXDLLEXPORT wxLogStream : public wxLog | |
123 | { | |
124 | public: | |
125 | // redirect log output to an ostream | |
126 | wxLogStream(ostream *ostr = NULL); | |
127 | ||
128 | protected: | |
129 | // implement sink function | |
130 | virtual void DoLogString(const char *szString); | |
131 | ||
132 | // @@ using ptr here to avoid including <iostream.h> from this file | |
133 | ostream *m_ostr; | |
134 | }; | |
135 | ||
136 | /* | |
137 | // log everything to a text window (GUI only of course) | |
138 | class WXDLLEXPORT wxLogTextCtrl : public wxLogStream | |
139 | { | |
140 | public: | |
141 | // we just create an ostream from wxTextCtrl and use it in base class | |
142 | wxLogTextCtrl(wxTextCtrl *pTextCtrl); | |
143 | ~wxLogTextCtrl(); | |
144 | }; | |
145 | */ | |
146 | ||
147 | // ---------------------------------------------------------------------------- | |
148 | // GUI log target, the default one for wxWindows programs | |
149 | // ---------------------------------------------------------------------------- | |
150 | class WXDLLEXPORT wxLogGui : public wxLog | |
151 | { | |
152 | public: | |
153 | // ctor | |
154 | wxLogGui(); | |
155 | ||
156 | // show all messages that were logged since the last Flush() | |
157 | virtual void Flush(); | |
158 | ||
159 | protected: | |
160 | virtual void DoLog(Level level, const char *szString); | |
161 | ||
162 | wxArrayString m_aMessages; | |
163 | bool m_bErrors; | |
164 | }; | |
165 | ||
166 | // ---------------------------------------------------------------------------- | |
167 | // /dev/null log target: suppress logging until this object goes out of scope | |
168 | // ---------------------------------------------------------------------------- | |
169 | ||
170 | // example of usage: | |
171 | /* | |
172 | void Foo() { | |
173 | wxFile file; | |
174 | ||
175 | // wxFile.Open() normally complains if file can't be opened, we don't want it | |
176 | wxLogNull logNo; | |
177 | if ( !file.Open("bar") ) | |
178 | ... process error ourselves ... | |
179 | ||
180 | // ~wxLogNull called, old log sink restored | |
181 | } | |
182 | */ | |
183 | class WXDLLEXPORT wxLogNull | |
184 | { | |
185 | public: | |
186 | // ctor saves old log target, dtor restores it | |
187 | wxLogNull() { m_pPrevLogger = wxLog::SetActiveTarget(NULL); } | |
188 | ~wxLogNull() { (void)wxLog::SetActiveTarget(m_pPrevLogger); } | |
189 | ||
190 | private: | |
191 | wxLog *m_pPrevLogger; // old log target | |
192 | }; | |
193 | ||
194 | // ============================================================================ | |
195 | // global functions | |
196 | // ============================================================================ | |
197 | ||
198 | // ---------------------------------------------------------------------------- | |
199 | // Log functions should be used by application instead of stdio, iostream &c | |
200 | // for log messages for easy redirection | |
201 | // ---------------------------------------------------------------------------- | |
202 | ||
203 | // define wxLog<level> | |
204 | // ------------------- | |
205 | ||
206 | // NB: all these functions take `wxTString' and not | |
207 | // `const wxTString&' because according to C++ standard | |
208 | // the first argument to a vararg function can not be | |
209 | // an array, function or reference :-( | |
210 | ||
211 | // the most generic log function | |
212 | void WXDLLEXPORT wxLogGeneric(wxLog::Level level, wxTString strFormat, ...); | |
213 | ||
214 | #define DECLARE_LOG_FUNCTION(level) \ | |
215 | extern void WXDLLEXPORT wxLog##level(wxTString strFormat, ...) | |
216 | ||
217 | // one function per each level | |
218 | DECLARE_LOG_FUNCTION(FatalError); | |
219 | DECLARE_LOG_FUNCTION(Error); | |
220 | DECLARE_LOG_FUNCTION(Warning); | |
221 | DECLARE_LOG_FUNCTION(Message); | |
222 | DECLARE_LOG_FUNCTION(Info); | |
223 | DECLARE_LOG_FUNCTION(Status); | |
224 | DECLARE_LOG_FUNCTION(Verbose); | |
225 | ||
226 | // additional one: as wxLogError, but also logs last system call error code | |
227 | // and the corresponding error message if available | |
228 | DECLARE_LOG_FUNCTION(SysError); | |
229 | ||
230 | // and another one which also takes the error code (for those broken APIs | |
231 | // that don't set the errno (like registry APIs in Win32)) | |
232 | void WXDLLEXPORT wxLogSysError(long lErrCode, wxTString strFormat, ...); | |
233 | ||
234 | // debug functions don't translate their arguments | |
235 | #undef DECLARE_LOG_FUNCTION | |
236 | #define DECLARE_LOG_FUNCTION(level) \ | |
237 | extern void WXDLLEXPORT wxLog##level(const char *szFormat, ...) | |
238 | ||
239 | DECLARE_LOG_FUNCTION(Debug); | |
240 | DECLARE_LOG_FUNCTION(Trace); | |
241 | ||
242 | // are we in 'verbose' mode? | |
243 | // (note that it's often handy to change this var manually from the | |
244 | // debugger, thus enabling/disabling verbose reporting for some | |
245 | // parts of the program only) | |
246 | WXDLLEXPORT_DATA(extern bool) g_bVerbose; | |
247 | ||
248 | // fwd decl to avoid including iostream.h here | |
249 | class ostream; | |
250 | ||
251 | // ---------------------------------------------------------------------------- | |
252 | // get error code/error message from system in a portable way | |
253 | // ---------------------------------------------------------------------------- | |
254 | ||
255 | // return the last system error code | |
256 | unsigned long WXDLLEXPORT wxSysErrorCode(); | |
257 | // return the error message for given (or last if 0) error code | |
258 | const char* WXDLLEXPORT wxSysErrorMsg(unsigned long nErrCode = 0); | |
259 | ||
260 | // ---------------------------------------------------------------------------- | |
261 | // debug only logging functions: use them with API name and error code | |
262 | // ---------------------------------------------------------------------------- | |
263 | ||
264 | #ifdef __DEBUG__ | |
265 | #define wxLogApiError(api, rc) \ | |
266 | wxLogDebug("At %s(%d) '%s' failed with error %lx (%s).", \ | |
267 | __FILE__, __LINE__, api, \ | |
268 | rc, wxSysErrorMsg(rc)) | |
269 | #define wxLogLastError(api) wxLogApiError(api, ::GetLastError()) | |
270 | #else //!debug | |
271 | #define wxLogApiError(api, rc) | |
272 | #define wxLogLastError(api) | |
273 | #endif //debug/!debug | |
274 | ||
275 | #endif //__LOGH__ |