From c7af6e94d839e5f3f4fee71d17ea3aff333dec2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Germain?= Date: Wed, 8 Apr 2026 14:02:22 -0700 Subject: [PATCH] list(TRANSFORM): Add PREDICATE selector Add a new `PREDICATE` selector to `list(TRANSFORM)` that uses a user-defined function or macro to decide which elements to transform. The predicate callable receives each element value and an output variable name. It must set the output variable to a truthy or falsy value in PARENT_SCOPE; only elements for which the predicate returns true are passed to the transform action. Adds a shared PredicateEvaluator helper class used by both TRANSFORM PREDICATE and (in a subsequent commit) FILTER PREDICATE. Includes parser wiring, error and success tests covering all existing actions (TOUPPER, TOLOWER, REPLACE, STRIP, GENEX_STRIP, APPEND, PREPEND, APPLY) combined with the PREDICATE selector. Issue: #27761 --- Help/command/list.rst | 33 ++++++ Source/cmList.cxx | 83 +++++++++++++++ Source/cmList.h | 4 + Source/cmListCommand.cxx | 19 +++- Tests/RunCMake/list/RunCMakeTest.cmake | 5 + ...TRANSFORM-APPLY-UnknownFunction-result.txt | 1 + ...TRANSFORM-APPLY-UnknownFunction-stderr.txt | 5 + .../TRANSFORM-APPLY-UnknownFunction.cmake | 2 + Tests/RunCMake/list/TRANSFORM-APPLY.cmake | 25 +++++ Tests/RunCMake/list/TRANSFORM-PREDICATE.cmake | 100 ++++++++++++++++++ ...-Selector-PREDICATE-NoArguments-result.txt | 1 + ...-Selector-PREDICATE-NoArguments-stderr.txt | 5 + ...SFORM-Selector-PREDICATE-NoArguments.cmake | 2 + ...ORM-Selector-PREDICATE-NoOutput-result.txt | 1 + ...ORM-Selector-PREDICATE-NoOutput-stderr.txt | 5 + ...RANSFORM-Selector-PREDICATE-NoOutput.cmake | 6 ++ ...ector-PREDICATE-UnknownFunction-result.txt | 1 + ...ector-PREDICATE-UnknownFunction-stderr.txt | 5 + ...M-Selector-PREDICATE-UnknownFunction.cmake | 2 + 19 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction-result.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction-stderr.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction.cmake create mode 100644 Tests/RunCMake/list/TRANSFORM-PREDICATE.cmake create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments-result.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments-stderr.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments.cmake create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput-result.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput-stderr.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput.cmake create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction-result.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction-stderr.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction.cmake diff --git a/Help/command/list.rst b/Help/command/list.rst index 6b7f044a15..43ae893ce2 100644 --- a/Help/command/list.rst +++ b/Help/command/list.rst @@ -316,6 +316,39 @@ Modification list(TRANSFORM REGEX ...) + ``PREDICATE`` + Specify a user-defined callable as a predicate. + Only elements for which the callable returns a true value will be + transformed. + + .. code-block:: cmake + + list(TRANSFORM PREDICATE ...) + + .. versionadded:: 4.4 + + ```` is a user-defined :command:`function` with exactly + two formal parameters: the input value and the name of an output + variable. The callable must set the output variable to a boolean + value. Standard CMake boolean evaluation is used. + If the callable does not set the output variable, it is an error. + + Example: + + .. code-block:: cmake + + function(is_relative path result) + if(NOT IS_ABSOLUTE "${path}") + set(${result} TRUE PARENT_SCOPE) + else() + set(${result} FALSE PARENT_SCOPE) + endif() + endfunction() + + set(search_paths /usr/include src lib /opt/lib) + list(TRANSFORM search_paths PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/" + PREDICATE is_relative) + Ordering ^^^^^^^^ diff --git a/Source/cmList.cxx b/Source/cmList.cxx index 1c76664d4e..c907b971b2 100644 --- a/Source/cmList.cxx +++ b/Source/cmList.cxx @@ -81,6 +81,61 @@ private: cmsys::RegularExpression& Regex; bool const IncludeMatches; }; + +class PredicateEvaluator +{ +public: + PredicateEvaluator(std::string const& functionName, cmMakefile& makefile, + std::string errorPrefix = "sub-command TRANSFORM, " + "selector PREDICATE") + : FunctionName(functionName) + , Makefile(&makefile) + , ErrorPrefix(std::move(errorPrefix)) + { + if (!makefile.GetState()->GetCommand(this->FunctionName)) { + throw cmList::transform_error(cmStrCat(this->ErrorPrefix, + ": unknown function \"", + this->FunctionName, "\".")); + } + } + + bool operator()(std::string const& value) + { + std::string const outputVar = "_list_predicate_out_"; + this->Makefile->RemoveDefinition(outputVar); + + cmListFileContext context = this->Makefile->GetBacktrace().Top(); + std::vector funcArgs; + funcArgs.emplace_back(value, cmListFileArgument::Quoted, context.Line); + funcArgs.emplace_back(outputVar, cmListFileArgument::Quoted, context.Line); + cmListFileFunction func{ this->FunctionName, context.Line, context.Line, + std::move(funcArgs) }; + + cmExecutionStatus status(*this->Makefile); + if (!this->Makefile->ExecuteCommand(func, status) || + status.GetNestedError()) { + throw cmList::transform_error( + cmStrCat(this->ErrorPrefix, ": function \"", this->FunctionName, + "\" failed during execution.")); + } + + cmValue result = this->Makefile->GetDefinition(outputVar); + if (!result) { + throw cmList::transform_error( + cmStrCat(this->ErrorPrefix, ": function \"", this->FunctionName, + "\" did not set the output variable.")); + } + + bool boolResult = cmIsOn(*result); + this->Makefile->RemoveDefinition(outputVar); + return boolResult; + } + +private: + std::string FunctionName; + cmMakefile* Makefile = nullptr; + std::string ErrorPrefix; +}; } cmList& cmList::filter(cm::string_view pattern, FilterMode mode) @@ -270,6 +325,26 @@ public: cmsys::RegularExpression Regex; }; +class TransformSelectorPredicate : public TransformSelector +{ +public: + TransformSelectorPredicate(std::string const& functionName, + cmMakefile& makefile) + : TransformSelector("PREDICATE") + , Evaluator(functionName, makefile) + { + } + + bool Validate(std::size_t) override { return true; } + + bool InSelection(std::string const& value) override + { + return this->Evaluator(value); + } + +private: + PredicateEvaluator Evaluator; +}; class TransformSelectorIndexes : public TransformSelector { public: @@ -827,6 +902,14 @@ std::unique_ptr cmList::TransformSelector::NewREGEX( return std::unique_ptr(selector.release()); } +std::unique_ptr +cmList::TransformSelector::NewPREDICATE(std::string const& functionName, + cmMakefile& makefile) +{ + return std::unique_ptr( + new TransformSelectorPredicate(functionName, makefile)); +} + cmList& cmList::transform(TransformAction action, std::unique_ptr selector) { diff --git a/Source/cmList.h b/Source/cmList.h index febc2c5ffc..d861d2e24a 100644 --- a/Source/cmList.h +++ b/Source/cmList.h @@ -886,6 +886,7 @@ public: struct AT; struct FOR; struct REGEX; + struct PREDICATE; virtual ~TransformSelector() = default; @@ -911,6 +912,9 @@ public: template static std::unique_ptr New(std::string&&); + static std::unique_ptr NewPREDICATE( + std::string const& functionName, cmMakefile& makefile); + cmMakefile* Makefile = nullptr; private: diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index 06eba11ed8..5a68019bf2 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -520,6 +520,7 @@ bool HandleTransformCommand(std::vector const& args, std::string const REGEX{ "REGEX" }; std::string const AT{ "AT" }; std::string const FOR{ "FOR" }; + std::string const PREDICATE{ "PREDICATE" }; std::string const OUTPUT_VARIABLE{ "OUTPUT_VARIABLE" }; std::unique_ptr selector; std::string outputName = listName; @@ -527,7 +528,8 @@ bool HandleTransformCommand(std::vector const& args, try { // handle optional arguments while (args.size() > index) { - if ((args[index] == REGEX || args[index] == AT || args[index] == FOR) && + if ((args[index] == REGEX || args[index] == AT || args[index] == FOR || + args[index] == PREDICATE) && selector) { status.SetError( cmStrCat("sub-command TRANSFORM, selector already specified (", @@ -653,6 +655,21 @@ bool HandleTransformCommand(std::vector const& args, continue; } + // PREDICATE selector + if (args[index] == PREDICATE) { + if (args.size() == ++index) { + status.SetError("sub-command TRANSFORM, selector PREDICATE expects " + "'function name' argument."); + return false; + } + + selector = cmList::TransformSelector::NewPREDICATE( + args[index], status.GetMakefile()); + + index += 1; + continue; + } + // output variable if (args[index] == OUTPUT_VARIABLE) { if (args.size() == ++index) { diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake index dd4264cb6a..94632cc7b4 100644 --- a/Tests/RunCMake/list/RunCMakeTest.cmake +++ b/Tests/RunCMake/list/RunCMakeTest.cmake @@ -65,6 +65,7 @@ run_cmake(TRANSFORM-REPLACE-InvalidRegex) run_cmake(TRANSFORM-REPLACE-InvalidReplace1) run_cmake(TRANSFORM-REPLACE-InvalidReplace2) run_cmake(TRANSFORM-APPLY-NoFunction) +run_cmake(TRANSFORM-APPLY-UnknownFunction) run_cmake(TRANSFORM-APPLY-NoOutput) # 'selector' oriented tests run_cmake(TRANSFORM-Selector-REGEX-NoArguments) @@ -81,6 +82,9 @@ run_cmake(TRANSFORM-Selector-FOR-InvalidIndex) run_cmake(TRANSFORM-Selector-FOR-ZeroStepArgument) run_cmake(TRANSFORM-Selector-FOR-NegativeStepArgument) run_cmake(TRANSFORM-Selector-FOR-BackwardsRange) +run_cmake(TRANSFORM-Selector-PREDICATE-NoArguments) +run_cmake(TRANSFORM-Selector-PREDICATE-UnknownFunction) +run_cmake(TRANSFORM-Selector-PREDICATE-NoOutput) # 'output' oriented tests run_cmake(TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments) run_cmake(TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments) @@ -93,6 +97,7 @@ run_cmake(TRANSFORM-APPEND) run_cmake(TRANSFORM-PREPEND) run_cmake(TRANSFORM-REPLACE) run_cmake(TRANSFORM-APPLY) +run_cmake(TRANSFORM-PREDICATE) run_cmake(CMP0186) # argument tests diff --git a/Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction-result.txt b/Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction-stderr.txt b/Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction-stderr.txt new file mode 100644 index 0000000000..cb599548ec --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at TRANSFORM-APPLY-UnknownFunction\.cmake:2 \(list\): + list sub-command TRANSFORM, action APPLY: unknown function + "no_such_function"\. +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction.cmake b/Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction.cmake new file mode 100644 index 0000000000..52754390aa --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-APPLY-UnknownFunction.cmake @@ -0,0 +1,2 @@ +set(mylist alpha bravo charlie) +list(TRANSFORM mylist APPLY no_such_function) diff --git a/Tests/RunCMake/list/TRANSFORM-APPLY.cmake b/Tests/RunCMake/list/TRANSFORM-APPLY.cmake index 14fe360220..68e1528636 100644 --- a/Tests/RunCMake/list/TRANSFORM-APPLY.cmake +++ b/Tests/RunCMake/list/TRANSFORM-APPLY.cmake @@ -104,3 +104,28 @@ list(TRANSFORM mylist APPLY make_empty) if(NOT mylist STREQUAL ";;") message(FATAL_ERROR "TRANSFORM(APPLY make_empty) is \"${mylist}\", expected is \";;\"") endif() + +# Recursive APPLY: an APPLY function that itself calls list(TRANSFORM APPLY). +# The inner function returns the output variable name it was given. +function(return_out_var_name in out) + set(${out} "${out}" PARENT_SCOPE) +endfunction() + +# The outer function triggers a nested APPLY and verifies that the inner +# output variable name differs from its own. +function(inner_name_is_different in out) + set(_inner x) + list(TRANSFORM _inner APPLY return_out_var_name OUTPUT_VARIABLE _inner_out) + # _inner_out now holds the inner output variable name + if("${out}" STREQUAL "${_inner_out}") + set(${out} "FALSE" PARENT_SCOPE) + else() + set(${out} "TRUE" PARENT_SCOPE) + endif() +endfunction() + +set(mylist a b c) +list(TRANSFORM mylist APPLY inner_name_is_different OUTPUT_VARIABLE output) +if(NOT output STREQUAL "TRUE;TRUE;TRUE") + message(FATAL_ERROR "TRANSFORM(APPLY nested smoke) is \"${output}\", expected \"TRUE;TRUE;TRUE\"") +endif() diff --git a/Tests/RunCMake/list/TRANSFORM-PREDICATE.cmake b/Tests/RunCMake/list/TRANSFORM-PREDICATE.cmake new file mode 100644 index 0000000000..103f0219df --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-PREDICATE.cmake @@ -0,0 +1,100 @@ +# Predicate: returns TRUE for items starting with "b" +function(starts_with_b input result) + if(input MATCHES "^b") + set(${result} TRUE PARENT_SCOPE) + else() + set(${result} FALSE PARENT_SCOPE) + endif() +endfunction() + +# Predicate as macro +macro(is_short input result) + string(LENGTH "${input}" _len) + if(_len LESS 4) + set(${result} TRUE) + else() + set(${result} FALSE) + endif() +endmacro() + +set(mylist alpha bravo charlie bravo_two delta) + +# Basic PREDICATE with TOUPPER - only items starting with "b" are uppercased +list(TRANSFORM mylist TOUPPER PREDICATE starts_with_b OUTPUT_VARIABLE output) +if(NOT output STREQUAL "alpha;BRAVO;charlie;BRAVO_TWO;delta") + message(FATAL_ERROR "TRANSFORM(TOUPPER PREDICATE) is \"${output}\", expected \"alpha;BRAVO;charlie;BRAVO_TWO;delta\"") +endif() + +# Verify original list unchanged (OUTPUT_VARIABLE) +if(NOT mylist STREQUAL "alpha;bravo;charlie;bravo_two;delta") + message(FATAL_ERROR "Original list modified: \"${mylist}\"") +endif() + +# PREDICATE in-place +list(TRANSFORM mylist TOUPPER PREDICATE starts_with_b) +if(NOT mylist STREQUAL "alpha;BRAVO;charlie;BRAVO_TWO;delta") + message(FATAL_ERROR "TRANSFORM(TOUPPER PREDICATE in-place) is \"${mylist}\", expected \"alpha;BRAVO;charlie;BRAVO_TWO;delta\"") +endif() + +# PREDICATE with macro +set(mylist ab cde fg hijklm no) +list(TRANSFORM mylist TOUPPER PREDICATE is_short OUTPUT_VARIABLE output) +if(NOT output STREQUAL "AB;CDE;FG;hijklm;NO") + message(FATAL_ERROR "TRANSFORM(TOUPPER PREDICATE macro) is \"${output}\", expected \"AB;CDE;FG;hijklm;NO\"") +endif() + +# PREDICATE combined with APPLY +function(add_prefix in out) + set(${out} "prefix_${in}" PARENT_SCOPE) +endfunction() + +set(mylist alpha bravo charlie delta) +list(TRANSFORM mylist APPLY add_prefix PREDICATE starts_with_b OUTPUT_VARIABLE output) +if(NOT output STREQUAL "alpha;prefix_bravo;charlie;delta") + message(FATAL_ERROR "TRANSFORM(APPLY PREDICATE) is \"${output}\", expected \"alpha;prefix_bravo;charlie;delta\"") +endif() + +# PREDICATE on empty list +set(empty_list "") +list(TRANSFORM empty_list TOUPPER PREDICATE starts_with_b OUTPUT_VARIABLE output) +if(NOT output STREQUAL "") + message(FATAL_ERROR "TRANSFORM(PREDICATE empty) is \"${output}\", expected \"\"") +endif() + +# PREDICATE where nothing matches (all elements unchanged) +set(mylist alpha charlie delta) +list(TRANSFORM mylist TOUPPER PREDICATE starts_with_b OUTPUT_VARIABLE output) +if(NOT output STREQUAL "alpha;charlie;delta") + message(FATAL_ERROR "TRANSFORM(PREDICATE no-match) is \"${output}\", expected \"alpha;charlie;delta\"") +endif() + +# PREDICATE where everything matches +set(mylist bravo bronze bull) +list(TRANSFORM mylist TOUPPER PREDICATE starts_with_b OUTPUT_VARIABLE output) +if(NOT output STREQUAL "BRAVO;BRONZE;BULL") + message(FATAL_ERROR "TRANSFORM(PREDICATE all-match) is \"${output}\", expected \"BRAVO;BRONZE;BULL\"") +endif() + +# Recursive PREDICATE: a PREDICATE function that itself calls list(TRANSFORM APPLY). +# The inner function returns the output variable name it was given. +function(return_pred_var_name in out) + set(${out} "${out}" PARENT_SCOPE) +endfunction() + +# The outer predicate triggers a nested APPLY and verifies that the inner +# output variable name differs from its own result variable. +function(inner_pred_name_is_different input result) + set(_inner x) + list(TRANSFORM _inner APPLY return_pred_var_name OUTPUT_VARIABLE _inner_names) + if("${result}" STREQUAL "${_inner_names}") + set(${result} FALSE PARENT_SCOPE) + else() + set(${result} TRUE PARENT_SCOPE) + endif() +endfunction() + +set(mylist x y z) +list(TRANSFORM mylist TOUPPER PREDICATE inner_pred_name_is_different OUTPUT_VARIABLE output) +if(NOT output STREQUAL "X;Y;Z") + message(FATAL_ERROR "TRANSFORM(PREDICATE nested smoke) is \"${output}\", expected \"X;Y;Z\"") +endif() diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments-stderr.txt new file mode 100644 index 0000000000..22c413358f --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at TRANSFORM-Selector-PREDICATE-NoArguments\.cmake:2 \(list\): + list sub-command TRANSFORM, selector PREDICATE expects 'function name' + argument\. +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments.cmake new file mode 100644 index 0000000000..f263d8b3e8 --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoArguments.cmake @@ -0,0 +1,2 @@ +set(mylist alpha bravo charlie) +list(TRANSFORM mylist TOUPPER PREDICATE) diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput-stderr.txt new file mode 100644 index 0000000000..87310b2efd --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at TRANSFORM-Selector-PREDICATE-NoOutput\.cmake:6 \(list\): + list sub-command TRANSFORM, selector PREDICATE: function "bad_predicate" + did not set the output variable\. +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput.cmake new file mode 100644 index 0000000000..73b18c20f4 --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-NoOutput.cmake @@ -0,0 +1,6 @@ +function(bad_predicate in out) + # Deliberately does NOT set ${out} +endfunction() + +set(mylist alpha bravo charlie) +list(TRANSFORM mylist TOUPPER PREDICATE bad_predicate) diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction-stderr.txt new file mode 100644 index 0000000000..21bea516c0 --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at TRANSFORM-Selector-PREDICATE-UnknownFunction\.cmake:2 \(list\): + list sub-command TRANSFORM, selector PREDICATE: unknown function + "no_such_function"\. +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction.cmake new file mode 100644 index 0000000000..d4972887bc --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-UnknownFunction.cmake @@ -0,0 +1,2 @@ +set(mylist alpha bravo charlie) +list(TRANSFORM mylist TOUPPER PREDICATE no_such_function)