Pārlūkot izejas kodu

Merge topic 'string-join'

689eeb67 string: Add JOIN subcommand

Acked-by: Kitware Robot <[email protected]>
Acked-by: Pavel Solodovnikov <[email protected]>
Merge-request: !1762
Brad King 7 gadi atpakaļ
vecāks
revīzija
846a4dd118

+ 10 - 0
Help/command/string.rst

@@ -151,6 +151,16 @@ CONCAT
 Concatenate all the input arguments together and store
 the result in the named output variable.
 
+JOIN
+""""
+
+::
+
+  string(JOIN <glue> <output variable> [<input>...])
+
+Join all the input arguments together using the glue
+string and store the result in the named output variable.
+
 TOLOWER
 """""""
 

+ 5 - 0
Help/release/dev/string-join.rst

@@ -0,0 +1,5 @@
+string-join
+-----------
+
+* The :command:`string` command learned a ``JOIN`` sub-command
+  to concatenate input strings separated by a glue string.

+ 23 - 2
Source/cmStringCommand.cxx

@@ -68,6 +68,9 @@ bool cmStringCommand::InitialPass(std::vector<std::string> const& args,
   if (subCommand == "CONCAT") {
     return this->HandleConcatCommand(args);
   }
+  if (subCommand == "JOIN") {
+    return this->HandleJoinCommand(args);
+  }
   if (subCommand == "SUBSTRING") {
     return this->HandleSubstringCommand(args);
   }
@@ -677,8 +680,26 @@ bool cmStringCommand::HandleConcatCommand(std::vector<std::string> const& args)
     return false;
   }
 
-  std::string const& variableName = args[1];
-  std::string value = cmJoin(cmMakeRange(args).advance(2), std::string());
+  return this->joinImpl(args, std::string(), 1);
+}
+
+bool cmStringCommand::HandleJoinCommand(std::vector<std::string> const& args)
+{
+  if (args.size() < 3) {
+    this->SetError("sub-command JOIN requires at least two arguments.");
+    return false;
+  }
+
+  return this->joinImpl(args, args[1], 2);
+}
+
+bool cmStringCommand::joinImpl(std::vector<std::string> const& args,
+                               std::string const& glue, const size_t varIdx)
+{
+  std::string const& variableName = args[varIdx];
+  // NOTE Items to concat/join placed right after the variable for
+  // both `CONCAT` and `JOIN` sub-commands.
+  std::string value = cmJoin(cmMakeRange(args).advance(varIdx + 1), glue);
 
   this->Makefile->AddDefinition(variableName, value.c_str());
   return true;

+ 5 - 0
Source/cmStringCommand.h

@@ -5,6 +5,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <cstddef>
 #include <string>
 #include <vector>
 
@@ -48,6 +49,7 @@ protected:
   bool HandleAppendCommand(std::vector<std::string> const& args);
   bool HandlePrependCommand(std::vector<std::string> const& args);
   bool HandleConcatCommand(std::vector<std::string> const& args);
+  bool HandleJoinCommand(std::vector<std::string> const& args);
   bool HandleStripCommand(std::vector<std::string> const& args);
   bool HandleRandomCommand(std::vector<std::string> const& args);
   bool HandleFindCommand(std::vector<std::string> const& args);
@@ -56,6 +58,9 @@ protected:
   bool HandleGenexStripCommand(std::vector<std::string> const& args);
   bool HandleUuidCommand(std::vector<std::string> const& args);
 
+  bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
+                size_t varIdx);
+
   class RegexReplacement
   {
   public:

+ 16 - 0
Tests/RunCMake/string/Join.cmake

@@ -0,0 +1,16 @@
+string(JOIN % out)
+if(NOT out STREQUAL "")
+  message(FATAL_ERROR "\"string(JOIN % out)\" set out to \"${out}\"")
+endif()
+string(JOIN % out a)
+if(NOT out STREQUAL "a")
+  message(FATAL_ERROR "\"string(JOIN % out a)\" set out to \"${out}\"")
+endif()
+string(JOIN % out a "b")
+if(NOT out STREQUAL "a%b")
+  message(FATAL_ERROR "\"string(JOIN % out a \"b\")\" set out to \"${out}\"")
+endif()
+string(JOIN :: out a "b")
+if(NOT out STREQUAL "a::b")
+  message(FATAL_ERROR "\"string(JOIN :: out a \"b\")\" set out to \"${out}\"")
+endif()

+ 1 - 0
Tests/RunCMake/string/JoinNoArgs-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
Tests/RunCMake/string/JoinNoArgs-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at JoinNoArgs.cmake:1 \(string\):
+  string sub-command JOIN requires at least two arguments.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 1 - 0
Tests/RunCMake/string/JoinNoArgs.cmake

@@ -0,0 +1 @@
+string(JOIN)

+ 1 - 0
Tests/RunCMake/string/JoinNoVar-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
Tests/RunCMake/string/JoinNoVar-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at JoinNoVar.cmake:1 \(string\):
+  string sub-command JOIN requires at least two arguments.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 1 - 0
Tests/RunCMake/string/JoinNoVar.cmake

@@ -0,0 +1 @@
+string(JOIN ";")

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

@@ -9,6 +9,10 @@ run_cmake(PrependNoArgs)
 run_cmake(Concat)
 run_cmake(ConcatNoArgs)
 
+run_cmake(Join)
+run_cmake(JoinNoArgs)
+run_cmake(JoinNoVar)
+
 run_cmake(Timestamp)
 run_cmake(TimestampEmpty)
 run_cmake(TimestampInvalid)