mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-29 18:51:05 -05:00
cmArgumentParser: Offer binding for list of parsed keywords
Some clients ask for this list in their `Parse()` call. Offer them a way to express this request as a binding.
This commit is contained in:
@@ -86,6 +86,9 @@ void Instance::Consume(cm::string_view arg)
|
|||||||
if (this->ParsedKeywords != nullptr) {
|
if (this->ParsedKeywords != nullptr) {
|
||||||
this->ParsedKeywords->emplace_back(it->first);
|
this->ParsedKeywords->emplace_back(it->first);
|
||||||
}
|
}
|
||||||
|
if (this->Bindings.ParsedKeyword) {
|
||||||
|
this->Bindings.ParsedKeyword(*this, it->first);
|
||||||
|
}
|
||||||
it->second(*this);
|
it->second(*this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ class ActionMap
|
|||||||
public:
|
public:
|
||||||
KeywordActionMap Keywords;
|
KeywordActionMap Keywords;
|
||||||
KeywordNameAction KeywordMissingValue;
|
KeywordNameAction KeywordMissingValue;
|
||||||
|
KeywordNameAction ParsedKeyword;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Base
|
class Base
|
||||||
@@ -103,6 +104,12 @@ public:
|
|||||||
static_cast<void>(inserted);
|
static_cast<void>(inserted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BindParsedKeyword(KeywordNameAction action)
|
||||||
|
{
|
||||||
|
assert(!this->Bindings.ParsedKeyword);
|
||||||
|
this->Bindings.ParsedKeyword = std::move(action);
|
||||||
|
}
|
||||||
|
|
||||||
void BindKeywordMissingValue(KeywordNameAction action)
|
void BindKeywordMissingValue(KeywordNameAction action)
|
||||||
{
|
{
|
||||||
assert(!this->Bindings.KeywordMissingValue);
|
assert(!this->Bindings.KeywordMissingValue);
|
||||||
@@ -187,6 +194,16 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmArgumentParser& BindParsedKeywords(
|
||||||
|
std::vector<cm::string_view> Result::*member)
|
||||||
|
{
|
||||||
|
this->Base::BindParsedKeyword(
|
||||||
|
[member](Instance& instance, cm::string_view arg) {
|
||||||
|
(static_cast<Result*>(instance.Result)->*member).emplace_back(arg);
|
||||||
|
});
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Range>
|
template <typename Range>
|
||||||
bool Parse(Result& result, Range const& args,
|
bool Parse(Result& result, Range const& args,
|
||||||
std::vector<std::string>* unparsedArguments,
|
std::vector<std::string>* unparsedArguments,
|
||||||
@@ -221,6 +238,13 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmArgumentParser& BindParsedKeywords(std::vector<cm::string_view>& ref)
|
||||||
|
{
|
||||||
|
this->Base::BindParsedKeyword(
|
||||||
|
[&ref](Instance&, cm::string_view arg) { ref.emplace_back(arg); });
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Range>
|
template <typename Range>
|
||||||
ParseResult Parse(
|
ParseResult Parse(
|
||||||
Range const& args, std::vector<std::string>* unparsedArguments,
|
Range const& args, std::vector<std::string>* unparsedArguments,
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ struct Result : public ArgumentParser::ParseResult
|
|||||||
std::vector<std::vector<std::string>> Multi2;
|
std::vector<std::vector<std::string>> Multi2;
|
||||||
cm::optional<std::vector<std::vector<std::string>>> Multi3;
|
cm::optional<std::vector<std::vector<std::string>>> Multi3;
|
||||||
cm::optional<std::vector<std::vector<std::string>>> Multi4;
|
cm::optional<std::vector<std::vector<std::string>>> Multi4;
|
||||||
|
|
||||||
|
std::vector<cm::string_view> ParsedKeywords;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::initializer_list<cm::string_view> const args = {
|
std::initializer_list<cm::string_view> const args = {
|
||||||
@@ -67,6 +69,23 @@ bool verifyResult(Result const& result,
|
|||||||
{
|
{
|
||||||
static std::vector<std::string> const foobar = { "foo", "bar" };
|
static std::vector<std::string> const foobar = { "foo", "bar" };
|
||||||
static std::vector<std::string> const barfoo = { "bar", "foo" };
|
static std::vector<std::string> const barfoo = { "bar", "foo" };
|
||||||
|
static std::vector<cm::string_view> const parsedKeywords = {
|
||||||
|
/* clang-format off */
|
||||||
|
"OPTION_1",
|
||||||
|
"STRING_1",
|
||||||
|
"STRING_2",
|
||||||
|
"STRING_4",
|
||||||
|
"LIST_1",
|
||||||
|
"LIST_2",
|
||||||
|
"LIST_3",
|
||||||
|
"LIST_3",
|
||||||
|
"LIST_4",
|
||||||
|
"LIST_6",
|
||||||
|
"MULTI_2",
|
||||||
|
"MULTI_3",
|
||||||
|
"MULTI_3",
|
||||||
|
/* clang-format on */
|
||||||
|
};
|
||||||
static std::map<cm::string_view, std::string> const keywordErrors = {
|
static std::map<cm::string_view, std::string> const keywordErrors = {
|
||||||
{ "STRING_1"_s, " missing required value\n" },
|
{ "STRING_1"_s, " missing required value\n" },
|
||||||
{ "LIST_1"_s, " missing required value\n" },
|
{ "LIST_1"_s, " missing required value\n" },
|
||||||
@@ -114,6 +133,8 @@ bool verifyResult(Result const& result,
|
|||||||
ASSERT_TRUE(unparsedArguments.size() == 1);
|
ASSERT_TRUE(unparsedArguments.size() == 1);
|
||||||
ASSERT_TRUE(unparsedArguments[0] == "bar");
|
ASSERT_TRUE(unparsedArguments[0] == "bar");
|
||||||
|
|
||||||
|
ASSERT_TRUE(result.ParsedKeywords == parsedKeywords);
|
||||||
|
|
||||||
ASSERT_TRUE(result.GetKeywordErrors().size() == keywordErrors.size());
|
ASSERT_TRUE(result.GetKeywordErrors().size() == keywordErrors.size());
|
||||||
for (auto const& ke : result.GetKeywordErrors()) {
|
for (auto const& ke : result.GetKeywordErrors()) {
|
||||||
auto const ki = keywordErrors.find(ke.first);
|
auto const ki = keywordErrors.find(ke.first);
|
||||||
@@ -147,6 +168,7 @@ bool testArgumentParserDynamic()
|
|||||||
.Bind("MULTI_2"_s, result.Multi2)
|
.Bind("MULTI_2"_s, result.Multi2)
|
||||||
.Bind("MULTI_3"_s, result.Multi3)
|
.Bind("MULTI_3"_s, result.Multi3)
|
||||||
.Bind("MULTI_4"_s, result.Multi4)
|
.Bind("MULTI_4"_s, result.Multi4)
|
||||||
|
.BindParsedKeywords(result.ParsedKeywords)
|
||||||
.Parse(args, &unparsedArguments);
|
.Parse(args, &unparsedArguments);
|
||||||
|
|
||||||
return verifyResult(result, unparsedArguments);
|
return verifyResult(result, unparsedArguments);
|
||||||
@@ -170,6 +192,7 @@ static auto const parserStatic = //
|
|||||||
.Bind("MULTI_2"_s, &Result::Multi2)
|
.Bind("MULTI_2"_s, &Result::Multi2)
|
||||||
.Bind("MULTI_3"_s, &Result::Multi3)
|
.Bind("MULTI_3"_s, &Result::Multi3)
|
||||||
.Bind("MULTI_4"_s, &Result::Multi4)
|
.Bind("MULTI_4"_s, &Result::Multi4)
|
||||||
|
.BindParsedKeywords(&Result::ParsedKeywords)
|
||||||
/* keep semicolon on own line */;
|
/* keep semicolon on own line */;
|
||||||
|
|
||||||
bool testArgumentParserStatic()
|
bool testArgumentParserStatic()
|
||||||
|
|||||||
Reference in New Issue
Block a user