portability/debug.hpp
#ifndef STLPLUS_DEBUG
#define STLPLUS_DEBUG
////////////////////////////////////////////////////////////////////////////////
// Author: Andy Rushton
// Copyright: (c) Southampton University 1999-2004
// (c) Andy Rushton 2004 onwards
// License: BSD License, see ../docs/license.html
// Set of simple debug utilities, all of which are switched off by the
// NDEBUG compiler directive
////////////////////////////////////////////////////////////////////////////////
#include "portability_fixes.hpp"
#include <stdexcept>
#include <string>
////////////////////////////////////////////////////////////////////////////////
// Problem with missing __FUNCTION__ macro
////////////////////////////////////////////////////////////////////////////////
// this macro is used in debugging but was missing in Visual Studio prior to version 7
#if defined(_MSC_VER) && (_MSC_VER < 1300)
#define __FUNCTION__ 0
#endif
// old versions of Borland compiler defined a macro __FUNC__ but more recent ones define __FUNCTION__
// I'm not sure at what version this change was made - assumed C++ Builder 6.32
#if defined(__BORLANDC__) && (__BORLANDC__ < 1585)
#define __FUNCTION__ __FUNC__
#endif
////////////////////////////////////////////////////////////////////////////////
// Exception thrown if an assertion fails
namespace stlplus
{
class assert_failed : public std::logic_error
{
public:
assert_failed(const char* file, int line, const char* function, const char* message) ;
~assert_failed(void) throw();
};
} // end namespace stlplus
////////////////////////////////////////////////////////////////////////////////
// The macros used in debugging
#ifndef NDEBUG
#define DEBUG_TRACE stlplus::debug_trace stlplus_debug_trace(__FILE__,__LINE__,__FUNCTION__)
#define IF_DEBUG(stmts) {if (stlplus_debug_trace.debug()){stlplus_debug_trace.prefix(__LINE__);stmts;}}
#define DEBUG_REPORT(str) IF_DEBUG(stlplus_debug_trace.report(__LINE__,str))
#define DEBUG_ERROR(str) stlplus_debug_trace.error(__LINE__,str)
#define DEBUG_STACKDUMP(str) stlplus_debug_trace.stackdump(__LINE__,str)
#define DEBUG_ON stlplus_debug_trace.debug_on(__LINE__,true)
#define DEBUG_ON_LOCAL stlplus_debug_trace.debug_on(__LINE__,false)
#define DEBUG_ON_GLOBAL stlplus::debug_global(__FILE__,__LINE__,__FUNCTION__,true)
#define DEBUG_OFF_GLOBAL stlplus::debug_global(__FILE__,__LINE__,__FUNCTION__,false)
#define DEBUG_OFF stlplus_debug_trace.debug_off(__LINE__)
#define DEBUG_ASSERT(test) if (!(test))stlplus::debug_assert_fail(__FILE__,__LINE__,__FUNCTION__,#test)
#else
#define DEBUG_TRACE
#define IF_DEBUG(stmts)
#define DEBUG_REPORT(str)
#define DEBUG_ERROR(str)
#define DEBUG_STACKDUMP(str)
#define DEBUG_ON
#define DEBUG_ON_LOCAL
#define DEBUG_ON_GLOBAL
#define DEBUG_OFF_GLOBAL
#define DEBUG_OFF
#define DEBUG_ASSERT(test)
#endif
////////////////////////////////////////////////////////////////////////////////
// infrastructure - don't use directly
namespace stlplus
{
void debug_global(const char* file, int line, const char* function, bool state = true);
// exceptions: assert_failed
void debug_assert_fail(const char* file, int line, const char* function, const char* test) ;
class debug_trace
{
public:
debug_trace(const char* f, int l, const char* fn);
~debug_trace(void);
const char* file(void) const;
int line(void) const;
bool debug(void) const;
void debug_on(int l, bool recurse);
void debug_off(int l);
void prefix(int l) const;
void report(int l, const std::string& message) const;
void report(const std::string& message) const;
void error(int l, const std::string& message) const;
void error(const std::string& message) const;
void stackdump(int l, const std::string& message) const;
void stackdump(const std::string& message) const;
void stackdump(void) const;
private:
const char* m_file;
int m_line;
const char* m_function;
unsigned m_depth;
const debug_trace* m_last;
bool m_dbg;
bool m_old;
void do_report(int l, const std::string& message) const;
void do_report(const std::string& message) const;
// make this class uncopyable
debug_trace(const debug_trace&);
debug_trace& operator = (const debug_trace&);
};
} // end namespace stlplus
////////////////////////////////////////////////////////////////////////////////
#endif