File indexing completed on 2024-12-08 09:37:15
0001 /* This file is part of the KDE libraries 0002 Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org) 0003 2000-2002 Stephan Kulow (coolo@kde.org) 0004 2002 Holger Freyther (freyther@kde.org) 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #ifndef _KDEBUG_H_ 0023 #define _KDEBUG_H_ 0024 0025 #include <kdelibs4support_export.h> 0026 0027 #ifdef KDELIBS4SUPPORT_NO_DEPRECATED_NOISE 0028 #warning "This file is deprecated." 0029 #endif 0030 0031 /** @file */ // Trigger doxygen coverage of global objects in the file, like macros 0032 0033 #include <QDebug> 0034 #include <QElapsedTimer> 0035 0036 /** 0037 * \addtogroup kdebug Debug message generators 0038 * @{ 0039 * KDE debug message streams let you and the user control just how many debug 0040 * messages you see. Debug message printing is controlled by (un)defining 0041 * QT_NO_DEBUG when compiling your source. If QT_NO_DEBUG is defined then debug 0042 * messages are not printed by default but can still be enabled by runtime 0043 * configuration, e.g. via kdebugdialog5 or by editing kdebugrc. 0044 * 0045 * You can also control what you see: see QT_MESSAGE_PATTERN in the QDebug documentation. 0046 * This is new in Qt 5.0 and replaces the KDE_DEBUG_* variables from KDE 4.x. 0047 */ 0048 0049 #if !defined(KDE_NO_DEBUG_OUTPUT) 0050 # if defined(QT_NO_DEBUG_OUTPUT) || defined(QT_NO_DEBUG_STREAM) 0051 # define KDE_NO_DEBUG_OUTPUT 0052 # endif 0053 #endif 0054 0055 #if !defined(KDE_NO_WARNING_OUTPUT) 0056 # if defined(QT_NO_WARNING_OUTPUT) 0057 # define KDE_NO_WARNING_OUTPUT 0058 # endif 0059 #endif 0060 0061 #ifdef QT_NO_DEBUG /* The application is compiled in release mode */ 0062 # define KDE_DEBUG_ENABLED_BY_DEFAULT false 0063 #else 0064 # define KDE_DEBUG_ENABLED_BY_DEFAULT true 0065 #endif 0066 0067 /** 0068 * An indicator of where you are in a source file, to be used in 0069 * warnings (perhaps debug messages too). 0070 * @deprecated kDebug takes care of printing the method name automatically now 0071 */ 0072 #define k_funcinfo "" 0073 0074 /** 0075 * An indicator of where you are in a source file, to be used in 0076 * warnings (perhaps debug messages too). Gives an accurate 0077 * idea of where the message comes from. Not suitable for 0078 * user-visible messages. 0079 * @deprecated kDebug takes care of printing the method name automatically now 0080 */ 0081 #define k_lineinfo "[" << __FILE__ << ":" << __LINE__ << "] " 0082 0083 /** 0084 * @internal 0085 * Returns a debug stream that may or may not output anything. 0086 */ 0087 KDELIBS4SUPPORT_DEPRECATED_EXPORT_NOISE QDebug kDebugStream(QtMsgType level, int area, const char *file = nullptr, 0088 int line = -1, const char *funcinfo = nullptr); 0089 0090 /** 0091 * @internal 0092 * Returns a debug stream that goes the way of the blackhole. 0093 */ 0094 KDELIBS4SUPPORT_DEPRECATED_EXPORT_NOISE QDebug kDebugDevNull(); 0095 0096 /** 0097 * @internal 0098 * The actual backtrace. 0099 */ 0100 KDELIBS4SUPPORT_DEPRECATED_EXPORT_NOISE QString kRealBacktrace(int); 0101 0102 /** 0103 * \relates KGlobal 0104 * Returns a backtrace. 0105 * Note: Hidden symbol visibility may negatively affect the information provided 0106 * by kBacktrace - you may want to pass -D__KDE_HAVE_GCC_VISIBILITY=0 to cmake 0107 * to turn hidden symbol visibility off. 0108 * @param levels the number of levels of the backtrace 0109 * @return a backtrace 0110 */ 0111 #if !defined(KDE_NO_DEBUG_OUTPUT) 0112 inline QString kBacktrace(int levels = -1) 0113 { 0114 return kRealBacktrace(levels); 0115 } 0116 #else 0117 static inline QString kBacktrace(int = -1) 0118 { 0119 return QString(); 0120 } 0121 #endif 0122 0123 /** 0124 * \relates KGlobal 0125 * Deletes the kdebugrc cache and therefore forces KDebug to reread the 0126 * config file 0127 */ 0128 KDELIBS4SUPPORT_DEPRECATED_EXPORT_NOISE void kClearDebugConfig(); 0129 0130 #ifndef KDE_DEFAULT_DEBUG_AREA 0131 # define KDE_DEFAULT_DEBUG_AREA 0 0132 #endif 0133 0134 /*! 0135 \macro KDE_DEFAULT_DEBUG_AREA 0136 \relates KGlobal 0137 0138 Denotes the debug area to use in kDebug/kWarning etc when not 0139 explicitly specified. The default is 0 (zero). 0140 0141 Define this macro to the debug area of your application/component 0142 before including any KDE headers. Usually, you want to add code like 0143 this to your \c CMakeLists.txt: 0144 0145 \code 0146 ... 0147 add_definitions( -DKDE_DEFAULT_DEBUG_AREA=1234 ) 0148 ... 0149 \endcode 0150 0151 This way, you save repeating the debug area all over your source 0152 code, in each debug/warning statement. 0153 */ 0154 0155 #if !defined(KDE_NO_DEBUG_OUTPUT) 0156 /** 0157 * \relates KGlobal 0158 * Returns a debug stream. You can use it to print debug 0159 * information. 0160 * @param area an id to identify the output, KDE_DEFAULT_DEBUG_AREA for default 0161 */ 0162 static inline QDebug kDebug(int area = KDE_DEFAULT_DEBUG_AREA) 0163 { 0164 return kDebugStream(QtDebugMsg, area); 0165 } 0166 static inline QDebug kDebug(bool cond, int area = KDE_DEFAULT_DEBUG_AREA) 0167 { 0168 return cond ? kDebug(area) : kDebugDevNull(); 0169 } 0170 0171 #else // KDE_NO_DEBUG_OUTPUT 0172 static inline QDebug kDebug(int = KDE_DEFAULT_DEBUG_AREA) 0173 { 0174 return kDebugDevNull(); 0175 } 0176 static inline QDebug kDebug(bool, int = KDE_DEFAULT_DEBUG_AREA) 0177 { 0178 return kDebugDevNull(); 0179 } 0180 #endif 0181 0182 #if !defined(KDE_NO_WARNING_OUTPUT) 0183 /** 0184 * \relates KGlobal 0185 * Returns a warning stream. You can use it to print warning 0186 * information. 0187 * @param area an id to identify the output, KDE_DEFAULT_DEBUG_AREA for default 0188 */ 0189 static inline QDebug kWarning(int area = KDE_DEFAULT_DEBUG_AREA) 0190 { 0191 return kDebugStream(QtWarningMsg, area); 0192 } 0193 static inline QDebug kWarning(bool cond, int area = KDE_DEFAULT_DEBUG_AREA) 0194 { 0195 return cond ? kWarning(area) : kDebugDevNull(); 0196 } 0197 0198 #else // KDE_NO_WARNING_OUTPUT 0199 static inline QDebug kWarning(int = KDE_DEFAULT_DEBUG_AREA) 0200 { 0201 return kDebugDevNull(); 0202 } 0203 static inline QDebug kWarning(bool, int = KDE_DEFAULT_DEBUG_AREA) 0204 { 0205 return kDebugDevNull(); 0206 } 0207 #endif 0208 0209 /** 0210 * \relates KGlobal 0211 * Returns an error stream. You can use it to print error 0212 * information. 0213 * @param area an id to identify the output, KDE_DEFAULT_DEBUG_AREA for default 0214 */ 0215 static inline QDebug kError(int area = KDE_DEFAULT_DEBUG_AREA) 0216 { 0217 return kDebugStream(QtCriticalMsg, area); 0218 } 0219 static inline QDebug kError(bool cond, int area = KDE_DEFAULT_DEBUG_AREA) 0220 { 0221 return cond ? kError(area) : kDebugDevNull(); 0222 } 0223 0224 /** 0225 * \relates KGlobal 0226 * Returns a fatal error stream. You can use it to print fatal error 0227 * information. 0228 * @param area an id to identify the output, KDE_DEFAULT_DEBUG_AREA for default 0229 */ 0230 static inline QDebug kFatal(int area = KDE_DEFAULT_DEBUG_AREA) 0231 { 0232 return kDebugStream(QtFatalMsg, area); 0233 } 0234 static inline QDebug kFatal(bool cond, int area = KDE_DEFAULT_DEBUG_AREA) 0235 { 0236 return cond ? kFatal(area) : kDebugDevNull(); 0237 } 0238 0239 struct KDebugTag { }; ///! @internal just a tag class 0240 typedef QDebug(*KDebugStreamFunction)(QDebug, KDebugTag); ///< @internal 0241 inline QDebug operator<<(QDebug s, KDebugStreamFunction f) 0242 { 0243 return (*f)(s, KDebugTag()); 0244 } 0245 0246 /** 0247 * \relates KGlobal 0248 * Print a message describing the last system error. 0249 * @param s the debug stream to write to 0250 * @return the debug stream (@p s) 0251 * @see perror(3) 0252 */ 0253 KDELIBS4SUPPORT_DEPRECATED_EXPORT_NOISE QDebug perror(QDebug, KDebugTag); 0254 0255 // operators for KDE types 0256 class QUrl; 0257 class KDateTime; 0258 class QObject; 0259 KDELIBS4SUPPORT_DEPRECATED_EXPORT_NOISE QDebug operator<<(QDebug s, const KDateTime &time); 0260 0261 #if 1 || defined(KDE3_SUPPORT) 0262 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED 0263 class KDELIBS4SUPPORT_DEPRECATED_NOISE kndbgstream { }; 0264 typedef QDebug kdbgstream; 0265 0266 static inline KDELIBS4SUPPORT_DEPRECATED_NOISE QDebug kdDebug(int area = KDE_DEFAULT_DEBUG_AREA) 0267 { 0268 return kDebug(area); 0269 } 0270 static inline KDELIBS4SUPPORT_DEPRECATED_NOISE QDebug kdWarning(int area = KDE_DEFAULT_DEBUG_AREA) 0271 { 0272 return kWarning(area); 0273 } 0274 static inline KDELIBS4SUPPORT_DEPRECATED_NOISE QDebug kdError(int area = KDE_DEFAULT_DEBUG_AREA) 0275 { 0276 return kError(area); 0277 } 0278 static inline KDELIBS4SUPPORT_DEPRECATED_NOISE QDebug kdFatal(int area = KDE_DEFAULT_DEBUG_AREA) 0279 { 0280 return kFatal(area); 0281 } 0282 inline KDELIBS4SUPPORT_DEPRECATED_NOISE QString kdBacktrace(int levels = -1) 0283 { 0284 return kBacktrace(levels); 0285 } 0286 0287 static inline KDELIBS4SUPPORT_DEPRECATED_NOISE QDebug kndDebug() 0288 { 0289 return kDebugDevNull(); 0290 } 0291 #endif 0292 #endif 0293 0294 class WrongSyntax {}; 0295 0296 /** 0297 * @internal 0298 * A class for using operator() 0299 */ 0300 class KDebug //krazy= ? 0301 { 0302 const char *file; 0303 const char *funcinfo; 0304 int line; 0305 QtMsgType level; 0306 public: 0307 class Block; 0308 KDELIBS4SUPPORT_DEPRECATED explicit inline KDebug(QtMsgType type, const char *f = nullptr, int l = -1, const char *info = nullptr) 0309 : file(f), funcinfo(info), line(l), level(type) 0310 { 0311 #ifdef KDE4_CMAKE_TOPLEVEL_DIR_LENGTH // set by FindKDE4Internal.cmake 0312 file = file + KDE4_CMAKE_TOPLEVEL_DIR_LENGTH + 1; 0313 #endif 0314 } 0315 0316 inline QDebug operator()(int area = KDE_DEFAULT_DEBUG_AREA) 0317 { 0318 return kDebugStream(level, area, file, line, funcinfo); 0319 } 0320 inline QDebug operator()(bool cond, int area = KDE_DEFAULT_DEBUG_AREA) 0321 { 0322 if (cond) { 0323 return operator()(area); 0324 } return kDebugDevNull(); 0325 } 0326 0327 /// @internal 0328 static KDELIBS4SUPPORT_DEPRECATED_EXPORT_NOISE bool hasNullOutput(QtMsgType type, 0329 bool condition, 0330 int area, 0331 bool enableByDefault); 0332 0333 /// @internal 0334 static inline bool hasNullOutputQtDebugMsg(int area = KDE_DEFAULT_DEBUG_AREA) 0335 { 0336 return hasNullOutput(QtDebugMsg, true, area, KDE_DEBUG_ENABLED_BY_DEFAULT); 0337 } 0338 /// @internal 0339 static inline bool hasNullOutputQtDebugMsg(bool condition, int area = KDE_DEFAULT_DEBUG_AREA) 0340 { 0341 return hasNullOutput(QtDebugMsg, condition, area, KDE_DEBUG_ENABLED_BY_DEFAULT); 0342 } 0343 0344 /** 0345 * @since 4.4 0346 * Register a debug area dynamically. 0347 * @param areaName the name of the area 0348 * @param enabled whether debug output should be enabled by default 0349 * (users can override this in kdebugdialog5 or with DisableAll=true in kdebugrc) 0350 * @return the area code that was allocated for this area 0351 * 0352 * Typical usage: 0353 * If all uses of the debug area are restricted to a single class, add a method like this 0354 * (e.g. into the Private class, if there's one) 0355 * <code> 0356 * static int debugArea() { static int s_area = KDebug::registerArea("areaName"); return s_area; } 0357 * </code> 0358 * Please do not use a file-static int, it would (indirectly) create KGlobal too early, 0359 * create KConfig instances too early (breaking unittests which change QStandardPaths dirs), etc. 0360 * By using a function as shown above, you make it all happen on-demand, rather than upfront. 0361 * 0362 * If all uses of the debug area are restricted to a single .cpp file, do the same 0363 * but outside any class, and then use a more specific name for the function. 0364 * 0365 * If however multiple classes and files need the debug area, then 0366 * declare it in one file without static, and use "extern int debugArea();" 0367 * in other files (with a better name for the function of course). 0368 */ 0369 static KDELIBS4SUPPORT_DEPRECATED_EXPORT_NOISE int registerArea(const QByteArray &areaName, bool enabled = true); 0370 0371 private: 0372 WrongSyntax operator()(const char *) 0373 { 0374 return WrongSyntax(); // error! Use kDebug() << "..." or kWarning() << "..." instead. 0375 } 0376 }; 0377 0378 #if !defined(KDE_NO_DEBUG_OUTPUT) 0379 /* __VA_ARGS__ should work with any supported GCC version and MSVC > 2005 */ 0380 # if defined(Q_CC_GNU) || (defined(Q_CC_MSVC) && _MSC_VER >= 1500) 0381 # define kDebug(...) for (bool _k_kDebugDoOutput_ = !KDebug::hasNullOutputQtDebugMsg(__VA_ARGS__); \ 0382 Q_UNLIKELY(_k_kDebugDoOutput_); _k_kDebugDoOutput_ = false) \ 0383 KDebug(QtDebugMsg, __FILE__, __LINE__, Q_FUNC_INFO)(__VA_ARGS__) 0384 # else 0385 # define kDebug KDebug(QtDebugMsg, __FILE__, __LINE__, Q_FUNC_INFO) 0386 # endif 0387 #else 0388 # define kDebug while (false) kDebug 0389 #endif 0390 #if !defined(KDE_NO_WARNING_OUTPUT) 0391 # define kWarning KDebug(QtWarningMsg, __FILE__, __LINE__, Q_FUNC_INFO) 0392 #else 0393 # define kWarning while (false) kWarning 0394 #endif 0395 0396 #ifndef KDE_NO_DEBUG_OUTPUT 0397 0398 /** 0399 * @class KDebug::Block 0400 * @short Use this to label sections of your code 0401 * @since 4.6 0402 * 0403 * Usage: 0404 * <code> 0405 * void function() 0406 * { 0407 * KDebug::Block myBlock( "section" ); 0408 * 0409 * debug() << "output1" << endl; 0410 * debug() << "output2" << endl; 0411 * } 0412 * </code> 0413 * 0414 * Will output: 0415 * 0416 * app: BEGIN: section 0417 * app: [prefix] output1 0418 * app: [prefix] output2 0419 * app: END: section - Took 0.1s 0420 * 0421 * Alternatively, use the KDEBUG_BLOCK macro, for automatic naming. 0422 */ 0423 class KDELIBS4SUPPORT_DEPRECATED_EXPORT KDebug::Block 0424 { 0425 public: 0426 Block(const char *label, int area = KDE_DEFAULT_DEBUG_AREA); 0427 ~Block(); 0428 0429 private: 0430 QElapsedTimer m_startTime; 0431 int m_area; 0432 class Private; 0433 Private *d; 0434 }; 0435 0436 /** 0437 * Convenience macro for making a standard KDebug::Block 0438 */ 0439 #define KDEBUG_BLOCK KDebug::Block _kDebugBlock(Q_FUNC_INFO); 0440 0441 #else 0442 0443 class KDELIBS4SUPPORT_DEPRECATED_EXPORT KDebug::Block 0444 { 0445 public: 0446 Block(const char *, int = KDE_DEFAULT_DEBUG_AREA) {} 0447 ~Block() {} 0448 }; 0449 0450 #define KDEBUG_BLOCK 0451 0452 #endif 0453 0454 /** 0455 * Convenience macro, use this to remind yourself to finish the implementation of a function 0456 * The function name will appear in the output (unless $KDE_DEBUG_NOMETHODNAME is set) 0457 * @since 4.6 0458 */ 0459 #define KWARNING_NOTIMPLEMENTED kWarning() << "NOT-IMPLEMENTED"; 0460 0461 /** 0462 * Convenience macro, use this to alert other developers to stop using a function 0463 * The function name will appear in the output (unless $KDE_DEBUG_NOMETHODNAME is set) 0464 * @since 4.6 0465 */ 0466 #define KWARNING_DEPRECATED kWarning() << "DEPRECATED"; 0467 0468 /** @} */ 0469 0470 #endif