debugging.h

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2001-2006, William Joseph.
00003 All Rights Reserved.
00004 
00005 This file is part of GtkRadiant.
00006 
00007 GtkRadiant is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 GtkRadiant is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GtkRadiant; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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; // send debug-break
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

Generated by  doxygen 1.6.2