1 // This code is in the public domain -- castanyo@yahoo.es 2 3 #ifndef NV_CORE_DEBUG_H 4 #define NV_CORE_DEBUG_H 5 6 #include <nvcore/nvcore.h> 7 8 #if defined(HAVE_STDARG_H) 9 # include <stdarg.h> // va_list 10 #endif 11 12 #define NV_ABORT_DEBUG 1 13 #define NV_ABORT_IGNORE 2 14 #define NV_ABORT_EXIT 3 15 16 #undef assert // avoid conflicts with assert method. 17 18 #define nvNoAssert(exp) \ 19 do { \ 20 (void)sizeof(exp); \ 21 } while(0) 22 23 #if NV_NO_ASSERT 24 25 # define nvAssert(exp) nvNoAssert(exp) 26 # define nvCheck(exp) nvNoAssert(exp) 27 # define nvDebugAssert(exp) nvNoAssert(exp) 28 # define nvDebugCheck(exp) nvNoAssert(exp) 29 # define nvDebugBreak() nvNoAssert(0) 30 31 #else // NV_NO_ASSERT 32 33 # if NV_CC_MSVC 34 // @@ Does this work in msvc-6 and earlier? 35 // @@ Do I have to include <intrin.h> ? 36 # define nvDebugBreak() __debugbreak() 37 // define nvDebugBreak() __asm int 3 38 # elif NV_CC_GNUC && NV_CPU_PPC && NV_OS_DARWIN 39 # define nvDebugBreak() __asm__ volatile ("trap"); 40 # elif NV_CC_GNUC && NV_CPU_X86 && NV_OS_DARWIN 41 # define nvDebugBreak() __asm__ volatile ("int3"); 42 # elif NV_CC_GNUC && NV_CPU_X86 43 # define nvDebugBreak() __asm__ ( "int %0" : :"I"(3) ) 44 # else 45 # include <signal.h> 46 # define nvDebugBreak() raise(SIGTRAP); 47 // define nvDebugBreak() *((int *)(0)) = 0 48 # endif 49 50 # define nvAssertMacro(exp) \ 51 do { \ 52 if(!(exp)) { \ 53 if( nvAbort(#exp, __FILE__, __LINE__, __FUNC__) == NV_ABORT_DEBUG ) { \ 54 nvDebugBreak(); \ 55 } \ 56 } \ 57 } while(false) 58 59 # define nvAssert(exp) nvAssertMacro(exp) 60 # define nvCheck(exp) nvAssertMacro(exp) 61 62 # if defined(_DEBUG) 63 # define nvDebugAssert(exp) nvAssertMacro(exp) 64 # define nvDebugCheck(exp) nvAssertMacro(exp) 65 # else // _DEBUG 66 # define nvDebugAssert(exp) nvNoAssert(exp) 67 # define nvDebugCheck(exp) nvNoAssert(exp) 68 # endif // _DEBUG 69 70 #endif // NV_NO_ASSERT 71 72 // Use nvAssume for very simple expresions only: nvAssume(0), nvAssume(value == true), etc. 73 #if defined(_DEBUG) 74 # if NV_CC_MSVC 75 # define nvAssume(exp) __assume(exp) 76 # else 77 # define nvAssume(exp) nvCheck(exp) 78 # endif 79 #else 80 # define nvAssume(exp) nvCheck(exp) 81 #endif 82 83 84 #define nvError(x) nvAbort(x, __FILE__, __LINE__, __FUNC__) 85 #define nvWarning(x) nvDebug("*** Warning %s/%d: %s\n", __FILE__, __LINE__, (x)) 86 87 88 #if PI_CC_MSVC 89 // @@ I'm not sure it's a good idea to use the default static assert. 90 # define nvStaticCheck(x) _STATIC_ASSERT(x) 91 #else 92 # define nvStaticCheck(x) typedef char NV_DO_STRING_JOIN2(__static_assert_,__LINE__)[(x)] 93 // define nvStaticCheck(x) switch(0) { case 0: case x:; } 94 #endif 95 96 NVCORE_API int nvAbort(const char *exp, const char *file, int line, const char * func = 0); 97 NVCORE_API void NV_CDECL nvDebug( const char *msg, ... ) __attribute__((format (printf, 1, 2))); 98 99 namespace nv 100 { 101 /** Message handler interface. */ 102 struct MessageHandler { 103 virtual void log(const char * str, va_list arg) = 0; ~MessageHandlerMessageHandler104 virtual ~MessageHandler() {} 105 }; 106 107 /** Assert handler interface. */ 108 struct AssertHandler { 109 virtual int assert(const char *exp, const char *file, int line, const char *func = 0) = 0; ~AssertHandlerAssertHandler110 virtual ~AssertHandler() {} 111 }; 112 113 114 namespace debug 115 { 116 NVCORE_API void dumpInfo(); 117 118 // These functions are not thread safe. 119 NVCORE_API void setMessageHandler( MessageHandler * messageHandler ); 120 NVCORE_API void resetMessageHandler(); 121 122 NVCORE_API void setAssertHandler( AssertHandler * assertHanlder ); 123 NVCORE_API void resetAssertHandler(); 124 125 NVCORE_API void enableSigHandler(); 126 NVCORE_API void disableSigHandler(); 127 } 128 129 } // nv namespace 130 131 #endif // NV_CORE_DEBUG_H 132