From 96c9a9c67dfbbe0c375e9015c1167a2ac1e8923b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Germain?= Date: Thu, 30 Apr 2026 21:44:32 -0700 Subject: [PATCH] list: Reject macros as APPLY/PREDICATE/COMPARATOR arguments Fixes: #27781 --- Help/command/list.rst | 30 +++++++++---------- Help/release/dev/list-PREDICATE.rst | 4 +-- Source/cmList.cxx | 12 +++++++- .../list/FILTER-PREDICATE-Exclude.cmake | 16 ---------- .../list/FILTER-PREDICATE-Include.cmake | 17 ----------- .../list/FILTER-PREDICATE-Macro-result.txt | 1 + .../list/FILTER-PREDICATE-Macro-stderr.txt | 5 ++++ .../list/FILTER-PREDICATE-Macro.cmake | 11 +++++++ Tests/RunCMake/list/RunCMakeTest.cmake | 4 +++ .../list/SORT-COMPARATOR-Macro-result.txt | 1 + .../list/SORT-COMPARATOR-Macro-stderr.txt | 5 ++++ .../RunCMake/list/SORT-COMPARATOR-Macro.cmake | 10 +++++++ Tests/RunCMake/list/SORT-COMPARATOR.cmake | 16 ---------- .../list/TRANSFORM-APPLY-Macro-result.txt | 1 + .../list/TRANSFORM-APPLY-Macro-stderr.txt | 5 ++++ .../RunCMake/list/TRANSFORM-APPLY-Macro.cmake | 6 ++++ Tests/RunCMake/list/TRANSFORM-APPLY.cmake | 18 ----------- Tests/RunCMake/list/TRANSFORM-PREDICATE.cmake | 17 ----------- ...NSFORM-Selector-PREDICATE-Macro-result.txt | 1 + ...NSFORM-Selector-PREDICATE-Macro-stderr.txt | 5 ++++ .../TRANSFORM-Selector-PREDICATE-Macro.cmake | 11 +++++++ 21 files changed, 94 insertions(+), 102 deletions(-) create mode 100644 Tests/RunCMake/list/FILTER-PREDICATE-Macro-result.txt create mode 100644 Tests/RunCMake/list/FILTER-PREDICATE-Macro-stderr.txt create mode 100644 Tests/RunCMake/list/FILTER-PREDICATE-Macro.cmake create mode 100644 Tests/RunCMake/list/SORT-COMPARATOR-Macro-result.txt create mode 100644 Tests/RunCMake/list/SORT-COMPARATOR-Macro-stderr.txt create mode 100644 Tests/RunCMake/list/SORT-COMPARATOR-Macro.cmake create mode 100644 Tests/RunCMake/list/TRANSFORM-APPLY-Macro-result.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-APPLY-Macro-stderr.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-APPLY-Macro.cmake create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro-result.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro-stderr.txt create mode 100644 Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro.cmake diff --git a/Help/command/list.rst b/Help/command/list.rst index 1280c40138..56e37b6e89 100644 --- a/Help/command/list.rst +++ b/Help/command/list.rst @@ -139,7 +139,7 @@ Modification :ref:`string(REGEX) `. ``PREDICATE`` - Specify a user-defined callable as a predicate. + Specify a user-defined :command:`function` as a predicate. .. code-block:: cmake @@ -148,11 +148,11 @@ Modification .. versionadded:: 4.4 ```` is a user-defined :command:`function` that acts as a - unary predicate. The callable must accept exactly two parameters: the - input value and the name of an output variable. The callable must set the + unary predicate. The function must accept exactly two parameters: the + input value and the name of an output variable. The function must set the output variable to a boolean value in the calling scope. The output variable is interpreted using standard CMake boolean evaluation. - If the callable does not set the output variable, it is an error. + If the function does not set the output variable, it is an error. Example: @@ -290,9 +290,9 @@ Modification See policy :policy:`CMP0186`. ``APPLY`` - Invoke a user-defined callable for each element of the list. - The callable must accept exactly two parameters: the input value and the - name of an output variable. The callable must set the output variable + Invoke a user-defined :command:`function` for each element of the list. + The function must accept exactly two parameters: the input value and the + name of an output variable. The function must set the output variable in the calling scope. .. signature:: @@ -356,8 +356,8 @@ 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 + Specify a user-defined :command:`function` as a predicate. + Only elements for which the function returns a true value will be transformed. .. code-block:: cmake @@ -368,9 +368,9 @@ Modification ```` 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 + variable. The function 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. + If the function does not set the output variable, it is an error. Example: @@ -450,21 +450,21 @@ Ordering Sorts the list in descending order. Instead of the built-in ``COMPARE`` methods, a user-defined comparison - function may be used with the ``COMPARATOR`` keyword. + :command:`function` may be used with the ``COMPARATOR`` keyword. .. versionadded:: 4.4 ``COMPARATOR`` is mutually exclusive with ``COMPARE``. The ``CASE`` and ``ORDER`` options may still be used alongside ``COMPARATOR``: the ``CASE`` filter is applied to both values before they are passed to - the callable, and ``ORDER DESCENDING`` reverses the comparison by + the function, and ``ORDER DESCENDING`` reverses the comparison by swapping the two arguments. - The callable must accept exactly three parameters: two input values and + The function must accept exactly three parameters: two input values and the name of an output variable. It must set the output variable to a boolean value (``TRUE`` if the first value should come before the second, ``FALSE`` otherwise) in the calling scope. - If the callable does not set the output variable, it is an error. + If the function does not set the output variable, it is an error. The comparator must define a `strict weak ordering `_. diff --git a/Help/release/dev/list-PREDICATE.rst b/Help/release/dev/list-PREDICATE.rst index 324bd07339..f54652db88 100644 --- a/Help/release/dev/list-PREDICATE.rst +++ b/Help/release/dev/list-PREDICATE.rst @@ -2,9 +2,9 @@ list-PREDICATE -------------- * The :command:`list(TRANSFORM)` command gained a new ``PREDICATE`` selector - that invokes a user-defined callable to decide which elements are + that invokes a user-defined :command:`function` to decide which elements are transformed. * The :command:`list(FILTER)` command gained a new ``PREDICATE`` mode - that invokes a user-defined callable to decide which elements are + that invokes a user-defined :command:`function` to decide which elements are included or excluded, complementing the existing ``REGEX`` mode. diff --git a/Source/cmList.cxx b/Source/cmList.cxx index 5a8434bb24..754a3d3f8b 100644 --- a/Source/cmList.cxx +++ b/Source/cmList.cxx @@ -14,6 +14,7 @@ #include #include +#include #include "cmsys/RegularExpression.hxx" @@ -24,6 +25,7 @@ #include "cmMakefile.h" #include "cmRange.h" #include "cmState.h" +#include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmStringReplaceHelper.h" #include "cmSystemTools.h" @@ -96,10 +98,18 @@ void RequireFunction(cmMakefile const& makefile, std::string const& functionName, std::string const& errorPrefix) { - if (!makefile.GetState()->GetCommand(functionName)) { + cm::optional type = + makefile.GetState()->GetCommandType(functionName); + if (!type) { throw cmList::transform_error( cmStrCat(errorPrefix, ": unknown function \"", functionName, "\".")); } + if (*type == cmStateEnums::CommandType::Macro) { + throw cmList::transform_error( + cmStrCat(errorPrefix, ": macro \"", functionName, + "\" may not be used here;" + " define it as a function() instead.")); + } } class PredicateEvaluator diff --git a/Tests/RunCMake/list/FILTER-PREDICATE-Exclude.cmake b/Tests/RunCMake/list/FILTER-PREDICATE-Exclude.cmake index 7b1f3492ee..16e0624596 100644 --- a/Tests/RunCMake/list/FILTER-PREDICATE-Exclude.cmake +++ b/Tests/RunCMake/list/FILTER-PREDICATE-Exclude.cmake @@ -12,22 +12,6 @@ message("mylist was: ${mylist}") list(FILTER mylist EXCLUDE PREDICATE starts_with_filter) message("mylist is: ${mylist}") -# EXCLUDE with macro predicate -macro(is_short input result) - string(LENGTH "${input}" _len) - if(_len LESS 6) - set(${result} TRUE) - else() - set(${result} FALSE) - endif() -endmacro() - -set(mylist ab cdefgh ij klmnop qr) -list(FILTER mylist EXCLUDE PREDICATE is_short) -if(NOT mylist STREQUAL "cdefgh;klmnop") - message(FATAL_ERROR "FILTER(EXCLUDE PREDICATE macro) is \"${mylist}\", expected \"cdefgh;klmnop\"") -endif() - # EXCLUDE on empty list set(empty_list "") list(FILTER empty_list EXCLUDE PREDICATE starts_with_filter) diff --git a/Tests/RunCMake/list/FILTER-PREDICATE-Include.cmake b/Tests/RunCMake/list/FILTER-PREDICATE-Include.cmake index 412ff25cf0..4d8aa321e0 100644 --- a/Tests/RunCMake/list/FILTER-PREDICATE-Include.cmake +++ b/Tests/RunCMake/list/FILTER-PREDICATE-Include.cmake @@ -7,28 +7,11 @@ function(starts_with_filter input result) endif() endfunction() -# Predicate as macro -macro(is_short input result) - string(LENGTH "${input}" _len) - if(_len LESS 6) - set(${result} TRUE) - else() - set(${result} FALSE) - endif() -endmacro() - set(mylist FILTER_THIS_BIT DO_NOT_FILTER_THIS thisisanitem FILTER_THIS_THING) message("mylist was: ${mylist}") list(FILTER mylist INCLUDE PREDICATE starts_with_filter) message("mylist is: ${mylist}") -# INCLUDE with macro predicate -set(mylist ab cdefgh ij klmnop qr) -list(FILTER mylist INCLUDE PREDICATE is_short) -if(NOT mylist STREQUAL "ab;ij;qr") - message(FATAL_ERROR "FILTER(INCLUDE PREDICATE macro) is \"${mylist}\", expected \"ab;ij;qr\"") -endif() - # INCLUDE on empty list set(empty_list "") list(FILTER empty_list INCLUDE PREDICATE starts_with_filter) diff --git a/Tests/RunCMake/list/FILTER-PREDICATE-Macro-result.txt b/Tests/RunCMake/list/FILTER-PREDICATE-Macro-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/list/FILTER-PREDICATE-Macro-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/FILTER-PREDICATE-Macro-stderr.txt b/Tests/RunCMake/list/FILTER-PREDICATE-Macro-stderr.txt new file mode 100644 index 0000000000..545e41fff2 --- /dev/null +++ b/Tests/RunCMake/list/FILTER-PREDICATE-Macro-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at FILTER-PREDICATE-Macro\.cmake:11 \(list\): + list sub-command FILTER, mode PREDICATE: macro "is_short" may not be used + here; define it as a function\(\) instead\. +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/FILTER-PREDICATE-Macro.cmake b/Tests/RunCMake/list/FILTER-PREDICATE-Macro.cmake new file mode 100644 index 0000000000..2678af5fd1 --- /dev/null +++ b/Tests/RunCMake/list/FILTER-PREDICATE-Macro.cmake @@ -0,0 +1,11 @@ +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) +list(FILTER mylist INCLUDE PREDICATE is_short) diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake index 9705b55ab1..91ad2cbf77 100644 --- a/Tests/RunCMake/list/RunCMakeTest.cmake +++ b/Tests/RunCMake/list/RunCMakeTest.cmake @@ -38,6 +38,7 @@ run_cmake(FILTER-REGEX-InvalidOperator) run_cmake(FILTER-REGEX-Valid0) run_cmake(FILTER-REGEX-Valid1) run_cmake(FILTER-PREDICATE-UnknownFunction) +run_cmake(FILTER-PREDICATE-Macro) run_cmake(FILTER-PREDICATE-NoOutput) run_cmake(FILTER-PREDICATE-TooManyArguments) run_cmake(FILTER-PREDICATE-Include) @@ -71,6 +72,7 @@ run_cmake(TRANSFORM-REPLACE-InvalidReplace1) run_cmake(TRANSFORM-REPLACE-InvalidReplace2) run_cmake(TRANSFORM-APPLY-NoFunction) run_cmake(TRANSFORM-APPLY-UnknownFunction) +run_cmake(TRANSFORM-APPLY-Macro) run_cmake(TRANSFORM-APPLY-NoOutput) # 'selector' oriented tests run_cmake(TRANSFORM-Selector-REGEX-NoArguments) @@ -89,6 +91,7 @@ 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-Macro) run_cmake(TRANSFORM-Selector-PREDICATE-NoOutput) # 'output' oriented tests run_cmake(TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments) @@ -115,6 +118,7 @@ run_cmake(SORT-DuplicateCompareOption) run_cmake(SORT-DuplicateCaseOption) run_cmake(SORT-NoCaseOption) run_cmake(SORT-COMPARATOR-UnknownFunction) +run_cmake(SORT-COMPARATOR-Macro) run_cmake(SORT-COMPARATOR-NoOutput) run_cmake(SORT-COMPARATOR-CompareConflict) run_cmake(SORT-COMPARATOR-CompareConflictReverse) diff --git a/Tests/RunCMake/list/SORT-COMPARATOR-Macro-result.txt b/Tests/RunCMake/list/SORT-COMPARATOR-Macro-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/list/SORT-COMPARATOR-Macro-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/SORT-COMPARATOR-Macro-stderr.txt b/Tests/RunCMake/list/SORT-COMPARATOR-Macro-stderr.txt new file mode 100644 index 0000000000..8abed12e34 --- /dev/null +++ b/Tests/RunCMake/list/SORT-COMPARATOR-Macro-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at SORT-COMPARATOR-Macro\.cmake:10 \(list\): + list sub-command SORT, COMPARATOR: macro "string_less_macro" may not be + used here; define it as a function\(\) instead\. +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/SORT-COMPARATOR-Macro.cmake b/Tests/RunCMake/list/SORT-COMPARATOR-Macro.cmake new file mode 100644 index 0000000000..3b9890e9e0 --- /dev/null +++ b/Tests/RunCMake/list/SORT-COMPARATOR-Macro.cmake @@ -0,0 +1,10 @@ +macro(string_less_macro a b result) + if(${a} STRLESS ${b}) + set(${result} TRUE) + else() + set(${result} FALSE) + endif() +endmacro() + +set(mylist c a b) +list(SORT mylist COMPARATOR string_less_macro) diff --git a/Tests/RunCMake/list/SORT-COMPARATOR.cmake b/Tests/RunCMake/list/SORT-COMPARATOR.cmake index 03038460bd..3a561cc256 100644 --- a/Tests/RunCMake/list/SORT-COMPARATOR.cmake +++ b/Tests/RunCMake/list/SORT-COMPARATOR.cmake @@ -7,15 +7,6 @@ function(string_less a b result) endif() endfunction() -# Comparator as macro -macro(string_less_macro a b result) - if(${a} STRLESS ${b}) - set(${result} TRUE) - else() - set(${result} FALSE) - endif() -endmacro() - # Comparator: string length comparison function(shorter_first a b result) string(LENGTH "${a}" len_a) @@ -34,13 +25,6 @@ if(NOT mylist STREQUAL "a;b;c") message(FATAL_ERROR "SORT(COMPARATOR function) is \"${mylist}\", expected \"a;b;c\"") endif() -## COMPARATOR with macro -set(mylist c a b) -list(SORT mylist COMPARATOR string_less_macro) -if(NOT mylist STREQUAL "a;b;c") - message(FATAL_ERROR "SORT(COMPARATOR macro) is \"${mylist}\", expected \"a;b;c\"") -endif() - ## COMPARATOR with ORDER DESCENDING set(mylist c a b) list(SORT mylist COMPARATOR string_less ORDER DESCENDING) diff --git a/Tests/RunCMake/list/TRANSFORM-APPLY-Macro-result.txt b/Tests/RunCMake/list/TRANSFORM-APPLY-Macro-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-APPLY-Macro-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/TRANSFORM-APPLY-Macro-stderr.txt b/Tests/RunCMake/list/TRANSFORM-APPLY-Macro-stderr.txt new file mode 100644 index 0000000000..cff7b0e842 --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-APPLY-Macro-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at TRANSFORM-APPLY-Macro\.cmake:6 \(list\): + list sub-command TRANSFORM, action APPLY: macro "wrap_angles" may not be + used here; define it as a function\(\) instead\. +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/TRANSFORM-APPLY-Macro.cmake b/Tests/RunCMake/list/TRANSFORM-APPLY-Macro.cmake new file mode 100644 index 0000000000..990b652ded --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-APPLY-Macro.cmake @@ -0,0 +1,6 @@ +macro(wrap_angles in out) + set(${out} "<${in}>") +endmacro() + +set(mylist alpha bravo charlie) +list(TRANSFORM mylist APPLY wrap_angles) diff --git a/Tests/RunCMake/list/TRANSFORM-APPLY.cmake b/Tests/RunCMake/list/TRANSFORM-APPLY.cmake index 68e1528636..72ae5607a6 100644 --- a/Tests/RunCMake/list/TRANSFORM-APPLY.cmake +++ b/Tests/RunCMake/list/TRANSFORM-APPLY.cmake @@ -8,11 +8,6 @@ function(add_prefix in out) set(${out} "prefix_${in}" PARENT_SCOPE) endfunction() -# Define a transform macro: wrap in angle brackets -macro(wrap_angles in out) - set(${out} "<${in}>") -endmacro() - set(mylist alpha bravo charlie delta) # Basic APPLY - all elements @@ -74,19 +69,6 @@ if(NOT output STREQUAL "prefix_alpha;prefix_bravo;prefix_charlie;prefix_delta") message(FATAL_ERROR "TRANSFORM(APPLY add_prefix) is \"${output}\", expected is \"prefix_alpha;prefix_bravo;prefix_charlie;prefix_delta\"") endif() -# APPLY with a macro -set(mylist alpha bravo charlie) -list(TRANSFORM mylist APPLY wrap_angles OUTPUT_VARIABLE output) -if(NOT output STREQUAL ";;") - message(FATAL_ERROR "TRANSFORM(APPLY macro) is \"${output}\", expected is \";;\"") -endif() - -# APPLY with macro and selector -list(TRANSFORM mylist APPLY wrap_angles AT 0 2 OUTPUT_VARIABLE output) -if(NOT output STREQUAL ";bravo;") - message(FATAL_ERROR "TRANSFORM(APPLY macro AT) is \"${output}\", expected is \";bravo;\"") -endif() - # APPLY on empty list set(empty_list "") list(TRANSFORM empty_list APPLY add_src_prefix OUTPUT_VARIABLE output) diff --git a/Tests/RunCMake/list/TRANSFORM-PREDICATE.cmake b/Tests/RunCMake/list/TRANSFORM-PREDICATE.cmake index 103f0219df..f010f64f02 100644 --- a/Tests/RunCMake/list/TRANSFORM-PREDICATE.cmake +++ b/Tests/RunCMake/list/TRANSFORM-PREDICATE.cmake @@ -7,16 +7,6 @@ function(starts_with_b input result) 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 @@ -36,13 +26,6 @@ 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) diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro-stderr.txt new file mode 100644 index 0000000000..8c2b77d042 --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at TRANSFORM-Selector-PREDICATE-Macro\.cmake:11 \(list\): + list sub-command TRANSFORM, selector PREDICATE: macro "is_short" may not be + used here; define it as a function\(\) instead\. +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro.cmake new file mode 100644 index 0000000000..c9334e8ca1 --- /dev/null +++ b/Tests/RunCMake/list/TRANSFORM-Selector-PREDICATE-Macro.cmake @@ -0,0 +1,11 @@ +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) +list(TRANSFORM mylist TOUPPER PREDICATE is_short)