diff options
| author | Phil Nash | 2014-03-24 18:15:04 +0000 |
|---|---|---|
| committer | Phil Nash | 2014-03-24 18:15:04 +0000 |
| commit | af8cd98f20a05828c0101e0344a28cc2a2bf9dd3 (patch) | |
| tree | 3a935a9a9d519f1de63af84b6ee58545cbd8b480 /include | |
| parent | 472dc2a61f9588ba817799742bac15d83c2432be (diff) | |
| download | catch3-af8cd98f20a05828c0101e0344a28cc2a2bf9dd3.tar.gz | |
New version of Clara that fixes operator= issue with ref member (#265)
Diffstat (limited to 'include')
| -rw-r--r-- | include/external/clara.h | 85 | ||||
| -rw-r--r-- | include/internal/catch_version.hpp | 2 |
2 files changed, 50 insertions, 37 deletions
diff --git a/include/external/clara.h b/include/external/clara.h index 4b83d1d6..549bade5 100644 --- a/include/external/clara.h +++ b/include/external/clara.h @@ -278,6 +278,10 @@ namespace Clara { functionObj->setFlag( config ); } bool takesArg() const { return functionObj->takesArg(); } + + bool isSet() const { + return functionObj != NULL; + } private: IArgFunction<ConfigT>* functionObj; }; @@ -426,11 +430,16 @@ namespace Clara { Detail::BoundArgFunction<ConfigT> boundField; std::string description; + std::string detail; std::string placeholder; // Only value if boundField takes an arg bool takesArg() const { return !placeholder.empty(); } + void validate() const { + if( !boundField.isSet() ) + throw std::logic_error( "option not bound" ); + } }; struct OptionArgProperties { std::vector<std::string> shortNames; @@ -442,7 +451,6 @@ namespace Clara { bool hasLongName( std::string const& _longName ) const { return _longName == longName; } - }; struct PositionalArgProperties { PositionalArgProperties() : position( -1 ) {} @@ -462,9 +470,6 @@ namespace Clara { using CommonArgProperties<ConfigT>::placeholder; // !TBD - bool isAnyPositional() const { - return position == -1 && shortNames.empty() && longName.empty(); - } std::string dbgName() const { if( !longName.empty() ) return "--" + longName; @@ -526,73 +531,72 @@ namespace Clara { class ArgBuilder { public: - ArgBuilder( Arg& arg ) : m_arg( arg ) {} + ArgBuilder( Arg* arg ) : m_arg( arg ) {} // Bind a non-boolean data member (requires placeholder string) template<typename C, typename M> void bind( M C::* field, std::string const& placeholder ) { - m_arg.boundField = new Detail::BoundDataMember<C,M>( field ); - m_arg.placeholder = placeholder; + m_arg->boundField = new Detail::BoundDataMember<C,M>( field ); + m_arg->placeholder = placeholder; } // Bind a boolean data member (no placeholder required) template<typename C> void bind( bool C::* field ) { - m_arg.boundField = new Detail::BoundDataMember<C,bool>( field ); + m_arg->boundField = new Detail::BoundDataMember<C,bool>( field ); } // Bind a method taking a single, non-boolean argument (requires a placeholder string) template<typename C, typename M> - void bind( void (C::*_unaryMethod)( M ), std::string const& placeholder ) { - m_arg.boundField = new Detail::BoundUnaryMethod<C,M>( _unaryMethod ); - m_arg.placeholder = placeholder; + void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod ); + m_arg->placeholder = placeholder; } // Bind a method taking a single, boolean argument (no placeholder string required) template<typename C> - void bind( void (C::*_unaryMethod)( bool ) ) { - m_arg.boundField = new Detail::BoundUnaryMethod<C,bool>( _unaryMethod ); + void bind( void (C::* unaryMethod)( bool ) ) { + m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod ); } // Bind a method that takes no arguments (will be called if opt is present) template<typename C> - void bind( void (C::*_nullaryMethod)() ) { - m_arg.boundField = new Detail::BoundNullaryMethod<C>( _nullaryMethod ); + void bind( void (C::* nullaryMethod)() ) { + m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod ); } // Bind a free function taking a single argument - the object to operate on (no placeholder string required) template<typename C> - void bind( void (*_unaryFunction)( C& ) ) { - m_arg.boundField = new Detail::BoundUnaryFunction<C>( _unaryFunction ); + void bind( void (* unaryFunction)( C& ) ) { + m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction ); } // Bind a free function taking a single argument - the object to operate on (requires a placeholder string) template<typename C, typename T> - void bind( void (*_binaryFunction)( C&, T ), std::string const& placeholder ) { - m_arg.boundField = new Detail::BoundBinaryFunction<C, T>( _binaryFunction ); - m_arg.placeholder = placeholder; + void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction ); + m_arg->placeholder = placeholder; } ArgBuilder& describe( std::string const& description ) { - m_arg.description = description; + m_arg->description = description; return *this; } - ArgBuilder& detail( std::string const& ) { -// m_arg.description = description; -// !TBD + ArgBuilder& detail( std::string const& detail ) { + m_arg->detail = detail; return *this; } protected: - Arg& m_arg; + Arg* m_arg; }; class OptBuilder : public ArgBuilder { public: - OptBuilder( Arg& arg ) : ArgBuilder( arg ) {} + OptBuilder( Arg* arg ) : ArgBuilder( arg ) {} OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {} OptBuilder& operator[]( std::string const& optName ) { - addOptName( ArgBuilder::m_arg, optName ); + addOptName( *ArgBuilder::m_arg, optName ); return *this; } }; @@ -624,7 +628,7 @@ namespace Clara { OptBuilder operator[]( std::string const& optName ) { m_options.push_back( Arg() ); addOptName( m_options.back(), optName ); - OptBuilder builder( m_options.back() ); + OptBuilder builder( &m_options.back() ); return builder; } @@ -633,7 +637,7 @@ namespace Clara { if( position > m_highestSpecifiedArgPosition ) m_highestSpecifiedArgPosition = position; setPositionalArg( m_positionalArgs[position], position ); - ArgBuilder builder( m_positionalArgs[position] ); + ArgBuilder builder( &m_positionalArgs[position] ); return builder; } @@ -642,7 +646,7 @@ namespace Clara { if( m_floatingArg.get() ) throw std::logic_error( "Only one unpositional argument can be added" ); m_floatingArg = ArgAutoPtr( new Arg() ); - ArgBuilder builder( *m_floatingArg ); + ArgBuilder builder( m_floatingArg.get() ); return builder; } @@ -665,9 +669,8 @@ namespace Clara { Detail::Text usage( it->commands(), Detail::TextAttributes() .setWidth( maxWidth+indent ) .setIndent( indent ) ); - // !TBD handle longer usage strings Detail::Text desc( it->description, Detail::TextAttributes() - .setWidth( width - maxWidth -3 ) ); + .setWidth( width - maxWidth - 3 ) ); for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) { std::string usageCol = i < usage.size() ? usage[i] : ""; @@ -712,6 +715,7 @@ namespace Clara { } void usage( std::ostream& os, std::string const& procName ) const { + validate(); os << "usage:\n " << procName << " "; argSynopsis( os ); if( !m_options.empty() ) { @@ -726,7 +730,7 @@ namespace Clara { return oss.str(); } - ConfigT parseInto( int argc, char const * const * argv ) const { + ConfigT parse( int argc, char const * const * argv ) const { ConfigT config; parseInto( argc, argv, config ); return config; @@ -745,9 +749,7 @@ namespace Clara { } std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const { - if( m_options.empty() && m_positionalArgs.empty() ) - throw std::logic_error( "No options or arguments specified" ); - + validate(); std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config ); unusedTokens = populateFixedArgs( unusedTokens, config ); unusedTokens = populateFloatingArgs( unusedTokens, config ); @@ -831,6 +833,17 @@ namespace Clara { return unusedTokens; } + void validate() const + { + if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() ) + throw std::logic_error( "No options or arguments specified" ); + + for( typename std::vector<Arg>::const_iterator it = m_options.begin(), + itEnd = m_options.end(); + it != itEnd; ++it ) + it->validate(); + } + private: Detail::BoundArgFunction<ConfigT> m_boundProcessName; std::vector<Arg> m_options; diff --git a/include/internal/catch_version.hpp b/include/internal/catch_version.hpp index c9bdeb84..ef1d2371 100644 --- a/include/internal/catch_version.hpp +++ b/include/internal/catch_version.hpp @@ -13,7 +13,7 @@ namespace Catch { // These numbers are maintained by a script - Version libraryVersion( 1, 0, 32, "master" ); + Version libraryVersion( 1, 0, 33, "master" ); } #endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED |