Quellcode durchsuchen

Merge topic 'genex-strip-nested' into release-4.1

8227028e49 string(GENEX_STRIP): Fix regression on nested generator expressions

Acked-by: Kitware Robot <[email protected]>
Merge-request: !11077
Brad King vor 3 Monaten
Ursprung
Commit
8fbddbc777

+ 19 - 16
Source/cmGeneratorExpression.cxx

@@ -164,33 +164,36 @@ static std::string extractAllGeneratorExpressions(
   std::string result;
   std::string::size_type pos = 0;
   std::string::size_type lastPos = pos;
-  // stack of { Generator Expression Name, Start Position of Value }
-  std::stack<std::pair<std::string, std::string::size_type>> genexps;
+  std::stack<char const*> starts; // indices of "$<"
+  std::stack<char const*> colons; // indices of ":"
   while ((pos = input.find("$<", lastPos)) != std::string::npos) {
     result += input.substr(lastPos, pos - lastPos);
+    starts.push(input.c_str() + pos);
     pos += 2;
     char const* c = input.c_str() + pos;
-    char const* cName = c;
     char const* const cStart = c;
     for (; *c; ++c) {
       if (cmGeneratorExpression::StartsWithGeneratorExpression(c)) {
+        starts.push(c);
         ++c;
-        cName = c + 1;
         continue;
       }
-      if (c[0] == ':' && cName) {
-        genexps.push({ input.substr(pos + (cName - cStart), c - cName),
-                       pos + (c + 1 - cStart) });
-        cName = nullptr;
+      if (c[0] == ':') {
+        if (colons.size() < starts.size()) {
+          colons.push(c);
+        }
       } else if (c[0] == '>') {
-        if (!cName && !genexps.empty()) {
-          if (collected) {
-            (*collected)[genexps.top().first].push_back(input.substr(
-              genexps.top().second, pos + c - cStart - genexps.top().second));
-          }
-          genexps.pop();
+        if (collected && !starts.empty() && !colons.empty()) {
+          (*collected)[std::string(starts.top() + 2, colons.top())].push_back(
+            std::string(colons.top() + 1, c));
+        }
+        if (!starts.empty()) {
+          starts.pop();
+        }
+        if (!colons.empty()) {
+          colons.pop();
         }
-        if (genexps.empty()) {
+        if (starts.empty()) {
           break;
         }
       }
@@ -202,7 +205,7 @@ static std::string extractAllGeneratorExpressions(
     pos += traversed;
     lastPos = pos;
   }
-  if (genexps.empty()) {
+  if (starts.empty()) {
     result += input.substr(lastPos);
   }
   return cmGeneratorExpression::StripEmptyListElements(result);

+ 37 - 0
Tests/RunCMake/string/GenexpStrip.cmake

@@ -0,0 +1,37 @@
+function(test_strip input expected)
+  string(GENEX_STRIP "${input}" strip)
+  if (NOT strip STREQUAL expected)
+    message(FATAL_ERROR "message(GENEXP_STRIP \"${input}\")
+evaluated to \"${strip}\"
+expected \"${expected}\"")
+  endif()
+endfunction()
+
+test_strip( # Simple case
+  "$<BOOL:1>"
+  ""
+)
+test_strip( # LHS contains generator expression
+  "$<$<CONFIG:Release>:NDEBUG>;DEBUG"
+  "DEBUG"
+)
+test_strip( # RHS contains generator expression
+  "$<AND:1,$<BOOL:TRUE>>"
+  ""
+)
+test_strip( # Empty and unfinished expressions
+  "$<>$<$<>"
+  "$<$<>"
+)
+test_strip( # Multiple independent expressions
+  "$<IF:TRUE,TRUE,FALSE> / $<IF:TRUE,TRUE,FALSE>"
+  " / "
+)
+test_strip( # Multiple : in one expression
+  "$<1:2:3>"
+  ""
+)
+test_strip( # Multiple case
+  "1$<AND:1,0>2$<IF:$<$<BOOL:1>:$<CONFIG:RELEASE>>,TRUE,FALSE>3"
+  "123"
+)

+ 2 - 0
Tests/RunCMake/string/RunCMakeTest.cmake

@@ -56,3 +56,5 @@ run_cmake(RepeatNegativeCount)
 run_cmake(Hex)
 run_cmake(HexTooManyArgs)
 run_cmake(HexNotEnoughArgs)
+
+run_cmake(GenexpStrip)