Permalink
Browse files

embedded v1.0-develop.2 of Clara, which addresses / prefixed options,…

… which should impact non-windows platforms

See #1054
  • Loading branch information...
philsquared committed Oct 21, 2017
1 parent 5af918e commit 75a77b6f8cf439c8ad57e6e7d922ec186665067e
Showing with 45 additions and 17 deletions.
  1. +17 −6 include/external/clara.hpp
  2. +28 −11 third_party/clara.hpp
View
@@ -1,4 +1,4 @@
// v1.0
// v1.0-develop.2
// See https://github.com/philsquared/Clara
#ifndef CATCH_CLARA_HPP_INCLUDED
@@ -409,6 +409,14 @@ namespace detail {
std::string token;
};
inline auto isOptPrefix( char c ) -> bool {
return c == '-'
#ifdef CATCH_PLATFORM_WINDOWS
|| c == '/'
#endif
;
}
// Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
class TokenStream {
using Iterator = std::vector<std::string>::const_iterator;
@@ -425,7 +433,7 @@ namespace detail {
if( it != itEnd ) {
auto const &next = *it;
if( next[0] == '-' || next[0] == '/' ) {
if( isOptPrefix( next[0] ) ) {
auto delimiterPos = next.find_first_of( " :=" );
if( delimiterPos != std::string::npos ) {
m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
@@ -915,9 +923,11 @@ namespace detail {
};
inline auto normaliseOpt( std::string const &optName ) -> std::string {
#ifdef CATCH_PLATFORM_WINDOWS
if( optName[0] == '/' )
return "-" + optName.substr( 1 );
else
#endif
return optName;
}
@@ -958,11 +968,7 @@ namespace detail {
}
auto isMatch( std::string const &optToken ) const -> bool {
#ifdef CATCH_PLATFORM_WINDOWS
auto normalisedToken = normaliseOpt( optToken );
#else
auto const &normalisedToken = optToken;
#endif
for( auto const &name : m_optNames ) {
if( normaliseOpt( name ) == normalisedToken )
return true;
@@ -1012,8 +1018,13 @@ namespace detail {
for( auto const &name : m_optNames ) {
if( name.empty() )
return Result::logicError( "Option name cannot be empty" );
#ifdef CATCH_PLATFORM_WINDOWS
if( name[0] != '-' && name[0] != '/' )
return Result::logicError( "Option name must begin with '-' or '/'" );
#else
if( name[0] != '-' )
return Result::logicError( "Option name must begin with '-'" );
#endif
}
return ParserRefImpl::validate();
}
View
@@ -1,4 +1,4 @@
// v1.0
// v1.0-develop.2
// See https://github.com/philsquared/Clara
#ifndef CLARA_HPP_INCLUDED
@@ -409,6 +409,14 @@ namespace detail {
std::string token;
};
inline auto isOptPrefix( char c ) -> bool {
return c == '-'
#ifdef CLARA_PLATFORM_WINDOWS
|| c == '/'
#endif
;
}
// Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled
class TokenStream {
using Iterator = std::vector<std::string>::const_iterator;
@@ -425,7 +433,7 @@ namespace detail {
if( it != itEnd ) {
auto const &next = *it;
if( next[0] == '-' || next[0] == '/' ) {
if( isOptPrefix( next[0] ) ) {
auto delimiterPos = next.find_first_of( " :=" );
if( delimiterPos != std::string::npos ) {
m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );
@@ -915,9 +923,11 @@ namespace detail {
};
inline auto normaliseOpt( std::string const &optName ) -> std::string {
#ifdef CLARA_PLATFORM_WINDOWS
if( optName[0] == '/' )
return "-" + optName.substr( 1 );
else
#endif
return optName;
}
@@ -958,11 +968,7 @@ namespace detail {
}
auto isMatch( std::string const &optToken ) const -> bool {
#ifdef CLARA_PLATFORM_WINDOWS
auto normalisedToken = normaliseOpt( optToken );
#else
auto const &normalisedToken = optToken;
#endif
for( auto const &name : m_optNames ) {
if( normaliseOpt( name ) == normalisedToken )
return true;
@@ -1012,8 +1018,13 @@ namespace detail {
for( auto const &name : m_optNames ) {
if( name.empty() )
return Result::logicError( "Option name cannot be empty" );
#ifdef CLARA_PLATFORM_WINDOWS
if( name[0] != '-' && name[0] != '/' )
return Result::logicError( "Option name must begin with '-' or '/'" );
#else
if( name[0] != '-' )
return Result::logicError( "Option name must begin with '-'" );
#endif
}
return ParserRefImpl::validate();
}
@@ -1142,18 +1153,24 @@ namespace detail {
size_t count = 0;
};
const size_t totalParsers = m_options.size() + m_args.size();
ParserInfo parseInfos[totalParsers];
size_t i = 0;
for( auto const& opt : m_options ) parseInfos[i++].parser = &opt;
for( auto const& arg : m_args ) parseInfos[i++].parser = &arg;
assert( totalParsers < 512 );
// ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do
ParserInfo parseInfos[512];
{
size_t i = 0;
for (auto const &opt : m_options) parseInfos[i++].parser = &opt;
for (auto const &arg : m_args) parseInfos[i++].parser = &arg;
}
m_exeName.set( exeName );
auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );
while( result.value().remainingTokens() ) {
bool tokenParsed = false;
for( auto& parseInfo : parseInfos ) {
for( size_t i = 0; i < totalParsers; ++i ) {
auto& parseInfo = parseInfos[i];
if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {
result = parseInfo.parser->parse(exeName, result.value().remainingTokens());
if (!result)

0 comments on commit 75a77b6

Please sign in to comment.