summaryrefslogtreecommitdiffstats
path: root/Source/cmCommandLineArgument.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmCommandLineArgument.h')
-rw-r--r--Source/cmCommandLineArgument.h107
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);
+ }
};