1/* This file is part of the KDE libraries
2 Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org)
3 2000-2002 Stephan Kulow (coolo@kde.org)
4 2002 Holger Freyther (freyther@kde.org)
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22#ifndef _KDEBUG_H_
23#define _KDEBUG_H_
24
25#include <kdecore_export.h>
26
27#include <QtCore/QDebug>
28#include <QtCore/QElapsedTimer>
29
30/**
31 * \addtogroup kdebug Debug message generators
32 * @{
33 * KDE debug message streams let you and the user control just how many debug
34 * messages you see. Debug message printing is controlled by (un)defining
35 * QT_NO_DEBUG when compiling your source. If QT_NO_DEBUG is defined then debug
36 * messages are not printed by default but can still be enabled by runtime
37 * configuration, e.g. via kdebugdialog or by editing kdebugrc.
38 *
39 * You can also control what you see: process name, area name, method name,
40 * file and line number, timestamp, etc. using environment variables.
41 * See http://techbase.kde.org/SysAdmin/Environment_Variables#KDE_DEBUG_NOPROCESSINFO
42 */
43
44#if !defined(KDE_NO_DEBUG_OUTPUT)
45# if defined(QT_NO_DEBUG_OUTPUT) || defined(QT_NO_DEBUG_STREAM)
46# define KDE_NO_DEBUG_OUTPUT
47# endif
48#endif
49
50#if !defined(KDE_NO_WARNING_OUTPUT)
51# if defined(QT_NO_WARNING_OUTPUT)
52# define KDE_NO_WARNING_OUTPUT
53# endif
54#endif
55
56#ifdef QT_NO_DEBUG /* The application is compiled in release mode */
57# define KDE_DEBUG_ENABLED_BY_DEFAULT false
58#else
59# define KDE_DEBUG_ENABLED_BY_DEFAULT true
60#endif
61
62/**
63 * An indicator of where you are in a source file, to be used in
64 * warnings (perhaps debug messages too).
65 * @deprecated kDebug takes care of printing the method name automatically now
66 */
67#define k_funcinfo ""
68
69/**
70 * An indicator of where you are in a source file, to be used in
71 * warnings (perhaps debug messages too). Gives an accurate
72 * idea of where the message comes from. Not suitable for
73 * user-visible messages.
74 * @deprecated kDebug takes care of printing the method name automatically now
75 */
76#define k_lineinfo "[" << __FILE__ << ":" << __LINE__ << "] "
77
78/**
79 * @internal
80 * Returns a debug stream that may or may not output anything.
81 */
82KDECORE_EXPORT QDebug kDebugStream(QtMsgType level, int area, const char *file = 0,
83 int line = -1, const char *funcinfo = 0);
84
85/**
86 * @internal
87 * Returns a debug stream that goes the way of the blackhole.
88 */
89KDECORE_EXPORT QDebug kDebugDevNull();
90
91/**
92 * @internal
93 * The actual backtrace.
94 */
95KDECORE_EXPORT QString kRealBacktrace(int);
96
97
98/**
99 * \relates KGlobal
100 * Returns a backtrace.
101 * Note: Hidden symbol visibility may negatively affect the information provided
102 * by kBacktrace - you may want to pass -D__KDE_HAVE_GCC_VISIBILITY=0 to cmake
103 * to turn hidden symbol visibility off.
104 * @param levels the number of levels of the backtrace
105 * @return a backtrace
106 */
107#if !defined(KDE_NO_DEBUG_OUTPUT)
108inline QString kBacktrace(int levels=-1) { return kRealBacktrace(levels); }
109#else
110static inline QString kBacktrace(int=-1) { return QString(); }
111#endif
112
113/**
114 * \relates KGlobal
115 * Deletes the kdebugrc cache and therefore forces KDebug to reread the
116 * config file
117 */
118KDECORE_EXPORT void kClearDebugConfig();
119
120#ifndef KDE_DEFAULT_DEBUG_AREA
121# define KDE_DEFAULT_DEBUG_AREA 0
122#endif
123
124/*!
125 \macro KDE_DEFAULT_DEBUG_AREA
126 \relates KGlobal
127
128 Denotes the debug area to use in kDebug/kWarning etc when not
129 explicitly specified. The default is 0 (zero).
130
131 Define this macro to the debug area of your application/component
132 before including any KDE headers. Usually, you want to add code like
133 this to your \c CMakeLists.txt:
134
135 \code
136 ...
137 add_definitions( -DKDE_DEFAULT_DEBUG_AREA=1234 )
138 ...
139 \endcode
140
141 This way, you save repeating the debug area all over your source
142 code, in each debug/warning statement.
143*/
144
145#if !defined(KDE_NO_DEBUG_OUTPUT)
146/**
147 * \relates KGlobal
148 * Returns a debug stream. You can use it to print debug
149 * information.
150 * @param area an id to identify the output, KDE_DEFAULT_DEBUG_AREA for default
151 */
152static inline QDebug kDebug(int area = KDE_DEFAULT_DEBUG_AREA)
153{ return kDebugStream(QtDebugMsg, area); }
154static inline QDebug kDebug(bool cond, int area = KDE_DEFAULT_DEBUG_AREA)
155{ return cond ? kDebug(area) : kDebugDevNull(); }
156
157#else // KDE_NO_DEBUG_OUTPUT
158static inline QDebug kDebug(int = KDE_DEFAULT_DEBUG_AREA) { return kDebugDevNull(); }
159static inline QDebug kDebug(bool, int = KDE_DEFAULT_DEBUG_AREA) { return kDebugDevNull(); }
160#endif
161
162#if !defined(KDE_NO_WARNING_OUTPUT)
163/**
164 * \relates KGlobal
165 * Returns a warning stream. You can use it to print warning
166 * information.
167 * @param area an id to identify the output, KDE_DEFAULT_DEBUG_AREA for default
168 */
169static inline QDebug kWarning(int area = KDE_DEFAULT_DEBUG_AREA)
170{ return kDebugStream(QtWarningMsg, area); }
171static inline QDebug kWarning(bool cond, int area = KDE_DEFAULT_DEBUG_AREA)
172{ return cond ? kWarning(area) : kDebugDevNull(); }
173
174#else // KDE_NO_WARNING_OUTPUT
175static inline QDebug kWarning(int = KDE_DEFAULT_DEBUG_AREA) { return kDebugDevNull(); }
176static inline QDebug kWarning(bool, int = KDE_DEFAULT_DEBUG_AREA) { return kDebugDevNull(); }
177#endif
178
179/**
180 * \relates KGlobal
181 * Returns an error stream. You can use it to print error
182 * information.
183 * @param area an id to identify the output, KDE_DEFAULT_DEBUG_AREA for default
184 */
185static inline QDebug kError(int area = KDE_DEFAULT_DEBUG_AREA)
186{ return kDebugStream(QtCriticalMsg, area); }
187static inline QDebug kError(bool cond, int area = KDE_DEFAULT_DEBUG_AREA)
188{ return cond ? kError(area) : kDebugDevNull(); }
189
190/**
191 * \relates KGlobal
192 * Returns a fatal error stream. You can use it to print fatal error
193 * information.
194 * @param area an id to identify the output, KDE_DEFAULT_DEBUG_AREA for default
195 */
196static inline QDebug kFatal(int area = KDE_DEFAULT_DEBUG_AREA)
197{ return kDebugStream(QtFatalMsg, area); }
198static inline QDebug kFatal(bool cond, int area = KDE_DEFAULT_DEBUG_AREA)
199{ return cond ? kFatal(area) : kDebugDevNull(); }
200
201struct KDebugTag { }; ///! @internal just a tag class
202typedef QDebug (*KDebugStreamFunction)(QDebug, KDebugTag); ///< @internal
203inline QDebug operator<<(QDebug s, KDebugStreamFunction f)
204{ return (*f)(s, KDebugTag()); }
205
206/**
207 * \relates KGlobal
208 * Print a message describing the last system error.
209 * @param s the debug stream to write to
210 * @return the debug stream (@p s)
211 * @see perror(3)
212 */
213KDECORE_EXPORT QDebug perror(QDebug, KDebugTag);
214
215// operators for KDE types
216class KUrl;
217class KDateTime;
218class QObject;
219KDECORE_EXPORT QDebug operator<<(QDebug s, const KUrl &url);
220KDECORE_EXPORT QDebug operator<<(QDebug s, const KDateTime &time);
221
222#if 1 || defined(KDE3_SUPPORT)
223#ifndef KDE_NO_DEPRECATED
224class KDE_DEPRECATED kndbgstream { };
225typedef QDebug kdbgstream;
226
227static inline KDE_DEPRECATED QDebug kdDebug(int area = KDE_DEFAULT_DEBUG_AREA) { return kDebug(area); }
228static inline KDE_DEPRECATED QDebug kdWarning(int area = KDE_DEFAULT_DEBUG_AREA) { return kWarning(area); }
229static inline KDE_DEPRECATED QDebug kdError(int area = KDE_DEFAULT_DEBUG_AREA) { return kError(area); }
230static inline KDE_DEPRECATED QDebug kdFatal(int area = KDE_DEFAULT_DEBUG_AREA) { return kFatal(area); }
231inline KDE_DEPRECATED QString kdBacktrace(int levels=-1) { return kBacktrace( levels ); }
232
233static inline KDE_DEPRECATED QDebug kndDebug() { return kDebugDevNull(); }
234#endif
235#endif
236
237class WrongSyntax {};
238
239/**
240 * @internal
241 * A class for using operator()
242 */
243class KDebug //krazy= ?
244{
245 const char *file;
246 const char *funcinfo;
247 int line;
248 QtMsgType level;
249public:
250 class Block;
251 explicit inline KDebug(QtMsgType type, const char *f = 0, int l = -1, const char *info = 0)
252 : file(f), funcinfo(info), line(l), level(type)
253 {
254#ifdef KDE4_CMAKE_TOPLEVEL_DIR_LENGTH // set by FindKDE4Internal.cmake
255 file = file + KDE4_CMAKE_TOPLEVEL_DIR_LENGTH + 1;
256#endif
257 }
258
259 inline QDebug operator()(int area = KDE_DEFAULT_DEBUG_AREA)
260 { return kDebugStream(level, area, file, line, funcinfo); }
261 inline QDebug operator()(bool cond, int area = KDE_DEFAULT_DEBUG_AREA)
262 { if (cond) return operator()(area); return kDebugDevNull(); }
263
264 /// @internal
265 static KDECORE_EXPORT bool hasNullOutput(QtMsgType type,
266 bool condition,
267 int area,
268 bool enableByDefault);
269
270 /// @internal
271 static inline bool hasNullOutputQtDebugMsg(int area = KDE_DEFAULT_DEBUG_AREA)
272 { return hasNullOutput(QtDebugMsg, true, area, KDE_DEBUG_ENABLED_BY_DEFAULT); }
273 /// @internal
274 static inline bool hasNullOutputQtDebugMsg(bool condition, int area = KDE_DEFAULT_DEBUG_AREA)
275 { return hasNullOutput(QtDebugMsg, condition, area, KDE_DEBUG_ENABLED_BY_DEFAULT); }
276
277 /**
278 * @since 4.4
279 * Register a debug area dynamically.
280 * @param areaName the name of the area
281 * @param enabled whether debug output should be enabled by default
282 * (users can override this in kdebugdialog or with DisableAll=true in kdebugrc)
283 * @return the area code that was allocated for this area
284 *
285 * Typical usage:
286 * If all uses of the debug area are restricted to a single class, add a method like this
287 * (e.g. into the Private class, if there's one)
288 * <code>
289 * static int debugArea() { static int s_area = KDebug::registerArea("areaName"); return s_area; }
290 * </code>
291 * Please do not use a file-static int, it would (indirectly) create KGlobal too early,
292 * create KConfig instances too early (breaking unittests which set KDEHOME), etc.
293 * By using a function as shown above, you make it all happen on-demand, rather than upfront.
294 *
295 * If all uses of the debug area are restricted to a single .cpp file, do the same
296 * but outside any class, and then use a more specific name for the function.
297 *
298 * If however multiple classes and files need the debug area, then
299 * declare it in one file without static, and use "extern int debugArea();"
300 * in other files (with a better name for the function of course).
301 */
302 static KDECORE_EXPORT int registerArea(const QByteArray& areaName, bool enabled = true);
303
304private:
305 WrongSyntax operator()(const char*) {return WrongSyntax();} // error! Use kDebug() << "..." or kWarning() << "..." instead.
306};
307
308
309#if !defined(KDE_NO_DEBUG_OUTPUT)
310/* __VA_ARGS__ should work with any supported GCC version and MSVC > 2005 */
311# if defined(Q_CC_GNU) || (defined(Q_CC_MSVC) && _MSC_VER >= 1500)
312# define kDebug(...) for (bool _k_kDebugDoOutput_ = !KDebug::hasNullOutputQtDebugMsg(__VA_ARGS__); \
313 KDE_ISUNLIKELY(_k_kDebugDoOutput_); _k_kDebugDoOutput_ = false) \
314 KDebug(QtDebugMsg, __FILE__, __LINE__, Q_FUNC_INFO)(__VA_ARGS__)
315# else
316# define kDebug KDebug(QtDebugMsg, __FILE__, __LINE__, Q_FUNC_INFO)
317# endif
318#else
319# define kDebug while (false) kDebug
320#endif
321#if !defined(KDE_NO_WARNING_OUTPUT)
322# define kWarning KDebug(QtWarningMsg, __FILE__, __LINE__, Q_FUNC_INFO)
323#else
324# define kWarning while (false) kWarning
325#endif
326
327#ifndef KDE_NO_DEBUG_OUTPUT
328
329/**
330 * @class KDebug::Block
331 * @short Use this to label sections of your code
332 * @since 4.6
333 *
334 * Usage:
335 * <code>
336 * void function()
337 * {
338 * KDebug::Block myBlock( "section" );
339 *
340 * debug() << "output1" << endl;
341 * debug() << "output2" << endl;
342 * }
343 * </code>
344 *
345 * Will output:
346 *
347 * app: BEGIN: section
348 * app: [prefix] output1
349 * app: [prefix] output2
350 * app: END: section - Took 0.1s
351 *
352 * Alternatively, use the KDEBUG_BLOCK macro, for automatic naming.
353 */
354class KDECORE_EXPORT KDebug::Block
355{
356public:
357 Block(const char* label, int area = KDE_DEFAULT_DEBUG_AREA);
358 ~Block();
359
360private:
361 QElapsedTimer m_startTime;
362 const char *m_label; // KDE5 TODO: REMOVE
363 int m_area;
364 int m_color;
365 class Private;
366 Private* d;
367};
368
369/**
370 * Convenience macro for making a standard KDebug::Block
371 */
372#define KDEBUG_BLOCK KDebug::Block _kDebugBlock(Q_FUNC_INFO);
373
374#else
375
376class KDECORE_EXPORT KDebug::Block
377{
378public:
379 Block(const char*, int = KDE_DEFAULT_DEBUG_AREA) {}
380 ~Block() {}
381};
382
383#define KDEBUG_BLOCK
384
385#endif
386
387/**
388 * Convenience macro, use this to remind yourself to finish the implementation of a function
389 * The function name will appear in the output (unless $KDE_DEBUG_NOMETHODNAME is set)
390 * @since 4.6
391 */
392#define KWARNING_NOTIMPLEMENTED kWarning() << "NOT-IMPLEMENTED";
393
394/**
395 * Convenience macro, use this to alert other developers to stop using a function
396 * The function name will appear in the output (unless $KDE_DEBUG_NOMETHODNAME is set)
397 * @since 4.6
398 */
399#define KWARNING_DEPRECATED kWarning() << "DEPRECATED";
400
401/** @} */
402
403#endif
404