Skip to content

Commit

Permalink
Disallow calling certain functions after parse()
Browse files Browse the repository at this point in the history
  • Loading branch information
eseiler committed Feb 8, 2024
1 parent 1d50ee1 commit fc4c414
Showing 1 changed file with 23 additions and 0 deletions.
23 changes: 23 additions & 0 deletions include/sharg/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ class parser
&& std::invocable<validator_type, option_type>
void add_option(option_type & value, config<validator_type> const & config)
{
check_parse_not_called("add_option");
verify_option_config(config);

// copy variables into the lambda because the calls are pushed to a stack
Expand All @@ -266,6 +267,7 @@ class parser
requires std::invocable<validator_type, bool>
void add_flag(bool & value, config<validator_type> const & config)
{
check_parse_not_called("add_flag");
verify_flag_config(config);

if (value)
Expand Down Expand Up @@ -308,6 +310,7 @@ class parser
&& std::invocable<validator_type, option_type>
void add_positional_option(option_type & value, config<validator_type> const & config)
{
check_parse_not_called("add_positional_option");
verify_positional_option_config(config);

if constexpr (detail::is_container_option<option_type>)
Expand Down Expand Up @@ -535,6 +538,7 @@ class parser
*/
void add_section(std::string const & title, bool const advanced_only = false)
{
check_parse_not_called("add_section");
std::visit(
[&title, advanced_only](auto & f)
{
Expand All @@ -554,6 +558,7 @@ class parser
*/
void add_subsection(std::string const & title, bool const advanced_only = false)
{
check_parse_not_called("add_subsection");
std::visit(
[&title, advanced_only](auto & f)
{
Expand All @@ -574,6 +579,7 @@ class parser
*/
void add_line(std::string const & text, bool is_paragraph = false, bool const advanced_only = false)
{
check_parse_not_called("add_line");
std::visit(
[&text, is_paragraph, advanced_only](auto & f)
{
Expand Down Expand Up @@ -603,6 +609,7 @@ class parser
*/
void add_list_item(std::string const & key, std::string const & desc, bool const advanced_only = false)
{
check_parse_not_called("add_list_item");
std::visit(
[&key, &desc, advanced_only](auto & f)
{
Expand Down Expand Up @@ -670,6 +677,7 @@ class parser
*/
void add_subcommands(std::vector<std::string> const & subcommands)
{
check_parse_not_called("add_subcommands");
for (auto const & sub : subcommands)
{
if (!std::regex_match(sub, app_name_regex))
Expand Down Expand Up @@ -1016,6 +1024,21 @@ class parser
if (!config.default_message.empty())
throw design_error{"A positional option may not have a default message because it is always required."};
}

/*!\brief Throws a sharg::design_error if parse() was already called.
* \param[in] function_name The name of the function that was called after parse().
* \throws sharg::design_error
* \details
* This function is used when calling functions which have no effect (add_line, add_option, ...) or unexpected
* behavior (add_subcommands) after parse() was called.
* Has no effect when parse() encounters a special format (help, version, ...), since those will terminate
* the program.
*/
inline void check_parse_not_called(std::string_view const function_name) const
{
if (parse_was_called)
throw design_error{detail::to_string(function_name.data(), " may only be used before calling parse().")};

Check warning on line 1040 in include/sharg/parser.hpp

View check run for this annotation

Codecov / codecov/patch

include/sharg/parser.hpp#L1040

Added line #L1040 was not covered by tests
}
};

} // namespace sharg

0 comments on commit fc4c414

Please sign in to comment.