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.&nbsp;
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.&nbsp;
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.&nbsp;
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.&nbsp;
137  * You will have to define your own macro when you want to use a second debug object.&nbsp;
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.&nbsp;
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