string: Add JOIN subcommand

This is just like CONCAT but accepts a glue string to put between
each value.  `JOIN ""` is equivalent to `CONCAT`.
This commit is contained in:
Alex Turbov
2018-02-11 21:20:57 +08:00
committed by Brad King
parent e24cda008e
commit 689eeb67cb
12 changed files with 75 additions and 2 deletions

View File

@@ -151,6 +151,16 @@ CONCAT
Concatenate all the input arguments together and store Concatenate all the input arguments together and store
the result in the named output variable. 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 TOLOWER
""""""" """""""

View File

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

View File

@@ -68,6 +68,9 @@ bool cmStringCommand::InitialPass(std::vector<std::string> const& args,
if (subCommand == "CONCAT") { if (subCommand == "CONCAT") {
return this->HandleConcatCommand(args); return this->HandleConcatCommand(args);
} }
if (subCommand == "JOIN") {
return this->HandleJoinCommand(args);
}
if (subCommand == "SUBSTRING") { if (subCommand == "SUBSTRING") {
return this->HandleSubstringCommand(args); return this->HandleSubstringCommand(args);
} }
@@ -677,8 +680,26 @@ bool cmStringCommand::HandleConcatCommand(std::vector<std::string> const& args)
return false; return false;
} }
std::string const& variableName = args[1]; return this->joinImpl(args, std::string(), 1);
std::string value = cmJoin(cmMakeRange(args).advance(2), std::string()); }
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()); this->Makefile->AddDefinition(variableName, value.c_str());
return true; return true;

View File

@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep #include "cmConfigure.h" // IWYU pragma: keep
#include <cstddef>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -48,6 +49,7 @@ protected:
bool HandleAppendCommand(std::vector<std::string> const& args); bool HandleAppendCommand(std::vector<std::string> const& args);
bool HandlePrependCommand(std::vector<std::string> const& args); bool HandlePrependCommand(std::vector<std::string> const& args);
bool HandleConcatCommand(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 HandleStripCommand(std::vector<std::string> const& args);
bool HandleRandomCommand(std::vector<std::string> const& args); bool HandleRandomCommand(std::vector<std::string> const& args);
bool HandleFindCommand(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 HandleGenexStripCommand(std::vector<std::string> const& args);
bool HandleUuidCommand(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 class RegexReplacement
{ {
public: public:

View File

@@ -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()

View File

@@ -0,0 +1 @@
1

View File

@@ -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\)

View File

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

View File

@@ -0,0 +1 @@
1

View File

@@ -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\)

View File

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

View File

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