Parse and store options from argc and argv.
Inspired by the Python library argparse.
Header-only library available at single_include/blet/args.h.
Documentation available at documentation.
#include <iostream>
#include "blet/args.h"
enum eLogLevel {
EMERG_LEVEL = 0,
ALERT_LEVEL,
CRITICAL_LEVEL,
ERROR_LEVEL,
WARNING_LEVEL,
NOTICE_LEVEL,
INFO_LEVEL,
DEBUG_LEVEL
};
void argToLogLevel(eLogLevel& logLevel, bool /*isExists*/, const std::string& argument) {
if (argument == "EMERG" || argument == "0") {
logLevel = EMERG_LEVEL;
}
else if (argument == "ALERT" || argument == "1") {
logLevel = ALERT_LEVEL;
}
else if (argument == "CRITICAL" || argument == "2") {
logLevel = CRITICAL_LEVEL;
}
else if (argument == "ERROR" || argument == "3") {
logLevel = ERROR_LEVEL;
}
else if (argument == "WARNING" || argument == "4") {
logLevel = WARNING_LEVEL;
}
else if (argument == "NOTICE" || argument == "5") {
logLevel = NOTICE_LEVEL;
}
else if (argument == "INFO" || argument == "6") {
logLevel = INFO_LEVEL;
}
else if (argument == "DEBUG" || argument == "7") {
logLevel = DEBUG_LEVEL;
}
}
int main(int argc, char* argv[]) {
eLogLevel logLevel = INFO_LEVEL;
blet::Args args;
// set message printed at version action option
args.setVersion("Version: 0.0.0");
// add required positional ARGUMENT
args.addArgument("ARGUMENT").help("help of positional argument").required();
// add version option (-v, --version)
args.addArgument("-v").flag("--version").help("print version").action(args.VERSION);
// add multiargument option (-o, --option)
args.addArgument(args.vector("-o", "--option")).help("help of option").nargs(2).metavar("OPT1 OPT2");
// add choise option (-l, --log-level) with "dest" function
args.addArgument("--log-level")
.flag("-l")
.help("help of log-level")
.metavar("LEVEL")
.valid(new blet::Args::ValidChoise(args.vector("0", "1", "2", "3", "4", "5", "6", "7", "EMERG", "ALERT",
"CRITICAL", "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG")))
.defaults("INFO")
.dest(logLevel, &argToLogLevel); // fill logLevel using argToLogLevel
try {
args.setStrict() // throw exception with additional arguments
.setAlternative() // accept simple '-' with a long flag
.setAbbreviate() // accept abbreviated long options (e.g., --ver for --version)
.setHelpException() // throw exception when help flag is called
.setVersionException() // throw exception when version flag is called
.parseArguments(argc, argv); // add help option automatically
}
catch (const blet::Args::VersionException& e) {
std::cout << e.what() << std::endl;
return 0;
}
catch (const blet::Args::HelpException& e) {
std::cout << e.what() << std::endl;
return 0;
}
catch (const blet::Args::ParseArgumentException& e) {
std::cerr << args.getBinaryName() << ": " << e.what();
std::cerr << " -- '" << e.argument() << "'" << std::endl;
return 1;
}
std::cout << "ARGUMENT: " << args["ARGUMENT"] << '\n';
// check if option exists
if (args["--option"]) {
std::cout << "--option: " << args["--option"][0] << ", " << args["--option"][1] << '\n';
}
std::cout << "--log-level: ";
switch (logLevel) {
case EMERG_LEVEL:
std::cout << "EMERG";
break;
case ALERT_LEVEL:
std::cout << "ALERT";
break;
case CRITICAL_LEVEL:
std::cout << "CRITICAL";
break;
case ERROR_LEVEL:
std::cout << "ERROR";
break;
case WARNING_LEVEL:
std::cout << "WARNING";
break;
case NOTICE_LEVEL:
std::cout << "NOTICE";
break;
case INFO_LEVEL:
std::cout << "INFO";
break;
case DEBUG_LEVEL:
std::cout << "DEBUG";
break;
}
std::cout << std::endl;
return 0;
}$ ./a.out --version
Version: 0.0.0
$ ./a.out -h
usage: a.out [-h] [-l LEVEL] [-o OPT1 OPT2] [-v] -- ARGUMENT
positional arguments:
ARGUMENT help of positional argument (required)
optional arguments:
-h, --help show this help message and exit
-l, --log-level LEVEL
help of log-level (default: INFO)
-o, --option OPT1 OPT2
help of option
-v, --version print version
$ ./a.out
./a.out: argument is required -- 'ARGUMENT'
$ ./a.out 42 -log-level Foo
./a.out: "Foo" is not a valid choise ("0", "1", "2", "3", "4", "5", "6", "7", "EMERG", "ALERT", "CRITICAL", "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG") -- '-l'
$ ./a.out 42
ARGUMENT: 42
--log-level: INFO
$ ./a.out 42 --log-level=DEBUG --option Foo
./a.out: bad number of argument -- 'option'
$ ./a.out 42 -l7 -o Foo Bar
ARGUMENT: 42
--option: Foo, Bar
--log-level: DEBUG
# Static Release with install
mkdir build; pushd build; cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=0 .. && make -j && make install; popd
# Dynamic Release with install
mkdir build; pushd build; cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1 .. && make -j && make install; popd
# Static Release C++98 with install
mkdir build; pushd build; cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=98 -DBUILD_SHARED_LIBS=0 .. && make -j && make install; popd
# Dynamic Release C++98 with install
mkdir build; pushd build; cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=98 -DBUILD_SHARED_LIBS=1 .. && make -j && make install; popd
# Install with custom directory
mkdir build; pushd build; cmake -DCMAKE_INSTALL_PREFIX="YOUR_INSTALL_PATH" .. && make -j && make install; popd
# Example
mkdir build; pushd build; cmake -DBUILD_EXAMPLE=1 .. && make -j; popd
# Single Include + Test
mkdir build; pushd build; cmake -DBUILD_SINGLE_INCLUDE=1 -DBUILD_TESTING=1 .. && make -j; popd
# Tests + Coverage
mkdir build; pushd build; cmake -DBUILD_SHARED_LIBS=0 -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=1 -DBUILD_COVERAGE=1 -DCMAKE_CXX_STANDARD=11 .. && make -j && make test -j; popdShort format
"-b" # [b] == true
"-s" "Simple" # [s] == Simple
"-sSimple" # [s] == Simple
"-s=Simple" # [s] == Simple
"-bsSimple" # [b] == true and [s] == Simple
"-bs=Simple" # [b] == true and [s] == SimpleLong format
"--boolean" # [boolean] == true
"--simple" "Simple" # [simple] == Simple
"--simple=Simple" # [simple] == Simple
"-simple" "Simple" # (alternative) [simple] == Simple
"-simple=Simple" # (alternative) [simple] == Simple
"--ver" # (abbreviated) [version] == true (if setAbbreviate is enabled)Define how a single command-line argument should be parsed.
std::vector<double> doublesFromArg;
blet::Args args;
args.addArgument({"-E", "--example"}) // Either a name or a list of option strings, e.g. foo or -f, --foo
.flag("--new-example") // Add option strings e.g. -f, --foo
.action(args.INFINITE) // The basic type of action to be taken when this argument is encountered at the command line
.help("help message") // A brief description of what the argument does
.required(true) // Whether or not the command-line option may be omitted (optionals only)
.metavar("ARGUMENT") // A name for the argument in usage messages
.nargs(1) // The number of command-line arguments that should be consumed
.defaults({"0"}) // A list of default string argument values
.valid(new blet::Args::ValidMinMax(0, 100)) // Validate class from IValid interface
.dest(doublesFromArg); // Fill argument in destination| Method | Description |
|---|---|
| action | The basic type of action to be taken when this argument is encountered at the command line. |
| defaults | A list of default string argument values. |
| dest | Fill argument in destination. |
| flag | Add option strings e.g. -f, --foo |
| help | A brief description of what the argument does. |
| metavar | A name for the argument in usage messages. |
| nargs | The number of command-line arguments that should be consumed. |
| required | Whether or not the command-line option may be omitted (optionals only). |
| valid | Validate argument from IValid interface. |
Convert argument strings to objects and assign them as attributes of the args map.
Previous calls to addArgument determine exactly what objects are created and how they are assigned.
void parseArguments(int argc, char* argv[]);blet::Args& setStrict(); // Throw exception if not all arguments are used; otherwise, you can take additional arguments with getAdditionalArguments method
blet::Args& setAlternative(); // Enable parsing to accept long options with only one '-' character
blet::Args& setAbbreviate(); // Enable parsing to accept abbreviated long options (e.g., --ver matches --version); throws on ambiguity
blet::Args& setHelpException(); // Throw a HelpException when help action is present in arguments; otherwise, exit(0) after outputting usage to stdout
blet::Args& setVersionException(); // Throw a VersionException when version action is present in arguments; otherwise, exit(0) after outputting usage to stdoutWhen setAbbreviate() is enabled, long options can be specified by any unambiguous prefix:
blet::Args args;
args.addArgument("--version").action(args.STORE_TRUE);
args.addArgument("--verbose").action(args.STORE_TRUE);
args.setAbbreviate();./program --vers # matches --version (unambiguous)
./program --verb # matches --verbose (unambiguous)
./program --ver # ERROR: ambiguous (matches both --version and --verbose)
./program --versio # matches --version (unambiguous)Important notes:
- Only works with long options (starting with
--) - Exact matches always take precedence over abbreviations
- Throws
ParseArgumentExceptionif abbreviation is ambiguous - Can be combined with
setAlternative()and other parsing options
Vector is an object that can be initialized with an initializer list, single string, or for C++98 with the vector static method.
blet::Args args;
args.addArgument("--simple");
args.addArgument({"-s", "--simple"});
args.addArgument("-s").flag("--simple");
args.addArgument(args.vector("-s", "--simple")); // C++98
args.addArgument((const char*[]){"-s", "--simple"}); // C++98| Method | Description |
|---|---|
| addArgument | Define how a single command-line argument should be parsed. |
| parseArguments | Convert argument strings to objects and assign them as attributes of the args map. Previous calls to addArgument determine exactly what objects are created and how they are assigned. If called without help action, defines '-h' and '--help' if not used. |
| Method | Description |
|---|---|
| getDescription | Get the description message. |
| getEpilog | Get the epilog message. |
| getUsage | Get the usage message. |
| setDescription | Set the description in usage message. |
| setEpilog | Set the epilog in usage message. |
| setUsage | Set the usage message. |
| setUsageWidth | Set the Usage Widths. |
| Method | Description |
|---|---|
| argumentExists | Check if argument exists. |
| clear | Clear and reset with default values. |
| getAdditionalArguments | Get the vector of additional arguments. |
| getArgument | Get the argument object. |
| getBinaryName | Get the binary name. |
| getVersion | Get the version message. |
| isAbbreviate | Get the status of abbreviated options. |
| isAlternative | Get the status of alternative. |
| isHelpException | Get the status of helpException. |
| isStrict | Get the status of strict. |
| isVersionException | Get the status of versionException. |
| removeArguments | Remove previously added arguments. |
| setAbbreviate | Enable parsing to accept abbreviated long options (e.g., --ver matches --version). |
| setAlternative | Enable parsing to accept long options with only one '-' character. |
| setBinaryName | Set the binary name. |
| setHelpException | Throw a HelpException when help action is present in arguments; otherwise, exit(0) after outputting usage to stdout. |
| setStrict | Throw exception if not all arguments are used; otherwise, you can take additional arguments with getAdditionalArguments method. |
| setVersion | Set the version message. |
| setVersionException | Throw a VersionException when version action is present in arguments; otherwise, exit(0) after outputting version to stdout. |
| updateArgument | Get the ref. of argument from name or flag. |
| Method | Description |
|---|---|
| action | Add an action when this argument is encountered at the command line. |
| defaults | Define the default string values. |
| dest | Define a reference to an object to insert the value after parseArguments method. |
| flag | Add flag to argument object. |
| help | Set the help description message for this argument. |
| metavar | A name for the argument in usage messages. |
| nargs | The number of command-line arguments that should be consumed by this object. |
| required | Whether or not the command-line argument may be omitted. |
| valid | You can check format of argument with IValid interface. |
| Enum | Description |
|---|---|
| APPEND | This stores a list, and appends each argument value to the list. It is useful to allow an option to be specified multiple times. |
| EXTEND | This stores a list, and extends each argument value to the list. |
| HELP | This is used to create the help flag. |
| INFINITE | This stores a list. |
| NONE | This just stores the argument's value. This is the default action. |
| STORE_FALSE | This is used to store the value false. |
| STORE_TRUE | This is used to store the value true. |
| VERSION | This is used to define the version flag. |
| Method | Description |
|---|---|
| count | After parseArguments method check if number of this argument in argv. |
| getAction | Get action option. |
| getDefault | Get the default value of argument. |
| getDefaults | Get the default(s) value(s) of this argument. |
| getHelp | Get help option. |
| getMetavar | Get metavar option. |
| getNameOrFlags | Get the name or flag(s) of this argument. |
| getNargs | Get nargs option. |
| getNumber | Get Number if isNumber. |
| getString | Get the string format of this argument. |
| isExists | After parseArguments method check if this argument is present in argv. |
| isNumber | Check if this argument is a number ("1234aaa" is true with 1234 like number). |
| isRequired | Get required option. |
| operator bool() | Check if argument object isExists. |
| operator std::string() | Call getString method. |
| operator std::vector<std::string>() | If the argument object contains a lot of one argument, you can get a std::vector of std::string. |
| operator std::vector<std::vector<std::string> >() | If the argument object contains a lot of one argument with number of argument (nargs) bigger than one, you can get a std::vector of std::vector of std::string. |
| operator T() | Call the getNumber method with your custom type. |
For more examples, see docs/examples.md.