00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef DEBUG_H
00017 #define DEBUG_H
00018
00019 #ifndef CWDEBUG
00020
00021 #ifndef DOXYGEN // No need to document this. See http://libcwd.sourceforge.net/ for more info.
00022
00023 #include <iostream>
00024 #include <cstdlib>
00025
00026 #define AllocTag1(p)
00027 #define AllocTag2(p, desc)
00028 #define AllocTag_dynamic_description(p, x)
00029 #define AllocTag(p, x)
00030 #define Debug(x)
00031 #define Dout(a, b)
00032 #define DoutEntering(a, b)
00033 #define DoutFatal(a, b) LibcwDoutFatal(::std, , a, b)
00034 #define ForAllDebugChannels(STATEMENT)
00035 #define ForAllDebugObjects(STATEMENT)
00036 #define LibcwDebug(dc_namespace, x)
00037 #define LibcwDout(a, b, c, d)
00038 #define LibcwDoutFatal(a, b, c, d) do { ::std::cerr << d << ::std::endl; ::std::exit(EXIT_FAILURE); } while (1)
00039 #define NEW(x) new x
00040 #define CWDEBUG_ALLOC 0
00041 #define CWDEBUG_MAGIC 0
00042 #define CWDEBUG_LOCATION 0
00043 #define CWDEBUG_LIBBFD 0
00044 #define CWDEBUG_DEBUG 0
00045 #define CWDEBUG_DEBUGOUTPUT 0
00046 #define CWDEBUG_DEBUGM 0
00047 #define CWDEBUG_DEBUGT 0
00048 #define CWDEBUG_MARKER 0
00049
00050 #endif // !DOXYGEN
00051
00052 #include <cassert>
00053 #ifdef DEBUG
00054 #define ASSERT(x) assert(x)
00055 #else
00056 #define ASSERT(x)
00057 #endif
00058
00059 #else // CWDEBUG
00060
00061
00062 #define ASSERT(x) LIBCWD_ASSERT(x)
00063
00064 #ifndef DEBUGCHANNELS
00065
00066
00067
00068
00069
00070
00071
00072
00073 #define DEBUGCHANNELS ::debug::channels
00074 #endif
00075 #include <libcwd/debug.h>
00076
00077
00078 namespace debug {
00079
00080 void init(void);
00081 void init_thread(void);
00082
00083
00084
00085
00086
00087 namespace channels {
00088
00089
00090 namespace dc {
00091 using namespace libcwd::channels::dc;
00092 using libcwd::channel_ct;
00093
00094 #ifndef DOXYGEN // Doxygen bug causes a warning here.
00095
00096
00097 extern channel_ct persist;
00098 extern channel_ct exceptions;
00099 extern channel_ct objects;
00100 extern channel_ct matcher;
00101 extern channel_ct expression;
00102 extern channel_ct maps;
00103 extern channel_ct clientinput;
00104 extern channel_ct serverinput;
00105 #endif
00106
00107 }
00108
00109 }
00110
00111 void dump_hex(libcwd::channel_ct const& channel, unsigned char const* buf, size_t size);
00112 #if CWDEBUG_LOCATION
00113 std::string call_location(void const* return_addr);
00114 #endif
00115
00116
00117
00118
00119
00120
00121
00122
00123 struct InvisibleAllocations {
00124 int M_on;
00125
00126 InvisibleAllocations() : M_on(0) { }
00127
00128 ~InvisibleAllocations() { while (M_on > 0) off(); }
00129
00130 void on(void) { libcwd::set_invisible_on(); ++M_on; }
00131
00132 void off(void) { assert(M_on > 0); --M_on; libcwd::set_invisible_off(); }
00133 };
00134
00135
00136
00137
00138
00139
00140 struct Indent {
00141 int M_indent;
00142
00143 Indent(int indent) : M_indent(indent) { if (M_indent > 0) libcwd::libcw_do.inc_indent(M_indent); }
00144
00145 ~Indent() { if (M_indent > 0) libcwd::libcw_do.dec_indent(M_indent); }
00146 };
00147
00148 extern bool secondary_connection;
00149
00150
00151
00152 struct SecondaryConnection {
00153 bool M_value;
00154 static int S_count;
00155 SecondaryConnection(bool value) : M_value(value)
00156 {
00157 if (value)
00158 {
00159 if (!secondary_connection)
00160 {
00161 Debug(libcw_do.push_marker());
00162 Debug(libcw_do.marker().append("[SECONDARY] "));
00163 }
00164 ++S_count;
00165 secondary_connection = true;
00166 }
00167 }
00168 ~SecondaryConnection()
00169 {
00170 if (M_value)
00171 {
00172 if (--S_count == 0)
00173 {
00174 secondary_connection = false;
00175 Debug(libcw_do.pop_marker());
00176 }
00177 }
00178 }
00179 };
00180
00181
00182
00183
00184 class TeeBuf : public std::streambuf {
00185 private:
00186 std::streambuf* M_sb1;
00187 std::streambuf* M_sb2;
00188
00189 public:
00190 TeeBuf(std::streambuf* sb1, std::streambuf* sb2) : M_sb1(sb1), M_sb2(sb2) { }
00191
00192 protected:
00193 virtual int sync(void) { M_sb2->pubsync(); return M_sb1->pubsync(); }
00194 virtual std::streamsize xsputn(char_type const* p, std::streamsize n) { M_sb2->sputn(p, n); return M_sb1->sputn(p, n); }
00195 virtual int_type overflow(int_type c = traits_type::eof()) { M_sb2->sputc(c); return M_sb1->sputc(c); }
00196 };
00197
00198
00199
00200
00201 class TeeStream : public std::ostream {
00202 private:
00203 TeeBuf M_teebuf;
00204 public:
00205 TeeStream(std::ostream& os1, std::ostream& os2) : std::ostream(&M_teebuf), M_teebuf(os1.rdbuf(), os2.rdbuf()) { }
00206 };
00207
00208 }
00209
00210
00211
00212
00213
00214 #define DoutEntering(cntrl, data) \
00215 int __ircproxy_debug_indentation = 2; \
00216 { \
00217 LIBCWD_TSD_DECLARATION; \
00218 if (LIBCWD_DO_TSD_MEMBER_OFF(::libcwd::libcw_do) < 0) \
00219 { \
00220 ::libcwd::channel_set_bootstrap_st __libcwd_channel_set(LIBCWD_DO_TSD(::libcwd::libcw_do) LIBCWD_COMMA_TSD); \
00221 bool on; \
00222 { \
00223 using namespace LIBCWD_DEBUGCHANNELS; \
00224 on = (__libcwd_channel_set|cntrl).on; \
00225 } \
00226 if (on) \
00227 Dout(cntrl, "Entering " << data); \
00228 else \
00229 __ircproxy_debug_indentation = 0; \
00230 } \
00231 } \
00232 debug::Indent __ircproxy_debug_indent(__ircproxy_debug_indentation);
00233
00234 #endif // CWDEBUG
00235
00236 #include "debug_ostream_operators.h"
00237
00238 #endif // DEBUG_H