Bugcheck.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //
  2. // Bugcheck.h
  3. //
  4. // $Id: //poco/1.4/Foundation/include/Poco/Bugcheck.h#1 $
  5. //
  6. // Library: Foundation
  7. // Package: Core
  8. // Module: Bugcheck
  9. //
  10. // Definition of the Bugcheck class and the self-testing macros.
  11. //
  12. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // SPDX-License-Identifier: BSL-1.0
  16. //
  17. #ifndef Foundation_Bugcheck_INCLUDED
  18. #define Foundation_Bugcheck_INCLUDED
  19. #include "Poco/Foundation.h"
  20. #include <string>
  21. #if defined(_DEBUG)
  22. # include <iostream>
  23. #endif
  24. namespace Poco {
  25. class Foundation_API Bugcheck
  26. /// This class provides some static methods that are
  27. /// used by the
  28. /// poco_assert_dbg(), poco_assert(), poco_check_ptr(),
  29. /// poco_bugcheck() and poco_unexpected() macros.
  30. /// You should not invoke these methods
  31. /// directly. Use the macros instead, as they
  32. /// automatically provide useful context information.
  33. {
  34. public:
  35. static void assertion(const char* cond, const char* file, int line, const char* text = 0);
  36. /// An assertion failed. Break into the debugger, if
  37. /// possible, then throw an AssertionViolationException.
  38. static void nullPointer(const char* ptr, const char* file, int line);
  39. /// An null pointer was encountered. Break into the debugger, if
  40. /// possible, then throw an NullPointerException.
  41. static void bugcheck(const char* file, int line);
  42. /// An internal error was encountered. Break into the debugger, if
  43. /// possible, then throw an BugcheckException.
  44. static void bugcheck(const char* msg, const char* file, int line);
  45. /// An internal error was encountered. Break into the debugger, if
  46. /// possible, then throw an BugcheckException.
  47. static void unexpected(const char* file, int line);
  48. /// An exception was caught in a destructor. Break into debugger,
  49. /// if possible and report exception. Must only be called from
  50. /// within a catch () block as it rethrows the exception to
  51. /// determine its class.
  52. static void debugger(const char* file, int line);
  53. /// An internal error was encountered. Break into the debugger, if
  54. /// possible.
  55. static void debugger(const char* msg, const char* file, int line);
  56. /// An internal error was encountered. Break into the debugger, if
  57. /// possible.
  58. protected:
  59. static std::string what(const char* msg, const char* file, int line, const char* text = 0);
  60. };
  61. } // namespace Poco
  62. //
  63. // useful macros (these automatically supply line number and file name)
  64. //
  65. #if defined(_DEBUG)
  66. #define poco_assert_dbg(cond) \
  67. if (!(cond)) Poco::Bugcheck::assertion(#cond, __FILE__, __LINE__); else (void) 0
  68. #define poco_assert_msg_dbg(cond, text) \
  69. if (!(cond)) Poco::Bugcheck::assertion(#cond, __FILE__, __LINE__, text); else (void) 0
  70. #else
  71. #define poco_assert_msg_dbg(cond, text)
  72. #define poco_assert_dbg(cond)
  73. #endif
  74. #define poco_assert(cond) \
  75. if (!(cond)) Poco::Bugcheck::assertion(#cond, __FILE__, __LINE__); else (void) 0
  76. #define poco_assert_msg(cond, text) \
  77. if (!(cond)) Poco::Bugcheck::assertion(#cond, __FILE__, __LINE__, text); else (void) 0
  78. #define poco_check_ptr(ptr) \
  79. if (!(ptr)) Poco::Bugcheck::nullPointer(#ptr, __FILE__, __LINE__); else (void) 0
  80. #define poco_bugcheck() \
  81. Poco::Bugcheck::bugcheck(__FILE__, __LINE__)
  82. #define poco_bugcheck_msg(msg) \
  83. Poco::Bugcheck::bugcheck(msg, __FILE__, __LINE__)
  84. #define poco_unexpected() \
  85. Poco::Bugcheck::unexpected(__FILE__, __LINE__);
  86. #define poco_debugger() \
  87. Poco::Bugcheck::debugger(__FILE__, __LINE__)
  88. #define poco_debugger_msg(msg) \
  89. Poco::Bugcheck::debugger(msg, __FILE__, __LINE__)
  90. #if defined(_DEBUG)
  91. # define poco_stdout_dbg(outstr) \
  92. std::cout << __FILE__ << '(' << std::dec << __LINE__ << "):" << outstr << std::endl;
  93. #else
  94. # define poco_stdout_dbg(outstr)
  95. #endif
  96. #if defined(_DEBUG)
  97. # define poco_stderr_dbg(outstr) \
  98. std::cerr << __FILE__ << '(' << std::dec << __LINE__ << "):" << outstr << std::endl;
  99. #else
  100. # define poco_stderr_dbg(outstr)
  101. #endif
  102. //
  103. // poco_static_assert
  104. //
  105. // The following was ported from <boost/static_assert.hpp>
  106. //
  107. GCC_DIAG_OFF(unused-local-typedefs) // supress numerous gcc warnings
  108. template <bool x>
  109. struct POCO_STATIC_ASSERTION_FAILURE;
  110. template <>
  111. struct POCO_STATIC_ASSERTION_FAILURE<true>
  112. {
  113. enum
  114. {
  115. value = 1
  116. };
  117. };
  118. template <int x>
  119. struct poco_static_assert_test
  120. {
  121. };
  122. #if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4))
  123. #define poco_static_assert(B) \
  124. typedef char POCO_JOIN(poco_static_assert_typedef_, __LINE__) \
  125. [POCO_STATIC_ASSERTION_FAILURE<(bool) (B)>::value]
  126. #else
  127. #define poco_static_assert(B) \
  128. typedef poco_static_assert_test<sizeof(POCO_STATIC_ASSERTION_FAILURE<(bool) (B)>)> \
  129. POCO_JOIN(poco_static_assert_typedef_, __LINE__)
  130. #endif
  131. #endif // Foundation_Bugcheck_INCLUDED