From 07901cd55b9eecb835e6b0aba86f313ba61259ba Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 28 Oct 2021 13:43:35 +0100 Subject: [PATCH] Revert "Add patch from !951" This reverts commit 5a4d1a198543362ed7b7b59106968a9a4f96ae55. --- debian/changelog | 6 - .../0003-Update-catch2-to-2.13.7.patch | 1510 ----------------- debian/patches/series | 1 - 3 files changed, 1517 deletions(-) delete mode 100644 debian/patches/0003-Update-catch2-to-2.13.7.patch delete mode 100644 debian/patches/series diff --git a/debian/changelog b/debian/changelog index 89d600112..55af5bf6c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,3 @@ -monado (21.0.0~dfsg1-2~ubuntu2110~20211027+2) impish; urgency=medium - - * Add d/patches/0003-Update-catch2-to-2.13.7.patch to fix FTBFS. - - -- Ryan Pavlik Wed, 27 Oct 2021 13:53:09 -0500 - monado (21.0.0~dfsg1-2~ubuntu2110~20211027+1) impish; urgency=medium * Create branch for backport, updating diff --git a/debian/patches/0003-Update-catch2-to-2.13.7.patch b/debian/patches/0003-Update-catch2-to-2.13.7.patch deleted file mode 100644 index 68ded8e9f..000000000 --- a/debian/patches/0003-Update-catch2-to-2.13.7.patch +++ /dev/null @@ -1,1510 +0,0 @@ -From: Ryan Pavlik -Date: Wed, 27 Oct 2021 13:49:10 -0500 -Subject: Update catch2 to 2.13.7. - -Forwarded: https://gitlab.freedesktop.org/monado/monado/-/merge_requests/951 ---- - src/external/Catch2/catch/catch.hpp | 779 ++++++++++++++++++++++++------------ - 1 file changed, 516 insertions(+), 263 deletions(-) - -diff --git a/src/external/Catch2/catch/catch.hpp b/src/external/Catch2/catch/catch.hpp -index f64422a..7e706f9 100644 ---- a/src/external/Catch2/catch/catch.hpp -+++ b/src/external/Catch2/catch/catch.hpp -@@ -1,9 +1,9 @@ - /* -- * Catch v2.12.2 -- * Generated: 2020-05-25 15:09:23.791719 -+ * 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) -@@ -14,8 +14,8 @@ - - - #define CATCH_VERSION_MAJOR 2 --#define CATCH_VERSION_MINOR 12 --#define CATCH_VERSION_PATCH 2 -+#define CATCH_VERSION_MINOR 13 -+#define CATCH_VERSION_PATCH 7 - - #ifdef __clang__ - # pragma clang system_header -@@ -66,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 --# if TARGET_OS_OSX == 1 --# define CATCH_PLATFORM_MAC --# elif TARGET_OS_IPHONE == 1 --# define CATCH_PLATFORM_IPHONE --# endif -+# include -+# 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 -@@ -132,13 +135,9 @@ namespace Catch { - - #endif - --#if defined(__cpp_lib_uncaught_exceptions) --# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS --#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) -+// 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" ) - -@@ -162,7 +161,7 @@ namespace Catch { - // ``` - // - // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. --# if !defined(__ibmxl__) -+# if !defined(__ibmxl__) && !defined(__CUDACC__) - # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ - # endif - -@@ -244,10 +243,6 @@ namespace Catch { - # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) - # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) - --# if _MSC_VER >= 1900 // Visual Studio 2015 or newer --# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS --# endif -- - // Universal Windows platform does not support SEH - // Or console colours (or console at all...) - # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) -@@ -330,7 +325,10 @@ namespace Catch { - - // Check if byte is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) -- # define CATCH_INTERNAL_CONFIG_CPP17_BYTE -+ # include -+ # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) -+ # define CATCH_INTERNAL_CONFIG_CPP17_BYTE -+ # endif - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) - - // Check if variant is available and usable -@@ -373,10 +371,6 @@ namespace Catch { - # define CATCH_CONFIG_CPP17_OPTIONAL - #endif - --#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) --# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS --#endif -- - #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) - # define CATCH_CONFIG_CPP17_STRING_VIEW - #endif -@@ -775,7 +769,7 @@ constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) n - #define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) - #define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) - #define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) --#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6) -+#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) - #define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) - #define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) - #define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) -@@ -1105,7 +1099,7 @@ struct AutoReg : NonCopyable { - int index = 0; \ - constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\ - using expander = int[];\ -- (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \ -+ (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \ - }\ - };\ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ -@@ -1151,7 +1145,7 @@ struct AutoReg : NonCopyable { - constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\ - constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\ - constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\ -- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\ -+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */\ - } \ - }; \ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ -@@ -1195,7 +1189,7 @@ struct AutoReg : NonCopyable { - void reg_tests() { \ - int index = 0; \ - using expander = int[]; \ -- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\ -+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\ - } \ - };\ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ -@@ -1229,7 +1223,7 @@ struct AutoReg : NonCopyable { - int index = 0; \ - constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\ - using expander = int[];\ -- (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \ -+ (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \ - }\ - };\ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ -@@ -1278,7 +1272,7 @@ struct AutoReg : NonCopyable { - constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\ - constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\ - constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\ -- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \ -+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */ \ - }\ - };\ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ -@@ -1325,7 +1319,7 @@ struct AutoReg : NonCopyable { - void reg_tests(){\ - int index = 0;\ - using expander = int[];\ -- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \ -+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \ - }\ - };\ - static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ -@@ -1829,8 +1823,8 @@ namespace Catch { - #endif - - namespace Detail { -- template -- std::string rangeToString(InputIterator first, InputIterator last) { -+ template -+ std::string rangeToString(InputIterator first, Sentinel last) { - ReusableStringStream rss; - rss << "{ "; - if (first != last) { -@@ -2468,7 +2462,7 @@ namespace Catch { - virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; - virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; - -- virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0; -+ virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0; - - #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - virtual void benchmarkPreparing( std::string const& name ) = 0; -@@ -4080,16 +4074,16 @@ namespace Generators { - return makeGenerators( value( T( std::forward( val ) ) ), std::forward( moreGenerators )... ); - } - -- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; -+ auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&; - - template - // Note: The type after -> is weird, because VS2015 cannot parse - // the expression used in the typedef inside, when it is in - // return type. Yeah. -- auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval().get()) { -+ auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval().get()) { - using UnderlyingType = typename decltype(generatorExpression())::type; - -- IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo ); -+ IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo ); - if (!tracker.hasGenerator()) { - tracker.setGenerator(pf::make_unique>(generatorExpression())); - } -@@ -4102,11 +4096,17 @@ namespace Generators { - } // namespace Catch - - #define GENERATE( ... ) \ -- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) -+ Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ -+ CATCH_INTERNAL_LINEINFO, \ -+ [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) - #define GENERATE_COPY( ... ) \ -- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) -+ Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ -+ CATCH_INTERNAL_LINEINFO, \ -+ [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) - #define GENERATE_REF( ... ) \ -- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) -+ Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \ -+ CATCH_INTERNAL_LINEINFO, \ -+ [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace) - - // end catch_generators.hpp - // start catch_generators_generic.hpp -@@ -4516,6 +4516,7 @@ namespace Catch { - virtual int abortAfter() const = 0; - virtual bool showInvisibles() const = 0; - virtual ShowDurations::OrNot showDurations() const = 0; -+ virtual double minDuration() const = 0; - virtual TestSpec const& testSpec() const = 0; - virtual bool hasTestFilters() const = 0; - virtual std::vector const& getTestsOrTags() const = 0; -@@ -5288,6 +5289,7 @@ namespace Catch { - Verbosity verbosity = Verbosity::Normal; - WarnAbout::What warnings = WarnAbout::Nothing; - ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter; -+ double minDuration = -1; - RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder; - UseColour::YesOrNo useColour = UseColour::Auto; - WaitForKeypress::When waitForKeypress = WaitForKeypress::Never; -@@ -5338,6 +5340,7 @@ namespace Catch { - bool warnAboutMissingAssertions() const override; - bool warnAboutNoTests() const override; - ShowDurations::OrNot showDurations() const override; -+ double minDuration() const override; - RunTests::InWhatOrder runOrder() const override; - unsigned int rngSeed() const override; - UseColour::YesOrNo useColour() const override; -@@ -5455,6 +5458,8 @@ namespace Catch { - } // namespace Catch - - // end catch_outlier_classification.hpp -+ -+#include - #endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - #include -@@ -5715,6 +5720,9 @@ namespace Catch { - // Returns double formatted as %.3f (format expected on output) - std::string getFormattedDuration( double duration ); - -+ //! Should the reporter show -+ bool shouldShowDuration( IConfig const& config, double duration ); -+ - std::string serializeFilters( std::vector const& container ); - - template -@@ -6108,8 +6116,6 @@ namespace Catch { - - static std::string getDescription(); - -- ReporterPreferences getPreferences() const override; -- - void noMatchingTestCases(std::string const& spec) override; - - void assertionStarting(AssertionInfo const&) override; -@@ -6338,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); -@@ -6875,7 +6882,7 @@ namespace Catch { - } - iters *= 2; - } -- throw optimized_away_error{}; -+ Catch::throw_exception(optimized_away_error{}); - } - } // namespace Detail - } // namespace Benchmark -@@ -6883,6 +6890,7 @@ namespace Catch { - - // end catch_run_for_at_least.hpp - #include -+#include - - namespace Catch { - namespace Benchmark { -@@ -7053,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 }; - } -@@ -7123,7 +7131,9 @@ namespace Catch { - } - template - EnvironmentEstimate> estimate_clock_cost(FloatDuration resolution) { -- auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration(clock_cost_estimation_time_limit)); -+ auto time_limit = (std::min)( -+ resolution * clock_cost_estimation_tick_limit, -+ FloatDuration(clock_cost_estimation_time_limit)); - auto time_clock = [](int k) { - return Detail::measure([k] { - for (int i = 0; i < k; ++i) { -@@ -7463,23 +7473,37 @@ namespace TestCaseTracking { - SourceLineInfo location; - - NameAndLocation( std::string const& _name, SourceLineInfo const& _location ); -+ friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) { -+ return lhs.name == rhs.name -+ && lhs.location == rhs.location; -+ } - }; - -- struct ITracker; -+ class ITracker; - - using ITrackerPtr = std::shared_ptr; - -- struct ITracker { -- virtual ~ITracker(); -+ class ITracker { -+ NameAndLocation m_nameAndLocation; -+ -+ public: -+ ITracker(NameAndLocation const& nameAndLoc) : -+ m_nameAndLocation(nameAndLoc) -+ {} - - // static queries -- virtual NameAndLocation const& nameAndLocation() const = 0; -+ NameAndLocation const& nameAndLocation() const { -+ return m_nameAndLocation; -+ } -+ -+ virtual ~ITracker(); - - // dynamic queries - virtual bool isComplete() const = 0; // Successfully completed or failed - virtual bool isSuccessfullyCompleted() const = 0; - virtual bool isOpen() const = 0; // Started but not complete - virtual bool hasChildren() const = 0; -+ virtual bool hasStarted() const = 0; - - virtual ITracker& parent() = 0; - -@@ -7534,7 +7558,6 @@ namespace TestCaseTracking { - }; - - using Children = std::vector; -- NameAndLocation m_nameAndLocation; - TrackerContext& m_ctx; - ITracker* m_parent; - Children m_children; -@@ -7543,11 +7566,13 @@ namespace TestCaseTracking { - public: - TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); - -- NameAndLocation const& nameAndLocation() const override; - bool isComplete() const override; - bool isSuccessfullyCompleted() const override; - bool isOpen() const override; - bool hasChildren() const override; -+ bool hasStarted() const override { -+ return m_runState != NotStarted; -+ } - - void addChild( ITrackerPtr const& child ) override; - -@@ -7586,6 +7611,10 @@ namespace TestCaseTracking { - - void addInitialFilters( std::vector const& filters ); - void addNextFilters( std::vector const& filters ); -+ //! Returns filters active in this tracker -+ std::vector const& getFilters() const; -+ //! Returns whitespace-trimmed name of the tracked section -+ std::string const& trimmedName() const; - }; - - } // namespace TestCaseTracking -@@ -7751,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; - -@@ -7770,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::iterator first, std::vector::iterator last) { -@@ -7910,7 +7939,11 @@ namespace Catch { - - #ifdef CATCH_PLATFORM_MAC - -- #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ -+ #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) - -@@ -7956,86 +7989,58 @@ namespace Catch { - - // 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 --#else --#include --#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 - - namespace Catch { - -- struct FatalConditionHandler { -- -- static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo); -+ // 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(); -- static void reset(); - ~FatalConditionHandler(); - -- private: -- static bool isSet; -- static ULONG guaranteeSize; -- static PVOID exceptionHandlerHandle; -- }; -- --} // namespace Catch -- --#elif defined ( CATCH_CONFIG_POSIX_SIGNALS ) -- --#include -- --namespace Catch { -- -- struct FatalConditionHandler { -- -- static bool isSet; -- static struct sigaction oldSigActions[]; -- static stack_t oldSigStack; -- static char altStackMem[]; -- -- static void handleSignal( int sig ); -+ void engage() { -+ assert(!m_started && "Handler cannot be installed twice."); -+ m_started = true; -+ engage_platform(); -+ } - -- FatalConditionHandler(); -- ~FatalConditionHandler(); -- static void reset(); -+ 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 -@@ -8095,7 +8100,7 @@ namespace Catch { - void sectionEnded( SectionEndInfo const& endInfo ) override; - void sectionEndedEarly( SectionEndInfo const& endInfo ) override; - -- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override; -+ auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override; - - #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - void benchmarkPreparing( std::string const& name ) override; -@@ -8161,6 +8166,7 @@ namespace Catch { - std::vector m_unfinishedSections; - std::vector m_activeSections; - TrackerContext m_trackerContext; -+ FatalConditionHandler m_fatalConditionhandler; - bool m_lastAssertionPassed = false; - bool m_shouldReportUnexpected = true; - bool m_includeSuccessfulResults; -@@ -9071,7 +9077,7 @@ namespace detail { - } - inline auto convertInto( std::string const &source, bool &target ) -> ParserResult { - std::string srcLC = source; -- std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast( std::tolower(c) ); } ); -+ std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast( std::tolower(c) ); } ); - if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") - target = true; - else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off") -@@ -9840,6 +9846,9 @@ namespace Catch { - | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" ) - ["-d"]["--durations"] - ( "show test durations" ) -+ | Opt( config.minDuration, "seconds" ) -+ ["-D"]["--min-duration"] -+ ( "show test durations for tests taking at least the given number of seconds" ) - | Opt( loadTestNamesFromFile, "filename" ) - ["-f"]["--input-file"] - ( "load test names to run from a file" ) -@@ -9987,6 +9996,7 @@ namespace Catch { - bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); } - bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); } - ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; } -+ double Config::minDuration() const { return m_data.minDuration; } - RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; } - unsigned int Config::rngSeed() const { return m_data.rngSeed; } - UseColour::YesOrNo Config::useColour() const { return m_data.useColour; } -@@ -10029,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 -+#else -+#include -+#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 - - namespace Catch { -@@ -10545,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; -@@ -10707,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 -+ -+#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. -@@ -10738,7 +10800,7 @@ namespace Catch { - { static_cast(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); -@@ -10749,38 +10811,50 @@ namespace Catch { - return EXCEPTION_CONTINUE_SEARCH; - } - -+ // 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; -+ -+ // For MSVC, we reserve part of the stack memory for handling -+ // memory overflow structured exception. - 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; -+ ULONG guaranteeSize = static_cast(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."; -+ } -+ } -+ -+ // 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); -- // Pass in guarantee size to be filled -- SetThreadStackGuarantee(&guaranteeSize); -+ if (!exceptionHandlerHandle) { -+ CATCH_RUNTIME_ERROR("Could not register vectored exception handler"); -+ } - } - -- void FatalConditionHandler::reset() { -- if (isSet) { -- RemoveVectoredExceptionHandler(exceptionHandlerHandle); -- SetThreadStackGuarantee(&guaranteeSize); -- exceptionHandlerHandle = nullptr; -- isSet = false; -+ void FatalConditionHandler::disengage_platform() { -+ if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) { -+ CATCH_RUNTIME_ERROR("Could not unregister vectored exception handler"); - } -+ exceptionHandlerHandle = nullptr; - } - -- FatalConditionHandler::~FatalConditionHandler() { -- reset(); -- } -+} // end namespace Catch - --bool FatalConditionHandler::isSet = false; --ULONG FatalConditionHandler::guaranteeSize = 0; --PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr; -+#endif // CATCH_CONFIG_WINDOWS_SEH - --} // namespace Catch -+#if defined( CATCH_CONFIG_POSIX_SIGNALS ) - --#elif defined( CATCH_CONFIG_POSIX_SIGNALS ) -+#include - - namespace Catch { - -@@ -10789,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" }, -@@ -10802,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 = ""; - for (auto const& def : signalDefs) { - if (sig == def.id) { -@@ -10810,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(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 = { }; -@@ -10831,40 +10943,17 @@ namespace Catch { - } - } - -- FatalConditionHandler::~FatalConditionHandler() { -- reset(); -- } -+#if defined(__GNUC__) -+# pragma GCC diagnostic pop -+#endif - -- 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; -- } -+ void FatalConditionHandler::disengage_platform() { -+ restorePreviousSignalHandlers(); - } - -- 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 -+} // end namespace Catch - --#if defined(__GNUC__) --# pragma GCC diagnostic pop --#endif -+#endif // CATCH_CONFIG_POSIX_SIGNALS - // end catch_fatal_condition.cpp - // start catch_generators.cpp - -@@ -10883,8 +10972,8 @@ namespace Generators { - - GeneratorUntypedBase::~GeneratorUntypedBase() {} - -- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { -- return getResultCapture().acquireGeneratorTracker( lineInfo ); -+ auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { -+ return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo ); - } - - } // namespace Generators -@@ -11419,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(lc - rc)); - return static_cast(ulpDiff) <= maxUlpDiff; - } - -@@ -11593,7 +11683,6 @@ Floating::WithinRelMatcher WithinRel(float target) { - - } // namespace Matchers - } // namespace Catch -- - // end catch_matchers_floating.cpp - // start catch_matchers_generic.cpp - -@@ -12009,7 +12098,7 @@ namespace Catch { - if (tmpnam_s(m_buffer)) { - CATCH_RUNTIME_ERROR("Could not get a temp filename"); - } -- if (fopen_s(&m_file, m_buffer, "w")) { -+ if (fopen_s(&m_file, m_buffer, "w+")) { - char buffer[100]; - if (strerror_s(buffer, errno)) { - CATCH_RUNTIME_ERROR("Could not translate errno to a string"); -@@ -12304,11 +12393,13 @@ namespace Catch { - namespace Catch { - - class StartupExceptionRegistry { -+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) - public: - void add(std::exception_ptr const& exception) noexcept; - std::vector const& getExceptions() const noexcept; - private: - std::vector m_exceptions; -+#endif - }; - - } // end namespace Catch -@@ -12391,7 +12482,11 @@ namespace Catch { - m_tagAliasRegistry.add( alias, tag, lineInfo ); - } - void registerStartupException() noexcept override { -+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) - m_exceptionRegistry.add(std::current_exception()); -+#else -+ CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!"); -+#endif - } - IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override { - return m_enumValuesRegistry; -@@ -12495,17 +12590,32 @@ namespace Catch { - std::shared_ptr tracker; - - ITracker& currentTracker = ctx.currentTracker(); -- if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { -+ // Under specific circumstances, the generator we want -+ // to acquire is also the current tracker. If this is -+ // the case, we have to avoid looking through current -+ // tracker's children, and instead return the current -+ // tracker. -+ // A case where this check is important is e.g. -+ // for (int i = 0; i < 5; ++i) { -+ // int n = GENERATE(1, 2); -+ // } -+ // -+ // without it, the code above creates 5 nested generators. -+ if (currentTracker.nameAndLocation() == nameAndLocation) { -+ auto thisTracker = currentTracker.parent().findChild(nameAndLocation); -+ assert(thisTracker); -+ assert(thisTracker->isGeneratorTracker()); -+ tracker = std::static_pointer_cast(thisTracker); -+ } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { - assert( childTracker ); - assert( childTracker->isGeneratorTracker() ); - tracker = std::static_pointer_cast( childTracker ); -- } -- else { -+ } else { - tracker = std::make_shared( nameAndLocation, ctx, ¤tTracker ); - currentTracker.addChild( tracker ); - } - -- if( !ctx.completedCycle() && !tracker->isComplete() ) { -+ if( !tracker->isComplete() ) { - tracker->open(); - } - -@@ -12519,8 +12629,68 @@ namespace Catch { - } - void close() override { - TrackerBase::close(); -- // Generator interface only finds out if it has another item on atual move -- if (m_runState == CompletedSuccessfully && m_generator->next()) { -+ // If a generator has a child (it is followed by a section) -+ // and none of its children have started, then we must wait -+ // until later to start consuming its values. -+ // This catches cases where `GENERATE` is placed between two -+ // `SECTION`s. -+ // **The check for m_children.empty cannot be removed**. -+ // doing so would break `GENERATE` _not_ followed by `SECTION`s. -+ const bool should_wait_for_child = [&]() { -+ // No children -> nobody to wait for -+ if ( m_children.empty() ) { -+ return false; -+ } -+ // If at least one child started executing, don't wait -+ if ( std::find_if( -+ m_children.begin(), -+ m_children.end(), -+ []( TestCaseTracking::ITrackerPtr tracker ) { -+ return tracker->hasStarted(); -+ } ) != m_children.end() ) { -+ return false; -+ } -+ -+ // No children have started. We need to check if they _can_ -+ // start, and thus we should wait for them, or they cannot -+ // start (due to filters), and we shouldn't wait for them -+ auto* parent = m_parent; -+ // This is safe: there is always at least one section -+ // tracker in a test case tracking tree -+ while ( !parent->isSectionTracker() ) { -+ parent = &( parent->parent() ); -+ } -+ assert( parent && -+ "Missing root (test case) level section" ); -+ -+ auto const& parentSection = -+ static_cast( *parent ); -+ auto const& filters = parentSection.getFilters(); -+ // No filters -> no restrictions on running sections -+ if ( filters.empty() ) { -+ return true; -+ } -+ -+ for ( auto const& child : m_children ) { -+ if ( child->isSectionTracker() && -+ std::find( filters.begin(), -+ filters.end(), -+ static_cast( *child ) -+ .trimmedName() ) != -+ filters.end() ) { -+ return true; -+ } -+ } -+ return false; -+ }(); -+ -+ // This check is a bit tricky, because m_generator->next() -+ // has a side-effect, where it consumes generator's current -+ // value, but we do not want to invoke the side-effect if -+ // this generator is still waiting for any child to start. -+ if ( should_wait_for_child || -+ ( m_runState == CompletedSuccessfully && -+ m_generator->next() ) ) { - m_children.clear(); - m_runState = Executing; - } -@@ -12656,10 +12826,10 @@ namespace Catch { - - return true; - } -- auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { -+ auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& { - using namespace Generators; -- GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) ); -- assert( tracker.isOpen() ); -+ GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext, -+ TestCaseTracking::NameAndLocation( static_cast(generatorName), lineInfo ) ); - m_lastAssertionInfo.lineInfo = lineInfo; - return tracker; - } -@@ -12702,17 +12872,17 @@ namespace Catch { - - #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING) - void RunContext::benchmarkPreparing(std::string const& name) { -- m_reporter->benchmarkPreparing(name); -- } -+ m_reporter->benchmarkPreparing(name); -+ } - void RunContext::benchmarkStarting( BenchmarkInfo const& info ) { - m_reporter->benchmarkStarting( info ); - } - void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) { - m_reporter->benchmarkEnded( stats ); - } -- void RunContext::benchmarkFailed(std::string const & error) { -- m_reporter->benchmarkFailed(error); -- } -+ void RunContext::benchmarkFailed(std::string const & error) { -+ m_reporter->benchmarkFailed(error); -+ } - #endif // CATCH_CONFIG_ENABLE_BENCHMARKING - - void RunContext::pushScopedMessage(MessageInfo const & message) { -@@ -12846,9 +13016,8 @@ namespace Catch { - } - - void RunContext::invokeActiveTestCase() { -- FatalConditionHandler fatalConditionHandler; // Handle signals -+ FatalConditionHandlerGuard _(&m_fatalConditionhandler); - m_activeTestCase->invoke(); -- fatalConditionHandler.reset(); - } - - void RunContext::handleUnfinishedSections() { -@@ -13433,6 +13602,7 @@ namespace Catch { - // end catch_singletons.cpp - // start catch_startup_exception_registry.cpp - -+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) - namespace Catch { - void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept { - CATCH_TRY { -@@ -13448,6 +13618,7 @@ void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexce - } - - } // end namespace Catch -+#endif - // end catch_startup_exception_registry.cpp - // start catch_stream.cpp - -@@ -13632,7 +13803,7 @@ namespace Catch { - - namespace { - char toLowerCh(char c) { -- return static_cast( std::tolower( c ) ); -+ return static_cast( std::tolower( static_cast(c) ) ); - } - } - -@@ -14015,24 +14186,28 @@ namespace Catch { - - namespace { - struct TestHasher { -- explicit TestHasher(Catch::SimplePcg32& rng) { -- basis = rng(); -- basis <<= 32; -- basis |= rng(); -- } -+ using hash_t = uint64_t; - -- uint64_t basis; -+ explicit TestHasher( hash_t hashSuffix ): -+ m_hashSuffix{ hashSuffix } {} - -- uint64_t operator()(TestCase const& t) const { -- // Modified FNV-1a hash -- static constexpr uint64_t prime = 1099511628211; -- uint64_t hash = basis; -- for (const char c : t.name) { -+ uint32_t operator()( TestCase const& t ) const { -+ // FNV-1a hash with multiplication fold. -+ const hash_t prime = 1099511628211u; -+ hash_t hash = 14695981039346656037u; -+ for ( const char c : t.name ) { - hash ^= c; - hash *= prime; - } -- return hash; -+ hash ^= m_hashSuffix; -+ hash *= prime; -+ const uint32_t low{ static_cast( hash ) }; -+ const uint32_t high{ static_cast( hash >> 32 ) }; -+ return low * high; - } -+ -+ private: -+ hash_t m_hashSuffix; - }; - } // end unnamed namespace - -@@ -14050,9 +14225,9 @@ namespace Catch { - - case RunTests::InRandomOrder: { - seedRng( config ); -- TestHasher h( rng() ); -+ TestHasher h{ config.rngSeed() }; - -- using hashedTest = std::pair; -+ using hashedTest = std::pair; - std::vector indexed_tests; - indexed_tests.reserve( unsortedTestCases.size() ); - -@@ -14215,15 +14390,12 @@ namespace TestCaseTracking { - m_currentTracker = tracker; - } - -- TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) -- : m_nameAndLocation( nameAndLocation ), -+ TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ): -+ ITracker(nameAndLocation), - m_ctx( ctx ), - m_parent( parent ) - {} - -- NameAndLocation const& TrackerBase::nameAndLocation() const { -- return m_nameAndLocation; -- } - bool TrackerBase::isComplete() const { - return m_runState == CompletedSuccessfully || m_runState == Failed; - } -@@ -14339,7 +14511,8 @@ namespace TestCaseTracking { - bool SectionTracker::isComplete() const { - bool complete = true; - -- if ((m_filters.empty() || m_filters[0] == "") -+ if (m_filters.empty() -+ || m_filters[0] == "" - || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) { - complete = TrackerBase::isComplete(); - } -@@ -14384,6 +14557,14 @@ namespace TestCaseTracking { - m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() ); - } - -+ std::vector const& SectionTracker::getFilters() const { -+ return m_filters; -+ } -+ -+ std::string const& SectionTracker::trimmedName() const { -+ return m_trimmed_name; -+ } -+ - } // namespace TestCaseTracking - - using TestCaseTracking::ITracker; -@@ -15118,11 +15299,48 @@ namespace Catch { - // end catch_totals.cpp - // start catch_uncaught_exceptions.cpp - -+// start catch_config_uncaught_exceptions.hpp -+ -+// Copyright Catch2 Authors -+// Distributed under the Boost Software License, Version 1.0. -+// (See accompanying file LICENSE_1_0.txt or copy at -+// https://www.boost.org/LICENSE_1_0.txt) -+ -+// SPDX-License-Identifier: BSL-1.0 -+ -+#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP -+#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP -+ -+#if defined(_MSC_VER) -+# if _MSC_VER >= 1900 // Visual Studio 2015 or newer -+# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -+# endif -+#endif -+ -+#include -+ -+#if defined(__cpp_lib_uncaught_exceptions) \ -+ && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) -+ -+# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -+#endif // __cpp_lib_uncaught_exceptions -+ -+#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \ -+ && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \ -+ && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) -+ -+# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS -+#endif -+ -+#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP -+// end catch_config_uncaught_exceptions.hpp - #include - - namespace Catch { - bool uncaught_exceptions() { --#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) -+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -+ return false; -+#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) - return std::uncaught_exceptions() > 0; - #else - return std::uncaught_exception(); -@@ -15162,7 +15380,7 @@ namespace Catch { - } - - Version const& libraryVersion() { -- static Version version( 2, 12, 2, "", 0 ); -+ static Version version( 2, 13, 7, "", 0 ); - return version; - } - -@@ -15564,6 +15782,17 @@ namespace Catch { - return std::string(buffer); - } - -+ bool shouldShowDuration( IConfig const& config, double duration ) { -+ if ( config.showDurations() == ShowDurations::Always ) { -+ return true; -+ } -+ if ( config.showDurations() == ShowDurations::Never ) { -+ return false; -+ } -+ const double min = config.minDuration(); -+ return min >= 0 && duration >= min; -+ } -+ - std::string serializeFilters( std::vector const& container ) { - ReusableStringStream oss; - bool first = true; -@@ -15830,10 +16059,6 @@ private: - return "Reports test results on a single line, suitable for IDEs"; - } - -- ReporterPreferences CompactReporter::getPreferences() const { -- return m_reporterPrefs; -- } -- - void CompactReporter::noMatchingTestCases( std::string const& spec ) { - stream << "No test cases matched '" << spec << '\'' << std::endl; - } -@@ -15860,8 +16085,9 @@ private: - } - - void CompactReporter::sectionEnded(SectionStats const& _sectionStats) { -- if (m_config->showDurations() == ShowDurations::Always) { -- stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; -+ double dur = _sectionStats.durationInSeconds; -+ if ( shouldShowDuration( *m_config, dur ) ) { -+ stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << std::endl; - } - } - -@@ -16281,8 +16507,9 @@ void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) { - stream << "\nNo assertions in test case"; - stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; - } -- if (m_config->showDurations() == ShowDurations::Always) { -- stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; -+ double dur = _sectionStats.durationInSeconds; -+ if (shouldShowDuration(*m_config, dur)) { -+ stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl; - } - if (m_headerPrinted) { - m_headerPrinted = false; -@@ -16566,6 +16793,7 @@ CATCH_REGISTER_REPORTER("console", ConsoleReporter) - #include - #include - #include -+#include - - namespace Catch { - -@@ -16593,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 &tags) { -@@ -16604,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 ) -@@ -16673,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 -@@ -16718,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; -@@ -16740,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() ) -@@ -16756,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 ) { -@@ -17180,6 +17425,10 @@ namespace Catch { - .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) - .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) - .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); -+ m_xml.scopedElement( "OverallResultsCases") -+ .writeAttribute( "successes", testGroupStats.totals.testCases.passed ) -+ .writeAttribute( "failures", testGroupStats.totals.testCases.failed ) -+ .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk ); - m_xml.endElement(); - } - -@@ -17189,6 +17438,10 @@ namespace Catch { - .writeAttribute( "successes", testRunStats.totals.assertions.passed ) - .writeAttribute( "failures", testRunStats.totals.assertions.failed ) - .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); -+ m_xml.scopedElement( "OverallResultsCases") -+ .writeAttribute( "successes", testRunStats.totals.testCases.passed ) -+ .writeAttribute( "failures", testRunStats.totals.testCases.failed ) -+ .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk ); - m_xml.endElement(); - } - diff --git a/debian/patches/series b/debian/patches/series deleted file mode 100644 index dff08b4af..000000000 --- a/debian/patches/series +++ /dev/null @@ -1 +0,0 @@ -0003-Update-catch2-to-2.13.7.patch