diff --git a/include/catch_runner.hpp b/include/catch_runner.hpp index eb679d14..a927e022 100644 --- a/include/catch_runner.hpp +++ b/include/catch_runner.hpp @@ -152,7 +152,7 @@ namespace Catch { OptionParser& opt = **it; os << " " << opt.optionNames() << " " << opt.argsSynopsis() << "\n"; } - os << "For more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line" << std::endl; + os << "\nFor more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line\n" << std::endl; } inline void showHelp( std::string exeName ) { std::string::size_type pos = exeName.find_last_of( "/\\" ); diff --git a/include/internal/catch_commandline.hpp b/include/internal/catch_commandline.hpp index 0ed4b8d4..0778eb5a 100644 --- a/include/internal/catch_commandline.hpp +++ b/include/internal/catch_commandline.hpp @@ -17,7 +17,8 @@ namespace Catch { public: Command(){} - explicit Command( const std::string& name ) : m_name( name ) {} + explicit Command( const std::string& name ) : m_name( name ) { + } Command& operator += ( const std::string& arg ) { m_args.push_back( arg ); @@ -46,9 +47,13 @@ namespace Catch { CATCH_ATTRIBUTE_NORETURN void raiseError( const std::string& message ) const { std::ostringstream oss; - oss << "Error while parsing " << m_name << ". " << message << "."; + if( m_name.empty() ) + oss << "Error while parsing " << m_name << ". " << message << "."; + else + oss << "Error while parsing arguments. " << message << "."; + if( m_args.size() > 0 ) - oss << " Arguments where:"; + oss << " Arguments were:"; for( std::size_t i = 0; i < m_args.size(); ++i ) oss << " " << m_args[i]; throw std::domain_error( oss.str() ); @@ -98,6 +103,10 @@ namespace Catch { class OptionParser : public SharedImpl { public: + OptionParser( int minArgs = 0, int maxArgs = 0 ) + : m_minArgs( minArgs ), m_maxArgs( maxArgs ) + {} + virtual ~OptionParser() {} Command find( const CommandParser& parser ) const { @@ -109,9 +118,24 @@ namespace Catch { return cmd; } + void validateArgs( const Command& args ) const { + if( tooFewArgs( args ) || tooManyArgs( args ) ) { + std::ostringstream oss; + if( m_maxArgs == -1 ) + oss <<"Expected at least " << pluralise( static_cast( m_minArgs ), "argument" ); + else if( m_minArgs == m_maxArgs ) + oss <<"Expected " << pluralise( static_cast( m_minArgs ), "argument" ); + else + oss <<"Expected between " << m_minArgs << " and " << m_maxArgs << " argument"; + args.raiseError( oss.str() ); + } + } + void parseIntoConfig( const CommandParser& parser, ConfigData& config ) { - if( Command cmd = find( parser ) ) + if( Command cmd = find( parser ) ) { + validateArgs( cmd ); parseIntoConfig( cmd, config ); + } } virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) = 0; @@ -138,7 +162,16 @@ namespace Catch { } protected: + + bool tooFewArgs( const Command& args ) const { + return args.argsCount() < static_cast( m_minArgs ); + } + bool tooManyArgs( const Command& args ) const { + return m_maxArgs >= 0 && args.argsCount() > static_cast( m_maxArgs ); + } std::vector m_optionNames; + int m_minArgs; + int m_maxArgs; }; namespace Options { @@ -164,7 +197,7 @@ namespace Catch { class TestCaseOptionParser : public OptionParser { public: - TestCaseOptionParser() { + TestCaseOptionParser() : OptionParser( 1, -1 ) { m_optionNames.push_back( "-t" ); m_optionNames.push_back( "--test" ); m_optionNames.push_back( "" ); // default option @@ -177,8 +210,6 @@ namespace Catch { } virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { - if( cmd.argsCount() == 0 ) - cmd.raiseError( "Expected at least one argument" ); std::string groupName; for( std::size_t i = 0; i < cmd.argsCount(); ++i ) { if( i != 0 ) @@ -200,7 +231,7 @@ namespace Catch { class ListOptionParser : public OptionParser { public: - ListOptionParser() { + ListOptionParser() : OptionParser( 0, 2 ) { m_optionNames.push_back( "-l" ); m_optionNames.push_back( "--list" ); } @@ -212,9 +243,6 @@ namespace Catch { } virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { - if( cmd.argsCount() > 2 ) - cmd.raiseError( "Expected upto 2 arguments" ); - config.listSpec = List::TestNames; if( cmd.argsCount() >= 1 ) { if( cmd[0] == "all" ) @@ -239,7 +267,7 @@ namespace Catch { class ReporterOptionParser : public OptionParser { public: - ReporterOptionParser() { + ReporterOptionParser() : OptionParser( 1, 1 ) { m_optionNames.push_back( "-r" ); m_optionNames.push_back( "--reporter" ); } @@ -251,15 +279,13 @@ namespace Catch { } virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { - if( cmd.argsCount() != 1 ) - cmd.raiseError( "Expected one argument" ); config.reporter = cmd[0]; } }; class OutputOptionParser : public OptionParser { public: - OutputOptionParser() { + OutputOptionParser() : OptionParser( 1, 1 ) { m_optionNames.push_back( "-o" ); m_optionNames.push_back( "--out" ); } @@ -271,8 +297,6 @@ namespace Catch { } virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { - if( cmd.argsCount() == 0 ) - cmd.raiseError( "Expected filename" ); if( cmd[0][0] == '%' ) config.stream = cmd[0].substr( 1 ); else @@ -294,8 +318,6 @@ namespace Catch { } virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { - if( cmd.argsCount() != 0 ) - cmd.raiseError( "Does not accept arguments" ); config.includeWhichResults = Include::SuccessfulResults; } }; @@ -314,15 +336,13 @@ namespace Catch { } virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { - if( cmd.argsCount() != 0 ) - cmd.raiseError( "Does not accept arguments" ); config.shouldDebugBreak = true; } }; class NameOptionParser : public OptionParser { public: - NameOptionParser() { + NameOptionParser() : OptionParser( 1, 1 ) { m_optionNames.push_back( "-n" ); m_optionNames.push_back( "--name" ); } @@ -334,15 +354,13 @@ namespace Catch { } virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { - if( cmd.argsCount() != 1 ) - cmd.raiseError( "Expected a name" ); config.name = cmd[0]; } }; class AbortOptionParser : public OptionParser { public: - AbortOptionParser() { + AbortOptionParser() : OptionParser( 0, 1 ) { m_optionNames.push_back( "-a" ); m_optionNames.push_back( "--abort" ); } @@ -354,8 +372,6 @@ namespace Catch { } virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { - if( cmd.argsCount() > 1 ) - cmd.raiseError( "Only accepts 0-1 arguments" ); int threshold = 1; if( cmd.argsCount() == 1 ) { std::stringstream ss; @@ -382,8 +398,6 @@ namespace Catch { } virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { - if( cmd.argsCount() != 0 ) - cmd.raiseError( "Does not accept arguments" ); config.allowThrows = false; } }; diff --git a/projects/SelfTest/TestMain.cpp b/projects/SelfTest/TestMain.cpp index d7031081..9575cfa1 100644 --- a/projects/SelfTest/TestMain.cpp +++ b/projects/SelfTest/TestMain.cpp @@ -159,7 +159,7 @@ TEST_CASE( "selftest/parser/2", "ConfigData" ) { SECTION( "-t/0", "When no test names are supplied it is an error" ) { const char* argv[] = { "test", "-t" }; - REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "at least one" ) ); + REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "at least 1" ) ); } } @@ -184,7 +184,7 @@ TEST_CASE( "selftest/parser/2", "ConfigData" ) { } SECTION( "-r/error", "reporter config only accepts one argument" ) { const char* argv[] = { "test", "-r", "one", "two" }; - REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "one argument" ) ); + REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "1 argument" ) ); } } @@ -203,7 +203,7 @@ TEST_CASE( "selftest/parser/2", "ConfigData" ) { } SECTION( "-b", "break option has no arguments" ) { const char* argv[] = { "test", "-b", "unexpected" }; - REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "not accept" ) ); + REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "0 arguments" ) ); } } @@ -230,7 +230,7 @@ TEST_CASE( "selftest/parser/2", "ConfigData" ) { } SECTION( "-a/error/two args", "cutoff only takes one argument" ) { const char* argv[] = { "test", "-a", "1", "2" }; - REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "accepts" ) ); + REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "0 and 1 argument" ) ); } } diff --git a/single_include/catch.hpp b/single_include/catch.hpp index 776178d7..fdb2b262 100644 --- a/single_include/catch.hpp +++ b/single_include/catch.hpp @@ -1,5 +1,5 @@ /* - * Generated: 2012-08-24 19:01:02.483106 + * Generated: 2012-08-27 21:42:22.556899 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. @@ -2480,7 +2480,8 @@ namespace Catch { public: Command(){} - explicit Command( const std::string& name ) : m_name( name ) {} + explicit Command( const std::string& name ) : m_name( name ) { + } Command& operator += ( const std::string& arg ) { m_args.push_back( arg ); @@ -2509,9 +2510,13 @@ namespace Catch { CATCH_ATTRIBUTE_NORETURN void raiseError( const std::string& message ) const { std::ostringstream oss; - oss << "Error while parsing " << m_name << ". " << message << "."; + if( m_name.empty() ) + oss << "Error while parsing " << m_name << ". " << message << "."; + else + oss << "Error while parsing arguments. " << message << "."; + if( m_args.size() > 0 ) - oss << " Arguments where:"; + oss << " Arguments were:"; for( std::size_t i = 0; i < m_args.size(); ++i ) oss << " " << m_args[i]; throw std::domain_error( oss.str() ); @@ -2535,9 +2540,12 @@ namespace Catch { return find( shortArg ) + find( longArg ); } Command find( const std::string& arg ) const { - for( std::size_t i = 1; i < m_argc; ++i ) - if( m_argv[i] == arg ) - return getArgs( m_argv[i], i+1 ); + if( arg.empty() ) + return getArgs( "", 1 ); + else + for( std::size_t i = 1; i < m_argc; ++i ) + if( m_argv[i] == arg ) + return getArgs( m_argv[i], i+1 ); return Command(); } Command getDefaultArgs() const { @@ -2556,109 +2564,349 @@ namespace Catch { char const * const * m_argv; }; - inline void parseIntoConfig( const CommandParser& parser, ConfigData& config ) { + class OptionParser : public SharedImpl { + public: + OptionParser( int minArgs = 0, int maxArgs = 0 ) + : m_minArgs( minArgs ), m_maxArgs( maxArgs ) + {} - if( Command cmd = parser.find( "-l", "--list" ) ) { - if( cmd.argsCount() > 2 ) - cmd.raiseError( "Expected upto 2 arguments" ); + virtual ~OptionParser() {} - config.listSpec = List::TestNames; - if( cmd.argsCount() >= 1 ) { - if( cmd[0] == "all" ) - config.listSpec = List::All; - else if( cmd[0] == "tests" ) - config.listSpec = List::Tests; - else if( cmd[0] == "reporters" ) - config.listSpec = List::Reports; + Command find( const CommandParser& parser ) const { + Command cmd; + for( std::vector::const_iterator it = m_optionNames.begin(); + it != m_optionNames.end(); + ++it ) + cmd += parser.find( *it ); + return cmd; + } + + void validateArgs( const Command& args ) const { + if( tooFewArgs( args ) || tooManyArgs( args ) ) { + std::ostringstream oss; + if( m_maxArgs == -1 ) + oss <<"Expected at least " << pluralise( static_cast( m_minArgs ), "argument" ); + else if( m_minArgs == m_maxArgs ) + oss <<"Expected " << pluralise( static_cast( m_minArgs ), "argument" ); else - cmd.raiseError( "Expected [tests] or [reporters]" ); + oss <<"Expected between " << m_minArgs << " and " << m_maxArgs << " argument"; + args.raiseError( oss.str() ); } - if( cmd.argsCount() >= 2 ) { - if( cmd[1] == "xml" ) - config.listSpec = static_cast( config.listSpec | List::AsXml ); - else if( cmd[1] == "text" ) - config.listSpec = static_cast( config.listSpec | List::AsText ); + } + + void parseIntoConfig( const CommandParser& parser, ConfigData& config ) { + if( Command cmd = find( parser ) ) { + validateArgs( cmd ); + parseIntoConfig( cmd, config ); + } + } + + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) = 0; + virtual std::string argsSynopsis() const = 0; + virtual std::string optionSummary() const = 0; + + std::string optionNames() const { + std::string names; + for( std::vector::const_iterator it = m_optionNames.begin(); + it != m_optionNames.end(); + ++it ) { + if( !it->empty() ) { + if( !names.empty() ) + names += ", "; + names += *it; + } + else { + names = "[" + names; + } + } + if( names[0] == '[' ) + names += "]"; + return names; + } + + protected: + + bool tooFewArgs( const Command& args ) const { + return args.argsCount() < static_cast( m_minArgs ); + } + bool tooManyArgs( const Command& args ) const { + return m_maxArgs >= 0 && args.argsCount() > static_cast( m_maxArgs ); + } + std::vector m_optionNames; + int m_minArgs; + int m_maxArgs; + }; + + namespace Options { + + class HelpOptionParser : public OptionParser { + public: + HelpOptionParser() { + m_optionNames.push_back( "-?" ); + m_optionNames.push_back( "-h" ); + m_optionNames.push_back( "--help" ); + } + virtual std::string argsSynopsis() const { + return ""; + } + virtual std::string optionSummary() const { + return "Shows this usage summary"; + } + + virtual void parseIntoConfig( const Command&, ConfigData& ) { + // Does not affect config + } + }; + + class TestCaseOptionParser : public OptionParser { + public: + TestCaseOptionParser() : OptionParser( 1, -1 ) { + m_optionNames.push_back( "-t" ); + m_optionNames.push_back( "--test" ); + m_optionNames.push_back( "" ); // default option + } + virtual std::string argsSynopsis() const { + return " [...]"; + } + virtual std::string optionSummary() const { + return "Specify which test case or cases to run"; + } + + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { + std::string groupName; + for( std::size_t i = 0; i < cmd.argsCount(); ++i ) { + if( i != 0 ) + groupName += " "; + groupName += cmd[i]; + } + TestCaseFilters filters( groupName ); + for( std::size_t i = 0; i < cmd.argsCount(); ++i ) { + if( startsWith( cmd[i], "exclude:" ) ) + filters.addFilter( TestCaseFilter( cmd[i].substr( 8 ), IfFilterMatches::ExcludeTests ) ); + else if( startsWith( cmd[i], "~" ) ) + filters.addFilter( TestCaseFilter( cmd[i].substr( 1 ), IfFilterMatches::ExcludeTests ) ); + else + filters.addFilter( TestCaseFilter( cmd[i] ) ); + } + config.filters.push_back( filters ); + } + }; + + class ListOptionParser : public OptionParser { + public: + ListOptionParser() : OptionParser( 0, 2 ) { + m_optionNames.push_back( "-l" ); + m_optionNames.push_back( "--list" ); + } + virtual std::string argsSynopsis() const { + return "[all | tests | reporters [xml]]"; + } + virtual std::string optionSummary() const { + return "!TBD"; + } + + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { + config.listSpec = List::TestNames; + if( cmd.argsCount() >= 1 ) { + if( cmd[0] == "all" ) + config.listSpec = List::All; + else if( cmd[0] == "tests" ) + config.listSpec = List::Tests; + else if( cmd[0] == "reporters" ) + config.listSpec = List::Reports; + else + cmd.raiseError( "Expected [tests] or [reporters]" ); + } + if( cmd.argsCount() >= 2 ) { + if( cmd[1] == "xml" ) + config.listSpec = static_cast( config.listSpec | List::AsXml ); + else if( cmd[1] == "text" ) + config.listSpec = static_cast( config.listSpec | List::AsText ); + else + cmd.raiseError( "Expected [xml] or [text]" ); + } + } + }; + + class ReporterOptionParser : public OptionParser { + public: + ReporterOptionParser() : OptionParser( 1, 1 ) { + m_optionNames.push_back( "-r" ); + m_optionNames.push_back( "--reporter" ); + } + virtual std::string argsSynopsis() const { + return ""; + } + virtual std::string optionSummary() const { + return "!TBD"; + } + + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { + config.reporter = cmd[0]; + } + }; + + class OutputOptionParser : public OptionParser { + public: + OutputOptionParser() : OptionParser( 1, 1 ) { + m_optionNames.push_back( "-o" ); + m_optionNames.push_back( "--out" ); + } + virtual std::string argsSynopsis() const { + return "|<%stream name>"; + } + virtual std::string optionSummary() const { + return "!TBD"; + } + + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { + if( cmd[0][0] == '%' ) + config.stream = cmd[0].substr( 1 ); else - cmd.raiseError( "Expected [xml] or [text]" ); + config.outputFilename = cmd[0]; } - } + }; - if( Command cmd = parser.find( "-t", "--test" ) + parser.getDefaultArgs() ) { - if( cmd.argsCount() == 0 ) - cmd.raiseError( "Expected at least one argument" ); - std::string groupName; - for( std::size_t i = 0; i < cmd.argsCount(); ++i ) { - if( i != 0 ) - groupName += " "; - groupName += cmd[i]; + class SuccesssOptionParser : public OptionParser { + public: + SuccesssOptionParser() { + m_optionNames.push_back( "-s" ); + m_optionNames.push_back( "--success" ); } - TestCaseFilters filters( groupName ); - for( std::size_t i = 0; i < cmd.argsCount(); ++i ) { - if( startsWith( cmd[i], "exclude:" ) ) - filters.addFilter( TestCaseFilter( cmd[i].substr( 8 ), IfFilterMatches::ExcludeTests ) ); - else if( startsWith( cmd[i], "~" ) ) - filters.addFilter( TestCaseFilter( cmd[i].substr( 1 ), IfFilterMatches::ExcludeTests ) ); - else - filters.addFilter( TestCaseFilter( cmd[i] ) ); + virtual std::string argsSynopsis() const { + return ""; } - config.filters.push_back( filters ); - } - - if( Command cmd = parser.find( "-r", "--reporter" ) ) { - if( cmd.argsCount() != 1 ) - cmd.raiseError( "Expected one argument" ); - config.reporter = cmd[0]; - } - - if( Command cmd = parser.find( "-o", "--out" ) ) { - if( cmd.argsCount() == 0 ) - cmd.raiseError( "Expected filename" ); - if( cmd[0][0] == '%' ) - config.stream = cmd[0].substr( 1 ); - else - config.outputFilename = cmd[0]; - } - - if( Command cmd = parser.find( "-s", "--success" ) ) { - if( cmd.argsCount() != 0 ) - cmd.raiseError( "Does not accept arguments" ); - config.includeWhichResults = Include::SuccessfulResults; - } - - if( Command cmd = parser.find( "-b", "--break" ) ) { - if( cmd.argsCount() != 0 ) - cmd.raiseError( "Does not accept arguments" ); - config.shouldDebugBreak = true; - } - - if( Command cmd = parser.find( "-n", "--name" ) ) { - if( cmd.argsCount() != 1 ) - cmd.raiseError( "Expected a name" ); - config.name = cmd[0]; - } - - if( Command cmd = parser.find( "-a", "--abort" ) ) { - if( cmd.argsCount() > 1 ) - cmd.raiseError( "Only accepts 0-1 arguments" ); - int threshold = 1; - if( cmd.argsCount() == 1 ) { - std::stringstream ss; - ss << cmd[0]; - ss >> threshold; - if( ss.fail() || threshold <= 0 ) - cmd.raiseError( "threshold must be a number greater than zero" ); + virtual std::string optionSummary() const { + return "!TBD"; } - config.cutoff = threshold; - } - if( Command cmd = parser.find( "-nt", "--nothrow" ) ) { - if( cmd.argsCount() != 0 ) - cmd.raiseError( "Does not accept arguments" ); - config.allowThrows = false; - } + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { + config.includeWhichResults = Include::SuccessfulResults; + } + }; + class DebugBreakOptionParser : public OptionParser { + public: + DebugBreakOptionParser() { + m_optionNames.push_back( "-b" ); + m_optionNames.push_back( "--break" ); + } + virtual std::string argsSynopsis() const { + return ""; + } + virtual std::string optionSummary() const { + return "!TBD"; + } + + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { + config.shouldDebugBreak = true; + } + }; + + class NameOptionParser : public OptionParser { + public: + NameOptionParser() : OptionParser( 1, 1 ) { + m_optionNames.push_back( "-n" ); + m_optionNames.push_back( "--name" ); + } + virtual std::string argsSynopsis() const { + return ""; + } + virtual std::string optionSummary() const { + return "!TBD"; + } + + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { + config.name = cmd[0]; + } + }; + + class AbortOptionParser : public OptionParser { + public: + AbortOptionParser() : OptionParser( 0, 1 ) { + m_optionNames.push_back( "-a" ); + m_optionNames.push_back( "--abort" ); + } + virtual std::string argsSynopsis() const { + return "[#]"; + } + virtual std::string optionSummary() const { + return "!TBD"; + } + + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { + int threshold = 1; + if( cmd.argsCount() == 1 ) { + std::stringstream ss; + ss << cmd[0]; + ss >> threshold; + if( ss.fail() || threshold <= 0 ) + cmd.raiseError( "threshold must be a number greater than zero" ); + } + config.cutoff = threshold; + } + }; + + class NoThrowOptionParser : public OptionParser { + public: + NoThrowOptionParser() { + m_optionNames.push_back( "-nt" ); + m_optionNames.push_back( "--nothrow" ); + } + virtual std::string argsSynopsis() const { + return ""; + } + virtual std::string optionSummary() const { + return "!TBD"; + } + + virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { + config.allowThrows = false; + } + }; } + class AllOptions + { + public: + typedef std::vector > Parsers; + typedef Parsers::const_iterator const_iterator; + typedef Parsers::const_iterator iterator; + + AllOptions() { + add(); + add(); + add(); + add(); + add(); + add(); + add(); + add(); + add(); + add(); + } + + void parseIntoConfig( const CommandParser& parser, ConfigData& config ) { + for( const_iterator it = m_parsers.begin(); it != m_parsers.end(); ++it ) + (*it)->parseIntoConfig( parser, config ); + } + + const_iterator begin() const { + return m_parsers.begin(); + } + const_iterator end() const { + return m_parsers.end(); + } + private: + + template + void add() { + m_parsers.push_back( new T() ); + } + Parsers m_parsers; + + }; + } // end namespace Catch // #included from: internal/catch_list.hpp @@ -3307,17 +3555,12 @@ namespace Catch { } inline void showUsage( std::ostream& os ) { - os << "\t-?, -h, --help\n" - << "\t-l, --list [all | tests | reporters [xml]]\n" - << "\t-t, --test [...]\n" - << "\t-r, --reporter \n" - << "\t-o, --out |<%stream name>\n" - << "\t-s, --success\n" - << "\t-b, --break\n" - << "\t-n, --name \n" - << "\t-a, --abort [#]\n" - << "\t-nt, --nothrow\n\n" - << "For more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line" << std::endl; + AllOptions options; + for( AllOptions::const_iterator it = options.begin(); it != options.end(); ++it ) { + OptionParser& opt = **it; + os << " " << opt.optionNames() << " " << opt.argsSynopsis() << "\n"; + } + os << "\nFor more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line\n" << std::endl; } inline void showHelp( std::string exeName ) { std::string::size_type pos = exeName.find_last_of( "/\\" ); @@ -3334,7 +3577,7 @@ namespace Catch { try { CommandParser parser( argc, argv ); - if( Command cmd = parser.find( "-h", "-?", "--help" ) ) { + if( Command cmd = Options::HelpOptionParser().find( parser ) ) { if( cmd.argsCount() != 0 ) cmd.raiseError( "Does not accept arguments" ); @@ -3343,7 +3586,9 @@ namespace Catch { return 0; } - parseIntoConfig( parser, config.data() ); + AllOptions options; + + options.parseIntoConfig( parser, config.data() ); } catch( std::exception& ex ) { std::cerr << ex.what() << "\n\nUsage: ...\n\n";