00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef MORE_DIAG_DEBUG_H
00033 #define MORE_DIAG_DEBUG_H
00034
00035 #include <iostream>
00036 #include <iomanip>
00037 #include <string>
00038 #include <memory>
00039 #include <more/io/fwd.h>
00040
00041
00042 #define MORE_SHOW(x) \
00043 ((void)(std::clog << __FILE__ << ":" << __LINE__ << ": info: " \
00044 << #x << " = " << x << std::endl))
00045 #define MORE_ECHO(x) \
00046 ((void)(std::clog << __FILE__ << ":" << __LINE__ << ": info: " \
00047 << #x << std::endl, (x)))
00048 #define MORE_SHOW_SOMETIMES(x) \
00049 ((more::diag::show_sometimes_helper())? MORE_SHOW(x) : (void)0)
00050 #define MORE_HERE \
00051 (std::cerr << __FILE__ << ":" << __LINE__ << ": info: Here!" << std::endl)
00052
00053
00054
00055
00056
00057
00058 #define MORE_CHECK(x) \
00059 ((x)? (void)0 : ::more::diag::bits::check_failed(__FILE__, __LINE__, #x))
00060
00061
00062
00063
00064
00065 #define MORE_CHECK_EQ(x, y) \
00066 (((x) == (y))? (void)0 : \
00067 (::more::diag::bits::check_failed(__FILE__, __LINE__, #x " == " #y), \
00068 std::cerr << " LHS = " << (x) << "\n RHS = " << (y) << std::endl, \
00069 (void)0))
00070
00071 #define MORE_CHECK_FAILED(msg) \
00072 more::diag::bits::check_failed(__FILE__, __LINE__, (msg))
00073
00074 #ifdef MORE_CHECK_ALLOCATIONS
00075 # define MORE_NEW(T, args...) \
00076 (::new(::more::diag::checkmem::alloc(sizeof(T), __FILE__, __LINE__)) \
00077 T(args))
00078 # define MORE_DELETE(T, ptr) \
00079 do { \
00080 if (T* p = (ptr)) { \
00081 p->~T(); \
00082 ::more::diag::checkmem::free(p, __FILE__, __LINE__); \
00083 } \
00084 } while (0)
00085 #else
00086 # define MORE_NEW(T, args...) new T(args)
00087 # define MORE_DELETE(T, ptr) delete (ptr)
00088 #endif
00089
00090
00091
00092 namespace more {
00093 namespace diag {
00094
00095 namespace bits {
00096 void check_failed(char const*, int, char const*);
00097 }
00098
00099
00100
00101
00102 int check_exit_status(int err = 0);
00103
00104
00105 void fatal(char const*);
00106
00107 std::ostream& cdbg(int);
00108 void set_debug_level(int);
00109 void parse_debug_level_from_cmdline(int& argc, char**& argv);
00110 void debug_init(io::cmdline&);
00111 bool show_sometimes_helper();
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 struct checkmem {
00124 struct header {
00125 unsigned long magic0;
00126 unsigned long magic1;
00127 header* next;
00128 header* prev;
00129 unsigned long serial;
00130 const char* file;
00131 int line;
00132 };
00133
00134 checkmem() { init(); }
00135
00136 static void* alloc(std::size_t, char const* = 0, int = 0);
00137 static void free(void*, char const* = 0, int = 0);
00138 static void init();
00139 static void finalize();
00140
00141 private:
00142 static bool is_init;
00143 static long alloc_count;
00144 static unsigned long serial;
00145 static header link;
00146 static unsigned long magic0;
00147 static unsigned long magic1;
00148 };
00149 struct checkmem_tag {};
00150
00151
00152
00153 template <typename T>
00154 struct auto_ptr {
00155 auto_ptr(T* p = 0) : m_p(p) {}
00156 auto_ptr(auto_ptr& ap) : m_p(ap.release()) {}
00157 auto_ptr& operator=(auto_ptr& ap) { reset(ap.release()); return *this; }
00158 ~auto_ptr() { MORE_DELETE(T, m_p); }
00159 T* operator->() { return m_p; }
00160 T& operator*() { return *m_p; }
00161 T* get() { return m_p; }
00162 T* release() { T* p = m_p; m_p = 0; return p; }
00163 void reset(T* p = 0) { MORE_DELETE(T, m_p); m_p = p; }
00164 private:
00165 T* m_p;
00166 };
00167 }}
00168
00169
00170 #endif