ArgParser
Synopsis
#include <ts/ArgParser.h>
Description
ArgParser
is a powerful and easy-to-use command line Parsing library for ATS.
The program defines what it requires by adding commands and options.
Then ArgParser
will figure out the related information from the command line.
All parsed arguments and function will be put in a key-value pairs structure
Arguments
available for users to use.
Usage
The usage of the ArgParser is straightforward. An ArgParser
instance is
created. Commands and options are then added to this instance, along with
details including ENV variable, arguments expected, etc. The method
parse(argv)
is called, passing the argv
from the command line
(main
function arguments). An object containing the parsed command line
information will be returned.
Create a parser
The first step to use ArgParser is to create a parser. The parser can be created simply by calling:
ts::ArgParser parser;
or initialize with the following arguments: name, help description, environment variable, argument number expected, function
ts::ArgParser parser("name", "description", "ENV_VAR", 0, &function);
To add the usage for the help message of this program:
parser.add_global_usage("traffic_blabla [--SWITCH]");
Add commands and options
We can perform all kinds of operations on the parser which is the ArgParser
or command which is a Command
.
To add commands to the program or current command:
ts::ArgParser &command1 = parser.add_command("command1", "description");
command1.add_command("command2", "description");
command1.add_command("command3", "description", "ENV_VAR", 0);
command1.add_command("command4", "description", "ENV_VAR", 0, &function, "lookup_key");
This function call returns the new Command
instance added.
Note
The 0 here is the number of arguments we expected. It can be also set to MORE_THAN_ZERO_ARG_N or MORE_THAN_ONE_ARG_N to specify that this command expects all the arguments come later (more than zero or more than one).
To add options to the parser or current command:
parser.add_option("--switch", "-s", "switch description");
command1.add_option("--switch", "-s", "switch description", "", 0);
command1.add_option("--switch", "-s", "switch description", "ENV_VAR", 1, "default", "lookup_key");
This function call returns the new Option
instance. (0 is also number of arguments expected)
We can also use the following chained way to add subcommand or option:
command.add_command("init", "description").add_command("subinit", "description");
command.add_command("remove", "description").add_option("-i", "--initoption");
which is equivalent to
ts::ArgParser::Command &init_command = command.add_command("init", "description");
ts::ArgParser::Command &remove_command = command.add_command("remove", "description");
init_command.add_command("subinit", "description");
remove_command.add_option("-i", "--initoption");
In this case, subinit is the subcommand of init and –initoption is a switch of command remove.
Parsing Arguments
ArgParser
parses arguments through the parse(argv)
method. This will inspect the command line
and walk through it. A Arguments
object will be built up from attributes
parsed out of the command line holding key-value pairs all the parsed data and the function.
Arguments args = parser.parse(argv);
Invoke functions
To invoke the function associated with certain commands, we can perform this by simply calling invoke()
from the Arguments
object returned from the parsing. The function can be a lambda.
args.invoke();
Help and Version messages
Help message will be outputted when a wrong usage of the program is detected or –help option found.
Version message is defined unified in
ArgParser::version_message()
.
Classes
-
class ArgParser
-
Option &add_option(std::string const &long_option, std::string const &short_option, std::string const &description, std::string const &envvar = "", unsigned arg_num = 0, std::string const &default_value = "", std::string const &key = "")
Add an option to current command with long name, short name, help description, environment variable, arguments expected, default value and lookup key. If no lookup key is provided, the long name will be used as lookup key without the prefix, for instance, for a long option
--debug
you should usedebug
as as lookup key. Return The Option object itself.
-
Command &add_command(std::string const &cmd_name, std::string const &cmd_description, std::function<void()> const &f = nullptr, std::string const &key = "")
Add a command with only name and description, function to invoke and lookup key. Return the new
Command
object.
-
Command &add_command(std::string const &cmd_name, std::string const &cmd_description, std::string const &cmd_envvar, unsigned cmd_arg_num, std::function<void()> const &f = nullptr, std::string const &key = "")
Add a command with name, description, environment variable, number of arguments expected, function to invoke and lookup key. The function can be passed by reference or be a lambda. It returns the new
Command
object.
-
void parse(const char **argv)
Parse the command line by calling
parser.parse(argv)
. Return the newArguments
instance.
-
void help_message() const
Output usage to the console.
-
void version_message() const
Output version string to the console.
-
void add_global_usage(std::string const &usage)
Add a global_usage for
help_message()
. Example: traffic_blabla [–SWITCH [ARG]].
-
void set_default_command(std::string const &cmd)
Set a default command to the parser. This method should be called after the adding of the commands.
-
Command &require_commands()
Make the parser require commands. If no command is found, output help message. Return The
Command
instance for chained calls.
-
void set_error(std::string e)
Set the user customized error message for the parser.
-
std::string get_error() const
Return the error message of the parser.
-
Option &add_option(std::string const &long_option, std::string const &short_option, std::string const &description, std::string const &envvar = "", unsigned arg_num = 0, std::string const &default_value = "", std::string const &key = "")
struct Option {
std::string long_option; // long option: --arg
std::string short_option; // short option: -a
std::string description; // help description
std::string envvar; // stored ENV variable
unsigned arg_num; // number of argument expected
std::string default_value; // default value of option
std::string key; // look-up key
};
-
class Command
Command
is a nested structure of command forArgParser
. Theadd_option()
,add_command()
andrequire_command()
are the same with those inArgParser
. Whenadd_command()
is called under certain command, it will be added as a subcommand for the current command. For Example,command1.add_command("command2", "description")
will makecommand2
a subcommand ofcommand1
.require_commands()
is also available withinCommand
.-
void add_example_usage(std::string const &usage)
Add an example usage for the command to output in help_message. For Example:
command.add_example_usage("traffic_blabla init --path=/path/to/file")
.
-
void add_example_usage(std::string const &usage)
-
class Arguments
Arguments
holds the parsed arguments and function to invoke. It basically contains a function to invoke and a private map holding key-value pairs. The key is the command or option name string and the value is the Parsed data object which contains the environment variable and arguments that belong to this certain command or option.-
std::string get(std::string const &name)
Return the
ArgumentData
object related to the name.
-
std::string set_env(std::string const &key, std::string const &value)
Set the environment variable given key.
-
void append(std::string const &key, ArgumentData const &value)
Append key-value pairs to the map in
Arguments
.
-
void append_arg(std::string const &key, std::string const &value)
Append value to the data of key.
-
void show_all_configuration() const
Show all the called commands, options, and associated arguments.
-
void invoke()
Invoke the function associated with the parsed command.
-
void has_action() const
return true if there is any function to invoke.
-
std::string get(std::string const &name)
-
class ArgumentData
ArgumentData
is a struct containing the parsed Environment variable and command line arguments. There are methods to get the data out of it.Note: More methods can be added later to get specific types from the arguments.
-
operator bool() const noexcept
bool for checking if certain command or option is called.
-
std::string const &operator[](int x) const
Index accessing operator.
-
std::string const &env() const noexcept
Return the environment variable associated with the argument.
-
std::vector<std::string>::const_iterator begin() const noexcept
Begin iterator for iterating the arguments data.
-
std::vector<std::string>::const_iterator end() const noexcept
End iterator for iterating the arguments data.
-
std::string const &at(unsigned index) const
Index accessing method.
-
std::string const &value() const noexcept
Return the first element of the arguments data.
-
operator bool() const noexcept
Example
ArgParser
Below is a short example of using the ArgParser. We add some options and some commands to it using different ways. This program will have such functionality:
--switch
,-s
as a global switch.Command
func
will callfunction()
and this command takes 2 argument.Command
func2
will callfunction2(int num)
.Command
init
has subcommandsubinit
and option--path
which take 1 argument.Command
remove
has option--path
which takes 1 argument and hasHOME
as the environment variable.
#include "ts/ArgParser.h"
void function() {
...
}
void function2(int num) {
...
}
int main (int, const char **argv) {
ts::ArgParser parser;
parser.add_global_usage("traffic_blabla [some stuff]");
parser.add_option("--switch", "-s", "top level switch");
parser.add_command("func", "some function", "ENV_VAR", 2, &function);
parser.add_command("func2", "some function2", [&]() { return function2(100); });
auto &init_command = parser.add_command("init", "initialize");
init_command.add_option("--path", "-p", "specify the path", "", 1);
init_command.add_command("subinit", "sub initialize");
parser.add_command("remove", "remove things").add_option("--path", "-p", "specify the path", "HOME", 1);
ts::Arguments parsed_data = parser.parse(argv);
parsed_data.invoke();
...
}
Arguments
To get the values from the arguments data, please refer to the methods in Arguments
and ArgumentData