1 // $Header$ 2 // 3 // Copyright (C) 2000 - 2004, by 4 // 5 // Carlo Wood, Run on IRC <carlo@alinoe.com> 6 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt 7 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61 8 // 9 // This file may be distributed under the terms of the Q Public License 10 // version 1.0 as appearing in the file LICENSE.QPL included in the 11 // packaging of this file. 12 // 13 14 /** \file libcwd/debug.h 15 * 16 * \brief This is the main header file of libcwd. 17 * 18 * Don't include this header file directly. 19 * Instead use a \link chapter_custom_debug_h custom debug.h \endlink header file that includes this file, 20 * that will allow others to compile your application without having libcwd installed. 21 */ 22 23 #ifndef CWDEBUG 24 25 // If you run into this error then you included <libcwd/debug.h> (or any other libcwd header file) 26 // while the macro CWDEBUG was not defined. Doing so would cause the compilation of your 27 // application to fail on machines that do not have libcwd installed. Instead you should use: 28 // #include "debug.h" 29 // and add a file debug.h to your applications distribution. Please see the the example-project 30 // that comes with the source code of libcwd (or is included in the documentation that comes with 31 // the rpm (ie: /usr/doc/libcwd-1.0/example-project) for a description of the content of "debug.h". 32 // Note1: CWDEBUG should be defined on the compiler commandline, for example: g++ -DCWDEBUG ... 33 #error "You are including <libcwd/debug.h> while CWDEBUG is not defined. See the comments in this header file for more information." 34 35 #else // CWDEBUG (normal usage of this file): 36 37 #ifndef LIBCWD_SYS_H 38 #error "You need to #include "sys.h" at the top of every source file (which in turn should #include <libcwd/sys.h>)." 39 #endif 40 41 #if defined(LIBCWD_DEFAULT_DEBUGCHANNELS) && defined(DEBUGCHANNELS) 42 // If you run into this error then you included <libcwd/debug.h> (or any other libcwd header file) 43 // without defining DEBUGCHANNELS, and later (the moment of this error) you included it with 44 // DEBUGCHANNELS defined. 45 // 46 // The most likely reason for this is that you include <libcwd/debug.h> in one of your headers 47 // instead of using #include "debug.h", and then included that header file before including 48 // "debug.h" in the .cpp file. 49 // End-applications should #include "debug.h" everywhere. See the the example-project that comes 50 // with the source code of libcwd (or is included in the documentation that comes with the rpm 51 // (ie: /usr/doc/libcwd-1.0/example-project) for a description of the content of "debug.h". 52 // More information for end-application users can be found on 53 // http://libcwd.sourceforge.net/reference-manual/preparation.html 54 // 55 // Third-party libraries should never include <libcwd/debug.h> but also not "debug.h". They 56 // should include <libcwd/libraries_debug.h> (and not use Dout et al in their headers). If you 57 // are using a library that did include <libcwd/debug.h> then please report this bug the author 58 // of that library. You can workaround it for now by including "debug.h" before including the 59 // header of that library. 60 // More information for library authors that use libcwd can be found on 61 // http://libcwd.sourceforge.net/reference-manual/group__chapter__custom__debug__h.html 62 #error "DEBUGCHANNELS is defined while previously it was not defined. See the comments in this header file for more information." 63 #endif 64 65 #endif // CWDEBUG 66 67 #ifndef LIBCWD_DEBUG_H 68 #define LIBCWD_DEBUG_H 69 70 #ifdef CWDEBUG 71 72 // The following header is also needed for end-applications, despite its name. 73 #include <libcwd/libraries_debug.h> 74 75 #ifndef LIBCWD_DOXYGEN 76 77 // The real code 78 #ifdef DEBUGCHANNELS 79 #define LIBCWD_DEBUGCHANNELS DEBUGCHANNELS 80 #else 81 #define LIBCWD_DEBUGCHANNELS libcwd::channels 82 #define LIBCWD_DEFAULT_DEBUGCHANNELS 83 #endif 84 85 #else // LIBCWD_DOXYGEN 86 87 // This is only here for the documentation. The user will define DEBUGCHANNELS, not LIBCWD_DEBUGCHANNELS. 88 /** 89 * \brief The namespace containing the current %debug %channels (dc) namespace. 90 * 91 * This macro is internally used by libcwd macros to include the chosen set of %debug %channels. 92 * For details please read section \ref chapter_custom_debug_h. 93 */ 94 #define DEBUGCHANNELS 95 #endif // LIBCWD_DOXYGEN 96 97 // For use in applications 98 /** \def Debug 99 * 100 * \brief Encapsulation macro for general debugging code. 101 * 102 * The parameter of this macro can be arbitrary code that will be eliminated 103 * from the application when the macro CWDEBUG is \em not defined. 104 * 105 * It uses the namespaces \ref DEBUGCHANNELS and libcwd, making it unnecessary to 106 * use the the full scopes for debug channels and utility functions provided by 107 * libcwd. 108 * 109 * <b>Examples:</b> 110 * 111 * \code 112 * Debug( check_configuration() ); // Configuration consistency check. 113 * Debug( dc::notice.on() ); // Switch debug channel NOTICE on. 114 * Debug( libcw_do.on() ); // Turn all debugging temporally off. 115 * Debug( list_channels_on(libcw_do) ); // List all debug channels. 116 * Debug( make_all_allocations_invisible_except(NULL) ); // Hide all allocations so far. 117 * Debug( list_allocations_on(libcw_do) ); // List all allocations. 118 * Debug( libcw_do.set_ostream(&std::cout) ); // Use std::cout as debug output stream. 119 * Debug( libcw_do.set_ostream(&std::cout, &mutex) ); // use `mutex' as lock for std::cout. 120 * Debug( libcw_do.inc_indent(4) ); // Increment indentation by 4 spaces. 121 * Debug( libcw_do.get_ostream()->flush() ); // Flush the current debug output stream. 122 * \endcode 123 */ 124 #define Debug(x) \ 125 LibcwDebug(LIBCWD_DEBUGCHANNELS, x) 126 127 /** \def Dout 128 * 129 * \brief Macro for writing %debug output. 130 * 131 * This macro is used for writing %debug output to the default %debug object 132 * \link libcwd::libcw_do libcw_do \endlink. 133 * No code is generated when the macro CWDEBUG is not defined, in that case the macro 134 * Dout is replaced by white space. 135 * 136 * The macro \ref Dout uses libcwds debug object \link libcwd::libcw_do libcw_do \endlink. 137 * You will have to define your own macro when you want to use a second debug object. 138 * Read chapter \ref page_why_macro for an explanation of why a macro was used instead of an inline function. 139 * 140 * \sa \ref group_control_flags 141 * \n \ref group_default_dc 142 * \n \link chapter_custom_debug_h Defining your own debug channels \endlink 143 * \n \link chapter_custom_do Defining your own debug objects \endlink 144 * \n \ref chapter_nesting "Nested debug calls" 145 * 146 * <b>Examples:</b> 147 * 148 * \code 149 * Dout(dc::notice, "Hello World"); 150 * Dout(dc::malloc|dc::warning, "Out of memory in function " << func_name); 151 * Dout(dc::notice|blank_label_cf, "The content of the object is: " << std::hex << obj); 152 * \endcode 153 */ 154 #define Dout(cntrl, data) \ 155 LibcwDout(LIBCWD_DEBUGCHANNELS, ::libcwd::libcw_do, cntrl, data) 156 157 /** 158 * \def DoutFatal 159 * \ingroup group_fatal_output 160 * 161 * \brief Macro for writing fatal %debug output to the default %debug object 162 * \link libcwd::libcw_do libcw_do \endlink. 163 */ 164 #define DoutFatal(cntrl, data) \ 165 LibcwDoutFatal(LIBCWD_DEBUGCHANNELS, ::libcwd::libcw_do, cntrl, data) 166 167 /** 168 * \def ForAllDebugChannels 169 * \ingroup group_special 170 * 171 * \brief Looping over all debug channels. 172 * 173 * The macro \c ForAllDebugChannels allows you to run over all %debug %channels. 174 * 175 * For example, 176 * 177 * \code 178 * ForAllDebugChannels( while (!debugChannel.is_on()) debugChannel.on() ); 179 * \endcode 180 * 181 * which turns all %channels on. 182 * And 183 * 184 * \code 185 * ForAllDebugChannels( if (debugChannel.is_on()) debugChannel.off() ); 186 * \endcode 187 * 188 * which turns all channels off. 189 */ 190 #define ForAllDebugChannels(STATEMENT...) \ 191 LibcwdForAllDebugChannels(LIBCWD_DEBUGCHANNELS, STATEMENT) 192 193 /** 194 * \def ForAllDebugObjects 195 * \ingroup group_special 196 * 197 * \brief Looping over all debug objects. 198 * 199 * The macro \c ForAllDebugObjects allows you to run over all %debug objects. 200 * 201 * For example, 202 * 203 * \code 204 * ForAllDebugObjects( debugObject.set_ostream(&std::cerr, &cerr_mutex) ); 205 * \endcode 206 * 207 * would set the output stream of all %debug objects to <CODE>std::cerr</CODE>. 208 */ 209 #define ForAllDebugObjects(STATEMENT...) \ 210 LibcwdForAllDebugObjects(LIBCWD_DEBUGCHANNELS, STATEMENT) 211 212 // Finally, in order for Dout() to be usable, we need this. 213 #ifndef LIBCW_IOSTREAM 214 #define LIBCW_IOSTREAM 215 #include <iostream> 216 #endif 217 218 #endif // CWDEBUG 219 #endif // LIBCWD_DEBUG_H 220