2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #if !defined( INCLUDED_DEBUGGING_DEBUGGING_H )
23 #define INCLUDED_DEBUGGING_DEBUGGING_H
26 /// \brief Debugging macros for fatal error/assert messages.
28 #include "globaldefs.h"
29 #include "stream/textstream.h"
31 #include "generic/static.h"
33 #if GDEF_COMPILER_MSVC && ( defined( _M_IX86 ) || defined( _M_AMD64 ) )
34 #define DEBUGGER_BREAKPOINT() __asm { int 3 }
35 #elif GDEF_COMPILER_GNU && __GNUC__ >= 2 && ( defined ( __i386__ ) || defined ( __x86_64__ ) )
36 #define DEBUGGER_BREAKPOINT() __asm__ __volatile__ ( "int $03" )
40 #define DEBUGGER_BREAKPOINT() raise( SIGTRAP );
44 #define STR2( x ) STR( x )
45 #define FILE_LINE __FILE__ ":" STR2( __LINE__ )
49 class DebugMessageHandler
52 virtual TextOutputStream& getOutputStream() = 0;
53 virtual bool handleMessage() = 0;
56 class NullDebugMessageHandler : public NullOutputStream, public DebugMessageHandler
59 virtual TextOutputStream& getOutputStream(){
62 virtual bool handleMessage(){
67 class DefaultDebugMessageHandler : public DebugMessageHandler
70 virtual TextOutputStream& getOutputStream(){
71 return globalErrorStream();
73 virtual bool handleMessage(){
75 return false; // send debug-break
82 class DebugMessageHandlerRef : public DefaultDebugMessageHandler
84 DebugMessageHandler* m_handler;
86 DebugMessageHandlerRef()
89 void setHandler( DebugMessageHandler& handler ){
92 DebugMessageHandler& getHandler(){
97 typedef Static<DebugMessageHandlerRef> GlobalDebugMessageHandler;
99 inline DebugMessageHandler& globalDebugMessageHandler(){
100 return GlobalDebugMessageHandler::instance().getHandler();
103 #if defined( DEBUG_ASSERTS )
105 /// \brief Sends a \p message to the current debug-message-handler text-output-stream if \p condition evaluates to false.
106 #define ASSERT_MESSAGE( condition, message ) do { \
107 if ( !( condition ) ) \
109 globalDebugMessageHandler().getOutputStream() << FILE_LINE "\nassertion failure: " << message << "\n"; \
110 if ( !globalDebugMessageHandler().handleMessage() ) { DEBUGGER_BREAKPOINT(); } \
113 /// \brief Sends a \p message to the current debug-message-handler text-output-stream.
114 #define ERROR_MESSAGE( message ) do { \
115 globalDebugMessageHandler().getOutputStream() << FILE_LINE "\nruntime error: " << message << "\n"; \
116 if ( !globalDebugMessageHandler().handleMessage() ) { DEBUGGER_BREAKPOINT(); }} while ( 0 )
118 #define ASSERT_NOTNULL( ptr ) ASSERT_MESSAGE( ptr != 0, "pointer \"" #ptr "\" is null" )
119 #define ASSERT_TRUE( flag ) ASSERT_MESSAGE( !!(flag) == true, "condition \"" #flag "\" is false" )
123 #define ASSERT_MESSAGE( condition, message )
124 #define ERROR_MESSAGE( message )
125 #define ASSERT_NOTNULL( ptr )