1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00

cmCommandLineArgument: OneOrMore mode supports = separator

Fixes #22187
This commit is contained in:
Robert Maynard
2021-05-19 11:07:34 -04:00
parent 372bf1bcc4
commit 396e0a840e
2 changed files with 46 additions and 32 deletions

View File

@@ -23,6 +23,14 @@ struct cmCommandLineArgument
No No
}; };
enum class ParseMode
{
Valid,
Invalid,
SyntaxError,
ValueError
};
std::string InvalidSyntaxMessage; std::string InvalidSyntaxMessage;
std::string InvalidValueMessage; std::string InvalidValueMessage;
std::string Name; std::string Name;
@@ -79,19 +87,20 @@ struct cmCommandLineArgument
bool matches(std::string const& input) const bool matches(std::string const& input) const
{ {
bool matched = false;
if (this->Type == Values::Zero) { if (this->Type == Values::Zero) {
return input == this->Name; matched = (input == this->Name);
} else if (this->SeparatorNeeded == RequiresSeparator::No) { } else if (this->SeparatorNeeded == RequiresSeparator::No) {
return cmHasPrefix(input, this->Name); matched = cmHasPrefix(input, this->Name);
} else if (cmHasPrefix(input, this->Name)) { } else if (cmHasPrefix(input, this->Name)) {
if (input.size() == this->Name.size()) { if (input.size() == this->Name.size()) {
return true; matched = true;
} else { } else {
return (input[this->Name.size()] == '=' || matched =
input[this->Name.size()] == ' '); (input[this->Name.size()] == '=' || input[this->Name.size()] == ' ');
} }
} }
return false; return matched;
} }
template <typename T, typename... CallState> template <typename T, typename... CallState>
@@ -99,13 +108,6 @@ struct cmCommandLineArgument
std::vector<std::string> const& allArgs, std::vector<std::string> const& allArgs,
CallState&&... state) const CallState&&... state) const
{ {
enum class ParseMode
{
Valid,
Invalid,
SyntaxError,
ValueError
};
ParseMode parseState = ParseMode::Valid; ParseMode parseState = ParseMode::Valid;
if (this->Type == Values::Zero) { if (this->Type == Values::Zero) {
@@ -139,23 +141,10 @@ struct cmCommandLineArgument
index = nextValueIndex; index = nextValueIndex;
} }
} else { } else {
// parse the string to get the value auto value = this->extract_single_value(input, parseState);
auto possible_value = cm::string_view(input).substr(this->Name.size());
if (possible_value.empty()) {
parseState = ParseMode::ValueError;
} else if (possible_value[0] == '=') {
possible_value.remove_prefix(1);
if (possible_value.empty()) {
parseState = ParseMode::ValueError;
}
}
if (parseState == ParseMode::Valid) { if (parseState == ParseMode::Valid) {
if (possible_value[0] == ' ') { parseState =
possible_value.remove_prefix(1); this->StoreCall(value, std::forward<CallState>(state)...)
}
parseState = this->StoreCall(std::string(possible_value),
std::forward<CallState>(state)...)
? ParseMode::Valid ? ParseMode::Valid
: ParseMode::Invalid; : ParseMode::Invalid;
} }
@@ -193,7 +182,13 @@ struct cmCommandLineArgument
index = (nextValueIndex - 1); index = (nextValueIndex - 1);
} }
} else { } else {
parseState = ParseMode::SyntaxError; auto value = this->extract_single_value(input, parseState);
if (parseState == ParseMode::Valid) {
parseState =
this->StoreCall(value, std::forward<CallState>(state)...)
? ParseMode::Valid
: ParseMode::Invalid;
}
} }
} }
@@ -205,4 +200,24 @@ struct cmCommandLineArgument
} }
return (parseState == ParseMode::Valid); return (parseState == ParseMode::Valid);
} }
private:
std::string extract_single_value(std::string const& input,
ParseMode& parseState) const
{
// parse the string to get the value
auto possible_value = cm::string_view(input).substr(this->Name.size());
if (possible_value.empty()) {
parseState = ParseMode::ValueError;
} else if (possible_value[0] == '=') {
possible_value.remove_prefix(1);
if (possible_value.empty()) {
parseState = ParseMode::ValueError;
}
}
if (parseState == ParseMode::Valid && possible_value[0] == ' ') {
possible_value.remove_prefix(1);
}
return std::string(possible_value);
}
}; };

View File

@@ -1,2 +1 @@
^CMake Error: '--target=invalid' is invalid syntax for --target ^Error: could not load cache
Usage: cmake --build \[<dir> \| --preset <preset>\] \[options\] \[-- \[native-options\]\]