embedded v1.0-develop.2 of Clara, which addresses / prefixed options, which should impact non-windows platforms

See #1054
This commit is contained in:
Phil Nash 2017-10-21 09:16:38 +02:00
parent 5af918eefd
commit 75a77b6f8c
2 changed files with 45 additions and 17 deletions

View File

@ -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();
}

39
third_party/clara.hpp vendored
View File

@ -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,10 +1153,15 @@ 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 );
@ -1153,7 +1169,8 @@ namespace detail {
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)