File indexing completed on 2024-03-24 15:27:21

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