diff options
Diffstat (limited to 'Source/cmCommandLineArgument.h')
-rw-r--r-- | Source/cmCommandLineArgument.h | 107 |
1 files changed, 85 insertions, 22 deletions
diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h index ddfff32..72ab045 100644 --- a/Source/cmCommandLineArgument.h +++ b/Source/cmCommandLineArgument.h @@ -17,10 +17,25 @@ struct cmCommandLineArgument OneOrMore }; + enum class RequiresSeparator + { + Yes, + No + }; + + enum class ParseMode + { + Valid, + Invalid, + SyntaxError, + ValueError + }; + std::string InvalidSyntaxMessage; std::string InvalidValueMessage; std::string Name; Values Type; + RequiresSeparator SeparatorNeeded; std::function<FunctionSignature> StoreCall; template <typename FunctionType> @@ -29,6 +44,19 @@ struct cmCommandLineArgument , InvalidValueMessage(cmStrCat("Invalid value used with ", n)) , Name(std::move(n)) , Type(t) + , SeparatorNeeded(RequiresSeparator::Yes) + , StoreCall(std::forward<FunctionType>(func)) + { + } + + template <typename FunctionType> + cmCommandLineArgument(std::string n, Values t, RequiresSeparator s, + FunctionType&& func) + : InvalidSyntaxMessage(cmStrCat(" is invalid syntax for ", n)) + , InvalidValueMessage(cmStrCat("Invalid value used with ", n)) + , Name(std::move(n)) + , Type(t) + , SeparatorNeeded(s) , StoreCall(std::forward<FunctionType>(func)) { } @@ -40,14 +68,39 @@ struct cmCommandLineArgument , InvalidValueMessage(std::move(failedMsg)) , Name(std::move(n)) , Type(t) + , SeparatorNeeded(RequiresSeparator::Yes) + , StoreCall(std::forward<FunctionType>(func)) + { + } + + template <typename FunctionType> + cmCommandLineArgument(std::string n, std::string failedMsg, Values t, + RequiresSeparator s, FunctionType&& func) + : InvalidSyntaxMessage(cmStrCat(" is invalid syntax for ", n)) + , InvalidValueMessage(std::move(failedMsg)) + , Name(std::move(n)) + , Type(t) + , SeparatorNeeded(s) , StoreCall(std::forward<FunctionType>(func)) { } bool matches(std::string const& input) const { - return (this->Type == Values::Zero) ? (input == this->Name) - : cmHasPrefix(input, this->Name); + bool matched = false; + if (this->Type == Values::Zero) { + matched = (input == this->Name); + } else if (this->SeparatorNeeded == RequiresSeparator::No) { + matched = cmHasPrefix(input, this->Name); + } else if (cmHasPrefix(input, this->Name)) { + if (input.size() == this->Name.size()) { + matched = true; + } else { + matched = + (input[this->Name.size()] == '=' || input[this->Name.size()] == ' '); + } + } + return matched; } template <typename T, typename... CallState> @@ -55,13 +108,6 @@ struct cmCommandLineArgument std::vector<std::string> const& allArgs, CallState&&... state) const { - enum class ParseMode - { - Valid, - Invalid, - SyntaxError, - ValueError - }; ParseMode parseState = ParseMode::Valid; if (this->Type == Values::Zero) { @@ -95,19 +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) { - parseState = this->StoreCall(std::string(possible_value), - std::forward<CallState>(state)...) + parseState = + this->StoreCall(value, std::forward<CallState>(state)...) ? ParseMode::Valid : ParseMode::Invalid; } @@ -145,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<CallState>(state)...) + ? ParseMode::Valid + : ParseMode::Invalid; + } } } @@ -157,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); + } }; |