Browse Source

Merge topic 'list-join'

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

Acked-by: Kitware Robot <[email protected]>
Merge-request: !1846
Brad King 7 years ago
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.
 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
 Search
 ^^^^^^
 ^^^^^^
 
 

+ 4 - 0
Help/command/string.rst

@@ -161,6 +161,10 @@ JOIN
 Join all the input arguments together using the glue
 Join all the input arguments together using the glue
 string and store the result in the named output variable.
 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
 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") {
   if (subCommand == "INSERT") {
     return this->HandleInsertCommand(args);
     return this->HandleInsertCommand(args);
   }
   }
+  if (subCommand == "JOIN") {
+    return this->HandleJoinCommand(args);
+  }
   if (subCommand == "REMOVE_AT") {
   if (subCommand == "REMOVE_AT") {
     return this->HandleRemoveAtCommand(args);
     return this->HandleRemoveAtCommand(args);
   }
   }
@@ -294,6 +297,34 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
   return true;
   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(
 bool cmListCommand::HandleRemoveItemCommand(
   std::vector<std::string> const& args)
   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 HandleAppendCommand(std::vector<std::string> const& args);
   bool HandleFindCommand(std::vector<std::string> const& args);
   bool HandleFindCommand(std::vector<std::string> const& args);
   bool HandleInsertCommand(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 HandleRemoveAtCommand(std::vector<std::string> const& args);
   bool HandleRemoveItemCommand(std::vector<std::string> const& args);
   bool HandleRemoveItemCommand(std::vector<std::string> const& args);
   bool HandleRemoveDuplicatesCommand(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(REMOVE_AT-InvalidIndex)
 
 
 run_cmake(FILTER-REGEX-TooManyArguments)
 run_cmake(FILTER-REGEX-TooManyArguments)
+run_cmake(JOIN-TooManyArguments)
 run_cmake(LENGTH-TooManyArguments)
 run_cmake(LENGTH-TooManyArguments)
 run_cmake(REMOVE_DUPLICATES-TooManyArguments)
 run_cmake(REMOVE_DUPLICATES-TooManyArguments)
 run_cmake(REVERSE-TooManyArguments)
 run_cmake(REVERSE-TooManyArguments)
@@ -31,3 +32,7 @@ run_cmake(FILTER-REGEX-InvalidMode)
 run_cmake(FILTER-REGEX-InvalidOperator)
 run_cmake(FILTER-REGEX-InvalidOperator)
 run_cmake(FILTER-REGEX-Valid0)
 run_cmake(FILTER-REGEX-Valid0)
 run_cmake(FILTER-REGEX-Valid1)
 run_cmake(FILTER-REGEX-Valid1)
+
+run_cmake(JOIN-NoArguments)
+run_cmake(JOIN-NoVariable)
+run_cmake(JOIN)