/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #ifndef GDCMTRACE_H #define GDCMTRACE_H #include "gdcmTypes.h" #include "gdcmSystem.h" #include #include namespace gdcm { /** * \brief Trace * \details Debug / Warning and Error are encapsulated in this class * by default the Trace class will redirect any debug/warning/error * to std::cerr. Unless SetStream was specified with another (open) stream or * SetStreamToFile was specified to a writable file on the system. * * \warning * All string messages are removed during compilation time when compiled with * CMAKE_BUILD_TYPE being set to either: * - Release * - MinSizeRel * It is recommended to compile with RelWithDebInfo and/or Debug during * prototyping of applications. */ class GDCM_EXPORT Trace { public : Trace(); ~Trace(); /// Explicitly set the ostream for gdcm::Trace to report to /// This will set the DebugStream, WarningStream and ErrorStream at once: static void SetStream(std::ostream &os); static std::ostream &GetStream(); /// Explicitly set the stream which receive Debug messages: static void SetDebugStream(std::ostream &os); static std::ostream &GetDebugStream(); /// Explicitly set the stream which receive Warning messages: static void SetWarningStream(std::ostream &os); static std::ostream &GetWarningStream(); /// Explicitly set the stream which receive Error messages: static void SetErrorStream(std::ostream &os); static std::ostream &GetErrorStream(); /// Explicitly set the filename for gdcm::Trace to report to /// The file will be created (it will not append to existing file) static void SetStreamToFile( const char *filename ); /// Turn debug messages on (default: false) static void SetDebug(bool debug); static void DebugOn(); static void DebugOff(); static bool GetDebugFlag(); /// Turn warning messages on (default: true) static void SetWarning(bool debug); static void WarningOn(); static void WarningOff(); static bool GetWarningFlag(); /// Turn error messages on (default: true) static void SetError(bool debug); static void ErrorOn(); static void ErrorOff(); static bool GetErrorFlag(); protected: private: }; // Here we define function this is the only way to be able to pass // stuff with indirection like: // gdcmDebug( "my message:" << i << '\t' ); // You cannot use function unless you use vnsprintf ... // __FUNCTION is not always defined by preprocessor // In c++ we should use __PRETTY_FUNCTION__ instead... #ifdef GDCM_CXX_HAS_FUNCTION // Handle particular case for GNU C++ which also defines __PRETTY_FUNCTION__ // which is a lot nice in C++ #ifdef __BORLANDC__ # define __FUNCTION__ __FUNC__ #endif #ifdef __GNUC__ # define GDCM_FUNCTION __PRETTY_FUNCTION__ #else # define GDCM_FUNCTION __FUNCTION__ #endif //__GNUC__ #else # define GDCM_FUNCTION "" #endif //GDCM_CXX_HAS_FUNCTION /** * \brief Debug * @param msg message part */ #if defined(NDEBUG) && !defined(GDCM_ALWAYS_TRACE_MACRO) #define gdcmDebugMacro(msg) GDCM_NOOP_STATEMENT #else #define gdcmDebugMacro(msg) \ { \ if( gdcm::Trace::GetDebugFlag() ) \ { \ std::ostringstream osmacro; \ osmacro << "Debug: In " __FILE__ ", line " << __LINE__ \ << ", function " << GDCM_FUNCTION << '\n' \ << "Last system error was: " \ << gdcm::System::GetLastSystemError() << '\n' << msg; \ std::ostream &_os = gdcm::Trace::GetDebugStream(); \ _os << osmacro.str() << "\n\n" << std::endl; \ } \ } \ GDCM_NOOP_STATEMENT #endif //NDEBUG /** * \brief Warning * @param msg message part */ #if defined(NDEBUG) && !defined(GDCM_ALWAYS_TRACE_MACRO) #define gdcmWarningMacro(msg) GDCM_NOOP_STATEMENT #else #define gdcmWarningMacro(msg) \ { \ if( gdcm::Trace::GetWarningFlag() ) \ { \ std::ostringstream osmacro; \ osmacro << "Warning: In " __FILE__ ", line " << __LINE__ \ << ", function " << GDCM_FUNCTION << "\n" \ << msg << "\n\n"; \ std::ostream &_os = gdcm::Trace::GetWarningStream(); \ _os << osmacro.str() << std::endl; \ } \ } \ GDCM_NOOP_STATEMENT #endif //NDEBUG /** * \brief Error this is pretty bad, more than just warning * It could mean lost of data, something not handle... * @param msg second message part */ #if defined(NDEBUG) && !defined(GDCM_ALWAYS_TRACE_MACRO) #define gdcmErrorMacro(msg) GDCM_NOOP_STATEMENT #else #define gdcmErrorMacro(msg) \ { \ if( gdcm::Trace::GetErrorFlag() ) \ { \ std::ostringstream osmacro; \ osmacro << "Error: In " __FILE__ ", line " << __LINE__ \ << ", function " << GDCM_FUNCTION << '\n' \ << msg << "\n\n"; \ std::ostream &_os = gdcm::Trace::GetErrorStream(); \ _os << osmacro.str() << std::endl; \ } \ } \ GDCM_NOOP_STATEMENT #endif //NDEBUG /** * \brief Assert * @param arg argument to test * An easy solution to pass also a message is to do: * gdcmAssertMacro( "my message" && 2 < 3 ) */ #if defined(NDEBUG) && !defined(GDCM_ALWAYS_TRACE_MACRO) #define gdcmAssertMacro(arg) GDCM_NOOP_STATEMENT #else #define gdcmAssertMacro(arg) \ { \ if( !(arg) ) \ { \ std::ostringstream osmacro; \ osmacro << "Assert: In " __FILE__ ", line " << __LINE__ \ << ", function " << GDCM_FUNCTION \ << "\n\n"; \ std::ostream &_os = gdcm::Trace::GetErrorStream(); \ _os << osmacro.str() << std::endl; \ assert ( arg ); \ } \ } \ GDCM_NOOP_STATEMENT #endif //NDEBUG /** * \brief AssertAlways * @param arg argument to test * An easy solution to pass also a message is to do: * gdcmAssertMacro( "my message" && 2 < 3 ) */ #if defined(NDEBUG) // User asked for release compilation, but still need to report // if grave issue. #define gdcmAssertAlwaysMacro(arg) \ { \ if( !(arg) ) \ { \ std::ostringstream osmacro; \ osmacro << "Assert: In " __FILE__ ", line " << __LINE__ \ << ", function " << GDCM_FUNCTION \ << "\n\n"; \ throw osmacro.str(); \ } \ } \ GDCM_NOOP_STATEMENT #else // Simply reproduce gdcmAssertMacro behavior: #define gdcmAssertAlwaysMacro(arg) gdcmAssertMacro(arg) #endif //NDEBUG } // end namespace gdcm //----------------------------------------------------------------------------- #endif //GDCMTRACE_H