From 698f51abacb572508c5386b406c2c8a30f0be1e8 Mon Sep 17 00:00:00 2001 From: Sebastian Lipponer Date: Wed, 3 Apr 2019 21:26:29 +0200 Subject: Genex: Add $ --- Help/manual/cmake-generator-expressions.7.rst | 2 + Help/release/dev/genex_filter.rst | 6 +++ Source/cmGeneratorExpressionNode.cxx | 47 ++++++++++++++++++++++ .../GeneratorExpression/FILTER-Exclude-check.cmake | 6 +++ .../GeneratorExpression/FILTER-Exclude.cmake | 4 ++ .../GeneratorExpression/FILTER-Include-check.cmake | 6 +++ .../GeneratorExpression/FILTER-Include.cmake | 4 ++ .../FILTER-InvalidOperator-result.txt | 1 + .../FILTER-InvalidOperator-stderr.txt | 8 ++++ .../FILTER-InvalidOperator.cmake | 3 ++ .../GeneratorExpression/FILTER-empty-check.cmake | 6 +++ .../GeneratorExpression/FILTER-empty.cmake | 3 ++ .../GeneratorExpression/RunCMakeTest.cmake | 4 ++ 13 files changed, 100 insertions(+) create mode 100644 Help/release/dev/genex_filter.rst create mode 100644 Tests/RunCMake/GeneratorExpression/FILTER-Exclude-check.cmake create mode 100644 Tests/RunCMake/GeneratorExpression/FILTER-Exclude.cmake create mode 100644 Tests/RunCMake/GeneratorExpression/FILTER-Include-check.cmake create mode 100644 Tests/RunCMake/GeneratorExpression/FILTER-Include.cmake create mode 100644 Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator-result.txt create mode 100644 Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator-stderr.txt create mode 100644 Tests/RunCMake/GeneratorExpression/FILTER-InvalidOperator.cmake create mode 100644 Tests/RunCMake/GeneratorExpression/FILTER-empty-check.cmake create mode 100644 Tests/RunCMake/GeneratorExpression/FILTER-empty.cmake 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``. ``$`` Removes duplicated items in the given ``list``. +``$`` + Includes or removes items from ``list`` that match the regular expression ``regex``. ``$`` Content of ``string`` converted to lower case. ``$`` 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 ``$`` + :manual:`generator expression ` + 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 #include #include +#include #include #include // IWYU pragma: keep #include @@ -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& parameters, + cmGeneratorExpressionContext* context, + const GeneratorExpressionContent* content, + cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override + { + if (parameters.size() != 3) { + reportError(context, content->GetOriginalExpression(), + "$ expression requires three parameters"); + return {}; + } + + if (parameters[1] != "INCLUDE" && parameters[1] != "EXCLUDE") { + reportError( + context, content->GetOriginalExpression(), + "$ 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(), + "$ failed to compile regex"); + return {}; + } + + std::vector 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 "$") 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 "$") 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: + + \$ + + \$ 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 "$") 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 "$") 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) -- cgit v0.12