From e9b56848815a4e0e465c1f26e280c8b9498e475b Mon Sep 17 00:00:00 2001 From: Enrico Seiler Date: Fri, 9 Feb 2024 13:00:14 +0100 Subject: [PATCH] alternative approach --- include/sharg/parser.hpp | 50 ++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/include/sharg/parser.hpp b/include/sharg/parser.hpp index 4b784651..9205365d 100644 --- a/include/sharg/parser.hpp +++ b/include/sharg/parser.hpp @@ -189,7 +189,11 @@ class parser { info.app_name = app_name; - add_subcommands(std::move(subcommands)); + for (auto const & subcommand : subcommands) + std::ignore /* function is nodisard */ = add_subcommand(subcommand); + + if (subcommands.empty()) + init(); } //!\overload @@ -453,12 +457,18 @@ class parser * \details * \stableapi{Since version 1.0.} */ - parser & get_sub_parser() + [[nodiscard]] parser & get_sub_parser() { + // Technically not, as sub_parser is set via init(), but if if no subcommand is used in the command line, + // we do not process special formats (help/short-help/etc.) for the top-level parser. + if (!parse_was_called) + throw design_error("The function parse() must be called before get_sub_parser!"); + + if (subcommands.empty()) + throw design_error("No subcommand was provided for the argument parser!"); + if (sub_parser == nullptr) - { - throw design_error("No subcommand was provided at the construction of the argument parser!"); - } + throw design_error("There is no subparser!"); return *sub_parser; } @@ -675,31 +685,31 @@ class parser * \param[in] subcommands A list of subcommands. * \throws sharg::design_error if the subcommand name contains illegal characters. */ - void add_subcommands(std::vector const & subcommands) + [[nodiscard]] parser * add_subcommand(std::string subcommand) { - check_parse_not_called("add_subcommands"); - for (auto const & sub : subcommands) + check_parse_not_called("add_subcommand"); + + if (!std::regex_match(subcommand, app_name_regex)) { - if (!std::regex_match(sub, app_name_regex)) - { - std::string const error_message = - detail::to_string(std::quoted(info.app_name), - " contains an invalid subcommand name: ", - std::quoted(sub), - ". The subcommand name must only contain alpha-numeric characters ", - "or '_' and '-' (regex: \"^[a-zA-Z0-9_-]+$\")."); - throw design_error{error_message}; - }; - } + std::string const error_message = + detail::to_string(std::quoted(info.app_name), + " contains an invalid subcommand name: ", + std::quoted(subcommand), + ". The subcommand name must only contain alpha-numeric characters ", + "or '_' and '-' (regex: \"^[a-zA-Z0-9_-]+$\")."); + throw design_error{error_message}; + }; auto & parser_subcommands = this->subcommands; - parser_subcommands.insert(parser_subcommands.end(), subcommands.cbegin(), subcommands.cend()); + parser_subcommands.emplace_back(std::move(subcommand)); std::ranges::sort(parser_subcommands); auto const [first, last] = std::ranges::unique(parser_subcommands); parser_subcommands.erase(first, last); init(); + + return sub_parser.get(); } private: