Genex: Add $<FILTER:list,INCLUDE|EXCLUDE,regex>

This commit is contained in:
Sebastian Lipponer 2019-04-03 21:26:29 +02:00
parent 4f07fdde26
commit 698f51abac
13 changed files with 100 additions and 0 deletions

View File

@ -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>``

View File

@ -0,0 +1,6 @@
genex_filter
------------
* A new ``$<FILTER:list,INCLUDE|EXCLUDE,regex>``
:manual:`generator expression <cmake-generator-expressions(7)>`
has been added.

View File

@ -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 },

View File

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

View File

@ -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_.+>")

View File

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

View File

@ -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_.+>")

View File

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

View File

@ -0,0 +1,3 @@
cmake_policy(VERSION 3.11)
file(GENERATE OUTPUT "FILTER-generated.txt" CONTENT "$<FILTER:,RM,>")

View File

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

View File

@ -0,0 +1,3 @@
cmake_policy(VERSION 3.11)
file(GENERATE OUTPUT "FILTER-generated.txt" CONTENT "$<FILTER:,INCLUDE,>")

View File

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