SeqAn3  3.0.0
The Modern C++ library for sequence analysis.
Argument Parser

The Argument Parser Module. More...

Classes

class  seqan3::argument_parser
 The SeqAn command line parser. More...
 
struct  seqan3::argument_parser_meta_data
 Stores all parser related meta information of the seqan3::argument_parser. More...
 
class  seqan3::arithmetic_range_validator
 A validator that checks whether a number is inside a given range. More...
 
class  seqan3::file_validator_base
 An abstract base class for the file and directory validators. More...
 
class  seqan3::input_directory_validator
 A validator that checks if a given path is a valid input directory. More...
 
class  seqan3::input_file_validator
 A validator that checks if a given path is a valid input file. More...
 
class  seqan3::output_directory_validator
 A validator that checks if a given path is a valid output directory. More...
 
class  seqan3::output_file_validator
 A validator that checks if a given path is a valid output file. More...
 
class  seqan3::regex_validator
 A validator that checks if a matches a regular expression pattern. More...
 
interface  seqan3::Validator
 The concept for option validators passed to add_option/positional_option. More...
 
class  seqan3::value_list_validator< option_value_type >
 A validator that checks whether a value is inside a list of valid values. More...
 

Enumerations

enum  seqan3::option_spec { seqan3::DEFAULT = 0, seqan3::REQUIRED = 1, seqan3::ADVANCED = 2, seqan3::HIDDEN = 4 }
 Used to further specify argument_parser options/flags. More...
 

Functions

template<Validator validator1_type, Validator validator2_type>
auto seqan3::operator| (validator1_type &&vali1, validator2_type &&vali2)
 Enables the chaining of validators. More...
 

Detailed Description

The Argument Parser Module.

The Argument Parser Class

The seqan3::argument_parser is a general purpose argument parser that provides convenient access to the command line arguments passed to the program. It automatically generates a help page and can export manual-pages as well as HTML documentation.

Furthermore common tool descriptor (CTD) files can be exported (soon) and a server be queried for available application updates.

Terminology

Since the terms option and arguments are frequently used in different contexts we want to first clarify our usage:

Add/get options, flags or positional Options

Adding an option is done in a single call. You simply need to provide a predeclared variable and some additional information like the identifier, description or advanced restrictions. To actually retrieve the value from the command line and enable every other mechanism you need to call the seqan3::argument_parser::parse function in the end.

int main(int argc, char ** argv)
{
seqan3::argument_parser myparser{"Grade-Average", argc, argv}; // initialize
std::string name{"Max Muster"}; // define default values directly in the variable.
bool bonus{false};
std::vector<double> grades{}; // you can also specify a vector that is treated as a list option.
myparser.add_option(name, 'n', "name", "Please specify your name.");
myparser.add_flag(bonus, 'b', "bonus", "Please specify if you got the bonus.");
myparser.add_positional_option(grades, "Please specify your grades.");
try
{
myparser.parse();
}
catch (seqan3::parser_invalid_argument const & ext) // the user did something wrong
{
std::cerr << "[PARSER ERROR] " << ext.what() << "\n"; // customize your error message
return -1;
}
if (bonus)
grades.push_back(1.0); // extra good grade
double avg{0};
for (auto g : grades)
avg += g;
avg = avg / grades.size();
seqan3::debug_stream << name << " has an average grade of " << avg << std::endl;
return 0;
}

Now you can call your application via the command line:

MaxMuster% ./grade_avg_app -n Peter --bonus 1.0 2.0 1.7
Peter has an average grade of 1.425

You can also display the help page automatically:

MaxMuster% ./grade_avg_app --help
Grade-Average
=============
POSITIONAL ARGUMENTS
ARGUMENT-1 List of DOUBLE's
Please specify your grades.
OPTIONS
-n, --name STRING
Please specify your name.
-b, --bonus
Please specify if you got the bonus.
VERSION
Last update:
Grade-Average version:
SeqAn version: 3.0.0

Errors that are caught by the argument_parser

There are two different kinds of errors: Developer errors and user errors.

Developer errors are those that violate the seqan3::argument_parser design (e.g. calling the seqan3::argument_parser::parse function twice or specifying two different options with the same identifier.) In this case, a seqan3::parser_design_error is thrown.

The second kind are user errors, due to invalid command line calls. In this case a seqan3::parser_invalid_argument is thrown.

For example:

MaxMuster% ./grade_avg_app -n Peter 2.0 abc 1.7
[PARSER ERROR] Value cast failed for positional option 2: Argument abc could not be casted to type DOUBLE.

See the seqan3::argument_parser::parse documentation for a detailed list of which exceptions are caught.

Update Notifications

SeqAn applications that are using the seqan3::argument_parser can check SeqAn servers for version updates. The functionality helps getting new versions out to users faster. It is also used to inform application developers of new versions of the SeqAn library which means that applications ship with less bugs. For privacy implications, please see: https://github.com/seqan/seqan3/wiki/Update-Notifications.

Developers that wish to disable this feature permanently can pass an extra constructor argument:

using namespace seqan3;
int main(int argc, char ** argv)
{
argument_parser myparser{"Game of Parsing", argc, argv, false};
// disable version checks permanently --------------------^
}

Users of applications that have this feature activated can opt-out, by either:

Note that in case there is no --version-check option (display available options with -h/--help), then the developer already disabled the version check functionality.

Parsing Command Line Arguments

