A simple command line parser written by standard C++.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
googletest
include
src/program_options
test
.gitignore
CMakeLists.txt
LICENSE
README.md

README.md

ProgramOptions

ProgramOptions is a helper for creating and managing CommandLine, it can be used for parsing command line as well as generate usage information automatically.

It stores options and values into a map.

It's easy to check whether an option exist, and get value with a specified type.

Usage

ProgramOptions includes two parts,

  • parser
  • usage generator

both part can be simply used as following:

parser

  1. Include the header 'program_options/parser.h'.
  2. Note that Parser is in the program_options namespace.
  3. Declare an object associates with Parser.
  4. Then call Parser::parse() manually.
  5. Verify an option by calling has(),has_or(),has_and().
  6. To get a value from specified option by calling get() and then as< T >().
// $ path/to/program -xyz 3.14 --option value
Parser parser;
parser.parse(argc, argv);

// to get a value from an option
parser.get("z")->as<double>();
parser.get("option")->val(); // std::string

// verify an option
parser.has("option")

// verify a sequence of options (deprecated)
parser.has_or(2, "x", "y");
parser.has_and(2, "option", "c");
parser.has_and(1, "-xy");

// more simple way
parser.has_or({"x", "y"});
parser.has_and({"option", "c"});
parser.has_and({"-xy"});

It also supports "=" to assign a value to an option:

// $ path/to/program --option=value1,value2... -c=config.json
parser.get("option")->val(); // value1,value2...
parser.get("c")->as<std::string>(); // config.json

Subroutine parsing is also ok:

// $ path/to/program pull --option xx
parser.get_subroutine_name(); // pull
parser.get("option")->val(); // xx

For more details and examples, check out test/parser_test.cc

usage generator

  1. Include the header 'program_options/generator.h'.
  2. Declare an object associate with Generator.
  3. Begin with Generator::make_usage().
  4. Then just append parentheses and add your options and descriptions.
  5. Finally, just std::cout << object; and you will get all usage information.
Generator generator;

generator.make_usage("Usage for example:")
      ("h,help", "show help information")
      ("o,option", "", "this is an option")
      (",option-2", "this is the option 2")
      ("c,", "this is option c")
      ("p,position", "0.0", "position of a place");

cout << generator;

/*
Usage for example:
  -h [ --help ]               show help information
  -o [ --option ] arg         this is an option
  --option-2                  this is the option 2
  -c                          this is option c
  -p [ --position ] arg = 0.0 position of a place
*/

Note:

  • The first parameter's format: short-form,long-form, You can set any one of them or both.
  • If you don't require a value of an option, you don't need to set the second parameter inside the parentheses, and the arg will not be displayed. Otherwise, set it.
  • If no comma in the first parameter, this usage row will be ignored.

Your program may has subroutines, it can be easily done with Generator::add_subroutine():

Generator generator;

generator.make_usage("Usage for example:")
         .add_subroutine("pull", "description of pull")
      ("h,help", "show help information")
      ("o,option", "", "this is an option")
      (",option-2", "this is the option 2")
      ("c,", "this is option c")
      ("p,position", "0.0", "position of a place");

cout << generator; // will print all subroutines you added.
cout << generator("pull"); // just the "pull" 's usages.

Note that every usages collection has a subroutine, if you didn't call add_subroutine, it will add a default routine EmptySubroutine (see Subroutine::get_default_name()). In fact, it will not be displayed while printing.

For more examples, check out test/generator_test.cc

Make a combination

At present, the two parts above can be used together.

Consider the following situation:

As the usage generator example shows, assignment of -o and --option are the same, but we don't know which one is given, how parser check it out?

In the previous version,

if (parser.has_or(2, "o", "option"))
    // -o or --option was set
// or
if (parser.has("o") || parser.has("option"))
    // -o or --option was set

as you see, when we have a lot of option to be checked, it's so wordy and unfriendly.

But now, you can get parser through Generator::make_parser():

Parser* parser = generator.make_parser();

then the parser have known the rules generated by generator.

if (parser->has("o"))
// or if(parser->has("option"))
// that's enough.

Don't worry about the value that any option takes, also ok for taking a value of default value from an option:

float position = parser->get("p")->as<float>();
// float position = parser->get("position")->as<float>();
// as you like.

For more examples, check out test/combination_test.cc

Make a template

The latest version of ProgramOption allows you to make an user-defined template for Generator:

Generator generator;
generator
    .add_subroutine("sub")
    .make_template("-% | --% %", {Row::kShort, Row::kLong, Row::kDescription})
    ("h,help", "show help");
std::cout << gen("sub");
/*
-h | --help show help
*/

Note that template allows you to use your own style for outputing, but it will lose some features such as: auto-align, it isn't smart enough. The default output style is recommended.

TODOs

Nothing to do at the moment. Waiting for your advice.