- Author: Gian Luis Bolivar Diana
- Email: gianluisbolivar1@gmail.com
- Requires C++23
- MIT License
In order to create a parser we must include the folder <parser.hpp>. To start parsing arguments create Parser object:
#include <input_parser/parser.hpp>
auto parser = input_parser::Parser();To add new options, simply call addOption. This method receives a function that doesn't receives parameter and returns an BaseOption child (see Option Types).
parser.addOption([] {
return input_parser::FlagOption();
});To parse the arguments, call the method parse with the amount of arguments and the array of string. This method will throw a ParsingError if the arguments provided at the command line don't correspond to the ones described previously.
A basic how to use information can be displayed calling displayUsage.
try {
parser.parse(argc, argv);
} catch (input_parser::ParsingError& error) {
std::cerr << error.what() << "\n";
parser.displayUsage();
return 1;
}This parser supports three option types: flag, single and compound.
A flag option is an option that must be placed alone. Represents a boolean value. For example:
auto flag_option = input_parser::FlagOption("-v", "--verbose")
.addDescription("Whether if the program will display the output or not")
.addDefaultValue(false);
auto parser = input_parser::Parser()
.addOption([flag_option] {
return flag_option;
});
try {
parser.parse(argc, argv);
} catch (input_parser::ParsingError& error) {
std::cerr << error.what() << "\n";
parser.displayUsage();
return 1;
}
const bool verbose = parser.getValue<bool>("-v");
if (verbose) std::cout << "Hello World!\n";And we can execute the code:
$ ./a.out
$ ./a.out -v
Hello World!
$ ./a.out --verbose
Hello World!-
Default value
The option manage default values different from the others two: if an option has a default value but the program is called with the flag activated, the value to be assigned will the opposite of the default. Look at this example:
auto parser = input_parser::Parser() .addOption([] { return input_parser::FlagOption("-v", "--verbose") .addDescription("Whether if the program will display information or not") .addDefaultValue(true); }); parser.parse(argc, argv); if (parser.getValue<bool>("-v")) std::cout << "Really important information!\n";
We can call the program like this:
$ ./a.out Really important information! $ ./a.out -v -
Transformation
Using a flag option allows you to create a different type value from a boolean. For example:
auto parser = input_parser::Parser() .addOption([] { return input_parser::FlagOption("-g", "--greeting") .addDescription("Whether if the program will say hi or bye") .addDefaultValue(false) .to<std::string>([](const bool& value) -> std::string { return value ? "Hi!" : "Bye!"; }); }); parser.parse(argc, argv); std::cout << parser.getValue<std::string>("-g") << '\n';
When executing the code, the string displayed will depend:
$ ./a.out Bye! $ ./a.out -g Hi! $ ./a.out --greeting Hi!
A single option is an option that must be placed with an extra argument. Originally is stored as a std::string. For example:
auto parser = input_parser::Parser()
.addOption([] {
return input_parser::SingleOption("-n")
.addDescription("The name of the person using this program");
});
parser.parse(argc, argv);
std::cout << parser.getValue<std::string>("-n") << " is using this program!\n";And we can execute the code:
$ ./a.out
terminate called after throwing an instance of 'input_parser::ParsingError'
what(): Missing option -n
Aborted
$ ./a.out -n
terminate called after throwing an instance of 'input_parser::ParsingError'
what(): After the -n option should be an extra argument!
Aborted
$ ./a.out -n Luke
Luke is using this program!A compound option is an option that must be placed with at least one extra argument. It stores its values on a std::vectorstd::string. Here's an example:
auto parser = input_parser::Parser()
.addOption([] {
return input_parser::CompoundOption("-n", "--numbers")
.addDescription("The numbers to be added together")
.toDouble();
});
parser.parse(argc, argv);
double result = 0;
for (auto& number : parser.getValue<std::vector<double>>("-n")) {
result += number;
}
std::cout << "The sum of the number is: " << result << '\n';And when executed, we get the following output:
$ ./a.out
terminate called after throwing an instance of 'input_parser::ParsingError'
what(): Missing option -n
Aborted
$ ./a.out -n
terminate called after throwing an instance of 'input_parser::ParsingError'
what(): After the -n option should be at least an extra argument!
Aborted
$ ./a.out -n 1 2
The sum of the number is: 3
$ ./a.out -n 1 2.201 3.4 -4
The sum of the number is: 2.601-
Transformation (each element)
This options allows the user to provide a callback function that will be applied to each of the elements stored using the elementsTo method. The callback provided must have one std::string parameter and return variable with the type desired.
auto parser = input_parser::Parser() .addOption([] { return input_parser::CompoundOption("--approves") .addDescription("A group of y's and n's that will be counted") .elementsTo<bool>([](const std::string& element) { return element == "y" || element == "Y"; }); }); parser.parse(argc, argv); int amount = 0; for (const auto approve : parser.getValue<std::vector<bool>>("--approves")) { amount += (approve ? 1 : 0); } std::cout << "There are " << amount << " people that approves\n";
We can execute the code and get the following results:
$ ./a.out --approves y n y y n n Y There are 4 people that approves
-
Transformation (all vector)
It also brings the possibility of transforming all the set calling the to method.
struct Coordinate { int x; int y; }; auto parser = input_parser::Parser() .addOption([] { return input_parser::CompoundOption("-c", "--coordinate") .addDescription("The coordinate of a point (x, y)") .to<Coordinate>([](const std::vector<std::string>& value) { return Coordinate{ std::stoi(value[0]), std::stoi(value[1]) }; }); }); parser.parse(argc, argv); auto [x, y] = parser.getValue<Coordinate>("-c"); std::cout << "The coordinates are (" << x << ", " << y << ")\n";
And as we can see, the Coordinate struct is created:
$ ./my_project -c 1.3 3 The coordinate are (1, 3) $ ./my_project -c -213 123 The coordinate are (-213, 123)
Just clone the repository and add these lines to your CMakeLists.txt file.
cmake_minimum_required(VERSION 3.22)
PROJECT(my_project)
add_executable(my_project src/main.cpp)
target_link_libraries(${PROJECT_NAME} input_parser)
add_subdirectory(InputParser)Another way to integrate this library is by using the FetchContent module. Just add these lines to your CMakeLists.txt file.
cmake_minimum_required(VERSION 3.22)
PROJECT(my_project)
include(FetchContent)
FetchContent_Declare(
input_parser
URL https://github.com/gianluisdiana/InputParser/releases/download/0.4.1/InputParser.zip)
FetchContent_MakeAvailable(input_parser)
add_executable(my_project src/main.cpp)
target_link_libraries(${PROJECT_NAME} input_parser)