From 18ccb45aa15f3fa26e428709a0fc064b6307adf4 Mon Sep 17 00:00:00 2001 From: Mikko Rautiainen Date: Tue, 27 Aug 2024 15:25:29 +0300 Subject: [PATCH] multitoken options --- include/cxxopts.hpp | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/include/cxxopts.hpp b/include/cxxopts.hpp index 991ba3f..92eb847 100644 --- a/include/cxxopts.hpp +++ b/include/cxxopts.hpp @@ -384,6 +384,9 @@ class Value : public std::enable_shared_from_this virtual bool is_container() const = 0; + virtual bool + is_multitoken() const = 0; + virtual bool has_implicit() const = 0; @@ -393,6 +396,9 @@ class Value : public std::enable_shared_from_this virtual std::string get_implicit_value() const = 0; + virtual std::shared_ptr + multitoken() = 0; + virtual std::shared_ptr default_value(const std::string& value) = 0; @@ -1188,6 +1194,12 @@ class abstract_value : public Value return type_is_container::value; } + bool + is_multitoken() const override + { + return m_multitoken; + } + void parse() const override { @@ -1206,6 +1218,13 @@ class abstract_value : public Value return m_implicit; } + std::shared_ptr + multitoken() override + { + m_multitoken = true; + return shared_from_this(); + } + std::shared_ptr default_value(const std::string& value) override { @@ -1263,6 +1282,7 @@ class abstract_value : public Value bool m_default = false; bool m_implicit = false; + bool m_multitoken = false; std::string m_default_value{}; std::string m_implicit_value{}; @@ -2499,6 +2519,8 @@ OptionParser::parse(int argc, const char* const* argv) int current = 1; bool consume_remaining = false; auto next_positional = m_positional.begin(); + std::shared_ptr current_multitoken = nullptr; + std::string current_multitoken_name; std::vector unmatched; @@ -2525,9 +2547,13 @@ OptionParser::parse(int argc, const char* const* argv) } } + if (current_multitoken != nullptr) + { + parse_option(current_multitoken, current_multitoken_name, argv[current]); + } //if true is returned here then it was consumed, otherwise it is //ignored - if (consume_positional(argv[current], next_positional)) + else if (consume_positional(argv[current], next_positional)) { } else @@ -2542,6 +2568,7 @@ OptionParser::parse(int argc, const char* const* argv) if (argu_desc.grouping) { const std::string& s = argu_desc.arg_name; + current_multitoken = nullptr; for (std::size_t i = 0; i != s.size(); ++i) { @@ -2560,6 +2587,11 @@ OptionParser::parse(int argc, const char* const* argv) } auto value = iter->second; + if (value->value().is_multitoken()) + { + current_multitoken = value; + current_multitoken_name = name; + } if (i + 1 == s.size()) { @@ -2586,6 +2618,7 @@ OptionParser::parse(int argc, const char* const* argv) else if (argu_desc.arg_name.length() != 0) { const std::string& name = argu_desc.arg_name; + current_multitoken = nullptr; auto iter = m_options.find(name); @@ -2603,6 +2636,11 @@ OptionParser::parse(int argc, const char* const* argv) } auto opt = iter->second; + if (opt->value().is_multitoken()) + { + current_multitoken = opt; + current_multitoken_name = name; + } //equals provided for long option? if (argu_desc.set_value)