////////////////////////////////////////////////////////////////////////// // Name: actDebug.h // Product: cv act library // Purpose: Integration of globally available debug macros and functions // // Copyright: (c) 2005 cv cryptovision GmbH // all rights reserved // Licence: The conditions for the use of this software are regulated // in the cv act library licence agreement. // // Autor: Markus Tesche (MTE) // Date: 12/15/2005 ////////////////////////////////////////////////////////////////////////// #ifndef ACT_Debug_h #define ACT_Debug_h #include "actEnv.h" #include "actBasics.h" #include "actException.h" // // ACT_NOOP use for semicolon terminated non operating macros. #ifdef _MSC_VER # if _MSC_VER >= 1210 # define ACT_NOOP __noop # else # define ACT_NOOP ((void) 0) # endif // MSVC specific # if !defined(DEBUG_NEW) # if defined(_DEBUG) && !defined(_WIN32_WCE) # include # define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) # else # define DEBUG_NEW new # endif # endif #else # define ACT_NOOP ((void) 0) # define DEBUG_NEW new #endif // // Declare all debug macros for release builds. #ifdef _DEBUG # ifdef UNDER_CE # define ACT_ASSERT ACT_NOOP # define ACT_ASSERT_ALWAYS(m, l, f) ACT_NOOP # endif # define ACT_DEBUG 1 # define ACT_DEBUG_PARAM(p) p # define ACT_DEBUG_SOURCE() act::FileAndLine(__FILE__, __LINE__) # define ACT_NOT_IMPLEMENTED(m, w) throw act::NotImplementedException(m, w) << ACT_DEBUG_SOURCE() #else # define ACT_DEBUG 0 # define ACT_DEBUG_SOURCE() act::FileAndLine() # define ACT_NOT_IMPLEMENTED(m, w) throw act::NotImplementedException(m, w) # if defined(_MSC_VER) && _MSC_VER < 1210 # define ACT_DEBUG_PARAM(p) p # define ACT_TRACE ACT_NOOP # define ACT_TRACELOG ACT_NOOP # define ACT_ASSERT ACT_NOOP # else # define ACT_DEBUG_PARAM(p) # define ACT_TRACE(...) ACT_NOOP # define ACT_TRACELOG(...) ACT_NOOP # define ACT_ASSERT(e) ACT_NOOP # endif # define ACT_ASSERT_ALWAYS(m, l, f) ACT_NOOP # define ACT_ASSERT_ON_THROW(m) ACT_NOOP #endif // _DEBUG // // ACT_ASSERT #ifndef ACT_ASSERT # if defined(_MSC_VER) # include # define ACT_ASSERT _ASSERTE # else # include # define ACT_ASSERT assert # endif #endif // ACT_ASSERT // // ACT_ASSERT_ALWAYS #ifndef ACT_ASSERT_ALWAYS # if defined(_MSC_VER) # include # define ACT_ASSERT_ALWAYS(m, f, l) _RPT_BASE((_CRT_ASSERT, f, l, 0, m)) # else # include # define ACT_ASSERT_ALWAYS(m, f, l) assert(f == 0) # endif #endif // ACT_ASSERT_ALWAYS // // ACT_ASSERT_ON_THROW #ifndef ACT_ASSERT_ON_THROW namespace act { class CheckForNoThrow : public FileAndLine { public: CheckForNoThrow(const char* msg, const char* file = 0, int line = 0) : FileAndLine(file, line) , m_msg(msg) { } ~CheckForNoThrow() { const bool uc = ::std::uncaught_exception(); if(uc == true) ACT_ASSERT_ALWAYS(m_msg, file(), line()); } private: const char* m_msg; }; } // namespace act #define ACT_ASSERT_ON_THROW(m) act::CheckForNoThrow __dbg_check_for_nothrow(m, __FILE__, __LINE__) #endif // ACT_ASSERT_ON_THROW // // ACT_ENABLE_TRACE #ifdef ACT_ENABLE_TRACE # ifdef ACT_TRACE # undef ACT_TRACE # endif # ifdef ACT_TRACELOG # undef ACT_TRACELOG # endif #endif // // ACT_TRACE #ifndef ACT_TRACE #ifndef ACT_TRACE_BUFFER #define ACT_TRACE_BUFFER 1024 #endif #include #include #include #if defined(ACT_WIN32) || defined(ACT_WIN32_WCE) #include namespace act { struct Trace { void __cdecl operator()(const char* pFormat, va_list ptr, const char* pFileName = 0, int nLine = 0) const { char szBuf[ACT_TRACE_BUFFER] = {'\0'}; int nLen = 0; if(pFileName != 0) { int nTemp = _snprintf(szBuf + nLen, ACT_TRACE_BUFFER - nLen, "%s(%d) : ", pFileName, nLine); if(nTemp < 0) nLen = ACT_TRACE_BUFFER; else nLen += nTemp; } _vsnprintf(szBuf + nLen, ACT_TRACE_BUFFER - nLen, pFormat, ptr); szBuf[ACT_TRACE_BUFFER - 1] = 0; #ifndef UNDER_CE ::OutputDebugStringA(szBuf); #else { wchar_t wtmp[ACT_TRACE_BUFFER]; mbstowcs(wtmp, szBuf, ACT_TRACE_BUFFER); ::OutputDebugStringW(wtmp); } #endif } }; } // namespace act #elif defined(ACT_POSIX) #include namespace act { struct Trace { void operator()(const char* pFormat, va_list ptr, const char* pFileName = 0, int nLine = 0) const { char szBuf[ACT_TRACE_BUFFER] = {'\0'}; int nLen = 0; if(pFileName != 0) { int nTemp = snprintf(szBuf + nLen, ACT_TRACE_BUFFER - nLen, "%s(%d) : ", pFileName, nLine); if(nTemp < 0) nLen = ACT_TRACE_BUFFER; else nLen += nTemp; } vsnprintf(szBuf + nLen, ACT_TRACE_BUFFER - nLen, pFormat, ptr); szBuf[ACT_TRACE_BUFFER - 1] = 0; syslog(LOG_DEBUG, "%s", szBuf); } }; } // namespace act #else # error act::Trace not implemented for this platform #endif // // act::TraceFileAndLine namespace act { class TraceFileAndLine : public FileAndLine { public: TraceFileAndLine() { } TraceFileAndLine(const FileAndLine& fl) : FileAndLine(fl) { } TraceFileAndLine(const char * file, int line) : FileAndLine(file, line) { } inline void setFileAndLine(const FileAndLine* fl) { if(fl != 0) *static_cast(this) = *fl; } inline TraceFileAndLine& operator<<(const FileAndLine& fl) { *static_cast(this) = fl; return *this; } // // default va_list based trace. void operator()(const char* pFormat, ...) { va_list ptr; va_start(ptr, pFormat); Trace()(pFormat, ptr, file(), line()); va_end(ptr); } // // Exception trace. void operator()(const Exception& e) { setFileAndLine(dynamic_cast(&e)); switch(e.GetId()) { case eiNoSuchAlgorithmException: (*this)("%s['0x%08x', '%&s', '%s', '%s']\n", typeid(e).name(), static_cast(e).algorithm(), e.code(), e.what(), e.where()); break; default: (*this)("%s['0x%08x', '%s', '%s']\n", typeid(e).name(), e.code(), e.what(), e.where()); } } void operator()(const Exception& e, const char* pName) { setFileAndLine(dynamic_cast(&e)); switch(e.GetId()) { case eiNoSuchAlgorithmException: (*this)("%s : %s['0x%08x', '%s', '%s', '%s']\n", pName, typeid(e).name(), e.code(), static_cast(e).algorithm(), e.what(), e.where()); break; default: (*this)("%s : %s['0x%08x', '%s', '%s']\n", pName, typeid(e).name(), e.code(), e.what(), e.where()); } } }; } // namespace act #define ACT_TRACE act::TraceFileAndLine(__FILE__, __LINE__) #define ACT_TRACELOG act::TraceFileAndLine() #endif // ACT_TRACE #endif // ACT_Debug_h