Equalizer 1.0
|
00001 00002 /* Copyright (c) 2007-2010, Stefan Eilemann <eile@equalizergraphics.com> 00003 * 00004 * This library is free software; you can redistribute it and/or modify it under 00005 * the terms of the GNU Lesser General Public License version 2.1 as published 00006 * by the Free Software Foundation. 00007 * 00008 * This library is distributed in the hope that it will be useful, but WITHOUT 00009 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00010 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00011 * details. 00012 * 00013 * You should have received a copy of the GNU Lesser General Public License 00014 * along with this library; if not, write to the Free Software Foundation, Inc., 00015 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00016 */ 00017 00018 #ifndef COBASE_DEBUG_H 00019 #define COBASE_DEBUG_H 00020 00021 #include <co/base/defines.h> 00022 #include <co/base/log.h> 00023 #include <typeinfo> 00024 00025 #ifndef _WIN32 00026 # include <cxxabi.h> 00027 # include <stdlib.h> 00028 #endif 00029 00030 // assertions 00031 // #define EQ_RELEASE_ASSERT 00032 00033 namespace co 00034 { 00035 namespace base 00036 { 00041 COBASE_API void abort(); 00042 00047 COBASE_API void checkHeap(); 00048 00055 COBASE_API std::ostream& sysError( std::ostream& os ); 00056 00063 COBASE_API std::ostream& backtrace( std::ostream& os ); 00064 00066 template< class T > inline std::string className( T* object ) 00067 { 00068 #ifdef _WIN32 00069 return std::string( typeid( *object ).name( )); 00070 #else 00071 int status; 00072 const char* mangled = typeid( *object ).name(); 00073 char* name = abi::__cxa_demangle( mangled, 0, 0, &status ); 00074 std::string result = name; 00075 if( status != 0 ) 00076 result = mangled; 00077 if( name ) 00078 free( name ); 00079 return result; 00080 #endif 00081 } 00082 00083 } 00084 } 00085 00086 #ifdef NDEBUG 00087 00088 # ifdef EQ_RELEASE_ASSERT 00089 # define EQASSERT(x) \ 00090 { \ 00091 if( !(x) ) \ 00092 EQERROR << "##### Assert: " << #x << " #####" << std::endl \ 00093 << co::base::forceFlush; \ 00094 co::base::checkHeap(); \ 00095 } 00096 # define EQASSERTINFO(x, info) \ 00097 { \ 00098 if( !(x) ) \ 00099 EQERROR << "##### Assert: " << #x << " [" << info << "] #####" \ 00100 << std::endl << co::base::forceFlush; \ 00101 co::base::checkHeap(); \ 00102 } 00103 # define EQCHECK(x) { const bool eqOk = x; EQASSERTINFO( eqOk, #x ) } 00104 # else 00105 # define EQASSERT(x) 00106 # define EQASSERTINFO(x, info) 00107 # define EQCHECK(x) { x; } 00108 # endif 00109 00110 # define EQUNIMPLEMENTED { EQERROR << "Unimplemented code" << std::endl \ 00111 << co::base::forceFlush; } 00112 # define EQUNREACHABLE { EQERROR << "Unreachable code" << std::endl \ 00113 << co::base::forceFlush; } 00114 # define EQDONTCALL \ 00115 { EQERROR << "Code is not supposed to be called in this context" \ 00116 << std::endl << co::base::forceFlush; } 00117 # define EQABORT( info ) { \ 00118 EQERROR << "##### Abort: " << info << " #####" << std::endl \ 00119 << co::base::forceFlush; } 00120 00121 #else // NDEBUG 00122 00123 # define EQASSERT(x) \ 00124 { \ 00125 if( !(x) ) \ 00126 { \ 00127 EQERROR << "Assert: " << #x << " "; \ 00128 co::base::abort(); \ 00129 } \ 00130 co::base::checkHeap(); \ 00131 } 00132 # define EQASSERTINFO(x, info) \ 00133 { \ 00134 if( !(x) ) \ 00135 { \ 00136 EQERROR << "Assert: " << #x << " [" << info << "] "; \ 00137 co::base::abort(); \ 00138 } \ 00139 co::base::checkHeap(); \ 00140 } 00141 00142 # define EQUNIMPLEMENTED \ 00143 { EQERROR << "Unimplemented code in " << co::base::className( this ) \ 00144 << " "; \ 00145 co::base::abort(); } 00146 # define EQUNREACHABLE \ 00147 { EQERROR << "Unreachable code in " << co::base::className( this ) \ 00148 << " "; \ 00149 co::base::abort(); } 00150 # define EQDONTCALL \ 00151 { EQERROR << "Code is not supposed to be called in this context, type " \ 00152 << co::base::className( this ) << " " ; \ 00153 co::base::abort(); } 00154 00155 # define EQCHECK(x) { const bool eqOk = x; EQASSERTINFO( eqOk, #x ) } 00156 # define EQABORT( info ) { \ 00157 EQERROR << "Abort: " << info << " "; \ 00158 co::base::abort(); } 00159 00160 #endif // NDEBUG 00161 00162 #define EQSAFECAST( to, in ) static_cast< to >( in ); \ 00163 EQASSERT( in == 0 || dynamic_cast< to >( static_cast< to >( in ))) 00164 00165 00166 #endif //COBASE_DEBUG_H