mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-14 02:31:12 +00:00
Update Catch to version 2.13.7
This commit is contained in:
+312
-273
@@ -1,26 +1,13 @@
|
||||
/*
|
||||
* Catch v2.13.4
|
||||
* Generated: 2020-12-29 14:48:00.116107
|
||||
* Catch v2.13.7
|
||||
* Generated: 2021-07-28 20:29:27.753164
|
||||
* ----------------------------------------------------------
|
||||
* This file has been merged from multiple headers. Please don't edit it directly
|
||||
* Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved.
|
||||
* Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
@@ -28,7 +15,7 @@
|
||||
|
||||
#define CATCH_VERSION_MAJOR 2
|
||||
#define CATCH_VERSION_MINOR 13
|
||||
#define CATCH_VERSION_PATCH 4
|
||||
#define CATCH_VERSION_PATCH 7
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang system_header
|
||||
@@ -79,13 +66,16 @@
|
||||
#if !defined(CATCH_CONFIG_IMPL_ONLY)
|
||||
// start catch_platform.h
|
||||
|
||||
// See e.g.:
|
||||
// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html
|
||||
#ifdef __APPLE__
|
||||
# include <TargetConditionals.h>
|
||||
# if TARGET_OS_OSX == 1
|
||||
# define CATCH_PLATFORM_MAC
|
||||
# elif TARGET_OS_IPHONE == 1
|
||||
# define CATCH_PLATFORM_IPHONE
|
||||
# endif
|
||||
# include <TargetConditionals.h>
|
||||
# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \
|
||||
(defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)
|
||||
# define CATCH_PLATFORM_MAC
|
||||
# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
|
||||
# define CATCH_PLATFORM_IPHONE
|
||||
# endif
|
||||
|
||||
#elif defined(linux) || defined(__linux) || defined(__linux__)
|
||||
# define CATCH_PLATFORM_LINUX
|
||||
@@ -145,9 +135,9 @@ namespace Catch {
|
||||
|
||||
#endif
|
||||
|
||||
// We have to avoid both ICC and Clang, because they try to mask themselves
|
||||
// as gcc, and we want only GCC in this block
|
||||
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__)
|
||||
// Only GCC compiler should be used in this block, so other compilers trying to
|
||||
// mask themselves as GCC should be ignored.
|
||||
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)
|
||||
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
|
||||
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
|
||||
|
||||
@@ -336,7 +326,7 @@ namespace Catch {
|
||||
// Check if byte is available and usable
|
||||
# if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
|
||||
# include <cstddef>
|
||||
# if __cpp_lib_byte > 0
|
||||
# if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)
|
||||
# define CATCH_INTERNAL_CONFIG_CPP17_BYTE
|
||||
# endif
|
||||
# endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
|
||||
@@ -1621,13 +1611,6 @@ namespace Catch {
|
||||
// If we decide for C++14, change these to enable_if_ts
|
||||
template <typename T, typename = void>
|
||||
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 <typename Fake = T>
|
||||
static
|
||||
typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type
|
||||
@@ -1649,7 +1632,6 @@ namespace Catch {
|
||||
return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace Detail {
|
||||
@@ -2596,10 +2578,6 @@ 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;
|
||||
};
|
||||
@@ -2694,60 +2672,6 @@ 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 <signal.h>
|
||||
|
||||
#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)
|
||||
@@ -2771,20 +2695,8 @@ 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 { \
|
||||
@@ -5546,6 +5458,8 @@ namespace Catch {
|
||||
} // namespace Catch
|
||||
|
||||
// end catch_outlier_classification.hpp
|
||||
|
||||
#include <iterator>
|
||||
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
|
||||
|
||||
#include <string>
|
||||
@@ -6430,9 +6344,10 @@ namespace Catch {
|
||||
|
||||
void writeTestCase(TestCaseNode const& testCaseNode);
|
||||
|
||||
void writeSection(std::string const& className,
|
||||
std::string const& rootName,
|
||||
SectionNode const& sectionNode);
|
||||
void writeSection( std::string const& className,
|
||||
std::string const& rootName,
|
||||
SectionNode const& sectionNode,
|
||||
bool testOkToFail );
|
||||
|
||||
void writeAssertions(SectionNode const& sectionNode);
|
||||
void writeAssertion(AssertionStats const& stats);
|
||||
@@ -6967,7 +6882,7 @@ namespace Catch {
|
||||
}
|
||||
iters *= 2;
|
||||
}
|
||||
throw optimized_away_error{};
|
||||
Catch::throw_exception(optimized_away_error{});
|
||||
}
|
||||
} // namespace Detail
|
||||
} // namespace Benchmark
|
||||
@@ -6975,6 +6890,7 @@ namespace Catch {
|
||||
|
||||
// end catch_run_for_at_least.hpp
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
namespace Catch {
|
||||
namespace Benchmark {
|
||||
@@ -7145,8 +7061,8 @@ namespace Catch {
|
||||
double b2 = bias - z1;
|
||||
double a1 = a(b1);
|
||||
double a2 = a(b2);
|
||||
auto lo = std::max(cumn(a1), 0);
|
||||
auto hi = std::min(cumn(a2), n - 1);
|
||||
auto lo = (std::max)(cumn(a1), 0);
|
||||
auto hi = (std::min)(cumn(a2), n - 1);
|
||||
|
||||
return { point, resample[lo], resample[hi], confidence_level };
|
||||
}
|
||||
@@ -7215,7 +7131,9 @@ namespace Catch {
|
||||
}
|
||||
template <typename Clock>
|
||||
EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {
|
||||
auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit));
|
||||
auto time_limit = (std::min)(
|
||||
resolution * clock_cost_estimation_tick_limit,
|
||||
FloatDuration<Clock>(clock_cost_estimation_time_limit));
|
||||
auto time_clock = [](int k) {
|
||||
return Detail::measure<Clock>([k] {
|
||||
for (int i = 0; i < k; ++i) {
|
||||
@@ -7862,7 +7780,7 @@ namespace Catch {
|
||||
double sb = stddev.point;
|
||||
double mn = mean.point / n;
|
||||
double mg_min = mn / 2.;
|
||||
double sg = std::min(mg_min / 4., sb / std::sqrt(n));
|
||||
double sg = (std::min)(mg_min / 4., sb / std::sqrt(n));
|
||||
double sg2 = sg * sg;
|
||||
double sb2 = sb * sb;
|
||||
|
||||
@@ -7881,7 +7799,7 @@ namespace Catch {
|
||||
return (nc / n) * (sb2 - nc * sg2);
|
||||
};
|
||||
|
||||
return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2;
|
||||
return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;
|
||||
}
|
||||
|
||||
bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
|
||||
@@ -8013,90 +7931,116 @@ std::string StringMaker<Catch::Detail::Approx>::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 <signal.h>
|
||||
|
||||
#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
|
||||
|
||||
// start catch_windows_h_proxy.h
|
||||
|
||||
|
||||
#if defined(CATCH_PLATFORM_WINDOWS)
|
||||
|
||||
#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
|
||||
# define CATCH_DEFINED_NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
|
||||
# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifdef __AFXDLL
|
||||
#include <AfxWin.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_DEFINED_NOMINMAX
|
||||
# undef NOMINMAX
|
||||
#endif
|
||||
#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
|
||||
# undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#endif // defined(CATCH_PLATFORM_WINDOWS)
|
||||
|
||||
// end catch_windows_h_proxy.h
|
||||
#if defined( CATCH_CONFIG_WINDOWS_SEH )
|
||||
#include <cassert>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct FatalConditionHandler {
|
||||
|
||||
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo);
|
||||
FatalConditionHandler();
|
||||
static void reset();
|
||||
~FatalConditionHandler();
|
||||
|
||||
private:
|
||||
static bool isSet;
|
||||
static ULONG guaranteeSize;
|
||||
static PVOID exceptionHandlerHandle;
|
||||
};
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#elif defined ( CATCH_CONFIG_POSIX_SIGNALS )
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct FatalConditionHandler {
|
||||
|
||||
static bool isSet;
|
||||
static struct sigaction oldSigActions[];
|
||||
static stack_t oldSigStack;
|
||||
static char altStackMem[];
|
||||
|
||||
static void handleSignal( int sig );
|
||||
// Wrapper for platform-specific fatal error (signals/SEH) handlers
|
||||
//
|
||||
// Tries to be cooperative with other handlers, and not step over
|
||||
// other handlers. This means that unknown structured exceptions
|
||||
// are passed on, previous signal handlers are called, and so on.
|
||||
//
|
||||
// Can only be instantiated once, and assumes that once a signal
|
||||
// is caught, the binary will end up terminating. Thus, there
|
||||
class FatalConditionHandler {
|
||||
bool m_started = false;
|
||||
|
||||
// Install/disengage implementation for specific platform.
|
||||
// Should be if-defed to work on current platform, can assume
|
||||
// engage-disengage 1:1 pairing.
|
||||
void engage_platform();
|
||||
void disengage_platform();
|
||||
public:
|
||||
// Should also have platform-specific implementations as needed
|
||||
FatalConditionHandler();
|
||||
~FatalConditionHandler();
|
||||
static void reset();
|
||||
|
||||
void engage() {
|
||||
assert(!m_started && "Handler cannot be installed twice.");
|
||||
m_started = true;
|
||||
engage_platform();
|
||||
}
|
||||
|
||||
void disengage() {
|
||||
assert(m_started && "Handler cannot be uninstalled without being installed first");
|
||||
m_started = false;
|
||||
disengage_platform();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#else
|
||||
|
||||
namespace Catch {
|
||||
struct FatalConditionHandler {
|
||||
void reset();
|
||||
//! Simple RAII guard for (dis)engaging the FatalConditionHandler
|
||||
class FatalConditionHandlerGuard {
|
||||
FatalConditionHandler* m_handler;
|
||||
public:
|
||||
FatalConditionHandlerGuard(FatalConditionHandler* handler):
|
||||
m_handler(handler) {
|
||||
m_handler->engage();
|
||||
}
|
||||
~FatalConditionHandlerGuard() {
|
||||
m_handler->disengage();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
} // end namespace Catch
|
||||
|
||||
// end catch_fatal_condition.h
|
||||
#include <string>
|
||||
@@ -8222,6 +8166,7 @@ namespace Catch {
|
||||
std::vector<SectionEndInfo> m_unfinishedSections;
|
||||
std::vector<ITracker*> m_activeSections;
|
||||
TrackerContext m_trackerContext;
|
||||
FatalConditionHandler m_fatalConditionhandler;
|
||||
bool m_lastAssertionPassed = false;
|
||||
bool m_shouldReportUnexpected = true;
|
||||
bool m_includeSuccessfulResults;
|
||||
@@ -8289,7 +8234,6 @@ 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
|
||||
@@ -8298,7 +8242,6 @@ 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();
|
||||
@@ -10096,6 +10039,36 @@ namespace Catch {
|
||||
}
|
||||
|
||||
// end catch_errno_guard.h
|
||||
// start catch_windows_h_proxy.h
|
||||
|
||||
|
||||
#if defined(CATCH_PLATFORM_WINDOWS)
|
||||
|
||||
#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
|
||||
# define CATCH_DEFINED_NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
|
||||
# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifdef __AFXDLL
|
||||
#include <AfxWin.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef CATCH_DEFINED_NOMINMAX
|
||||
# undef NOMINMAX
|
||||
#endif
|
||||
#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN
|
||||
# undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#endif // defined(CATCH_PLATFORM_WINDOWS)
|
||||
|
||||
// end catch_windows_h_proxy.h
|
||||
#include <sstream>
|
||||
|
||||
namespace Catch {
|
||||
@@ -10612,7 +10585,7 @@ namespace Catch {
|
||||
// Extracts the actual name part of an enum instance
|
||||
// In other words, it returns the Blue part of Bikeshed::Colour::Blue
|
||||
StringRef extractInstanceName(StringRef enumInstance) {
|
||||
// Find last occurence of ":"
|
||||
// Find last occurrence of ":"
|
||||
size_t name_start = enumInstance.size();
|
||||
while (name_start > 0 && enumInstance[name_start - 1] != ':') {
|
||||
--name_start;
|
||||
@@ -10774,25 +10747,47 @@ namespace Catch {
|
||||
// end catch_exception_translator_registry.cpp
|
||||
// start catch_fatal_condition.cpp
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
#include <algorithm>
|
||||
|
||||
#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS )
|
||||
|
||||
namespace Catch {
|
||||
|
||||
// If neither SEH nor signal handling is required, the handler impls
|
||||
// do not have to do anything, and can be empty.
|
||||
void FatalConditionHandler::engage_platform() {}
|
||||
void FatalConditionHandler::disengage_platform() {}
|
||||
FatalConditionHandler::FatalConditionHandler() = default;
|
||||
FatalConditionHandler::~FatalConditionHandler() = default;
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS
|
||||
|
||||
#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS )
|
||||
#error "Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time"
|
||||
#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS
|
||||
|
||||
#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )
|
||||
|
||||
namespace {
|
||||
// Report the error condition
|
||||
//! Signals fatal error message to the run context
|
||||
void reportFatal( char const * const message ) {
|
||||
Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // signals/SEH handling
|
||||
//! Minimal size Catch2 needs for its own fatal error handling.
|
||||
//! Picked anecdotally, so it might not be sufficient on all
|
||||
//! platforms, and for all configurations.
|
||||
constexpr std::size_t minStackSizeForErrors = 32 * 1024;
|
||||
} // end unnamed namespace
|
||||
|
||||
#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS
|
||||
|
||||
#if defined( CATCH_CONFIG_WINDOWS_SEH )
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct SignalDefs { DWORD id; const char* name; };
|
||||
|
||||
// There is no 1-1 mapping between signals and windows exceptions.
|
||||
@@ -10805,7 +10800,7 @@ namespace Catch {
|
||||
{ static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" },
|
||||
};
|
||||
|
||||
LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||
static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||
for (auto const& def : signalDefs) {
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {
|
||||
reportFatal(def.name);
|
||||
@@ -10816,38 +10811,50 @@ namespace Catch {
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
FatalConditionHandler::FatalConditionHandler() {
|
||||
isSet = true;
|
||||
// 32k seems enough for Catch to handle stack overflow,
|
||||
// but the value was found experimentally, so there is no strong guarantee
|
||||
guaranteeSize = 32 * 1024;
|
||||
exceptionHandlerHandle = nullptr;
|
||||
// Register as first handler in current chain
|
||||
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
||||
// Pass in guarantee size to be filled
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
}
|
||||
// Since we do not support multiple instantiations, we put these
|
||||
// into global variables and rely on cleaning them up in outlined
|
||||
// constructors/destructors
|
||||
static PVOID exceptionHandlerHandle = nullptr;
|
||||
|
||||
void FatalConditionHandler::reset() {
|
||||
if (isSet) {
|
||||
RemoveVectoredExceptionHandler(exceptionHandlerHandle);
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
exceptionHandlerHandle = nullptr;
|
||||
isSet = false;
|
||||
// For MSVC, we reserve part of the stack memory for handling
|
||||
// memory overflow structured exception.
|
||||
FatalConditionHandler::FatalConditionHandler() {
|
||||
ULONG guaranteeSize = static_cast<ULONG>(minStackSizeForErrors);
|
||||
if (!SetThreadStackGuarantee(&guaranteeSize)) {
|
||||
// We do not want to fully error out, because needing
|
||||
// the stack reserve should be rare enough anyway.
|
||||
Catch::cerr()
|
||||
<< "Failed to reserve piece of stack."
|
||||
<< " Stack overflows will not be reported successfully.";
|
||||
}
|
||||
}
|
||||
|
||||
FatalConditionHandler::~FatalConditionHandler() {
|
||||
reset();
|
||||
// We do not attempt to unset the stack guarantee, because
|
||||
// Windows does not support lowering the stack size guarantee.
|
||||
FatalConditionHandler::~FatalConditionHandler() = default;
|
||||
|
||||
void FatalConditionHandler::engage_platform() {
|
||||
// Register as first handler in current chain
|
||||
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
||||
if (!exceptionHandlerHandle) {
|
||||
CATCH_RUNTIME_ERROR("Could not register vectored exception handler");
|
||||
}
|
||||
}
|
||||
|
||||
bool FatalConditionHandler::isSet = false;
|
||||
ULONG FatalConditionHandler::guaranteeSize = 0;
|
||||
PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr;
|
||||
void FatalConditionHandler::disengage_platform() {
|
||||
if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
|
||||
CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler");
|
||||
}
|
||||
exceptionHandlerHandle = nullptr;
|
||||
}
|
||||
|
||||
} // namespace Catch
|
||||
} // end namespace Catch
|
||||
|
||||
#elif defined( CATCH_CONFIG_POSIX_SIGNALS )
|
||||
#endif // CATCH_CONFIG_WINDOWS_SEH
|
||||
|
||||
#if defined( CATCH_CONFIG_POSIX_SIGNALS )
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -10856,10 +10863,6 @@ namespace Catch {
|
||||
const char* name;
|
||||
};
|
||||
|
||||
// 32kb for the alternate stack seems to be sufficient. However, this value
|
||||
// is experimentally determined, so that's not guaranteed.
|
||||
static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
|
||||
|
||||
static SignalDefs signalDefs[] = {
|
||||
{ SIGINT, "SIGINT - Terminal interrupt signal" },
|
||||
{ SIGILL, "SIGILL - Illegal instruction signal" },
|
||||
@@ -10869,7 +10872,32 @@ namespace Catch {
|
||||
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
|
||||
};
|
||||
|
||||
void FatalConditionHandler::handleSignal( int sig ) {
|
||||
// Older GCCs trigger -Wmissing-field-initializers for T foo = {}
|
||||
// which is zero initialization, but not explicit. We want to avoid
|
||||
// that.
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
|
||||
static char* altStackMem = nullptr;
|
||||
static std::size_t altStackSize = 0;
|
||||
static stack_t oldSigStack{};
|
||||
static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};
|
||||
|
||||
static void restorePreviousSignalHandlers() {
|
||||
// We set signal handlers back to the previous ones. Hopefully
|
||||
// nobody overwrote them in the meantime, and doesn't expect
|
||||
// their signal handlers to live past ours given that they
|
||||
// installed them after ours..
|
||||
for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
|
||||
sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
|
||||
}
|
||||
// Return the old stack
|
||||
sigaltstack(&oldSigStack, nullptr);
|
||||
}
|
||||
|
||||
static void handleSignal( int sig ) {
|
||||
char const * name = "<unknown signal>";
|
||||
for (auto const& def : signalDefs) {
|
||||
if (sig == def.id) {
|
||||
@@ -10877,16 +10905,33 @@ namespace Catch {
|
||||
break;
|
||||
}
|
||||
}
|
||||
reset();
|
||||
reportFatal(name);
|
||||
// We need to restore previous signal handlers and let them do
|
||||
// their thing, so that the users can have the debugger break
|
||||
// when a signal is raised, and so on.
|
||||
restorePreviousSignalHandlers();
|
||||
reportFatal( name );
|
||||
raise( sig );
|
||||
}
|
||||
|
||||
FatalConditionHandler::FatalConditionHandler() {
|
||||
isSet = true;
|
||||
assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
|
||||
if (altStackSize == 0) {
|
||||
altStackSize = std::max(static_cast<size_t>(SIGSTKSZ), minStackSizeForErrors);
|
||||
}
|
||||
altStackMem = new char[altStackSize]();
|
||||
}
|
||||
|
||||
FatalConditionHandler::~FatalConditionHandler() {
|
||||
delete[] altStackMem;
|
||||
// We signal that another instance can be constructed by zeroing
|
||||
// out the pointer.
|
||||
altStackMem = nullptr;
|
||||
}
|
||||
|
||||
void FatalConditionHandler::engage_platform() {
|
||||
stack_t sigStack;
|
||||
sigStack.ss_sp = altStackMem;
|
||||
sigStack.ss_size = sigStackSize;
|
||||
sigStack.ss_size = altStackSize;
|
||||
sigStack.ss_flags = 0;
|
||||
sigaltstack(&sigStack, &oldSigStack);
|
||||
struct sigaction sa = { };
|
||||
@@ -10898,40 +10943,17 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
|
||||
FatalConditionHandler::~FatalConditionHandler() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void FatalConditionHandler::reset() {
|
||||
if( isSet ) {
|
||||
// Set signals back to previous values -- hopefully nobody overwrote them in the meantime
|
||||
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
|
||||
sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);
|
||||
}
|
||||
// Return the old stack
|
||||
sigaltstack(&oldSigStack, nullptr);
|
||||
isSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FatalConditionHandler::isSet = false;
|
||||
struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
|
||||
stack_t FatalConditionHandler::oldSigStack = {};
|
||||
char FatalConditionHandler::altStackMem[sigStackSize] = {};
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
#else
|
||||
|
||||
namespace Catch {
|
||||
void FatalConditionHandler::reset() {}
|
||||
}
|
||||
|
||||
#endif // signals/SEH handling
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
void FatalConditionHandler::disengage_platform() {
|
||||
restorePreviousSignalHandlers();
|
||||
}
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // CATCH_CONFIG_POSIX_SIGNALS
|
||||
// end catch_fatal_condition.cpp
|
||||
// start catch_generators.cpp
|
||||
|
||||
@@ -11486,7 +11508,8 @@ namespace {
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
auto ulpDiff = std::abs(lc - rc);
|
||||
// static cast as a workaround for IBM XLC
|
||||
auto ulpDiff = std::abs(static_cast<FP>(lc - rc));
|
||||
return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
|
||||
}
|
||||
|
||||
@@ -11660,7 +11683,6 @@ Floating::WithinRelMatcher WithinRel(float target) {
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
||||
// end catch_matchers_floating.cpp
|
||||
// start catch_matchers_generic.cpp
|
||||
|
||||
@@ -12994,9 +13016,8 @@ namespace Catch {
|
||||
}
|
||||
|
||||
void RunContext::invokeActiveTestCase() {
|
||||
FatalConditionHandler fatalConditionHandler; // Handle signals
|
||||
FatalConditionHandlerGuard _(&m_fatalConditionhandler);
|
||||
m_activeTestCase->invoke();
|
||||
fatalConditionHandler.reset();
|
||||
}
|
||||
|
||||
void RunContext::handleUnfinishedSections() {
|
||||
@@ -15359,7 +15380,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
Version const& libraryVersion() {
|
||||
static Version version( 2, 13, 4, "", 0 );
|
||||
static Version version( 2, 13, 7, "", 0 );
|
||||
return version;
|
||||
}
|
||||
|
||||
@@ -16772,6 +16793,7 @@ CATCH_REGISTER_REPORTER("console", ConsoleReporter)
|
||||
#include <sstream>
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -16799,7 +16821,7 @@ namespace Catch {
|
||||
#else
|
||||
std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
|
||||
#endif
|
||||
return std::string(timeStamp);
|
||||
return std::string(timeStamp, timeStampSize-1);
|
||||
}
|
||||
|
||||
std::string fileNameTag(const std::vector<std::string> &tags) {
|
||||
@@ -16810,6 +16832,17 @@ namespace Catch {
|
||||
return it->substr(1);
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// Formats the duration in seconds to 3 decimal places.
|
||||
// This is done because some genius defined Maven Surefire schema
|
||||
// in a way that only accepts 3 decimal places, and tools like
|
||||
// Jenkins use that schema for validation JUnit reporter output.
|
||||
std::string formatDuration( double seconds ) {
|
||||
ReusableStringStream rss;
|
||||
rss << std::fixed << std::setprecision( 3 ) << seconds;
|
||||
return rss.str();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
JunitReporter::JunitReporter( ReporterConfig const& _config )
|
||||
@@ -16879,7 +16912,7 @@ namespace Catch {
|
||||
if( m_config->showDurations() == ShowDurations::Never )
|
||||
xml.writeAttribute( "time", "" );
|
||||
else
|
||||
xml.writeAttribute( "time", suiteTime );
|
||||
xml.writeAttribute( "time", formatDuration( suiteTime ) );
|
||||
xml.writeAttribute( "timestamp", getCurrentTimestamp() );
|
||||
|
||||
// Write properties if there are any
|
||||
@@ -16924,12 +16957,13 @@ namespace Catch {
|
||||
if ( !m_config->name().empty() )
|
||||
className = m_config->name() + "." + className;
|
||||
|
||||
writeSection( className, "", rootSection );
|
||||
writeSection( className, "", rootSection, stats.testInfo.okToFail() );
|
||||
}
|
||||
|
||||
void JunitReporter::writeSection( std::string const& className,
|
||||
std::string const& rootName,
|
||||
SectionNode const& sectionNode ) {
|
||||
void JunitReporter::writeSection( std::string const& className,
|
||||
std::string const& rootName,
|
||||
SectionNode const& sectionNode,
|
||||
bool testOkToFail) {
|
||||
std::string name = trim( sectionNode.stats.sectionInfo.name );
|
||||
if( !rootName.empty() )
|
||||
name = rootName + '/' + name;
|
||||
@@ -16946,13 +16980,18 @@ namespace Catch {
|
||||
xml.writeAttribute( "classname", className );
|
||||
xml.writeAttribute( "name", name );
|
||||
}
|
||||
xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
|
||||
xml.writeAttribute( "time", formatDuration( sectionNode.stats.durationInSeconds ) );
|
||||
// This is not ideal, but it should be enough to mimic gtest's
|
||||
// junit output.
|
||||
// Ideally the JUnit reporter would also handle `skipTest`
|
||||
// events and write those out appropriately.
|
||||
xml.writeAttribute( "status", "run" );
|
||||
|
||||
if (sectionNode.stats.assertions.failedButOk) {
|
||||
xml.scopedElement("skipped")
|
||||
.writeAttribute("message", "TEST_CASE tagged with !mayfail");
|
||||
}
|
||||
|
||||
writeAssertions( sectionNode );
|
||||
|
||||
if( !sectionNode.stdOut.empty() )
|
||||
@@ -16962,9 +17001,9 @@ namespace Catch {
|
||||
}
|
||||
for( auto const& childNode : sectionNode.childSections )
|
||||
if( className.empty() )
|
||||
writeSection( name, "", *childNode );
|
||||
writeSection( name, "", *childNode, testOkToFail );
|
||||
else
|
||||
writeSection( className, name, *childNode );
|
||||
writeSection( className, name, *childNode, testOkToFail );
|
||||
}
|
||||
|
||||
void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
|
||||
|
||||
Reference in New Issue
Block a user