Browse Source

cmCommandLineArgument: OneOrMore mode supports `=` separator

Fixes #22187
Robert Maynard 4 years ago
parent
commit
396e0a840e

+ 45 - 30
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 <typename T, typename... CallState>
@@ -99,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) {
@@ -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<CallState>(state)...)
+          parseState =
+            this->StoreCall(value, std::forward<CallState>(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<CallState>(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);
+  }
 };

+ 1 - 2
Tests/RunCMake/CommandLine/build-invalid-target-syntax-stderr.txt

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