sharg 1.0.0
THE argument parser for bio-c++ tools.
The Sharg Cookbook

This document provides example recipes on how to carry out particular tasks using the Sharg functionalities in C++. Please note that these recipes are not ordered. You can use the links in the table of contents or the search function of your browser to navigate them.

It will take some time, but we hope to expand this document into containing numerous great examples. If you have suggestions for how to improve the Cookbook and/or examples you would like included, please feel free to contact us.

Constructing a basic parser

#include <sharg/all.hpp>
void run_program(std::filesystem::path const & reference_path, std::filesystem::path const & index_path)
{
std::cerr << "reference_file_path: " << reference_path << '\n';
std::cerr << "index_path " << index_path << '\n';
}
struct cmd_arguments
{
std::filesystem::path reference_path{};
std::filesystem::path index_path{"out.index"};
};
void initialise_parser(sharg::parser & parser, cmd_arguments & args)
{
parser.info.author = "E. coli";
parser.info.short_description = "Creates an index over a reference.";
parser.info.version = "1.0.0";
parser.add_option(args.reference_path,
sharg::config{.short_id = 'r',
.long_id = "reference",
.description = "The path to the reference.",
.required = true,
.validator = sharg::input_file_validator{{"fa", "fasta"}}});
parser.add_option(
args.index_path,
sharg::config{.short_id = 'o',
.long_id = "output",
.description = "The output index file path.",
.validator =
sharg::output_file_validator{sharg::output_file_open_options::create_new, {"index"}}});
}
int main(int argc, char const ** argv)
{
sharg::parser parser("Indexer", argc, argv);
cmd_arguments args{};
initialise_parser(parser, args);
try
{
parser.parse();
}
catch (sharg::parser_error const & ext)
{
std::cerr << "[PARSER ERROR] " << ext.what() << '\n';
return -1;
}
run_program(args.reference_path, args.index_path);
return 0;
}
Meta-header for the Parser module .
Parser exception that is thrown whenever there is an error while parsing the command line arguments.
Definition: exceptions.hpp:43
The Sharg command line parser.
Definition: parser.hpp:156
void add_option(option_type &value, config< validator_type > const &config)
Adds an option to the sharg::parser.
Definition: parser.hpp:251
parser_meta_data info
Aggregates all parser related meta data (see sharg::parser_meta_data struct).
Definition: parser.hpp:661
Option struct that is passed to the sharg::parser::add_option() function.
Definition: config.hpp:46
std::string short_description
A short description of the application (e.g. "A tool for mapping reads to the genome").
Definition: auxiliary.hpp:60
std::string version
The version information MAJOR.MINOR.PATH (e.g. 3.1.3)
Definition: auxiliary.hpp:57
std::string author
Your name ;-)
Definition: auxiliary.hpp:63
T what(T... args)

Constructing a subcommand parser

#include <sharg/all.hpp>
// =====================================================================================================================
// pull
// =====================================================================================================================
struct pull_arguments
{
std::string repository{};
std::string branch{};
bool progress{false};
};
int run_git_pull(sharg::parser & parser)
{
pull_arguments args{};
parser.add_positional_option(args.repository, sharg::config{.description = "The repository name to pull from."});
parser.add_positional_option(args.branch, sharg::config{.description = "The branch name to pull from."});
try
{
parser.parse();
}
catch (sharg::parser_error const & ext)
{
std::cerr << "[Error git pull] " << ext.what() << "\n";
return -1;
}
std::cerr << "Git pull with repository " << args.repository << " and branch " << args.branch << '\n';
return 0;
}
// =====================================================================================================================
// push
// =====================================================================================================================
struct push_arguments
{
std::string repository{};
bool push_all{false};
};
int run_git_push(sharg::parser & parser)
{
push_arguments args{};
parser.add_positional_option(args.repository, sharg::config{.description = "The repository name to push to."});
parser.add_positional_option(args.branches, sharg::config{.description = "The branch names to push."});
try
{
parser.parse();
}
catch (sharg::parser_error const & ext)
{
std::cerr << "[Error git push] " << ext.what() << "\n";
return -1;
}
std::cerr << "Git push with repository " << args.repository << " and branches ";
for (auto && branch : args.branches)
std::cerr << branch << ' ';
std::cerr << '\n';
return 0;
}
// =====================================================================================================================
// main
// =====================================================================================================================
int main(int argc, char const ** argv)
{
sharg::parser top_level_parser{"mygit", argc, argv, sharg::update_notifications::on, {"push", "pull"}};
// Add information and flags, but no (positional) options to your top-level parser.
// Because of ambiguity, we do not allow any (positional) options for the top-level parser.
top_level_parser.info.description.push_back("You can push or pull from a remote repository.");
bool flag{false};
top_level_parser.add_flag(flag, sharg::config{.short_id = 'f', .long_id = "flag", .description = "some flag"});
try
{
top_level_parser.parse(); // trigger command line parsing
}
catch (sharg::parser_error const & ext) // catch user errors
{
std::cerr << "[Error] " << ext.what() << "\n"; // customise your error message
return -1;
}
sharg::parser & sub_parser = top_level_parser.get_sub_parser(); // hold a reference to the sub_parser
std::cout << "Proceed to sub parser.\n";
if (sub_parser.info.app_name == std::string_view{"mygit-pull"})
return run_git_pull(sub_parser);
else if (sub_parser.info.app_name == std::string_view{"mygit-push"})
return run_git_push(sub_parser);
else
std::cout << "Unhandled subparser named " << sub_parser.info.app_name << '\n';
// Note: Arriving in this else branch means you did not handle all sub_parsers in the if branches above.
return 0;
}
void add_positional_option(option_type &value, config< validator_type > const &config)
Adds a positional option to the sharg::parser.
Definition: parser.hpp:319
void parse()
Initiates the actual command line parsing.
Definition: parser.hpp:404
parser & get_sub_parser()
Returns a reference to the sub-parser instance if subcommand parsing was enabled.
Definition: parser.hpp:449
@ on
Automatic update notifications should be enabled.
char short_id
The short identifier for the option (e.g. 'a', making the option callable via -a).
Definition: config.hpp:56
std::string app_name
The application name that will be displayed on the help page.
Definition: auxiliary.hpp:54

Write a custom validator

This recipe implements a validator that checks whether a numeric argument is an integral square (i.e. 0, 1, 4, 9...). Invalid values throw a sharg::validation_error.

#include <cmath>
struct custom_validator
{
using option_value_type = double; // used for all arithmetic types
void operator()(option_value_type const & val) const
{
if ((std::round(val) != val) || // not an integer
(std::pow(std::round(std::sqrt(val)), 2) != val)) // not a square
{
throw sharg::validation_error{"The provided number is not an arithmetic square."};
}
}
std::string get_help_page_message() const
{
return "Value must be the square of an integral number.";
}
};
Parser exception thrown when an argument could not be casted to the according type.
Definition: exceptions.hpp:183