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 #ifndef _CVC_lite__debug_h
00031 #define _CVC_lite__debug_h
00032
00033 #include <string>
00034 #include <iostream>
00035 #include <sstream>
00036 #include <vector>
00037 #include "exception.h"
00038
00039
00040
00041
00042
00043
00044 #define FatalAssert(cond, msg) if(!(cond)) \
00045 CVCL::fatalError(__FILE__, __LINE__, #cond, msg)
00046
00047 namespace CVCL {
00048
00049
00050
00051 extern void fatalError(const std::string& file, int line,
00052 const std::string& cond, const std::string& msg);
00053 }
00054
00055 #ifdef DEBUG
00056
00057 #include "compat_hash_map.h"
00058 #include "compat_hash_set.h"
00059
00060
00061 #define IF_DEBUG(code) code
00062
00063
00064
00065
00066 #define DBG_PRINT(cond, pre, v, post) if(cond) CVCL::debugger.getOS() \
00067 << (pre) << (v) << (post) << std::endl
00068
00069
00070 #define DBG_PRINT_MSG(cond, msg) \
00071 if(cond) CVCL::debugger.getOS() << (msg) << std::endl
00072
00073
00074
00075 #define TRACE(flag, pre, v, post) \
00076 DBG_PRINT(CVCL::debugger.trace(flag), pre, v, post)
00077
00078
00079 #define TRACE_MSG(flag, msg) \
00080 DBG_PRINT_MSG(CVCL::debugger.trace(flag), msg)
00081
00082
00083 #define DebugAssert(cond, str) if(!(cond)) \
00084 CVCL::debugError(__FILE__, __LINE__, #cond, str)
00085
00086
00087 namespace CVCL {
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 class ScopeWatcher {
00099 private:
00100 bool *d_flag;
00101 public:
00102 ScopeWatcher(bool *flag): d_flag(flag) { *d_flag = true; }
00103 ~ScopeWatcher() { *d_flag = false; }
00104 };
00105
00106 class Expr;
00107
00108 class DebugException: public Exception {
00109 public:
00110
00111 DebugException(const std::string& msg): Exception(msg) { }
00112
00113 virtual std::string toString() const {
00114 return "Assertion violation " + d_msg;
00115 }
00116 };
00117
00118
00119
00120 extern void debugError(const std::string& file, int line,
00121 const std::string& cond, const std::string& msg)
00122 throw(Exception);
00123
00124
00125
00126
00127
00128
00129 class DebugFlag {
00130 private:
00131 bool* d_flag;
00132 public:
00133
00134
00135 DebugFlag(bool& flag) : d_flag(&flag) { }
00136
00137 ~DebugFlag() { }
00138
00139 operator bool() { return *d_flag; }
00140
00141
00142
00143 bool operator--() { *d_flag = false; return false; }
00144 bool operator++() { *d_flag = true; return true; }
00145
00146 bool operator--(int) { bool x=*d_flag; *d_flag=false; return x; }
00147 bool operator++(int) { bool x=*d_flag; *d_flag=true; return x; }
00148
00149 DebugFlag& operator=(bool x) { *d_flag=(x!=false); return *this; }
00150
00151 friend bool operator==(const DebugFlag& f1, const DebugFlag& f2);
00152 friend bool operator!=(const DebugFlag& f1, const DebugFlag& f2);
00153
00154 friend std::ostream& operator<<(std::ostream& os, const DebugFlag& f);
00155 };
00156
00157
00158 inline bool operator==(const DebugFlag& f1, const DebugFlag& f2) {
00159 return (*f1.d_flag) == (*f2.d_flag);
00160 }
00161
00162 inline bool operator!=(const DebugFlag& f1, const DebugFlag& f2) {
00163 return (*f1.d_flag) != (*f2.d_flag);
00164 }
00165
00166 inline std::ostream& operator<<(std::ostream& os, const DebugFlag& f) {
00167 if(*f.d_flag) return(os << "true");
00168 else return(os << "false");
00169 }
00170
00171
00172
00173
00174
00175 class DebugCounter {
00176 private:
00177 int* d_counter;
00178 public:
00179
00180
00181
00182 DebugCounter(int& c) : d_counter(&c) { }
00183
00184 ~DebugCounter() { }
00185
00186
00187
00188 operator int() { return *d_counter; }
00189
00190
00191
00192
00193 int operator--() { return --(*d_counter); }
00194
00195 int operator++() { return ++(*d_counter); }
00196
00197 int operator--(int) { return (*d_counter)--; }
00198
00199 int operator++(int) { return (*d_counter)++; }
00200
00201 DebugCounter& operator=(int x) { *d_counter=x; return *this; }
00202 DebugCounter& operator+=(int x) { *d_counter+=x; return *this; }
00203 DebugCounter& operator-=(int x) { *d_counter-=x; return *this; }
00204
00205
00206 DebugCounter& operator=(const DebugCounter& x)
00207 { *d_counter=*x.d_counter; return *this; }
00208
00209 DebugCounter& operator-=(const DebugCounter& x)
00210 { *d_counter-=*x.d_counter; return *this; }
00211
00212 DebugCounter& operator+=(const DebugCounter& x)
00213 { *d_counter+=*x.d_counter; return *this; }
00214
00215 friend bool operator==(const DebugCounter& c1, const DebugCounter& c2);
00216 friend bool operator!=(const DebugCounter& c1, const DebugCounter& c2);
00217 friend bool operator==(int c1, const DebugCounter& c2);
00218 friend bool operator!=(int c1, const DebugCounter& c2);
00219 friend bool operator==(const DebugCounter& c1, int c2);
00220 friend bool operator!=(const DebugCounter& c1, int c2);
00221
00222 friend std::ostream& operator<<(std::ostream& os, const DebugCounter& f);
00223 };
00224
00225 inline bool operator==(const DebugCounter& c1, const DebugCounter& c2) {
00226 return (*c1.d_counter) == (*c2.d_counter);
00227 }
00228 inline bool operator!=(const DebugCounter& c1, const DebugCounter& c2) {
00229 return (*c1.d_counter) != (*c2.d_counter);
00230 }
00231 inline bool operator==(int c1, const DebugCounter& c2) {
00232 return c1 == (*c2.d_counter);
00233 }
00234 inline bool operator!=(int c1, const DebugCounter& c2) {
00235 return c1 != (*c2.d_counter);
00236 }
00237 inline bool operator==(const DebugCounter& c1, int c2) {
00238 return (*c1.d_counter) == c2;
00239 }
00240 inline bool operator!=(const DebugCounter& c1, int c2) {
00241 return (*c1.d_counter) != c2;
00242 }
00243 inline std::ostream& operator<<(std::ostream& os, const DebugCounter& c) {
00244 return (os << *c.d_counter);
00245 }
00246
00247
00248
00249
00250
00251 class DebugTime;
00252
00253
00254
00255
00256
00257 class DebugTimer {
00258 private:
00259 DebugTime* d_time;
00260 bool d_clean_time;
00261 public:
00262
00263
00264
00265 DebugTimer(DebugTime* time, bool take_time = false)
00266 : d_time(time), d_clean_time(take_time) { }
00267
00268
00269
00270
00271
00272
00273
00274 DebugTimer(const DebugTimer& timer);
00275
00276 DebugTimer& operator=(const DebugTimer& timer);
00277
00278
00279 ~DebugTimer();
00280
00281
00282
00283 void reset();
00284 DebugTimer& operator+=(const DebugTimer& timer);
00285 DebugTimer& operator-=(const DebugTimer& timer);
00286
00287 DebugTimer operator+(const DebugTimer& timer);
00288
00289 DebugTimer operator-(const DebugTimer& timer);
00290
00291
00292 friend class Debug;
00293
00294 friend bool operator==(const DebugTimer& t1, const DebugTimer& t2);
00295 friend bool operator!=(const DebugTimer& t1, const DebugTimer& t2);
00296 friend bool operator<(const DebugTimer& t1, const DebugTimer& t2);
00297 friend bool operator>(const DebugTimer& t1, const DebugTimer& t2);
00298 friend bool operator<=(const DebugTimer& t1, const DebugTimer& t2);
00299 friend bool operator>=(const DebugTimer& t1, const DebugTimer& t2);
00300
00301
00302 friend std::ostream& operator<<(std::ostream& os, const DebugTimer& timer);
00303 };
00304
00305
00306
00307
00308
00309
00310
00311 class Debug {
00312 private:
00313
00314 const std::vector<std::pair<std::string,bool> >* d_traceOptions;
00315
00316 const std::string* d_dumpName;
00317
00318 std::ostream* d_os;
00319
00320 std::ostream* d_osDumpTrace;
00321
00322 class stringHash {
00323 public:
00324 size_t operator()(const std::string& s) const {
00325 std::hash<char*> h;
00326 return h(s.c_str());
00327 }
00328 };
00329
00330 typedef std::hash_map<std::string, bool, stringHash> FlagMap;
00331 typedef std::hash_map<std::string, int, stringHash> CounterMap;
00332 typedef std::hash_map<std::string, DebugTime*, stringHash> TimerMap;
00333 FlagMap d_flags;
00334 FlagMap d_traceFlags;
00335 CounterMap d_counters;
00336
00337
00338
00339 TimerMap d_timers;
00340
00341 public:
00342
00343 Debug(): d_traceOptions(NULL), d_os(&std::cerr), d_osDumpTrace(NULL) { }
00344
00345 ~Debug();
00346
00347 void init(const std::vector<std::pair<std::string,bool> >* traceOptions,
00348 const std::string* dumpName);
00349
00350
00351
00352 DebugFlag flag(const std::string& name)
00353 { return DebugFlag(d_flags[name]); }
00354
00355
00356
00357 DebugFlag traceFlag(const std::string& name)
00358 { return DebugFlag(d_traceFlags[name]); }
00359
00360 DebugFlag traceFlag(char* name);
00361
00362 void traceAll(bool enable = true);
00363
00364
00365 DebugCounter counter(const std::string& name)
00366 { return DebugCounter(d_counters[name]); }
00367
00368
00369 DebugTimer timer(const std::string& name);
00370
00371
00372
00373
00374 bool trace(const std::string& name);
00375
00376
00377
00378
00379
00380
00381
00382
00383 static DebugTimer newTimer();
00384
00385
00386 void setCurrentTime(DebugTimer& timer);
00387 void setCurrentTime(const std::string& name) {
00388 DebugTimer t(timer(name));
00389 setCurrentTime(t);
00390 }
00391
00392
00393
00394
00395
00396 void setElapsed(DebugTimer& timer);
00397
00398
00399 std::ostream& getOS() { return *d_os; }
00400
00401 std::ostream& getOSDumpTrace();
00402
00403
00404 void dumpTrace(const std::string& title,
00405 const std::vector<std::pair<std::string,std::string> >&
00406 fields);
00407
00408 void setOS(std::ostream& os) { d_os = &os; }
00409
00410
00411 void printAll(std::ostream& os);
00412
00413
00414 void printAll() { printAll(*d_os); }
00415
00416
00417
00418 int scopeLevel();
00419
00420 };
00421
00422 extern Debug debugger;
00423
00424 }
00425
00426 #else // if DEBUG is not defined
00427
00428
00429
00430 #define IF_DEBUG(code)
00431
00432 #define DebugAssert(cond, str)
00433
00434 #define DBG_PRINT(cond, pre, v, post)
00435 #define TRACE(cond, pre, v, post)
00436
00437 #define DBG_PRINT_MSG(cond, msg)
00438 #define TRACE_MSG(flag, msg)
00439
00440 #endif // DEBUG
00441
00442 #include "cvclutil.h"
00443
00444 #endif // _CVC_lite__debug_h