Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multitoken options #444

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion include/cxxopts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ class Value : public std::enable_shared_from_this<Value>
virtual bool
is_container() const = 0;

virtual bool
is_multitoken() const = 0;

virtual bool
has_implicit() const = 0;

Expand All @@ -394,6 +397,9 @@ class Value : public std::enable_shared_from_this<Value>
virtual std::string
get_implicit_value() const = 0;

virtual std::shared_ptr<Value>
multitoken() = 0;

virtual std::shared_ptr<Value>
default_value(const std::string& value) = 0;

Expand Down Expand Up @@ -1189,6 +1195,12 @@ class abstract_value : public Value
return type_is_container<T>::value;
}

bool
is_multitoken() const override
{
return m_multitoken;
}

void
parse() const override
{
Expand All @@ -1207,6 +1219,13 @@ class abstract_value : public Value
return m_implicit;
}

std::shared_ptr<Value>
multitoken() override
{
m_multitoken = true;
return shared_from_this();
}

std::shared_ptr<Value>
default_value(const std::string& value) override
{
Expand Down Expand Up @@ -1264,6 +1283,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{};
Expand Down Expand Up @@ -2506,6 +2526,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<OptionDetails> current_multitoken = nullptr;
std::string current_multitoken_name;

std::vector<std::string> unmatched;

Expand All @@ -2532,9 +2554,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
Expand All @@ -2549,6 +2575,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)
{
Expand All @@ -2567,6 +2594,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())
{
Expand All @@ -2593,6 +2625,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);

Expand All @@ -2610,6 +2643,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)
Expand Down
Loading