From 2e285b957936647a788d9915f95d077031d97856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sun, 4 Mar 2018 14:25:23 +0100 Subject: [PATCH] Use char const * const * for Session::run Needed to embed newer version of Clara Closes #1178 Closes #1031 --- include/external/clara.hpp | 45 ++++++++++++++++++++---------- include/internal/catch_session.cpp | 2 +- include/internal/catch_session.h | 2 +- third_party/clara.hpp | 45 ++++++++++++++++++++---------- 4 files changed, 62 insertions(+), 32 deletions(-) diff --git a/include/external/clara.hpp b/include/external/clara.hpp index 9c03c8e3..1762651f 100644 --- a/include/external/clara.hpp +++ b/include/external/clara.hpp @@ -5,7 +5,7 @@ // // See https://github.com/philsquared/Clara for more details -// Clara v1.1.2 +// Clara v1.1.3 #ifndef CATCH_CLARA_HPP_INCLUDED #define CATCH_CLARA_HPP_INCLUDED @@ -18,6 +18,15 @@ #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH #endif +#ifndef CLARA_CONFIG_OPTIONAL_TYPE +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define CLARA_CONFIG_OPTIONAL_TYPE std::optional +#endif +#endif +#endif + + // ----------- #included from clara_textflow.hpp ----------- // TextFlowCpp @@ -389,11 +398,9 @@ namespace detail { std::vector m_args; public: - Args( int argc, char *argv[] ) { - m_exeName = argv[0]; - for( int i = 1; i < argc; ++i ) - m_args.push_back( argv[i] ); - } + Args( int argc, char const* const* argv ) + : m_exeName(argv[0]), + m_args(argv + 1, argv + argc) {} Args( std::initializer_list args ) : m_exeName( *args.begin() ), @@ -580,15 +587,13 @@ namespace detail { protected: void enforceOk() const override { - // !TBD: If no exceptions, std::terminate here or something - switch( m_type ) { - case ResultBase::LogicError: - throw std::logic_error( m_errorMessage ); - case ResultBase::RuntimeError: - throw std::runtime_error( m_errorMessage ); - case ResultBase::Ok: - break; - } + + // Errors shouldn't reach this point, but if they do + // the actual error message will be in m_errorMessage + assert( m_type != ResultBase::LogicError ); + assert( m_type != ResultBase::RuntimeError ); + if( m_type != ResultBase::Ok ) + std::abort(); } std::string m_errorMessage; // Only populated if resultType is an error @@ -658,6 +663,16 @@ namespace detail { return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" ); return ParserResult::ok( ParseResultType::Matched ); } +#ifdef CLARA_CONFIG_OPTIONAL_TYPE + template + inline auto convertInto( std::string const &source, std::optional& target ) -> ParserResult { + T temp; + auto result = convertInto( source, temp ); + if( result ) + target = temp; + return result; + } +#endif // CLARA_CONFIG_OPTIONAL_TYPE struct NonCopyable { NonCopyable() = default; diff --git a/include/internal/catch_session.cpp b/include/internal/catch_session.cpp index 9ccb16f8..58df6276 100644 --- a/include/internal/catch_session.cpp +++ b/include/internal/catch_session.cpp @@ -165,7 +165,7 @@ namespace Catch { << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl; } - int Session::applyCommandLine( int argc, char* argv[] ) { + int Session::applyCommandLine( int argc, char const * const * argv ) { if( m_startupExceptions ) return 1; diff --git a/include/internal/catch_session.h b/include/internal/catch_session.h index b814aa6a..09e8c2ed 100644 --- a/include/internal/catch_session.h +++ b/include/internal/catch_session.h @@ -25,7 +25,7 @@ namespace Catch { void showHelp() const; void libIdentify(); - int applyCommandLine( int argc, char* argv[] ); + int applyCommandLine( int argc, char const * const * argv ); void useConfigData( ConfigData const& configData ); diff --git a/third_party/clara.hpp b/third_party/clara.hpp index 9a60c174..257ba10f 100644 --- a/third_party/clara.hpp +++ b/third_party/clara.hpp @@ -5,7 +5,7 @@ // // See https://github.com/philsquared/Clara for more details -// Clara v1.1.2 +// Clara v1.1.3 #ifndef CLARA_HPP_INCLUDED #define CLARA_HPP_INCLUDED @@ -18,6 +18,15 @@ #define CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH #endif +#ifndef CLARA_CONFIG_OPTIONAL_TYPE +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define CLARA_CONFIG_OPTIONAL_TYPE std::optional +#endif +#endif +#endif + + // ----------- #included from clara_textflow.hpp ----------- // TextFlowCpp @@ -389,11 +398,9 @@ namespace detail { std::vector m_args; public: - Args( int argc, char *argv[] ) { - m_exeName = argv[0]; - for( int i = 1; i < argc; ++i ) - m_args.push_back( argv[i] ); - } + Args( int argc, char const* const* argv ) + : m_exeName(argv[0]), + m_args(argv + 1, argv + argc) {} Args( std::initializer_list args ) : m_exeName( *args.begin() ), @@ -580,15 +587,13 @@ namespace detail { protected: void enforceOk() const override { - // !TBD: If no exceptions, std::terminate here or something - switch( m_type ) { - case ResultBase::LogicError: - throw std::logic_error( m_errorMessage ); - case ResultBase::RuntimeError: - throw std::runtime_error( m_errorMessage ); - case ResultBase::Ok: - break; - } + + // Errors shouldn't reach this point, but if they do + // the actual error message will be in m_errorMessage + assert( m_type != ResultBase::LogicError ); + assert( m_type != ResultBase::RuntimeError ); + if( m_type != ResultBase::Ok ) + std::abort(); } std::string m_errorMessage; // Only populated if resultType is an error @@ -658,6 +663,16 @@ namespace detail { return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" ); return ParserResult::ok( ParseResultType::Matched ); } +#ifdef CLARA_CONFIG_OPTIONAL_TYPE + template + inline auto convertInto( std::string const &source, std::optional& target ) -> ParserResult { + T temp; + auto result = convertInto( source, temp ); + if( result ) + target = temp; + return result; + } +#endif // CLARA_CONFIG_OPTIONAL_TYPE struct NonCopyable { NonCopyable() = default;