1
0
Эх сурвалжийг харах

Merge topic 'list-join'

a58158727b list(): add `JOIN` sub-command

Acked-by: Kitware Robot <[email protected]>
Merge-request: !1846
Brad King 7 жил өмнө
parent
commit
d41abae70f

+ 11 - 0
Help/command/list.rst

@@ -54,6 +54,17 @@ GET
 
 Returns the list of elements specified by indices from the list.
 
+JOIN
+""""
+
+::
+
+  list(JOIN <list> <glue> <output variable>)
+
+Returns a string joining all list's elements using the glue string.
+To join multiple strings, which are not part of a list, use ``JOIN`` operator
+from :command:`string` command.
+
 Search
 ^^^^^^
 

+ 4 - 0
Help/command/string.rst

@@ -161,6 +161,10 @@ JOIN
 Join all the input arguments together using the glue
 string and store the result in the named output variable.
 
+To join list's elements, use preferably the ``JOIN`` operator
+from :command:`list` command. This allows for the elements to have
+special characters like ``;`` in them.
+
 TOLOWER
 """""""
 

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

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

+ 31 - 0
Source/cmListCommand.cxx

@@ -42,6 +42,9 @@ bool cmListCommand::InitialPass(std::vector<std::string> const& args,
   if (subCommand == "INSERT") {
     return this->HandleInsertCommand(args);
   }
+  if (subCommand == "JOIN") {
+    return this->HandleJoinCommand(args);
+  }
   if (subCommand == "REMOVE_AT") {
     return this->HandleRemoveAtCommand(args);
   }
@@ -294,6 +297,34 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
   return true;
 }
 
+bool cmListCommand::HandleJoinCommand(std::vector<std::string> const& args)
+{
+  if (args.size() != 4) {
+    std::ostringstream error;
+    error << "sub-command JOIN requires three arguments (" << args.size() - 1
+          << " found).";
+    this->SetError(error.str());
+    return false;
+  }
+
+  const std::string& listName = args[1];
+  const std::string& glue = args[2];
+  const std::string& variableName = args[3];
+
+  // expand the variable
+  std::vector<std::string> varArgsExpanded;
+  if (!this->GetList(varArgsExpanded, listName)) {
+    this->Makefile->AddDefinition(variableName, "");
+    return true;
+  }
+
+  std::string value =
+    cmJoin(cmMakeRange(varArgsExpanded.begin(), varArgsExpanded.end()), glue);
+
+  this->Makefile->AddDefinition(variableName, value.c_str());
+  return true;
+}
+
 bool cmListCommand::HandleRemoveItemCommand(
   std::vector<std::string> const& args)
 {

+ 1 - 0
Source/cmListCommand.h

@@ -37,6 +37,7 @@ protected:
   bool HandleAppendCommand(std::vector<std::string> const& args);
   bool HandleFindCommand(std::vector<std::string> const& args);
   bool HandleInsertCommand(std::vector<std::string> const& args);
+  bool HandleJoinCommand(std::vector<std::string> const& args);
   bool HandleRemoveAtCommand(std::vector<std::string> const& args);
   bool HandleRemoveItemCommand(std::vector<std::string> const& args);
   bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args);

+ 1 - 0
Tests/RunCMake/list/JOIN-NoArguments-result.txt

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

+ 4 - 0
Tests/RunCMake/list/JOIN-NoArguments-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Error at JOIN-NoArguments.cmake:1 \(list\):
+  list sub-command JOIN requires three arguments \(1 found\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/list/JOIN-NoArguments.cmake

@@ -0,0 +1 @@
+list(JOIN mylist)

+ 1 - 0
Tests/RunCMake/list/JOIN-NoVariable-result.txt

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

+ 4 - 0
Tests/RunCMake/list/JOIN-NoVariable-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Error at JOIN-NoVariable.cmake:1 \(list\):
+  list sub-command JOIN requires three arguments \(2 found\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/list/JOIN-NoVariable.cmake

@@ -0,0 +1 @@
+list(JOIN mylist "glue")

+ 1 - 0
Tests/RunCMake/list/JOIN-TooManyArguments-result.txt

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

+ 4 - 0
Tests/RunCMake/list/JOIN-TooManyArguments-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Error at JOIN-TooManyArguments.cmake:1 \(list\):
+  list sub-command JOIN requires three arguments \(4 found\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/list/JOIN-TooManyArguments.cmake

@@ -0,0 +1 @@
+list(JOIN mylist "glue" out one_too_many)

+ 18 - 0
Tests/RunCMake/list/JOIN.cmake

@@ -0,0 +1,18 @@
+list(JOIN undefList % out)
+if(NOT out STREQUAL "")
+  message(FATAL_ERROR "\"list(JOIN undefList % out)\" set out to \"${out}\"")
+endif()
+set(myList a)
+list(JOIN myList % out)
+if(NOT out STREQUAL "a")
+  message(FATAL_ERROR "\"list(JOIN \"a\" % out)\" set out to \"${out}\"")
+endif()
+set(myList a b)
+list(JOIN myList % out)
+if(NOT out STREQUAL "a%b")
+  message(FATAL_ERROR "\"list(JOIN \"a;b\" % out)\" set out to \"${out}\"")
+endif()
+list(JOIN myList "" out)
+if(NOT out STREQUAL "ab")
+  message(FATAL_ERROR "\"list(JOIN \"a;b\" \"\" out a)\" set out to \"${out}\"")
+endif()

+ 5 - 0
Tests/RunCMake/list/RunCMakeTest.cmake

@@ -15,6 +15,7 @@ run_cmake(INSERT-InvalidIndex)
 run_cmake(REMOVE_AT-InvalidIndex)
 
 run_cmake(FILTER-REGEX-TooManyArguments)
+run_cmake(JOIN-TooManyArguments)
 run_cmake(LENGTH-TooManyArguments)
 run_cmake(REMOVE_DUPLICATES-TooManyArguments)
 run_cmake(REVERSE-TooManyArguments)
@@ -31,3 +32,7 @@ run_cmake(FILTER-REGEX-InvalidMode)
 run_cmake(FILTER-REGEX-InvalidOperator)
 run_cmake(FILTER-REGEX-Valid0)
 run_cmake(FILTER-REGEX-Valid1)
+
+run_cmake(JOIN-NoArguments)
+run_cmake(JOIN-NoVariable)
+run_cmake(JOIN)