From c8e7037ed1ec34b96a6b2975ade039febdecaf10 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 7 May 2018 15:04:18 +0100 Subject: [PATCH] Make some custom changes to Catch2 for a better experience * Add CATCH_CONFIG_FORCE_FALLBACK_STRINGIFIER to force use of ToStr in all cases. We can handle ints, etc, we don't need ostringstream, and this allows us to handle enums that would otherwise just be printed as their integer value. * Add CATCH_CONFIG_INLINE_DEBUG_BREAK which restores the Catch 1.0 behaviour of debugbreaks happening in macros and so in-line at the actual site failure. So the debugger stops on the CHECK() or REQUIRE() call instead of inside AssertionHandler::complete() Cherry pick from https://github.com/baldurk/renderdoc/commit/4232736fc21fc6a13a4de6997a5ae106598b225f --- renderdoc/3rdparty/catch/official/catch.hpp | 147 +++++++++++++------- 1 file changed, 93 insertions(+), 54 deletions(-) diff --git a/renderdoc/3rdparty/catch/official/catch.hpp b/renderdoc/3rdparty/catch/official/catch.hpp index 7e706f947..8ef0132d5 100644 --- a/renderdoc/3rdparty/catch/official/catch.hpp +++ b/renderdoc/3rdparty/catch/official/catch.hpp @@ -8,6 +8,19 @@ * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ + +/* + * Includes RenderDoc customisations + * Add CATCH_CONFIG_FORCE_FALLBACK_STRINGIFIER to force use of ToStr in + all cases. We can handle ints, etc, we don't need ostringstream, and + this allows us to handle enums that would otherwise just be printed as + their integer value. + * Add CATCH_CONFIG_INLINE_DEBUG_BREAK which restores the Catch 1.0 + behaviour of debugbreaks happening in macros and so in-line at the + actual site failure. So the debugger stops on the CHECK() or REQUIRE() + call instead of inside AssertionHandler::complete() +* https://github.com/baldurk/renderdoc/commit/4232736fc21fc6a13a4de6997a5ae106598b225f +*/ #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED // start catch.hpp @@ -1611,6 +1624,13 @@ namespace Catch { // If we decide for C++14, change these to enable_if_ts template struct StringMaker { +#if defined(CATCH_CONFIG_FORCE_FALLBACK_STRINGIFIER) + static + typename std::string + convert( const T& value ) { + return CATCH_CONFIG_FALLBACK_STRINGIFIER(value); + } +#else template static typename std::enable_if<::Catch::Detail::IsStreamInsertable::value, std::string>::type @@ -1632,6 +1652,7 @@ namespace Catch { return CATCH_CONFIG_FALLBACK_STRINGIFIER(value); #endif } +#endif }; namespace Detail { @@ -2578,6 +2599,10 @@ namespace Catch { void complete(); void setCompleted(); +#if defined(CATCH_CONFIG_INLINE_DEBUG_BREAK) + bool shouldDebugBreak() { return m_reaction.shouldDebugBreak; } +#endif + // query auto allowThrows() const -> bool; }; @@ -2672,6 +2697,60 @@ namespace Catch { } // end namespace Catch // end catch_message.h +// start catch_debugger.h + +namespace Catch { + bool isDebuggerActive(); +} + +#ifdef CATCH_PLATFORM_MAC + + #if defined(__i386__) || defined(__x86_64__) + #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ + #elif defined(__aarch64__) + #define CATCH_TRAP() __asm__(".inst 0xd4200000") + #endif + +#elif defined(CATCH_PLATFORM_IPHONE) + + // use inline assembler + #if defined(__i386__) || defined(__x86_64__) + #define CATCH_TRAP() __asm__("int $3") + #elif defined(__aarch64__) + #define CATCH_TRAP() __asm__(".inst 0xd4200000") + #elif defined(__arm__) && !defined(__thumb__) + #define CATCH_TRAP() __asm__(".inst 0xe7f001f0") + #elif defined(__arm__) && defined(__thumb__) + #define CATCH_TRAP() __asm__(".inst 0xde01") + #endif + +#elif defined(CATCH_PLATFORM_LINUX) + // If we can use inline assembler, do it because this allows us to break + // directly at the location of the failing check instead of breaking inside + // raise() called from it, i.e. one stack frame below. + #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) + #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ + #else // Fall back to the generic way. + #include + + #define CATCH_TRAP() raise(SIGTRAP) + #endif +#elif defined(_MSC_VER) + #define CATCH_TRAP() __debugbreak() +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) void __stdcall DebugBreak(); + #define CATCH_TRAP() DebugBreak() +#endif + +#ifndef CATCH_BREAK_INTO_DEBUGGER + #ifdef CATCH_TRAP + #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }() + #else + #define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing() + #endif +#endif + +// end catch_debugger.h #if !defined(CATCH_CONFIG_DISABLE) #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) @@ -2695,8 +2774,20 @@ namespace Catch { #endif +#if defined(CATCH_CONFIG_INLINE_DEBUG_BREAK) + +#define INTERNAL_CATCH_REACT( handler ) \ + if(handler.shouldDebugBreak()) { \ + CATCH_BREAK_INTO_DEBUGGER(); \ + } \ + handler.complete(); + +#else + #define INTERNAL_CATCH_REACT( handler ) handler.complete(); +#endif + /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ do { \ @@ -7931,60 +8022,6 @@ std::string StringMaker::convert(Catch::Detail::Approx co // end catch_approx.cpp // start catch_assertionhandler.cpp -// start catch_debugger.h - -namespace Catch { - bool isDebuggerActive(); -} - -#ifdef CATCH_PLATFORM_MAC - - #if defined(__i386__) || defined(__x86_64__) - #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ - #elif defined(__aarch64__) - #define CATCH_TRAP() __asm__(".inst 0xd4200000") - #endif - -#elif defined(CATCH_PLATFORM_IPHONE) - - // use inline assembler - #if defined(__i386__) || defined(__x86_64__) - #define CATCH_TRAP() __asm__("int $3") - #elif defined(__aarch64__) - #define CATCH_TRAP() __asm__(".inst 0xd4200000") - #elif defined(__arm__) && !defined(__thumb__) - #define CATCH_TRAP() __asm__(".inst 0xe7f001f0") - #elif defined(__arm__) && defined(__thumb__) - #define CATCH_TRAP() __asm__(".inst 0xde01") - #endif - -#elif defined(CATCH_PLATFORM_LINUX) - // If we can use inline assembler, do it because this allows us to break - // directly at the location of the failing check instead of breaking inside - // raise() called from it, i.e. one stack frame below. - #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) - #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ - #else // Fall back to the generic way. - #include - - #define CATCH_TRAP() raise(SIGTRAP) - #endif -#elif defined(_MSC_VER) - #define CATCH_TRAP() __debugbreak() -#elif defined(__MINGW32__) - extern "C" __declspec(dllimport) void __stdcall DebugBreak(); - #define CATCH_TRAP() DebugBreak() -#endif - -#ifndef CATCH_BREAK_INTO_DEBUGGER - #ifdef CATCH_TRAP - #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }() - #else - #define CATCH_BREAK_INTO_DEBUGGER() []{}() - #endif -#endif - -// end catch_debugger.h // start catch_run_context.h // start catch_fatal_condition.h @@ -8234,6 +8271,7 @@ namespace Catch { void AssertionHandler::complete() { setCompleted(); +#if !defined(CATCH_CONFIG_INLINE_DEBUG_BREAK) if( m_reaction.shouldDebugBreak ) { // If you find your debugger stopping you here then go one level up on the @@ -8242,6 +8280,7 @@ namespace Catch { // (To go back to the test and change execution, jump over the throw, next) CATCH_BREAK_INTO_DEBUGGER(); } +#endif if (m_reaction.shouldThrow) { #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) throw Catch::TestFailureException();