Attention
The function must be called at the very end of all parser related code and should be enclosed in a try catch block.
Exceptions
seqan3::parser_design_errorif this function was already called before.
seqan3::option_declared_multiple_timesif an option that is not a list was declared multiple times.
seqan3::overflow_error_on_conversionif the numeric argument would cause an overflow error when converted into the expected type.
seqan3::parser_invalid_argumentif the user provided wrong arguments.
seqan3::required_option_missingif the user did not provide a required option.
seqan3::too_many_argumentsif the command line call contained more arguments than expected.
seqan3::too_few_argumentsif the command line call contained less arguments than expected.
seqan3::type_conversion_failedif the argument value could not be converted into the expected type.
seqan3::validation_failedif the argument was not excepted by the provided validator.

When no specific key words are supplied, the seqan3::argument_parser starts to process the command line for specified options, flags and positional options.

If the given command line input (argv) contains the following keywords (in order of checking), the parser will exit (std::exit) with error code 0 after doing the following:

Example:

Note
Since the argument parser may throw, you should always wrap parse() into a try-catch block.
int main(int argc, char ** argv)
{
seqan3::argument_parser myparser{"The-Age-App", argc, argv}; // initialize
int age{30}; // define default values directly in the variable
myparser.add_option(age, 'a', "user-age", "Please specify your age.");
try
{
myparser.parse();
}
catch (seqan3::parser_invalid_argument const & ext) // the user did something wrong
{
std::cerr << "The-Age-App - [PARSER ERROR] " << ext.what() << "\n"; // customize your error message
return -1;
}
seqan3::debug_stream << "integer given by user: " << age << std::endl;
return 0;
}

The code above gives the following output when calling --help:

MaxMuster$ ./age_app --help
The-Age-App
===========
OPTIONS
-a, --user-age (signed 32 bit integer)
Please specify your age.
VERSION
Last update:
The-Age-App version:
SeqAn version: 3.0.0
Thanks for using The-Age-App!

If the user does something wrong, it looks like this:

MaxMuster$ ./age_app --foo
The Age App - [PARSER ERROR] Unknown option --foo. Please see -h/--help for more information.
MaxMuster$ ./age_app -a abc
The Age App - [PARSER ERROR] Value cast failed for option -a: Argument abc
could not be casted to type (signed 32 bit integer).

Argument Validation

The SeqAn 3 Argument Parser offers a validation mechanism for (positional_)options via callables. You can pass any functor that fulfils the seqan3::Validator and takes the value passed to the add_(positional_)option function call as a parameter. We provide some commonly used functor that might come in handy:

Enumeration Type Documentation

◆ option_spec

Used to further specify argument_parser options/flags.

All options and flags are set to option_spec::DEFAULT unless specified otherwise by the developer, e.g. when calling argument_parser::add_option().

argument_parser myparser{"Test", argc, argv};
std::string myvar{"Example"};
myparser.add_option(myvar, 's', "special-op", "You know what you doin'?",
Enumerator
DEFAULT 

The default were no checking or special displaying is happening.

REQUIRED 

Set an option as required if you want to enforce that the user supplies this option when calling the program via the command line. If the option is missing, the argument_parser will automatically detect this and throw a invalid_argument exception.

ADVANCED 

Set an option/flag to advanced if you do not want the option to be displayed in the normal help page (-h/--help). Instead, the advanced options are only displayed when calling -hh/--advanced-help

HIDDEN 

Set an option/flag to hidden, if you want to completely hide it from the user. It will never appear on the help page nor any export format. For example, this can be useful for debugging reasons. (e.g. "A tool for mapping reads to the genome").

Function Documentation

◆ operator|()

template<Validator validator1_type, Validator validator2_type>
auto seqan3::operator| ( validator1_type &&  vali1,
validator2_type &&  vali2 
)

Enables the chaining of validators.

Template Parameters
validator1_typeThe type of the fist validator; Must satisfy the seqan3::Validator and the same value_type as the second validator type.
validator2_typeThe type of the second validator; Must satisfy the seqan3::Validator and the same value_type as the fist validator type.
Parameters
[in]vali1The first validator to chain.
[in]vali2The second validator to chain.
Returns
A new validator that tests a value for both vali1 and vali2.

The pipe operator is the AND operation for two validators, which means that a value must pass both validators in order to be accepted by the new validator.

For example you may want a file name that only accepts absolute paths but also must have one out of some given file extensions. For this purpose you can chain a seqan3::regex_validator to a seqan3::input_file_validator like this:

int main(int argc, const char ** argv)
{
seqan3::argument_parser myparser{"Test", argc, argv}; // initialize
std::string file_name;
seqan3::regex_validator absolute_path_validator{"(/[^/]+)+/.*\\.[^/\\.]+$"};
seqan3::input_file_validator my_file_ext_validator{{"sa", "so"}};
myparser.add_option(file_name, 'f', "file","Give me a file name with an absolute path.",
seqan3::option_spec::DEFAULT, absolute_path_validator | my_file_ext_validator);
// an exception will be thrown if the user specifies a file name
// that is not an absolute path or does not have one of the file extension [sa,so]
try
{
myparser.parse();
}
catch (seqan3::parser_invalid_argument const & ext) // the user did something wrong
{
std::cerr << "[PARSER ERROR] " << ext.what() << "\n"; // customize your error message
return -1;
}
std::cout << "filename given by user passed validation: " << file_name << "\n";
return 0;
}

You can chain as many validators as you want which will be evaluated one after the other from left to right (first to last).