199 char const *
const *
const argv,
209 if (version_check_future.valid())
242 template <
typename option_type,
typename val
idator_type>
247 check_parse_not_called(
"add_option");
248 verify_option_config(
config);
250 auto operation = [
this, &value,
config]()
252 auto visit_fn = [&value, &
config](
auto & f)
254 f.add_option(value,
config);
260 operations.push_back(std::move(operation));
276 template <
typename val
idator_type>
280 check_parse_not_called(
"add_flag");
281 verify_flag_config(
config);
284 throw design_error(
"A flag's default value must be false.");
286 auto operation = [
this, &value,
config]()
288 auto visit_fn = [&value, &
config](
auto & f)
290 f.add_flag(value,
config);
296 operations.push_back(std::move(operation));
326 template <
typename option_type,
typename val
idator_type>
331 check_parse_not_called(
"add_positional_option");
332 verify_positional_option_config(
config);
335 has_positional_list_option =
true;
337 auto operation = [
this, &value,
config]()
339 auto visit_fn = [&value, &
config](
auto & f)
341 f.add_positional_option(value,
config);
347 operations.push_back(std::move(operation));
420 if (parse_was_called)
421 throw design_error(
"The function parse() must only be called once!");
423 parse_was_called =
true;
426 verify_app_and_subcommand_names();
429 determine_format_and_subcommand();
432 for (
auto & operation : operations)
454 if (sub_parser ==
nullptr)
456 throw design_error(
"No subcommand was provided at the construction of the argument parser!");
492 template <
typename id_type>
497 if (!parse_was_called)
498 throw design_error{
"You can only ask which options have been set after calling the function `parse()`."};
502 if (id_pair.long_id.size() == 1u)
504 throw design_error{
"Long option identifiers must be longer than one character! If " + id_pair.long_id
505 +
"' was meant to be a short identifier, please pass it as a char ('') not a string"
510 if (it == used_option_ids.end())
511 throw design_error{
"You can only ask for option identifiers that you added with add_option() before."};
516 return option_it != option_end;
534 check_parse_not_called(
"add_section");
536 auto operation = [
this, title, advanced_only]()
538 auto visit_fn = [&title, advanced_only](
auto & f)
540 f.add_section(title, advanced_only);
546 operations.push_back(std::move(operation));
561 check_parse_not_called(
"add_subsection");
563 auto operation = [
this, title, advanced_only]()
565 auto visit_fn = [&title, advanced_only](
auto & f)
567 f.add_subsection(title, advanced_only);
573 operations.push_back(std::move(operation));
589 check_parse_not_called(
"add_line");
591 auto operation = [
this, text, is_paragraph, advanced_only]()
593 auto visit_fn = [&text, is_paragraph, advanced_only](
auto & f)
595 f.add_line(text, is_paragraph, advanced_only);
601 operations.push_back(std::move(operation));
626 check_parse_not_called(
"add_list_item");
628 auto operation = [
this, key, desc, advanced_only]()
630 auto visit_fn = [&key, &desc, advanced_only](
auto & f)
632 f.add_list_item(key, desc, advanced_only);
638 operations.push_back(std::move(operation));
654 auto & parser_subcommands = this->subcommands;
655 parser_subcommands.
insert(parser_subcommands.end(), subcommands.
cbegin(), subcommands.
cend());
659 parser_subcommands.erase(first, last);
717 bool parse_was_called{
false};
720 bool has_positional_list_option{
false};
729 friend struct ::sharg::detail::test_accessor;
765 {
'\0' ,
"advanced-help"},
767 {
'\0',
"export-help"},
769 {
'\0',
"copyright"}};
815 assert(!arguments.empty());
817 auto it = arguments.begin();
820 executable_name.emplace_back(arg);
824 auto read_next_arg = [
this, &it, &arg]() ->
bool
826 assert(it != arguments.end());
828 if (++it == arguments.end())
836 auto found_subcommand = [
this, &it, &arg]() ->
bool
838 if (subcommands.empty())
841 auto copy_metadata_to_subparser = [
this](
parser & sub_parser)
843 sub_parser.info.version = info.
version;
844 sub_parser.info.author = info.
author;
845 sub_parser.info.email = info.
email;
846 sub_parser.info.date = info.
date;
847 sub_parser.info.url = info.
url;
850 sub_parser.info.citation = info.
citation;
858 copy_metadata_to_subparser(get_sub_parser());
862 sub_parser->executable_name.insert(sub_parser->executable_name.begin(),
863 executable_name.begin(),
864 executable_name.end());
872 if (!arg.starts_with(
'-'))
874 std::string message =
"You specified an unknown subcommand! Available subcommands are: [";
876 message += command +
", ";
877 message.
replace(message.
size() - 2, 2,
"]. Use -h/--help for more information.");
887 for (; read_next_arg();)
893 format_arguments.emplace_back(arg);
898 format_arguments.emplace_back(arg);
908 if (found_subcommand())
911 if (arg ==
"-h" || arg ==
"--help")
915 else if (arg ==
"-hh" || arg ==
"--advanced-help")
919 else if (arg ==
"--version")
923 else if (arg ==
"--copyright")
927 else if (arg ==
"--export-help" || arg.starts_with(
"--export-help="))
934 if (!read_next_arg())
939 arg.remove_prefix(1u);
944 else if (arg ==
"man")
946 else if (arg ==
"ctd")
948 else if (arg ==
"cwl")
952 "Value must be one of "
953 + detail::supported_exports +
"."};
955 else if (arg ==
"--version-check")
957 if (!read_next_arg())
960 if (arg ==
"1" || arg ==
"true")
961 version_check_user_decision =
true;
962 else if (arg ==
"0" || arg ==
"false")
963 version_check_user_decision =
false;
965 throw validation_error{
"Value for option --version-check must be true (1) or false (0)."};
970 format_arguments.emplace_back(arg);
980 if (!format_arguments.empty() || sub_parser)
995 auto is_valid = [](
char const c) ->
bool
997 return (c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z') || (c >=
'0' && c <=
'9')
998 || c ==
'@' || c ==
'_' || c ==
'-';
1001 if (short_id ==
'\0' && long_id.
empty())
1002 throw design_error{
"Short and long identifiers may not both be empty."};
1004 if (short_id !=
'\0')
1006 if (short_id ==
'-' || !is_valid(short_id))
1007 throw design_error{
"Short identifiers may only contain alphanumeric characters, '_', or '@'."};
1012 if (!long_id.
empty())
1014 if (long_id.
size() == 1)
1015 throw design_error{
"Long identifiers must be either empty or longer than one character."};
1016 if (long_id[0] ==
'-')
1017 throw design_error{
"Long identifiers may not use '-' as first character."};
1019 throw design_error{
"Long identifiers may only contain alphanumeric characters, '_', '-', or '@'."};
1021 throw design_error{
"Long identifier '" + long_id +
"' was already used before."};
1024 used_option_ids.emplace(short_id, long_id);
1028 template <
typename val
idator_t>
1039 throw design_error{
"A required option cannot have a default message."};
1043 template <
typename val
idator_t>
1049 throw design_error{
"A flag may not have a default message because the default is always `false`."};
1053 template <
typename val
idator_t>
1057 throw design_error{
"Positional options are identified by their position on the command line. "
1058 "Short or long ids are not permitted!"};
1061 throw design_error{
"Positional options are always required and therefore cannot be advanced nor hidden!"};
1063 if (!subcommands.empty())
1064 throw design_error{
"You may only specify flags and options for the top-level parser."};
1066 if (has_positional_list_option)
1067 throw design_error{
"You added a positional option with a list value before so you cannot add "
1068 "any other positional options."};
1071 throw design_error{
"A positional option may not have a default message because it is always required."};
1085 if (parse_was_called)
1102 throw design_error{(
"The application name must only contain alpha-numeric characters or '_' and '-' "
1103 "(regex: \"^[a-zA-Z0-9_-]+$\").")};
1106 for (
auto & sub : this->subcommands)
1110 throw design_error{
"The subcommand name must only contain alpha-numeric characters or '_' and '-' "
1111 "(regex: \"^[a-zA-Z0-9_-]+$\")."};
1125 if (app_version.decide_if_check_is_performed(version_check_dev_decision, version_check_user_decision))
1129 version_check_future = app_version_prom.
get_future();
1130 app_version(std::move(app_version_prom));
1146 auto format_parse_fn = [
this]<
typename format_t>(format_t & f)
1149 f.parse(info, executable_name);
1154 std::visit(std::move(format_parse_fn), format);
Parser exception that is thrown whenever there is an design error directed at the developer of the ap...
Definition exceptions.hpp:207
A functor whose operator() performs the server http request and version checks.
Definition version_check.hpp:55
The Sharg command line parser.
Definition parser.hpp:158
void verify_app_and_subcommand_names() const
Verifies that the app and subcommand names are correctly formatted.
Definition parser.hpp:1096
void verify_identifiers(char const short_id, std::string const &long_id)
Verifies that the short and the long identifiers are correctly formatted.
Definition parser.hpp:993
void add_option(option_type &value, config< validator_type > const &config)
Adds an option to the sharg::parser.
Definition parser.hpp:245
std::future< bool > version_check_future
The future object that keeps track of the detached version check call thread.
Definition parser.hpp:732
void add_flag(bool &value, config< validator_type > const &config)
Adds a flag to the sharg::parser.
Definition parser.hpp:278
parser(std::string app_name, std::vector< std::string > arguments, update_notifications version_updates=update_notifications::on, std::vector< std::string > const &subcommands={})
Initializes an sharg::parser object from the command line arguments.
Definition parser.hpp:185
void parse_format()
Parses the command line arguments according to the format.
Definition parser.hpp:1144
parser(std::string app_name, int const argc, char const *const *const argv, update_notifications version_updates=update_notifications::on, std::vector< std::string > const &subcommands={})
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition parser.hpp:197
void add_subsection(std::string const &title, bool const advanced_only=false)
Adds an help page subsection to the sharg::parser.
Definition parser.hpp:559
bool is_option_set(id_type const &id) const
Checks whether the option identifier (id) was set on the command line by the user.
Definition parser.hpp:494
std::optional< bool > version_check_user_decision
Whether the user specified to perform the version check (true) or not (false), default unset.
Definition parser.hpp:726
void add_subcommands(std::vector< std::string > const &subcommands)
Adds subcommands to the parser.
Definition parser.hpp:652
void add_positional_option(option_type &value, config< validator_type > const &config)
Adds a positional option to the sharg::parser.
Definition parser.hpp:329
parser_meta_data info
Aggregates all parser related meta data (see sharg::parser_meta_data struct).
Definition parser.hpp:713
parser(parser &&)=default
Defaulted.
void parse()
Initiates the actual command line parsing.
Definition parser.hpp:418
parser & operator=(parser const &)=delete
Deleted.
parser(parser const &)=delete
Deleted.
void add_list_item(std::string const &key, std::string const &desc, bool const advanced_only=false)
Adds an help page list item (key-value) to the sharg::parser.
Definition parser.hpp:624
std::vector< std::function< void()> > operations
Vector of functions that stores all calls.
Definition parser.hpp:784
parser & operator=(parser &&)=default
Defaulted.
void check_parse_not_called(std::string_view const function_name) const
Throws a sharg::design_error if parse() was already called.
Definition parser.hpp:1083
void add_section(std::string const &title, bool const advanced_only=false)
Adds an help page section to the sharg::parser.
Definition parser.hpp:532
~parser()
The destructor.
Definition parser.hpp:206
std::vector< std::string > arguments
The original command line arguments.
Definition parser.hpp:775
void determine_format_and_subcommand()
Handles format and subcommand detection.
Definition parser.hpp:813
std::vector< std::string > subcommands
Stores the sub-parser names in case subcommand parsing is enabled.
Definition parser.hpp:744
parser & get_sub_parser()
Returns a reference to the sub-parser instance if subcommand parsing was enabled.
Definition parser.hpp:452
update_notifications version_check_dev_decision
Set on construction and indicates whether the developer deactivates the version check calls completel...
Definition parser.hpp:723
void verify_flag_config(config< validator_t > const &config)
brief Verify the configuration given to a sharg::parser::add_flag call.
Definition parser.hpp:1044
void add_line(std::string const &text, bool is_paragraph=false, bool const advanced_only=false)
Adds an help page text line to the sharg::parser.
Definition parser.hpp:587
void run_version_check()
Runs the version check if the user has not disabled it.
Definition parser.hpp:1121
void verify_option_config(config< validator_t > const &config)
brief Verify the configuration given to a sharg::parser::add_option call.
Definition parser.hpp:1029
void verify_positional_option_config(config< validator_t > const &config) const
brief Verify the configuration given to a sharg::parser::add_positional_option call.
Definition parser.hpp:1054
Parser exception thrown when too few arguments are provided.
Definition exceptions.hpp:100
Parser exception thrown when an argument could not be casted to the according type.
Definition exceptions.hpp:180
Whether the option type is considered to be a container.
Definition detail/concept.hpp:38
Checks whether the the type can be used in an add_(positional_)option call on the parser.
Definition concept.hpp:91
Provides sharg::config class.
std::string to_string(value_types &&... values)
Streams all parameters via std::ostringstream and returns a concatenated string.
Definition to_string.hpp:40
update_notifications
Indicates whether application allows automatic update notifications by the sharg::parser.
Definition auxiliary.hpp:27
@ off
Automatic update notifications should be disabled.
@ on
Automatic update notifications should be enabled.
Option struct that is passed to the sharg::parser::add_option() function.
Definition config.hpp:43
std::string long_id
The long identifier for the option (e.g. "age", making the option callable via --age).
Definition config.hpp:62
bool hidden
Whether the option should be hidden.
Definition config.hpp:117
bool advanced
Whether the option should only be displayed on the advanced help page.
Definition config.hpp:105
bool required
Whether the option is required.
Definition config.hpp:129
char short_id
The short identifier for the option (e.g. 'a', making the option callable via -a).
Definition config.hpp:53
std::string default_message
The default message to be shown on any (exported) help page.
Definition config.hpp:87
A simple struct to store a short and a long identifier for an option.
Definition id_pair.hpp:25
static bool contains(std::unordered_set< id_pair > const &used_ids, id_type const &id)
Checks whether an id is already contained in a set of used ids.
Definition id_pair.hpp:161
static auto find(std::unordered_set< id_pair > const &used_ids, id_type const &id)
Finds an id_pair in a set of used ids.
Definition id_pair.hpp:148
Provides the version check functionality.