From 396e0a840e75afb3f5ed7b50892b93ce946fac2e Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 19 May 2021 11:07:34 -0400 Subject: cmCommandLineArgument: OneOrMore mode supports `=` separator Fixes #22187 --- Source/cmCommandLineArgument.h | 75 +++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 30 deletions(-) (limited to 'Source/cmCommandLineArgument.h') diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h index e2697718f9..72ab0450fd 100644 --- a/Source/cmCommandLineArgument.h +++ b/Source/cmCommandLineArgument.h @@ -23,6 +23,14 @@ struct cmCommandLineArgument No }; + enum class ParseMode + { + Valid, + Invalid, + SyntaxError, + ValueError + }; + std::string InvalidSyntaxMessage; std::string InvalidValueMessage; std::string Name; @@ -79,19 +87,20 @@ struct cmCommandLineArgument bool matches(std::string const& input) const { + bool matched = false; if (this->Type == Values::Zero) { - return input == this->Name; + matched = (input == this->Name); } else if (this->SeparatorNeeded == RequiresSeparator::No) { - return cmHasPrefix(input, this->Name); + matched = cmHasPrefix(input, this->Name); } else if (cmHasPrefix(input, this->Name)) { if (input.size() == this->Name.size()) { - return true; + matched = true; } else { - return (input[this->Name.size()] == '=' || - input[this->Name.size()] == ' '); + matched = + (input[this->Name.size()] == '=' || input[this->Name.size()] == ' '); } } - return false; + return matched; } template @@ -99,13 +108,6 @@ struct cmCommandLineArgument std::vector const& allArgs, CallState&&... state) const { - enum class ParseMode - { - Valid, - Invalid, - SyntaxError, - ValueError - }; ParseMode parseState = ParseMode::Valid; if (this->Type == Values::Zero) { @@ -139,23 +141,10 @@ struct cmCommandLineArgument index = nextValueIndex; } } else { - // 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; - } - } + auto value = this->extract_single_value(input, parseState); if (parseState == ParseMode::Valid) { - if (possible_value[0] == ' ') { - possible_value.remove_prefix(1); - } - - parseState = this->StoreCall(std::string(possible_value), - std::forward(state)...) + parseState = + this->StoreCall(value, std::forward(state)...) ? ParseMode::Valid : ParseMode::Invalid; } @@ -193,7 +182,13 @@ struct cmCommandLineArgument index = (nextValueIndex - 1); } } else { - parseState = ParseMode::SyntaxError; + auto value = this->extract_single_value(input, parseState); + if (parseState == ParseMode::Valid) { + parseState = + this->StoreCall(value, std::forward(state)...) + ? ParseMode::Valid + : ParseMode::Invalid; + } } } @@ -205,4 +200,24 @@ struct cmCommandLineArgument } 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); + } }; -- cgit v1.2.1