summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst2
-rw-r--r--Help/release/dev/genex_filter.rst6
-rw-r--r--Source/cmGeneratorExpressionNode.cxx47
-rw-r--r--Tests/RunCMake/GeneratorExpression/FILTER-Exclude-check.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/FILTER-Exclude.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/FILTER-Include-check.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/FILTER-Include.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator.cmake3
-rw-r--r--Tests/RunCMake/GeneratorExpression/FILTER-empty-check.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/FILTER-empty.cmake3
-rw-r--r--Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake4
13 files changed, 100 insertions, 0 deletions
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 8f4c4fc..e3a96bd 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -293,6 +293,8 @@ String Transformations
Joins the list with the content of ``string``.
``$<REMOVE_DUPLICATES:list>``
Removes duplicated items in the given ``list``.
+``$<FILTER:list,INCLUDE|EXCLUDE,regex>``
+ Includes or removes items from ``list`` that match the regular expression ``regex``.
``$<LOWER_CASE:string>``
Content of ``string`` converted to lower case.
``$<UPPER_CASE:string>``
diff --git a/Help/release/dev/genex_filter.rst b/Help/release/dev/genex_filter.rst
new file mode 100644
index 0000000..ad23134
--- /dev/null
+++ b/Help/release/dev/genex_filter.rst
@@ -0,0 +1,6 @@
+genex_filter
+------------
+
+* A new ``$<FILTER:list,INCLUDE|EXCLUDE,regex>``
+ :manual:`generator expression <cmake-generator-expressions(7)>`
+ has been added.
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index cef36fc..d8e1c42 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -28,6 +28,7 @@
#include <algorithm>
#include <assert.h>
#include <errno.h>
+#include <iterator>
#include <map>
#include <memory> // IWYU pragma: keep
#include <set>
@@ -327,6 +328,51 @@ static const struct InListNode : public cmGeneratorExpressionNode
}
} inListNode;
+static const struct FilterNode : public cmGeneratorExpressionNode
+{
+ FilterNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return 3; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+ {
+ if (parameters.size() != 3) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<FILTER:...> expression requires three parameters");
+ return {};
+ }
+
+ if (parameters[1] != "INCLUDE" && parameters[1] != "EXCLUDE") {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<FILTER:...> second parameter must be either INCLUDE or EXCLUDE");
+ return {};
+ }
+
+ const bool exclude = parameters[1] == "EXCLUDE";
+
+ cmsys::RegularExpression re;
+ if (!re.compile(parameters[2])) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<FILTER:...> failed to compile regex");
+ return {};
+ }
+
+ std::vector<std::string> values, result;
+ cmSystemTools::ExpandListArgument(parameters.front(), values, true);
+
+ std::copy_if(values.cbegin(), values.cend(), std::back_inserter(result),
+ [&re, exclude](std::string const& input) {
+ return exclude ^ re.find(input);
+ });
+ return cmJoin(cmMakeRange(result.cbegin(), result.cend()), ";");
+ }
+} filterNode;
+
static const struct RemoveDuplicatesNode : public cmGeneratorExpressionNode
{
RemoveDuplicatesNode() {} // NOLINT(modernize-use-equals-default)
@@ -2331,6 +2377,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "STREQUAL", &strEqualNode },
{ "EQUAL", &equalNode },
{ "IN_LIST", &inListNode },
+ { "FILTER", &filterNode },
{ "REMOVE_DUPLICATES", &removeDuplicatesNode },
{ "LOWER_CASE", &lowerCaseNode },
{ "UPPER_CASE", &upperCaseNode },
diff --git a/Tests/RunCMake/GeneratorExpression/FILTER-Exclude-check.cmake b/Tests/RunCMake/GeneratorExpression/FILTER-Exclude-check.cmake
new file mode 100644
index 0000000..605ae4d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/FILTER-Exclude-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/FILTER-generated.txt" content)
+
+set(expected "DO_NOT_FILTER_THIS;thisisanitem")
+if(NOT content STREQUAL expected)
+ set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/FILTER-Exclude.cmake b/Tests/RunCMake/GeneratorExpression/FILTER-Exclude.cmake
new file mode 100644
index 0000000..b879be2
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/FILTER-Exclude.cmake
@@ -0,0 +1,4 @@
+cmake_policy(VERSION 3.11)
+
+set(mylist FILTER_THIS_BIT DO_NOT_FILTER_THIS thisisanitem FILTER_THIS_THING)
+file(GENERATE OUTPUT "FILTER-generated.txt" CONTENT "$<FILTER:${mylist},EXCLUDE,^FILTER_THIS_.+>")
diff --git a/Tests/RunCMake/GeneratorExpression/FILTER-Include-check.cmake b/Tests/RunCMake/GeneratorExpression/FILTER-Include-check.cmake
new file mode 100644
index 0000000..9d48d98
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/FILTER-Include-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/FILTER-generated.txt" content)
+
+set(expected "FILTER_THIS_BIT;FILTER_THIS_THING")
+if(NOT content STREQUAL expected)
+ set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/FILTER-Include.cmake b/Tests/RunCMake/GeneratorExpression/FILTER-Include.cmake
new file mode 100644
index 0000000..5e0260a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/FILTER-Include.cmake
@@ -0,0 +1,4 @@
+cmake_policy(VERSION 3.11)
+
+set(mylist FILTER_THIS_BIT DO_NOT_FILTER_THIS thisisanitem FILTER_THIS_THING)
+file(GENERATE OUTPUT "FILTER-generated.txt" CONTENT "$<FILTER:${mylist},INCLUDE,^FILTER_THIS_.+>")
diff --git a/Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator-result.txt b/Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator-stderr.txt b/Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator-stderr.txt
new file mode 100644
index 0000000..dd10925
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at FILTER-InvalidOperator.cmake:3 \(file\):
+ Error evaluating generator expression:
+
+ \$<FILTER:,RM,>
+
+ \$<FILTER:...> second parameter must be either INCLUDE or EXCLUDE
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator.cmake b/Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator.cmake
new file mode 100644
index 0000000..26f3917
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.11)
+
+file(GENERATE OUTPUT "FILTER-generated.txt" CONTENT "$<FILTER:,RM,>")
diff --git a/Tests/RunCMake/GeneratorExpression/FILTER-empty-check.cmake b/Tests/RunCMake/GeneratorExpression/FILTER-empty-check.cmake
new file mode 100644
index 0000000..2844484
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/FILTER-empty-check.cmake
@@ -0,0 +1,6 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/FILTER-generated.txt" content)
+
+set(expected "")
+if(NOT content STREQUAL expected)
+ set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/FILTER-empty.cmake b/Tests/RunCMake/GeneratorExpression/FILTER-empty.cmake
new file mode 100644
index 0000000..e0fc671
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/FILTER-empty.cmake
@@ -0,0 +1,3 @@
+cmake_policy(VERSION 3.11)
+
+file(GENERATE OUTPUT "FILTER-generated.txt" CONTENT "$<FILTER:,INCLUDE,>")
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 68bffa7..4202064 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -62,6 +62,10 @@ run_cmake(REMOVE_DUPLICATES-1)
run_cmake(REMOVE_DUPLICATES-2)
run_cmake(REMOVE_DUPLICATES-3)
run_cmake(REMOVE_DUPLICATES-4)
+run_cmake(FILTER-empty)
+run_cmake(FILTER-InvalidOperator)
+run_cmake(FILTER-Exclude)
+run_cmake(FILTER-Include)
run_cmake(ImportedTarget-TARGET_BUNDLE_DIR)
run_cmake(ImportedTarget-TARGET_BUNDLE_CONTENT_DIR)