debugging.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined(INCLUDED_DEBUGGING_DEBUGGING_H)
00023 #define INCLUDED_DEBUGGING_DEBUGGING_H
00024
00030 #include "stream/textstream.h"
00031 #include "generic/static.h"
00032
00033 #if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
00034 #define DEBUGGER_BREAKPOINT() __asm__ __volatile__ ("int $03")
00035 #else
00036 #include <signal.h>
00037 #define DEBUGGER_BREAKPOINT() raise(SIGTRAP);
00038 #endif
00039
00040 #define STR(x) #x
00041 #define STR2(x) STR(x)
00042 #define FILE_LINE __FILE__ ":" STR2(__LINE__)
00043
00044 #define DEBUG_ASSERTS
00045
00046 class DebugMessageHandler {
00047 public:
00048 virtual ~DebugMessageHandler(){}
00049 virtual TextOutputStream& getOutputStream() = 0;
00050 virtual bool handleMessage() = 0;
00051 };
00052
00053 class NullDebugMessageHandler : public NullOutputStream, public DebugMessageHandler {
00054 public:
00055 virtual TextOutputStream& getOutputStream() {
00056 return *this;
00057 }
00058 virtual bool handleMessage() {
00059 return false;
00060 }
00061 };
00062
00063 class DefaultDebugMessageHandler : public DebugMessageHandler {
00064 public:
00065 virtual TextOutputStream& getOutputStream() {
00066 return globalErrorStream();
00067 }
00068 virtual bool handleMessage() {
00069 #if defined(DEBUG)
00070 return false;
00071 #else
00072 return true;
00073 #endif
00074 }
00075 };
00076
00077 class DebugMessageHandlerRef : public DefaultDebugMessageHandler {
00078 DebugMessageHandler* m_handler;
00079 public:
00080 DebugMessageHandlerRef()
00081 : m_handler(this) {
00082 }
00083 void setHandler(DebugMessageHandler& handler) {
00084 m_handler = &handler;
00085 }
00086 DebugMessageHandler& getHandler() {
00087 return *m_handler;
00088 }
00089 };
00090
00091 typedef Static<DebugMessageHandlerRef> GlobalDebugMessageHandler;
00092
00093 inline DebugMessageHandler& globalDebugMessageHandler() {
00094 return GlobalDebugMessageHandler::instance().getHandler();
00095 }
00096
00097 #if defined(DEBUG_ASSERTS)
00098
00100 #define ASSERT_MESSAGE(condition, message) do{\
00101 if(!(condition))\
00102 {\
00103 globalDebugMessageHandler().getOutputStream() << FILE_LINE "\nassertion failure: " << message << "\n";\
00104 if(!globalDebugMessageHandler().handleMessage()) { DEBUGGER_BREAKPOINT(); }\
00105 }} while(0)
00106
00108 #define ERROR_MESSAGE(message) do{\
00109 globalDebugMessageHandler().getOutputStream() << FILE_LINE "\nruntime error: " << message << "\n";\
00110 if(!globalDebugMessageHandler().handleMessage()) { DEBUGGER_BREAKPOINT(); }} while(0)
00111
00112 #define ASSERT_NOTNULL(ptr) ASSERT_MESSAGE(ptr != 0, "pointer \"" #ptr "\" is null")
00113
00114 #else
00115
00116 #define ASSERT_MESSAGE(condition, message)
00117 #define ERROR_MESSAGE(message)
00118 #define ASSERT_NOTNULL(ptr)
00119
00120 #endif
00121
00122 #endif