1 #ifndef STLPLUS_DEBUG 2 #define STLPLUS_DEBUG 3 //////////////////////////////////////////////////////////////////////////////// 4 5 // Author: Andy Rushton 6 // Copyright: (c) Southampton University 1999-2004 7 // (c) Andy Rushton 2004 onwards 8 // License: BSD License, see ../docs/license.html 9 10 // Set of simple debug utilities, all of which are switched off by the 11 // NDEBUG compiler directive 12 13 //////////////////////////////////////////////////////////////////////////////// 14 15 #include "portability_fixes.hpp" 16 #include <stdexcept> 17 #include <string> 18 19 //////////////////////////////////////////////////////////////////////////////// 20 // Problem with missing __FUNCTION__ macro 21 //////////////////////////////////////////////////////////////////////////////// 22 23 // this macro is used in debugging but was missing in Visual Studio prior to version 7 24 #if defined(_MSC_VER) && (_MSC_VER < 1300) 25 #define __FUNCTION__ 0 26 #endif 27 28 // old versions of Borland compiler defined a macro __FUNC__ but more recent ones define __FUNCTION__ 29 // I'm not sure at what version this change was made - assumed C++ Builder 6.32 30 #if defined(__BORLANDC__) && (__BORLANDC__ < 1585) 31 #define __FUNCTION__ __FUNC__ 32 #endif 33 34 //////////////////////////////////////////////////////////////////////////////// 35 // Exception thrown if an assertion fails 36 37 namespace stlplus 38 { 39 40 class assert_failed : public std::logic_error 41 { 42 public: 43 assert_failed(const char* file, int line, const char* function, const char* message) ; 44 ~assert_failed(void) throw(); 45 }; 46 47 } // end namespace stlplus 48 49 //////////////////////////////////////////////////////////////////////////////// 50 // The macros used in debugging 51 52 #ifndef NDEBUG 53 54 #define DEBUG_TRACE stlplus::debug_trace stlplus_debug_trace(__FILE__,__LINE__,__FUNCTION__) 55 #define IF_DEBUG(stmts) {if (stlplus_debug_trace.debug()){stlplus_debug_trace.prefix(__LINE__);stmts;}} 56 #define DEBUG_REPORT(str) IF_DEBUG(stlplus_debug_trace.report(__LINE__,str)) 57 #define DEBUG_ERROR(str) stlplus_debug_trace.error(__LINE__,str) 58 #define DEBUG_STACKDUMP(str) stlplus_debug_trace.stackdump(__LINE__,str) 59 #define DEBUG_ON stlplus_debug_trace.debug_on(__LINE__,true) 60 #define DEBUG_ON_LOCAL stlplus_debug_trace.debug_on(__LINE__,false) 61 #define DEBUG_ON_GLOBAL stlplus::debug_global(__FILE__,__LINE__,__FUNCTION__,true) 62 #define DEBUG_OFF_GLOBAL stlplus::debug_global(__FILE__,__LINE__,__FUNCTION__,false) 63 #define DEBUG_OFF stlplus_debug_trace.debug_off(__LINE__) 64 #define DEBUG_ASSERT(test) if (!(test))stlplus::debug_assert_fail(__FILE__,__LINE__,__FUNCTION__,#test) 65 66 #else 67 68 #define DEBUG_TRACE 69 #define IF_DEBUG(stmts) 70 #define DEBUG_REPORT(str) 71 #define DEBUG_ERROR(str) 72 #define DEBUG_STACKDUMP(str) 73 #define DEBUG_ON 74 #define DEBUG_ON_LOCAL 75 #define DEBUG_ON_GLOBAL 76 #define DEBUG_OFF_GLOBAL 77 #define DEBUG_OFF 78 #define DEBUG_ASSERT(test) 79 80 #endif 81 82 //////////////////////////////////////////////////////////////////////////////// 83 // infrastructure - don't use directly 84 85 namespace stlplus 86 { 87 88 void debug_global(const char* file, int line, const char* function, bool state = true); 89 // exceptions: assert_failed 90 void debug_assert_fail(const char* file, int line, const char* function, const char* test) ; 91 92 class debug_trace 93 { 94 public: 95 debug_trace(const char* f, int l, const char* fn); 96 ~debug_trace(void); 97 const char* file(void) const; 98 int line(void) const; 99 bool debug(void) const; 100 void debug_on(int l, bool recurse); 101 void debug_off(int l); 102 void prefix(int l) const; 103 void report(int l, const std::string& message) const; 104 void report(const std::string& message) const; 105 void error(int l, const std::string& message) const; 106 void error(const std::string& message) const; 107 void stackdump(int l, const std::string& message) const; 108 void stackdump(const std::string& message) const; 109 void stackdump(void) const; 110 111 private: 112 const char* m_file; 113 int m_line; 114 const char* m_function; 115 unsigned m_depth; 116 const debug_trace* m_last; 117 bool m_dbg; 118 bool m_old; 119 void do_report(int l, const std::string& message) const; 120 void do_report(const std::string& message) const; 121 122 // make this class uncopyable 123 debug_trace(const debug_trace&); 124 debug_trace& operator = (const debug_trace&); 125 }; 126 127 } // end namespace stlplus 128 129 //////////////////////////////////////////////////////////////////////////////// 130 #endif 131