Last active
May 21, 2018 22:43
-
-
Save martinmoene/af3373474cacc0f93051 to your computer and use it in GitHub Desktop.
C++ option handling without dedicated library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using text = std::string; | |
| using texts = std::vector<text>; | |
| inline auto split_option( text arg ) -> std::tuple<text, text> | |
| { | |
| auto pos = arg.rfind( '=' ); | |
| return pos == text::npos | |
| ? std::make_tuple( arg, "" ) | |
| : std::make_tuple( arg.substr( 0, pos ), arg.substr( pos + 1 ) ); | |
| } | |
| inline auto split_arguments( texts args ) -> std::tuple<options, texts> | |
| { | |
| options option; texts in; | |
| bool in_options = true; | |
| for ( auto & arg : args ) | |
| { | |
| if ( in_options ) | |
| { | |
| text opt, val; | |
| std::tie( opt, val ) = split_option( arg ); | |
| if ( opt[0] != '-' ) { in_options = false; } | |
| else if ( opt == "--" ) { in_options = false; continue; } | |
| else if ( opt == "-h" || "--help" == opt ) { option.help = true; continue; } | |
| else if ( opt == "-a" || "--abort" == opt ) { option.abort = true; continue; } | |
| else if ( opt == "-c" || "--count" == opt ) { option.count = true; continue; } | |
| else if ( opt == "-g" || "--list-tags" == opt ) { option.tags = true; continue; } | |
| else if ( opt == "-l" || "--list-tests" == opt ) { option.list = true; continue; } | |
| else if ( opt == "-t" || "--time" == opt ) { option.time = true; continue; } | |
| else if ( opt == "-p" || "--pass" == opt ) { option.pass = true; continue; } | |
| else if ( "--version" == opt ) { option.version = true; continue; } | |
| else if ( opt == "--order" && "declared" == val ) { /* by definition */ ; continue; } | |
| else if ( opt == "--order" && "lexical" == val ) { option.lexical = true; continue; } | |
| else if ( opt == "--order" && "random" == val ) { option.random = true; continue; } | |
| else if ( opt == "--random-seed" ) { option.seed = seed ( "--random-seed", val ); continue; } | |
| else if ( opt == "--repeat" ) { option.repeat = repeat( "--repeat" , val ); continue; } | |
| else throw std::runtime_error( "unrecognised option '" + arg + "' (try option --help)" ); | |
| } | |
| in.push_back( arg ); | |
| } | |
| return std::make_tuple( option, in ); | |
| } | |
| inline int usage( std::ostream & os ) | |
| { | |
| os << | |
| "\nUsage: test [options] [test-spec ...]\n" | |
| "\n" | |
| "Options:\n" | |
| " -h, --help this help message\n" | |
| " -a, --abort abort at first failure\n" | |
| " -c, --count count selected tests\n" | |
| " -g, --list-tags list tags of selected tests\n" | |
| " -l, --list-tests list selected tests\n" | |
| " -p, --pass also report passing tests\n" | |
| " -t, --time list duration of selected tests\n" | |
| " --order=declared use source code test order (default)\n" | |
| " --order=lexical use lexical sort test order\n" | |
| " --order=random use random test order\n" | |
| " --random-seed=n use n for random generator seed\n" | |
| " --random-seed=time use time for random generator seed\n" | |
| " --repeat=n repeat selected tests n times (-1: indefinite)\n" | |
| " --version report lest version and compiler used\n" | |
| " -- end options\n" | |
| "\n" | |
| "Test specification:\n" | |
| " \"@\", \"*\" all tests, unless excluded\n" | |
| " empty all tests, unless tagged [hide] or [.optional-name]\n" | |
| #if lest_FEATURE_REGEX_SEARCH | |
| " \"re\" select tests that match regular expression\n" | |
| " \"!re\" omit tests that match regular expression\n" | |
| #else | |
| " \"text\" select tests that contain text (case insensitive)\n" | |
| " \"!text\" omit tests that contain text (case insensitive)\n" | |
| #endif | |
| ; | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment