summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--CONTRIBUTING.rst1
-rw-r--r--Help/command/list.rst73
-rw-r--r--Help/release/dev/list-transform.rst5
-rw-r--r--Modules/CMakeCUDACompiler.cmake.in1
-rw-r--r--Modules/CMakeParseImplicitLinkInfo.cmake2
-rw-r--r--Modules/Compiler/Clang-CXX.cmake47
-rw-r--r--Modules/FindOpenAL.cmake2
-rw-r--r--Modules/FindOpenMP.cmake17
-rw-r--r--Modules/FindOpenSSL.cmake65
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx23
-rw-r--r--Source/cmGlobalXCodeGenerator.h2
-rw-r--r--Source/cmListCommand.cxx556
-rw-r--r--Source/cmListCommand.h1
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx13
-rw-r--r--Source/cmStringCommand.cxx100
-rw-r--r--Source/cmStringCommand.h23
-rw-r--r--Source/cmStringReplaceHelper.cxx117
-rw-r--r--Source/cmStringReplaceHelper.h69
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx27
-rw-r--r--Source/kwsys/SystemInformation.cxx2
-rw-r--r--Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in6
-rw-r--r--Tests/CudaOnly/CMakeLists.txt4
-rw-r--r--Tests/CudaOnly/PDB/CMakeLists.txt19
-rw-r--r--Tests/CudaOnly/PDB/check_pdbs.cmake10
-rw-r--r--Tests/CudaOnly/PDB/main.cu4
-rw-r--r--Tests/Module/ExternalData/Data5/CMakeLists.txt6
-rw-r--r--Tests/Module/ExternalData/Data5/Data5.dat.md51
-rw-r--r--Tests/RunCMake/VS10Project/ExplicitCMakeLists-check.cmake25
-rw-r--r--Tests/RunCMake/VS10Project/ExplicitCMakeLists.cmake3
-rw-r--r--Tests/RunCMake/VS10Project/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/XcodeProject/ExplicitCMakeLists-check.cmake20
-rw-r--r--Tests/RunCMake/XcodeProject/ExplicitCMakeLists.cmake2
-rw-r--r--Tests/RunCMake/XcodeProject/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/list/RunCMakeTest.cmake41
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-APPEND.cmake48
-rw-r--r--Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-GENEX_STRIP.cmake49
-rw-r--r--Tests/RunCMake/list/TRANSFORM-InvalidAction-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-InvalidAction-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-InvalidAction.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-NoAction-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-NoAction-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-NoAction.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-PREPEND.cmake48
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-REPLACE.cmake48
-rw-r--r--Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-STRIP.cmake49
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-stderr.txt5
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOLOWER.cmake48
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-result.txt1
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-stderr.txt4
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments.cmake2
-rw-r--r--Tests/RunCMake/list/TRANSFORM-TOUPPER.cmake48
-rwxr-xr-xbootstrap7
133 files changed, 1682 insertions, 170 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a27c662..3ee67cb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -546,7 +546,7 @@ macro (CMAKE_BUILD_UTILITIES)
#---------------------------------------------------------------------
# Build libuv library.
if(CMAKE_USE_SYSTEM_LIBUV)
- find_package(LibUV 1.0.0)
+ find_package(LibUV 1.10.0)
if(NOT LIBUV_FOUND)
message(FATAL_ERROR
"CMAKE_USE_SYSTEM_LIBUV is ON but a libuv is not found!")
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index fa2c23d..01987be 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -36,6 +36,7 @@ To contribute patches:
#. Push a topic branch to a personal repository fork on GitLab.
#. Create a GitLab Merge Request targeting the upstream ``master`` branch
(even if the change is intended for merge to the ``release`` branch).
+ Check the box to allow edits from maintainers.
The merge request will enter the `CMake Review Process`_ for consideration.
diff --git a/Help/command/list.rst b/Help/command/list.rst
index 6218a2a..e240b65 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -151,6 +151,79 @@ REMOVE_DUPLICATES
Removes duplicated items in the list.
+TRANSFORM
+"""""""""
+
+::
+
+ list(TRANSFORM <list> <ACTION> [<SELECTOR>]
+ [OUTPUT_VARIABLE <output variable>])
+
+Transforms the list by applying an action to all or, by specifying a
+``<SELECTOR>``, to the selected elements of the list, storing result in-place
+or in the specified output variable.
+
+.. note::
+
+ ``TRANSFORM`` sub-command does not change the number of elements of the
+ list. If a ``<SELECTOR>`` is specified, only some elements will be changed,
+ the other ones will remain same as before the transformation.
+
+``<ACTION>`` specify the action to apply to the elements of list.
+The actions have exactly the same semantics as sub-commands of
+:command:`string` command.
+
+The ``<ACTION>`` may be one of:
+
+``APPEND``, ``PREPEND``: Append, prepend specified value to each element of
+the list. ::
+
+ list(TRANSFORM <list> <APPEND|PREPEND> <value> ...)
+
+``TOUPPER``, ``TOLOWER``: Convert each element of the list to upper, lower
+characters. ::
+
+ list(TRANSFORM <list> <TOLOWER|TOUPPER> ...)
+
+``STRIP``: Remove leading and trailing spaces from each element of the
+list. ::
+
+ list(TRANSFORM <list> STRIP ...)
+
+``GENEX_STRIP``: Strip any
+:manual:`generator expressions <cmake-generator-expressions(7)>` from each
+element of the list. ::
+
+ list(TRANSFORM <list> GENEX_STRIP ...)
+
+``REPLACE``: Match the regular expression as many times as possible and
+substitute the replacement expression for the match for each element
+of the list
+(Same semantic as ``REGEX REPLACE`` from :command:`string` command). ::
+
+ list(TRANSFORM <list> REPLACE <regular_expression>
+ <replace_expression> ...)
+
+``<SELECTOR>`` select which elements of the list will be transformed. Only one
+type of selector can be specified at a time.
+
+The ``<SELECTOR>`` may be one of:
+
+``AT``: Specify a list of indexes. ::
+
+ list(TRANSFORM <list> <ACTION> AT <index> [<index> ...] ...)
+
+``FOR``: Specify a range with, optionaly, an increment used to iterate over
+the range. ::
+
+ list(TRANSFORM <list> <ACTION> FOR <start> <stop> [<step>] ...)
+
+``REGEX``: Specify a regular expression. Only elements matching the regular
+expression will be transformed. ::
+
+ list(TRANSFORM <list> <ACTION> REGEX <regular_expression> ...)
+
+
Sorting
^^^^^^^
diff --git a/Help/release/dev/list-transform.rst b/Help/release/dev/list-transform.rst
new file mode 100644
index 0000000..4a6dacc
--- /dev/null
+++ b/Help/release/dev/list-transform.rst
@@ -0,0 +1,5 @@
+list-transform
+--------------
+
+* The :command:`list` command learned a ``TRANSFORM`` sub-command
+ to apply various string transformation to list's elements.
diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in
index f524e5f..9761d8c 100644
--- a/Modules/CMakeCUDACompiler.cmake.in
+++ b/Modules/CMakeCUDACompiler.cmake.in
@@ -11,6 +11,7 @@ set(CMAKE_CUDA_SIMULATE_VERSION "@CMAKE_CUDA_SIMULATE_VERSION@")
set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX")
set(CMAKE_CUDA_HOST_COMPILER_ENV_VAR "CUDAHOSTCXX")
+set(CMAKE_CUDA_COMPILER_LOADED 1)
set(CMAKE_CUDA_COMPILER_ID_RUN 1)
set(CMAKE_CUDA_SOURCE_FILE_EXTENSIONS cu)
set(CMAKE_CUDA_LINKER_PREFERENCE 15)
diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake
index 63d18ab..935f92d 100644
--- a/Modules/CMakeParseImplicitLinkInfo.cmake
+++ b/Modules/CMakeParseImplicitLinkInfo.cmake
@@ -142,7 +142,7 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj
# We remove items that are not language-specific.
set(implicit_libs "")
foreach(lib IN LISTS implicit_libs_tmp)
- if("x${lib}" MATCHES "^x(crt.*\\.o|gcc_eh.*|System.*|.*libclang_rt.*|msvcrt.*|libvcruntime.*|libucrt.*|libcmt.*)$")
+ if("x${lib}" MATCHES "^x(crt.*\\.o|gcc_eh.*|.*libgcc_eh.*|System.*|.*libclang_rt.*|msvcrt.*|libvcruntime.*|libucrt.*|libcmt.*)$")
string(APPEND log " remove lib [${lib}]\n")
elseif(IS_ABSOLUTE "${lib}")
get_filename_component(abs "${lib}" ABSOLUTE)
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 77866e9..e99011b 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -51,8 +51,33 @@ if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
endif()
unset(_clang_version_std17)
+
+ __compiler_check_default_language_standard(CXX 2.1 98)
+elseif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9
+ AND CMAKE_CXX_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.0)
+ # This version of clang-cl and the MSVC version it simulates have
+ # support for -std: flags.
+ set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std:c++14")
+ set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std:c++14")
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
+ set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++17")
+ set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++17")
+ set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
+ set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
+ else()
+ set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++latest")
+ set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++latest")
+ endif()
+
+ __compiler_check_default_language_standard(CXX 3.9 14)
else()
- # clang-cl does not know these options because it behaves like cl.exe
+ # This version of clang-cl, or the MSVC version it simulates, does not have
+ # language standards. Set these options as empty strings so the feature
+ # test infrastructure can at least check to see if they are defined.
set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "")
@@ -63,10 +88,22 @@ else()
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "")
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "")
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "")
-endif()
-if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
- __compiler_check_default_language_standard(CXX 2.1 98)
-else()
+ # There is no meaningful default for this
set(CMAKE_CXX_STANDARD_DEFAULT "")
+
+ # There are no compiler modes so we only need to test features once.
+ # Override the default macro for this special case. Pretend that
+ # all language standards are available so that at least compilation
+ # can be attempted.
+ macro(cmake_record_cxx_compile_features)
+ list(APPEND CMAKE_CXX_COMPILE_FEATURES
+ cxx_std_98
+ cxx_std_11
+ cxx_std_14
+ cxx_std_17
+ cxx_std_20
+ )
+ _record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
+ endmacro()
endif()
diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake
index c3d202e..7521d51 100644
--- a/Modules/FindOpenAL.cmake
+++ b/Modules/FindOpenAL.cmake
@@ -58,7 +58,7 @@
find_path(OPENAL_INCLUDE_DIR al.h
HINTS
ENV OPENALDIR
- PATH_SUFFIXES include/AL include/OpenAL include
+ PATH_SUFFIXES include/AL include/OpenAL include AL OpenAL
PATHS
~/Library/Frameworks
/Library/Frameworks
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index e252ba5..329ace1 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -242,19 +242,10 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
endforeach()
set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
else()
- # The Intel compiler on windows has no verbose mode, so we need to treat it explicitly
- if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Intel" AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
- set("${OPENMP_LIB_NAMES_VAR}" "libiomp5md" PARENT_SCOPE)
- find_library(OpenMP_libiomp5md_LIBRARY
- NAMES "libiomp5md"
- HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
- CMAKE_FIND_ROOT_PATH_BOTH
- NO_DEFAULT_PATH
- )
- mark_as_advanced(OpenMP_libiomp5md_LIBRARY)
- else()
- set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
- endif()
+ # We do not know how to extract implicit OpenMP libraries for this compiler.
+ # Assume that it handles them automatically, e.g. the Intel Compiler on
+ # Windows should put the dependency in its object files.
+ set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
endif()
break()
elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang"
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index c358ff1..d5cd8bc 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -7,6 +7,12 @@
#
# Find the OpenSSL encryption library.
#
+# Optional COMPONENTS
+# ^^^^^^^^^^^^^^^^^^^
+#
+# This module supports two optional COMPONENTS: ``Crypto`` and ``SSL``. Both
+# components have associated imported targets, as described below.
+#
# Imported Targets
# ^^^^^^^^^^^^^^^^
#
@@ -23,7 +29,8 @@
# This module will set the following variables in your project:
#
# ``OPENSSL_FOUND``
-# System has the OpenSSL library.
+# System has the OpenSSL library. If no components are requested it only
+# requires the crypto library.
# ``OPENSSL_INCLUDE_DIR``
# The OpenSSL include directory.
# ``OPENSSL_CRYPTO_LIBRARY``
@@ -371,28 +378,47 @@ if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h")
endif ()
endif ()
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-
set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} )
-if (OPENSSL_VERSION)
- find_package_handle_standard_args(OpenSSL
- REQUIRED_VARS
- #OPENSSL_SSL_LIBRARY # FIXME: require based on a component request?
- OPENSSL_CRYPTO_LIBRARY
- OPENSSL_INCLUDE_DIR
- VERSION_VAR
- OPENSSL_VERSION
- FAIL_MESSAGE
- "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
- )
-else ()
- find_package_handle_standard_args(OpenSSL "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
- #OPENSSL_SSL_LIBRARY # FIXME: require based on a component request?
+foreach(_comp IN LISTS OpenSSL_FIND_COMPONENTS)
+ if(_comp STREQUAL "Crypto")
+ if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND
+ (EXISTS "${OPENSSL_CRYPTO_LIBRARY}" OR
+ EXISTS "${LIB_EAY_LIBRARY_DEBUG}" OR
+ EXISTS "${LIB_EAY_LIBRARY_RELEASE}")
+ )
+ set(OpenSSL_${_comp}_FOUND TRUE)
+ else()
+ set(OpenSSL_${_comp}_FOUND FALSE)
+ endif()
+ elseif(_comp STREQUAL "SSL")
+ if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND
+ (EXISTS "${OPENSSL_SSL_LIBRARY}" OR
+ EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR
+ EXISTS "${SSL_EAY_LIBRARY_RELEASE}")
+ )
+ set(OpenSSL_${_comp}_FOUND TRUE)
+ else()
+ set(OpenSSL_${_comp}_FOUND FALSE)
+ endif()
+ else()
+ message(WARNING "${_comp} is not a valid OpenSSL component")
+ set(OpenSSL_${_comp}_FOUND FALSE)
+ endif()
+endforeach()
+unset(_comp)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(OpenSSL
+ REQUIRED_VARS
OPENSSL_CRYPTO_LIBRARY
OPENSSL_INCLUDE_DIR
- )
-endif ()
+ VERSION_VAR
+ OPENSSL_VERSION
+ HANDLE_COMPONENTS
+ FAIL_MESSAGE
+ "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
+)
mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)
@@ -425,6 +451,7 @@ if(OPENSSL_FOUND)
IMPORTED_LOCATION_DEBUG "${LIB_EAY_LIBRARY_DEBUG}")
endif()
endif()
+
if(NOT TARGET OpenSSL::SSL AND
(EXISTS "${OPENSSL_SSL_LIBRARY}" OR
EXISTS "${SSL_EAY_LIBRARY_DEBUG}" OR
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index e23b070..a007098 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -557,6 +557,7 @@ set(SRCS
cmSiteNameCommand.h
cmSourceGroupCommand.cxx
cmSourceGroupCommand.h
+ cmStringReplaceHelper.cxx
cmStringCommand.cxx
cmStringCommand.h
cmSubdirCommand.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 593c139..d5174c4 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 11)
-set(CMake_VERSION_PATCH 20180412)
+set(CMake_VERSION_PATCH 20180418)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index df671c2..4481bdc 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -841,6 +841,19 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
return buildFile;
}
+void cmGlobalXCodeGenerator::AddXCodeProjBuildRule(
+ cmGeneratorTarget* target, std::vector<cmSourceFile*>& sources) const
+{
+ std::string listfile =
+ target->GetLocalGenerator()->GetCurrentSourceDirectory();
+ listfile += "/CMakeLists.txt";
+ cmSourceFile* srcCMakeLists = target->Makefile->GetOrCreateSource(listfile);
+ if (std::find(sources.begin(), sources.end(), srcCMakeLists) ==
+ sources.end()) {
+ sources.push_back(srcCMakeLists);
+ }
+}
+
std::string GetSourcecodeValueFromFileExtension(const std::string& _ext,
const std::string& lang,
bool& keepLastKnownFileType)
@@ -1063,10 +1076,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
}
// Add CMakeLists.txt file for user convenience.
- std::string listfile =
- gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
- listfile += "/CMakeLists.txt";
- classes.push_back(gtgt->Makefile->GetOrCreateSource(listfile));
+ this->AddXCodeProjBuildRule(gtgt, classes);
std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
@@ -2359,10 +2369,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
}
// Add CMakeLists.txt file for user convenience.
- std::string listfile =
- gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
- listfile += "/CMakeLists.txt";
- sources.push_back(gtgt->Makefile->GetOrCreateSource(listfile));
+ this->AddXCodeProjBuildRule(gtgt, sources);
for (auto sourceFile : sources) {
if (!sourceFile->GetPropertyAsBool("GENERATED")) {
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index b45887e..7c51177 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -198,6 +198,8 @@ private:
cmGeneratorTarget* target);
cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen, cmSourceFile* sf,
cmGeneratorTarget* gtgt);
+ void AddXCodeProjBuildRule(cmGeneratorTarget* target,
+ std::vector<cmSourceFile*>& sources) const;
bool CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmXCodeObject*>&);
bool IsHeaderFile(cmSourceFile*);
void AddDependTarget(cmXCodeObject* target, cmXCodeObject* dependTarget);
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 821e6d1..31bc1c0 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -5,14 +5,19 @@
#include "cmsys/RegularExpression.hxx"
#include <algorithm>
#include <assert.h>
+#include <functional>
#include <iterator>
+#include <set>
#include <sstream>
+#include <stdexcept>
#include <stdio.h>
#include <stdlib.h> // required for atoi
#include "cmAlgorithms.h"
+#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
+#include "cmStringReplaceHelper.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -54,6 +59,9 @@ bool cmListCommand::InitialPass(std::vector<std::string> const& args,
if (subCommand == "REMOVE_DUPLICATES") {
return this->HandleRemoveDuplicatesCommand(args);
}
+ if (subCommand == "TRANSFORM") {
+ return this->HandleTransformCommand(args);
+ }
if (subCommand == "SORT") {
return this->HandleSortCommand(args);
}
@@ -407,6 +415,554 @@ bool cmListCommand::HandleRemoveDuplicatesCommand(
return true;
}
+// Helpers for list(TRANSFORM <list> ...)
+namespace {
+using transform_type = std::function<std::string(const std::string&)>;
+
+class transform_error : public std::runtime_error
+{
+public:
+ transform_error(const std::string& error)
+ : std::runtime_error(error)
+ {
+ }
+};
+
+class TransformSelector
+{
+public:
+ virtual ~TransformSelector() {}
+
+ std::string Tag;
+
+ virtual bool Validate(std::size_t count = 0) = 0;
+
+ virtual bool InSelection(const std::string&) = 0;
+
+ virtual void Transform(std::vector<std::string>& list,
+ const transform_type& transform)
+ {
+ std::transform(list.begin(), list.end(), list.begin(), transform);
+ }
+
+protected:
+ TransformSelector(std::string&& tag)
+ : Tag(std::move(tag))
+ {
+ }
+};
+class TransformNoSelector : public TransformSelector
+{
+public:
+ TransformNoSelector()
+ : TransformSelector("NO SELECTOR")
+ {
+ }
+
+ bool Validate(std::size_t) override { return true; }
+
+ bool InSelection(const std::string&) override { return true; }
+};
+class TransformSelectorRegex : public TransformSelector
+{
+public:
+ TransformSelectorRegex(const std::string& regex)
+ : TransformSelector("REGEX")
+ , Regex(regex)
+ {
+ }
+
+ bool Validate(std::size_t) override { return this->Regex.is_valid(); }
+
+ bool InSelection(const std::string& value) override
+ {
+ return this->Regex.find(value);
+ }
+
+ cmsys::RegularExpression Regex;
+};
+class TransformSelectorIndexes : public TransformSelector
+{
+public:
+ std::vector<int> Indexes;
+
+ bool InSelection(const std::string&) override { return true; }
+
+ void Transform(std::vector<std::string>& list,
+ const transform_type& transform) override
+ {
+ this->Validate(list.size());
+
+ for (auto index : this->Indexes) {
+ list[index] = transform(list[index]);
+ }
+ }
+
+protected:
+ TransformSelectorIndexes(std::string&& tag)
+ : TransformSelector(std::move(tag))
+ {
+ }
+ TransformSelectorIndexes(std::string&& tag, std::vector<int>&& indexes)
+ : TransformSelector(std::move(tag))
+ , Indexes(indexes)
+ {
+ }
+
+ int NormalizeIndex(int index, std::size_t count)
+ {
+ if (index < 0) {
+ index = static_cast<int>(count) + index;
+ }
+ if (index < 0 || count <= static_cast<std::size_t>(index)) {
+ std::ostringstream str;
+ str << "sub-command TRANSFORM, selector " << this->Tag
+ << ", index: " << index << " out of range (-" << count << ", "
+ << count - 1 << ").";
+ throw transform_error(str.str());
+ }
+ return index;
+ }
+};
+class TransformSelectorAt : public TransformSelectorIndexes
+{
+public:
+ TransformSelectorAt(std::vector<int>&& indexes)
+ : TransformSelectorIndexes("AT", std::move(indexes))
+ {
+ }
+
+ bool Validate(std::size_t count) override
+ {
+ decltype(Indexes) indexes;
+
+ for (auto index : Indexes) {
+ indexes.push_back(this->NormalizeIndex(index, count));
+ }
+ this->Indexes = std::move(indexes);
+
+ return true;
+ }
+};
+class TransformSelectorFor : public TransformSelectorIndexes
+{
+public:
+ TransformSelectorFor(int start, int stop, int step)
+ : TransformSelectorIndexes("FOR")
+ , Start(start)
+ , Stop(stop)
+ , Step(step)
+ {
+ }
+
+ bool Validate(std::size_t count) override
+ {
+ this->Start = this->NormalizeIndex(this->Start, count);
+ this->Stop = this->NormalizeIndex(this->Stop, count);
+
+ // compute indexes
+ auto size = (this->Stop - this->Start + 1) / this->Step;
+ if ((this->Stop - this->Start + 1) % this->Step != 0) {
+ size += 1;
+ }
+
+ this->Indexes.resize(size);
+ auto start = this->Start, step = this->Step;
+ std::generate(this->Indexes.begin(), this->Indexes.end(),
+ [&start, step]() -> int {
+ auto r = start;
+ start += step;
+ return r;
+ });
+
+ return true;
+ }
+
+private:
+ int Start, Stop, Step;
+};
+
+class TransformAction
+{
+public:
+ virtual ~TransformAction() {}
+
+ virtual std::string Transform(const std::string& input) = 0;
+};
+class TransformReplace : public TransformAction
+{
+public:
+ TransformReplace(const std::vector<std::string>& arguments,
+ cmMakefile* makefile)
+ : ReplaceHelper(arguments[0], arguments[1], makefile)
+ {
+ makefile->ClearMatches();
+
+ if (!this->ReplaceHelper.IsRegularExpressionValid()) {
+ std::ostringstream error;
+ error
+ << "sub-command TRANSFORM, action REPLACE: Failed to compile regex \""
+ << arguments[0] << "\".";
+ throw transform_error(error.str());
+ }
+ if (!this->ReplaceHelper.IsReplaceExpressionValid()) {
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, action REPLACE: "
+ << this->ReplaceHelper.GetError() << ".";
+ throw transform_error(error.str());
+ }
+ }
+
+ std::string Transform(const std::string& input) override
+ {
+ // Scan through the input for all matches.
+ std::string output;
+
+ if (!this->ReplaceHelper.Replace(input, output)) {
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, action REPLACE: "
+ << this->ReplaceHelper.GetError() << ".";
+ throw transform_error(error.str());
+ }
+
+ return output;
+ }
+
+private:
+ cmStringReplaceHelper ReplaceHelper;
+};
+}
+
+bool cmListCommand::HandleTransformCommand(
+ std::vector<std::string> const& args)
+{
+ if (args.size() < 3) {
+ this->SetError(
+ "sub-command TRANSFORM requires an action to be specified.");
+ return false;
+ }
+
+ // Structure collecting all elements of the command
+ struct Command
+ {
+ Command(const std::string& listName)
+ : ListName(listName)
+ , OutputName(listName)
+ {
+ }
+
+ std::string Name;
+ std::string ListName;
+ std::vector<std::string> Arguments;
+ std::unique_ptr<TransformAction> Action;
+ std::unique_ptr<TransformSelector> Selector;
+ std::string OutputName;
+ } command(args[1]);
+
+ // Descriptor of action
+ // Arity: number of arguments required for the action
+ // Transform: lambda function implementing the action
+ struct ActionDescriptor
+ {
+ ActionDescriptor(const std::string& name)
+ : Name(name)
+ {
+ }
+ ActionDescriptor(const std::string& name, int arity,
+ const transform_type& transform)
+ : Name(name)
+ , Arity(arity)
+ , Transform(transform)
+ {
+ }
+
+ operator const std::string&() const { return Name; }
+
+ std::string Name;
+ int Arity = 0;
+ transform_type Transform;
+ };
+
+ // Build a set of supported actions.
+ std::set<ActionDescriptor,
+ std::function<bool(const std::string&, const std::string&)>>
+ descriptors(
+ [](const std::string& x, const std::string& y) { return x < y; });
+ descriptors = { { "APPEND", 1,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return s + command.Arguments[0];
+ }
+
+ return s;
+ } },
+ { "PREPEND", 1,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return command.Arguments[0] + s;
+ }
+
+ return s;
+ } },
+ { "TOUPPER", 0,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return cmSystemTools::UpperCase(s);
+ }
+
+ return s;
+ } },
+ { "TOLOWER", 0,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return cmSystemTools::LowerCase(s);
+ }
+
+ return s;
+ } },
+ { "STRIP", 0,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return cmSystemTools::TrimWhitespace(s);
+ }
+
+ return s;
+ } },
+ { "GENEX_STRIP", 0,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return cmGeneratorExpression::Preprocess(
+ s,
+ cmGeneratorExpression::StripAllGeneratorExpressions);
+ }
+
+ return s;
+ } },
+ { "REPLACE", 2,
+ [&command](const std::string& s) -> std::string {
+ if (command.Selector->InSelection(s)) {
+ return command.Action->Transform(s);
+ }
+
+ return s;
+ } } };
+
+ using size_type = std::vector<std::string>::size_type;
+ size_type index = 2;
+
+ // Parse all possible function parameters
+ auto descriptor = descriptors.find(args[index]);
+
+ if (descriptor == descriptors.end()) {
+ std::ostringstream error;
+ error << " sub-command TRANSFORM, " << args[index] << " invalid action.";
+ this->SetError(error.str());
+ return false;
+ }
+
+ // Action arguments
+ index += 1;
+ if (args.size() < index + descriptor->Arity) {
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, action " << descriptor->Name
+ << " expects " << descriptor->Arity << " argument(s).";
+ this->SetError(error.str());
+ return false;
+ }
+
+ command.Name = descriptor->Name;
+ index += descriptor->Arity;
+ if (descriptor->Arity > 0) {
+ command.Arguments =
+ std::vector<std::string>(args.begin() + 3, args.begin() + index);
+ }
+
+ if (command.Name == "REPLACE") {
+ try {
+ command.Action =
+ cm::make_unique<TransformReplace>(command.Arguments, this->Makefile);
+ } catch (const transform_error& e) {
+ this->SetError(e.what());
+ return false;
+ }
+ }
+
+ const std::string REGEX{ "REGEX" }, AT{ "AT" }, FOR{ "FOR" },
+ OUTPUT_VARIABLE{ "OUTPUT_VARIABLE" };
+
+ // handle optional arguments
+ while (args.size() > index) {
+ if ((args[index] == REGEX || args[index] == AT || args[index] == FOR) &&
+ command.Selector) {
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, selector already specified ("
+ << command.Selector->Tag << ").";
+ this->SetError(error.str());
+ return false;
+ }
+
+ // REGEX selector
+ if (args[index] == REGEX) {
+ if (args.size() == ++index) {
+ this->SetError("sub-command TRANSFORM, selector REGEX expects "
+ "'regular expression' argument.");
+ return false;
+ }
+
+ command.Selector = cm::make_unique<TransformSelectorRegex>(args[index]);
+ if (!command.Selector->Validate()) {
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, selector REGEX failed to compile "
+ "regex \"";
+ error << args[index] << "\".";
+ this->SetError(error.str());
+ return false;
+ }
+
+ index += 1;
+ continue;
+ }
+
+ // AT selector
+ if (args[index] == AT) {
+ // get all specified indexes
+ std::vector<int> indexes;
+ while (args.size() > ++index) {
+ std::size_t pos;
+ int value;
+
+ try {
+ value = std::stoi(args[index], &pos);
+ if (pos != args[index].length()) {
+ // this is not a number, stop processing
+ break;
+ }
+ indexes.push_back(value);
+ } catch (const std::invalid_argument&) {
+ // this is not a number, stop processing
+ break;
+ }
+ }
+
+ if (indexes.empty()) {
+ this->SetError(
+ "sub-command TRANSFORM, selector AT expects at least one "
+ "numeric value.");
+ return false;
+ }
+
+ command.Selector =
+ cm::make_unique<TransformSelectorAt>(std::move(indexes));
+
+ continue;
+ }
+
+ // FOR selector
+ if (args[index] == FOR) {
+ if (args.size() <= ++index + 1) {
+ this->SetError("sub-command TRANSFORM, selector FOR expects, at least,"
+ " two arguments.");
+ return false;
+ }
+
+ int start = 0, stop = 0, step = 1;
+ bool valid = true;
+ try {
+ std::size_t pos;
+
+ start = std::stoi(args[index], &pos);
+ if (pos != args[index].length()) {
+ // this is not a number
+ valid = false;
+ } else {
+ stop = std::stoi(args[++index], &pos);
+ if (pos != args[index].length()) {
+ // this is not a number
+ valid = false;
+ }
+ }
+ } catch (const std::invalid_argument&) {
+ // this is not numbers
+ valid = false;
+ }
+ if (!valid) {
+ this->SetError("sub-command TRANSFORM, selector FOR expects, "
+ "at least, two numeric values.");
+ return false;
+ }
+ // try to read a third numeric value for step
+ if (args.size() > ++index) {
+ try {
+ std::size_t pos;
+
+ step = std::stoi(args[index], &pos);
+ if (pos != args[index].length()) {
+ // this is not a number
+ step = 1;
+ } else {
+ index += 1;
+ }
+ } catch (const std::invalid_argument&) {
+ // this is not number, ignore exception
+ }
+ }
+
+ if (step < 0) {
+ this->SetError("sub-command TRANSFORM, selector FOR expects "
+ "non negative numeric value for <step>.");
+ }
+
+ command.Selector =
+ cm::make_unique<TransformSelectorFor>(start, stop, step);
+
+ continue;
+ }
+
+ // output variable
+ if (args[index] == OUTPUT_VARIABLE) {
+ if (args.size() == ++index) {
+ this->SetError("sub-command TRANSFORM, OUTPUT_VARIABLE "
+ "expects variable name argument.");
+ return false;
+ }
+
+ command.OutputName = args[index++];
+ continue;
+ }
+
+ std::ostringstream error;
+ error << "sub-command TRANSFORM, '"
+ << cmJoin(cmMakeRange(args).advance(index), " ")
+ << "': unexpected argument(s).";
+ this->SetError(error.str());
+ return false;
+ }
+
+ // expand the list variable
+ std::vector<std::string> varArgsExpanded;
+ if (!this->GetList(varArgsExpanded, command.ListName)) {
+ this->Makefile->AddDefinition(command.OutputName, "");
+ return true;
+ }
+
+ if (!command.Selector) {
+ // no selector specified, apply transformation to all elements
+ command.Selector = cm::make_unique<TransformNoSelector>();
+ }
+
+ try {
+ command.Selector->Transform(varArgsExpanded, descriptor->Transform);
+ } catch (const transform_error& e) {
+ this->SetError(e.what());
+ return false;
+ }
+
+ this->Makefile->AddDefinition(command.OutputName,
+ cmJoin(varArgsExpanded, ";").c_str());
+
+ return true;
+}
+
bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
{
assert(args.size() >= 2);
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index d69d8f9..76a9856 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -41,6 +41,7 @@ protected:
bool HandleRemoveAtCommand(std::vector<std::string> const& args);
bool HandleRemoveItemCommand(std::vector<std::string> const& args);
bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args);
+ bool HandleTransformCommand(std::vector<std::string> const& args);
bool HandleSortCommand(std::vector<std::string> const& args);
bool HandleSublistCommand(std::vector<std::string> const& args);
bool HandleReverseCommand(std::vector<std::string> const& args);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index acb5921..fcdcdc5 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1364,7 +1364,18 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
for (size_t ci = 0; ci < configs.size(); ++ci) {
acs.Configs.push_back(ci);
}
- sources.Sources.emplace_back(std::move(acs));
+ bool haveCMakeLists = false;
+ for (cmGeneratorTarget::AllConfigSource& si : sources.Sources) {
+ if (si.Source == sf) {
+ haveCMakeLists = true;
+ // Replace the explicit source reference with our generated one.
+ si = acs;
+ break;
+ }
+ }
+ if (!haveCMakeLists) {
+ sources.Sources.emplace_back(std::move(acs));
+ }
}
}
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 9631912..dabec47 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -13,6 +13,7 @@
#include "cmCryptoHash.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
+#include "cmStringReplaceHelper.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmUuid.h"
@@ -344,46 +345,17 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
std::string const& regex = args[2];
std::string const& replace = args[3];
std::string const& outvar = args[4];
+ cmStringReplaceHelper replaceHelper(regex, replace, this->Makefile);
- // Pull apart the replace expression to find the escaped [0-9] values.
- std::vector<RegexReplacement> replacement;
- std::string::size_type l = 0;
- while (l < replace.length()) {
- std::string::size_type r = replace.find('\\', l);
- if (r == std::string::npos) {
- r = replace.length();
- replacement.push_back(replace.substr(l, r - l));
- } else {
- if (r - l > 0) {
- replacement.push_back(replace.substr(l, r - l));
- }
- if (r == (replace.length() - 1)) {
- this->SetError("sub-command REGEX, mode REPLACE: "
- "replace-expression ends in a backslash.");
- return false;
- }
- if ((replace[r + 1] >= '0') && (replace[r + 1] <= '9')) {
- replacement.push_back(replace[r + 1] - '0');
- } else if (replace[r + 1] == 'n') {
- replacement.push_back("\n");
- } else if (replace[r + 1] == '\\') {
- replacement.push_back("\\");
- } else {
- std::string e = "sub-command REGEX, mode REPLACE: Unknown escape \"";
- e += replace.substr(r, 2);
- e += "\" in replace-expression.";
- this->SetError(e);
- return false;
- }
- r += 2;
- }
- l = r;
+ if (!replaceHelper.IsReplaceExpressionValid()) {
+ this->SetError("sub-command REGEX, mode REPLACE: " +
+ replaceHelper.GetError() + ".");
+ return false;
}
this->Makefile->ClearMatches();
- // Compile the regular expression.
- cmsys::RegularExpression re;
- if (!re.compile(regex.c_str())) {
+
+ if (!replaceHelper.IsRegularExpressionValid()) {
std::string e =
"sub-command REGEX, mode REPLACE failed to compile regex \"" + regex +
"\".";
@@ -392,60 +364,16 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
}
// Concatenate all the last arguments together.
- std::string input = cmJoin(cmMakeRange(args).advance(5), std::string());
-
- // Scan through the input for all matches.
+ const std::string input =
+ cmJoin(cmMakeRange(args).advance(5), std::string());
std::string output;
- std::string::size_type base = 0;
- while (re.find(input.c_str() + base)) {
- this->Makefile->ClearMatches();
- this->Makefile->StoreMatches(re);
- std::string::size_type l2 = re.start();
- std::string::size_type r = re.end();
-
- // Concatenate the part of the input that was not matched.
- output += input.substr(base, l2);
-
- // Make sure the match had some text.
- if (r - l2 == 0) {
- std::string e = "sub-command REGEX, mode REPLACE regex \"" + regex +
- "\" matched an empty string.";
- this->SetError(e);
- return false;
- }
- // Concatenate the replacement for the match.
- for (RegexReplacement const& i : replacement) {
- if (i.number < 0) {
- // This is just a plain-text part of the replacement.
- output += i.value;
- } else {
- // Replace with part of the match.
- int n = i.number;
- std::string::size_type start = re.start(n);
- std::string::size_type end = re.end(n);
- std::string::size_type len = input.length() - base;
- if ((start != std::string::npos) && (end != std::string::npos) &&
- (start <= len) && (end <= len)) {
- output += input.substr(base + start, end - start);
- } else {
- std::string e =
- "sub-command REGEX, mode REPLACE: replace expression \"" +
- replace + "\" contains an out-of-range escape for regex \"" +
- regex + "\".";
- this->SetError(e);
- return false;
- }
- }
- }
-
- // Move past the match.
- base += r;
+ if (!replaceHelper.Replace(input, output)) {
+ this->SetError("sub-command REGEX, mode REPLACE: " +
+ replaceHelper.GetError() + ".");
+ return false;
}
- // Concatenate the text after the last match.
- output += input.substr(base, input.length() - base);
-
// Store the output in the provided variable.
this->Makefile->AddDefinition(outvar, output.c_str());
return true;
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index 569ed83..cbff73e 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -60,29 +60,6 @@ protected:
bool joinImpl(std::vector<std::string> const& args, std::string const& glue,
size_t varIdx);
-
- class RegexReplacement
- {
- public:
- RegexReplacement(const char* s)
- : number(-1)
- , value(s)
- {
- }
- RegexReplacement(const std::string& s)
- : number(-1)
- , value(s)
- {
- }
- RegexReplacement(int n)
- : number(n)
- , value()
- {
- }
- RegexReplacement() {}
- int number;
- std::string value;
- };
};
#endif
diff --git a/Source/cmStringReplaceHelper.cxx b/Source/cmStringReplaceHelper.cxx
new file mode 100644
index 0000000..69b7ced
--- /dev/null
+++ b/Source/cmStringReplaceHelper.cxx
@@ -0,0 +1,117 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmStringReplaceHelper.h"
+
+#include "cmMakefile.h"
+#include <sstream>
+
+cmStringReplaceHelper::cmStringReplaceHelper(const std::string& regex,
+ const std::string& replace_expr,
+ cmMakefile* makefile)
+ : RegExString(regex)
+ , RegularExpression(regex)
+ , ReplaceExpression(replace_expr)
+ , Makefile(makefile)
+{
+ this->ParseReplaceExpression();
+}
+
+bool cmStringReplaceHelper::Replace(const std::string& input,
+ std::string& output)
+{
+ output.clear();
+
+ // Scan through the input for all matches.
+ std::string::size_type base = 0;
+ while (this->RegularExpression.find(input.c_str() + base)) {
+ if (this->Makefile != nullptr) {
+ this->Makefile->ClearMatches();
+ this->Makefile->StoreMatches(this->RegularExpression);
+ }
+ auto l2 = this->RegularExpression.start();
+ auto r = this->RegularExpression.end();
+
+ // Concatenate the part of the input that was not matched.
+ output += input.substr(base, l2);
+
+ // Make sure the match had some text.
+ if (r - l2 == 0) {
+ std::ostringstream error;
+ error << "regex \"" << this->RegExString << "\" matched an empty string";
+ this->ErrorString = error.str();
+ return false;
+ }
+
+ // Concatenate the replacement for the match.
+ for (const auto& replacement : this->Replacements) {
+ if (replacement.Number < 0) {
+ // This is just a plain-text part of the replacement.
+ output += replacement.Value;
+ } else {
+ // Replace with part of the match.
+ auto n = replacement.Number;
+ auto start = this->RegularExpression.start(n);
+ auto end = this->RegularExpression.end(n);
+ auto len = input.length() - base;
+ if ((start != std::string::npos) && (end != std::string::npos) &&
+ (start <= len) && (end <= len)) {
+ output += input.substr(base + start, end - start);
+ } else {
+ std::ostringstream error;
+ error << "replace expression \"" << this->ReplaceExpression
+ << "\" contains an out-of-range escape for regex \""
+ << this->RegExString << "\"";
+ this->ErrorString = error.str();
+ return false;
+ }
+ }
+ }
+
+ // Move past the match.
+ base += r;
+ }
+
+ // Concatenate the text after the last match.
+ output += input.substr(base, input.length() - base);
+
+ return true;
+}
+
+void cmStringReplaceHelper::ParseReplaceExpression()
+{
+ std::string::size_type l = 0;
+ while (l < this->ReplaceExpression.length()) {
+ auto r = this->ReplaceExpression.find('\\', l);
+ if (r == std::string::npos) {
+ r = this->ReplaceExpression.length();
+ this->Replacements.push_back(this->ReplaceExpression.substr(l, r - l));
+ } else {
+ if (r - l > 0) {
+ this->Replacements.push_back(this->ReplaceExpression.substr(l, r - l));
+ }
+ if (r == (this->ReplaceExpression.length() - 1)) {
+ this->ValidReplaceExpression = false;
+ this->ErrorString = "replace-expression ends in a backslash";
+ return;
+ }
+ if ((this->ReplaceExpression[r + 1] >= '0') &&
+ (this->ReplaceExpression[r + 1] <= '9')) {
+ this->Replacements.push_back(this->ReplaceExpression[r + 1] - '0');
+ } else if (this->ReplaceExpression[r + 1] == 'n') {
+ this->Replacements.push_back("\n");
+ } else if (this->ReplaceExpression[r + 1] == '\\') {
+ this->Replacements.push_back("\\");
+ } else {
+ this->ValidReplaceExpression = false;
+ std::ostringstream error;
+ error << "Unknown escape \"" << this->ReplaceExpression.substr(r, 2)
+ << "\" in replace-expression";
+ this->ErrorString = error.str();
+ return;
+ }
+ r += 2;
+ }
+ l = r;
+ }
+}
diff --git a/Source/cmStringReplaceHelper.h b/Source/cmStringReplaceHelper.h
new file mode 100644
index 0000000..938325a
--- /dev/null
+++ b/Source/cmStringReplaceHelper.h
@@ -0,0 +1,69 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmStringReplaceHelper_h
+#define cmStringReplaceHelper_h
+
+#include "cmsys/RegularExpression.hxx"
+
+#include <string>
+#include <vector>
+
+class cmMakefile;
+
+class cmStringReplaceHelper
+{
+public:
+ cmStringReplaceHelper(const std::string& regex,
+ const std::string& replace_expr,
+ cmMakefile* makefile = nullptr);
+
+ bool IsRegularExpressionValid() const
+ {
+ return this->RegularExpression.is_valid();
+ }
+ bool IsReplaceExpressionValid() const
+ {
+ return this->ValidReplaceExpression;
+ }
+
+ bool Replace(const std::string& input, std::string& output);
+
+ const std::string& GetError() { return this->ErrorString; }
+
+private:
+ class RegexReplacement
+ {
+ public:
+ RegexReplacement(const char* s)
+ : Number(-1)
+ , Value(s)
+ {
+ }
+ RegexReplacement(const std::string& s)
+ : Number(-1)
+ , Value(s)
+ {
+ }
+ RegexReplacement(int n)
+ : Number(n)
+ , Value()
+ {
+ }
+ RegexReplacement() {}
+
+ int Number;
+ std::string Value;
+ };
+
+ void ParseReplaceExpression();
+
+ std::string ErrorString;
+ std::string RegExString;
+ cmsys::RegularExpression RegularExpression;
+ bool ValidReplaceExpression = true;
+ std::string ReplaceExpression;
+ std::vector<RegexReplacement> Replacements;
+ cmMakefile* Makefile = nullptr;
+};
+
+#endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 13af167..19cb50b 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1894,7 +1894,14 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
this->GeneratorTarget->GetAllConfigSources();
+ cmSourceFile const* srcCMakeLists =
+ this->LocalGenerator->CreateVCProjBuildRule();
+
for (cmGeneratorTarget::AllConfigSource const& si : sources) {
+ if (si.Source == srcCMakeLists) {
+ // Skip explicit reference to CMakeLists.txt source.
+ continue;
+ }
const char* tool = nullptr;
switch (si.Kind) {
case cmGeneratorTarget::SourceKindAppManifest:
@@ -2690,6 +2697,20 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
cudaOptions.AppendFlagString("AdditionalOptions", "-x cu");
}
+ // Specify the compiler program database file if configured.
+ std::string pdb = this->GeneratorTarget->GetCompilePDBPath(configName);
+ if (!pdb.empty()) {
+ // CUDA does not have a field for this and does not honor the
+ // ProgramDataBaseFileName field in ClCompile. Work around this
+ // limitation by creating the directory and passing the flag ourselves.
+ std::string const pdbDir = cmSystemTools::GetFilenamePath(pdb);
+ cmSystemTools::MakeDirectory(pdbDir);
+ pdb = this->ConvertPath(pdb, true);
+ ConvertToWindowsSlash(pdb);
+ std::string const clFd = "-Xcompiler=\"-Fd\\\"" + pdb + "\\\"\"";
+ cudaOptions.AppendFlagString("AdditionalOptions", clFd);
+ }
+
// CUDA automatically passes the proper '--machine' flag to nvcc
// for the current architecture, but does not reflect this default
// in the user-visible IDE settings. Set it explicitly.
@@ -3646,10 +3667,8 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
"{" + this->GlobalGenerator->GetGUID(name) + "}", 3);
this->WriteElem("Name", name, 3);
this->WriteDotNetReferenceCustomTags(name);
- if (csproj == this->ProjectType) {
- if (!this->GlobalGenerator->TargetCanBeReferenced(dt)) {
- this->WriteElem("ReferenceOutputAssembly", "false", 3);
- }
+ if (!this->GlobalGenerator->TargetCanBeReferenced(dt)) {
+ this->WriteElem("ReferenceOutputAssembly", "false", 3);
}
this->WriteString("</ProjectReference>\n", 2);
}
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 2b9d7b1..7426816 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -94,7 +94,6 @@ typedef int siginfo_t;
#endif
#ifdef __APPLE__
-#include <fenv.h>
#include <mach/host_info.h>
#include <mach/mach.h>
#include <mach/mach_types.h>
@@ -114,7 +113,6 @@ typedef int siginfo_t;
#endif
#if defined(__linux) || defined(__sun) || defined(_SCO_DS)
-#include <fenv.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
diff --git a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
index 65487bb..9157c76 100644
--- a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
+++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
@@ -349,6 +349,12 @@ set(aix_xlf90_64_libs "xlf90;xlopt;xlf;xlomp_ser;m;c")
set(aix_xlf90_64_dirs "/usr/lpp/xlf/lib")
list(APPEND platforms aix_xlf90_64)
+# g++ dummy.c -v
+set(aix_g++_text " /prefix/libexec/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/collect2 -bpT:0x10000000 -bpD:0x20000000 -btextro /lib/crt0.o /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/crtcxa.o /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/crtdbase.o -L/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0 -L/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/../../.. /tmp//ccKROJ1f.o -lstdc++ -lm -lgcc_s /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a -lc -lgcc_s /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a")
+set(aix_g++_libs "stdc++;m;gcc_s;/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a;c;gcc_s;/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a")
+set(aix_g++_dirs "/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0;/prefix/lib")
+list(APPEND platforms aix_g++)
+
#-----------------------------------------------------------------------------
# HP
diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt
index 565baca..59f3e84 100644
--- a/Tests/CudaOnly/CMakeLists.txt
+++ b/Tests/CudaOnly/CMakeLists.txt
@@ -6,3 +6,7 @@ ADD_TEST_MACRO(CudaOnly.LinkSystemDeviceLibraries CudaOnlyLinkSystemDeviceLibrar
ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols)
ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation)
ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs)
+
+if(MSVC)
+ ADD_TEST_MACRO(CudaOnly.PDB CudaOnlyPDB)
+endif()
diff --git a/Tests/CudaOnly/PDB/CMakeLists.txt b/Tests/CudaOnly/PDB/CMakeLists.txt
new file mode 100644
index 0000000..34e1e5c
--- /dev/null
+++ b/Tests/CudaOnly/PDB/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.11)
+project (CudaOnlyPDB CUDA)
+
+add_executable(CudaOnlyPDB main.cu)
+set_target_properties(CudaOnlyPDB PROPERTIES
+ PDB_NAME LinkPDBName
+ PDB_OUTPUT_DIRECTORY LinkPDBDir
+ COMPILE_PDB_NAME CompPDBName
+ COMPILE_PDB_OUTPUT_DIRECTORY CompPDBDir
+ )
+
+set(pdbs
+ ${CMAKE_CURRENT_BINARY_DIR}/CompPDBDir/${CMAKE_CFG_INTDIR}/CompPDBName.pdb
+ ${CMAKE_CURRENT_BINARY_DIR}/LinkPDBDir/${CMAKE_CFG_INTDIR}/LinkPDBName.pdb
+ )
+add_custom_command(TARGET CudaOnlyPDB POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -Dconfig=$<CONFIG> "-Dpdbs=${pdbs}"
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check_pdbs.cmake
+ )
diff --git a/Tests/CudaOnly/PDB/check_pdbs.cmake b/Tests/CudaOnly/PDB/check_pdbs.cmake
new file mode 100644
index 0000000..5e01ca7
--- /dev/null
+++ b/Tests/CudaOnly/PDB/check_pdbs.cmake
@@ -0,0 +1,10 @@
+if(NOT "${config}" MATCHES "[Dd][Ee][Bb]")
+ return()
+endif()
+foreach(pdb ${pdbs})
+ if(EXISTS "${pdb}")
+ message(STATUS "PDB Exists: ${pdb}")
+ else()
+ message(SEND_ERROR "PDB MISSING:\n ${pdb}")
+ endif()
+endforeach()
diff --git a/Tests/CudaOnly/PDB/main.cu b/Tests/CudaOnly/PDB/main.cu
new file mode 100644
index 0000000..f8b643a
--- /dev/null
+++ b/Tests/CudaOnly/PDB/main.cu
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/Module/ExternalData/Data5/CMakeLists.txt b/Tests/Module/ExternalData/Data5/CMakeLists.txt
index 13c7fab..ea67f05 100644
--- a/Tests/Module/ExternalData/Data5/CMakeLists.txt
+++ b/Tests/Module/ExternalData/Data5/CMakeLists.txt
@@ -2,21 +2,21 @@
ExternalData_Add_Test(Data5.A
NAME Data5Check.A
COMMAND ${CMAKE_COMMAND}
- -D Data5=DATA{../Data.dat}
+ -D Data5=DATA{Data5.dat}
-P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
)
ExternalData_Add_Target(Data5.A)
ExternalData_Add_Test(Data5.B
NAME Data5Check.B
COMMAND ${CMAKE_COMMAND}
- -D Data5=DATA{../Data.dat}
+ -D Data5=DATA{Data5.dat}
-P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
)
ExternalData_Add_Target(Data5.B)
ExternalData_Add_Test(Data5.C
NAME Data5Check.C
COMMAND ${CMAKE_COMMAND}
- -D Data5=DATA{../Data.dat}
+ -D Data5=DATA{Data5.dat}
-P ${CMAKE_CURRENT_SOURCE_DIR}/Data5Check.cmake
)
ExternalData_Add_Target(Data5.C)
diff --git a/Tests/Module/ExternalData/Data5/Data5.dat.md5 b/Tests/Module/ExternalData/Data5/Data5.dat.md5
new file mode 100644
index 0000000..70e39bd
--- /dev/null
+++ b/Tests/Module/ExternalData/Data5/Data5.dat.md5
@@ -0,0 +1 @@
+8c018830e3efa5caf3c7415028335a57
diff --git a/Tests/RunCMake/VS10Project/ExplicitCMakeLists-check.cmake b/Tests/RunCMake/VS10Project/ExplicitCMakeLists-check.cmake
new file mode 100644
index 0000000..b671e35
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/ExplicitCMakeLists-check.cmake
@@ -0,0 +1,25 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+ return()
+endif()
+
+set(foundCMakeLists 0)
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+ if(line MATCHES "<([A-Za-z0-9_]+) +Include=.*CMakeLists.txt")
+ set(rule "${CMAKE_MATCH_1}")
+ if(NOT rule STREQUAL "CustomBuild")
+ set(RunCMake_TEST_FAILED "CMakeLists.txt referenced as ${rule} instead of CustomBuild")
+ return()
+ endif()
+ if(foundCMakeLists)
+ set(RunCMake_TEST_FAILED "CMakeLists.txt referenced multiple times")
+ return()
+ endif()
+ set(foundCMakeLists 1)
+ endif()
+endforeach()
+if(NOT foundCMakeLists)
+ set(RunCMake_TEST_FAILED "CMakeLists.txt not referenced")
+endif()
diff --git a/Tests/RunCMake/VS10Project/ExplicitCMakeLists.cmake b/Tests/RunCMake/VS10Project/ExplicitCMakeLists.cmake
new file mode 100644
index 0000000..c9e4456
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/ExplicitCMakeLists.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_CONFIGURATION_TYPES Debug)
+enable_language(CXX)
+add_executable(foo foo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index afe9d6d..e42e662 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -1,4 +1,7 @@
include(RunCMake)
+
+run_cmake(ExplicitCMakeLists)
+
run_cmake(VsConfigurationType)
run_cmake(VsTargetsFileReferences)
run_cmake(VsCustomProps)
diff --git a/Tests/RunCMake/XcodeProject/ExplicitCMakeLists-check.cmake b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists-check.cmake
new file mode 100644
index 0000000..3073e0b
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists-check.cmake
@@ -0,0 +1,20 @@
+set(xcProjectFile "${RunCMake_TEST_BINARY_DIR}/ExplicitCMakeLists.xcodeproj/project.pbxproj")
+if(NOT EXISTS "${xcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${xcProjectFile} does not exist.")
+ return()
+endif()
+
+set(foundCMakeLists 0)
+file(STRINGS "${xcProjectFile}" lines)
+foreach(line IN LISTS lines)
+ if(line MATCHES "PBXBuildFile.*fileRef.*CMakeLists.txt")
+ if(foundCMakeLists)
+ set(RunCMake_TEST_FAILED "CMakeLists.txt referenced multiple times")
+ return()
+ endif()
+ set(foundCMakeLists 1)
+ endif()
+endforeach()
+if(NOT foundCMakeLists)
+ set(RunCMake_TEST_FAILED "CMakeLists.txt not referenced")
+endif()
diff --git a/Tests/RunCMake/XcodeProject/ExplicitCMakeLists.cmake b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists.cmake
new file mode 100644
index 0000000..678b0ea
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/ExplicitCMakeLists.cmake
@@ -0,0 +1,2 @@
+enable_language(CXX)
+add_executable(foo foo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index 5eff6b9..1150666 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -4,6 +4,8 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 9)
set(IOS_DEPLOYMENT_TARGET "-DCMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET=10")
endif()
+run_cmake(ExplicitCMakeLists)
+
run_cmake(XcodeFileType)
run_cmake(XcodeAttributeLocation)
run_cmake(XcodeAttributeGenex)
diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake
index 3913783..bdc23a4 100644
--- a/Tests/RunCMake/list/RunCMakeTest.cmake
+++ b/Tests/RunCMake/list/RunCMakeTest.cmake
@@ -43,3 +43,44 @@ run_cmake(SUBLIST-NoArguments)
run_cmake(SUBLIST-NoVariable)
run_cmake(SUBLIST-InvalidLength)
run_cmake(SUBLIST)
+
+run_cmake(TRANSFORM-NoAction)
+run_cmake(TRANSFORM-InvalidAction)
+# 'action' oriented tests
+run_cmake(TRANSFORM-TOUPPER-TooManyArguments)
+run_cmake(TRANSFORM-TOLOWER-TooManyArguments)
+run_cmake(TRANSFORM-STRIP-TooManyArguments)
+run_cmake(TRANSFORM-GENEX_STRIP-TooManyArguments)
+run_cmake(TRANSFORM-APPEND-NoArguments)
+run_cmake(TRANSFORM-APPEND-TooManyArguments)
+run_cmake(TRANSFORM-PREPEND-NoArguments)
+run_cmake(TRANSFORM-PREPEND-TooManyArguments)
+run_cmake(TRANSFORM-REPLACE-NoArguments)
+run_cmake(TRANSFORM-REPLACE-NoEnoughArguments)
+run_cmake(TRANSFORM-REPLACE-TooManyArguments)
+run_cmake(TRANSFORM-REPLACE-InvalidRegex)
+run_cmake(TRANSFORM-REPLACE-InvalidReplace1)
+run_cmake(TRANSFORM-REPLACE-InvalidReplace2)
+# 'selector' oriented tests
+run_cmake(TRANSFORM-Selector-REGEX-NoArguments)
+run_cmake(TRANSFORM-Selector-REGEX-TooManyArguments)
+run_cmake(TRANSFORM-Selector-REGEX-InvalidRegex)
+run_cmake(TRANSFORM-Selector-AT-NoArguments)
+run_cmake(TRANSFORM-Selector-AT-BadArgument)
+run_cmake(TRANSFORM-Selector-AT-InvalidIndex)
+run_cmake(TRANSFORM-Selector-FOR-NoArguments)
+run_cmake(TRANSFORM-Selector-FOR-NoEnoughArguments)
+run_cmake(TRANSFORM-Selector-FOR-TooManyArguments)
+run_cmake(TRANSFORM-Selector-FOR-BadArgument)
+run_cmake(TRANSFORM-Selector-FOR-InvalidIndex)
+# 'output' oriented tests
+run_cmake(TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments)
+run_cmake(TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments)
+# Successful tests
+run_cmake(TRANSFORM-TOUPPER)
+run_cmake(TRANSFORM-TOLOWER)
+run_cmake(TRANSFORM-STRIP)
+run_cmake(TRANSFORM-GENEX_STRIP)
+run_cmake(TRANSFORM-APPEND)
+run_cmake(TRANSFORM-PREPEND)
+run_cmake(TRANSFORM-REPLACE)
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-stderr.txt
new file mode 100644
index 0000000..028f8d5
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-APPEND-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, action APPEND expects 1 argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments.cmake
new file mode 100644
index 0000000..f161187
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist APPEND)
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..aeb646d
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-APPEND-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments.cmake
new file mode 100644
index 0000000..8430a4c
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist APPEND delta one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-APPEND.cmake b/Tests/RunCMake/list/TRANSFORM-APPEND.cmake
new file mode 100644
index 0000000..9639088
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-APPEND.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist APPEND "_A" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_A;bravo_A;charlie_A;delta_A")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha_A;bravo_A;charlie_A;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie;delta_A")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie_A;delta")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie_A;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie_A;delta")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie_A;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie_A;delta_A")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie_A;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_A;bravo;charlie_A;delta")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha_A;bravo;charlie_A;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo_A;charlie;delta_A")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${output}\", expected is \"alpha;bravo_A;charlie;delta_A\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist APPEND "_A" REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;bravo_A;charlie;delta_A")
+ message (FATAL_ERROR "TRANSFORM(APPEND) is \"${mylist}\", expected is \"alpha;bravo_A;charlie;delta_A\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..6071a00
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-GENEX_STRIP-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments.cmake
new file mode 100644
index 0000000..257d7fe
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist GENEX_STRIP one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP.cmake b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP.cmake
new file mode 100644
index 0000000..8045eef
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-GENEX_STRIP.cmake
@@ -0,0 +1,49 @@
+set(mylist one "$<1:two\;three>" four "$<TARGET_OBJECTS:some_target>")
+
+list(TRANSFORM mylist GENEX_STRIP OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one;;four;")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one;;four;\"")
+endif()
+
+set(mylist "one $<CONFIG>" "$<1:two\;three>-$<PLATFORM_ID>" "$<ANGLE-R>four" "$<TARGET_OBJECTS:some_target>")
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;$<ANGLE-R>four;")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;$<ANGLE-R>four;\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one $<CONFIG>;-;four;")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one $<CONFIG>;-;four;\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one ;$<1:two;three>-$<PLATFORM_ID>;four;$<TARGET_OBJECTS:some_target>")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one ;$<1:two;three>-$<PLATFORM_ID>;four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP REGEX "(D|G)>" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${output}\", expected is \"one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist GENEX_STRIP REGEX "(D|G)>")
+if (NOT mylist STREQUAL "one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>")
+ message (FATAL_ERROR "TRANSFORM(GENEX_STRIP) is \"${mylist}\", expected is \"one ;-;$<ANGLE-R>four;$<TARGET_OBJECTS:some_target>\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-InvalidAction-result.txt b/Tests/RunCMake/list/TRANSFORM-InvalidAction-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-InvalidAction-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-InvalidAction-stderr.txt b/Tests/RunCMake/list/TRANSFORM-InvalidAction-stderr.txt
new file mode 100644
index 0000000..0fa45c9
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-InvalidAction-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-InvalidAction.cmake:2 \(list\):
+ list sub-command TRANSFORM, BAD_ACTION invalid action.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-InvalidAction.cmake b/Tests/RunCMake/list/TRANSFORM-InvalidAction.cmake
new file mode 100644
index 0000000..fb2cc30
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-InvalidAction.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist BAD_ACTION)
diff --git a/Tests/RunCMake/list/TRANSFORM-NoAction-result.txt b/Tests/RunCMake/list/TRANSFORM-NoAction-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-NoAction-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-NoAction-stderr.txt b/Tests/RunCMake/list/TRANSFORM-NoAction-stderr.txt
new file mode 100644
index 0000000..68e9e9d
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-NoAction-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-NoAction.cmake:2 \(list\):
+ list sub-command TRANSFORM requires an action to be specified.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-NoAction.cmake b/Tests/RunCMake/list/TRANSFORM-NoAction.cmake
new file mode 100644
index 0000000..3690f14
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-NoAction.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist)
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-stderr.txt
new file mode 100644
index 0000000..b4f4e06
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, OUTPUT_VARIABLE expects variable name argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake
new file mode 100644
index 0000000..acc4094
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER OUTPUT_VARIABLE)
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..9a58346
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake
new file mode 100644
index 0000000..c4da864
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Output-OUTPUT_VARIABLE-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER OUTPUT_VARIABLE output one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-stderr.txt
new file mode 100644
index 0000000..413ce30
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-PREPEND-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, action PREPEND expects 1 argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments.cmake
new file mode 100644
index 0000000..a8e4530
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist PREPEND)
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..6ff1b89
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-PREPEND-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments.cmake
new file mode 100644
index 0000000..1f904ad
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist PREPEND delta one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-PREPEND.cmake b/Tests/RunCMake/list/TRANSFORM-PREPEND.cmake
new file mode 100644
index 0000000..55b8867
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-PREPEND.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist PREPEND "P_" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "P_alpha;P_bravo;P_charlie;P_delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"P_alpha;P_bravo;P_charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;charlie;P_delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;P_charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;P_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;P_charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;P_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;P_charlie;P_delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;P_charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "P_alpha;bravo;P_charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"P_alpha;bravo;P_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;P_bravo;charlie;P_delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${output}\", expected is \"alpha;P_bravo;charlie;P_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist PREPEND "P_" REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;P_bravo;charlie;P_delta")
+ message (FATAL_ERROR "TRANSFORM(PREPEND) is \"${mylist}\", expected is \"alpha;P_bravo;charlie;P_delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-stderr.txt
new file mode 100644
index 0000000..334c96e
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-REPLACE-InvalidRegex.cmake:2 \(list\):
+ list sub-command TRANSFORM, action REPLACE: Failed to compile regex
+ "\^\(alpha\$".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex.cmake
new file mode 100644
index 0000000..f440c35
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidRegex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^(alpha$" "zulu")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-stderr.txt
new file mode 100644
index 0000000..7671c83
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-REPLACE-InvalidReplace1.cmake:2 \(list\):
+ list sub-command TRANSFORM, action REPLACE: replace-expression ends in a
+ backslash.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1.cmake
new file mode 100644
index 0000000..35387f0
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace1.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$" "zulu\\")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-stderr.txt
new file mode 100644
index 0000000..e0aabd7
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-REPLACE-InvalidReplace2.cmake:2 \(list\):
+ list sub-command TRANSFORM, action REPLACE: Unknown escape "\\z" in
+ replace-expression.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2.cmake
new file mode 100644
index 0000000..2f1f2c7
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-InvalidReplace2.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$" "\\zulu")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-stderr.txt
new file mode 100644
index 0000000..3d39e72
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-REPLACE-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, action REPLACE expects 2 argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments.cmake
new file mode 100644
index 0000000..b7b1e9d
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE)
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-stderr.txt
new file mode 100644
index 0000000..dc80f33
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-REPLACE-NoEnoughArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, action REPLACE expects 2 argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments.cmake
new file mode 100644
index 0000000..1d418c0
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-NoEnoughArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..3d4e15a
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-REPLACE-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments.cmake
new file mode 100644
index 0000000..baed0af
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist REPLACE "^alpha$" "zulu" "one_too_many")
diff --git a/Tests/RunCMake/list/TRANSFORM-REPLACE.cmake b/Tests/RunCMake/list/TRANSFORM-REPLACE.cmake
new file mode 100644
index 0000000..256b1b8
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-REPLACE.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_alpha;bravo;charlie;delta_delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha_alpha;bravo;charlie;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta_delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+e)$" "\\1_\\1" AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie_charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+e)$" "\\1_\\1" FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie_charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie_charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta_delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie_A;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha_alpha;bravo;charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha_alpha;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta_delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${output}\", expected is \"alpha;bravo;charlie;delta_delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist REPLACE "(.+a)$" "\\1_\\1" REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;bravo;charlie;delta_delta")
+ message (FATAL_ERROR "TRANSFORM(REPLACE) is \"${mylist}\", expected is \"alpha;bravo;charlie;delta_delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..534f940
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-STRIP-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments.cmake
new file mode 100644
index 0000000..c6a8213
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist STRIP one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-STRIP.cmake b/Tests/RunCMake/list/TRANSFORM-STRIP.cmake
new file mode 100644
index 0000000..366c63a
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-STRIP.cmake
@@ -0,0 +1,49 @@
+set(mylist " alpha" "bravo " " charlie " delta)
+
+list(TRANSFORM mylist STRIP OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \"alpha;bravo;charlie;delta\"")
+endif()
+
+set(mylist " alpha" "bravo " " charlie " "delta ")
+unset(output)
+list(TRANSFORM mylist STRIP AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo; charlie ;delta")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo; charlie ;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo;charlie;delta ")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo;charlie;delta \"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo;charlie;delta ")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo;charlie;delta \"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo;charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo ;charlie;delta ")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \"alpha;bravo ;charlie;delta \"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL " alpha;bravo; charlie ;delta")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${output}\", expected is \" alpha;bravo; charlie ;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist STRIP REGEX "(r|t)a")
+if (NOT mylist STREQUAL " alpha;bravo; charlie ;delta")
+ message (FATAL_ERROR "TRANSFORM(STRIP) is \"${mylist}\", expected is \" alpha;bravo; charlie ;delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-stderr.txt
new file mode 100644
index 0000000..cec520f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-AT-BadArgument.cmake:2 \(list\):
+ list sub-command TRANSFORM, '1x 2': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument.cmake
new file mode 100644
index 0000000..f61b86b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-BadArgument.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER AT 0 1x 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-stderr.txt
new file mode 100644
index 0000000..7e2898b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-AT-InvalidIndex.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector AT, index: 3 out of range \(-3, 2\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex.cmake
new file mode 100644
index 0000000..d33586c
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-InvalidIndex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER AT 0 3 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-stderr.txt
new file mode 100644
index 0000000..eaf5281
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-AT-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector AT expects at least one numeric value.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments.cmake
new file mode 100644
index 0000000..052b79b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-AT-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER AT)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-stderr.txt
new file mode 100644
index 0000000..a0f701f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-Selector-FOR-BadArgument.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector FOR expects, at least, two numeric
+ values.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument.cmake
new file mode 100644
index 0000000..55527be
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-BadArgument.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 0 1x 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-stderr.txt
new file mode 100644
index 0000000..c50cc0a
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-InvalidIndex.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector FOR, index: 6 out of range \(-3, 2\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex.cmake
new file mode 100644
index 0000000..6e2374e
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-InvalidIndex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 0 6 2)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-stderr.txt
new file mode 100644
index 0000000..5881b67
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector FOR expects, at least, two arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments.cmake
new file mode 100644
index 0000000..4902cc9
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-stderr.txt
new file mode 100644
index 0000000..b1081d9
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-NoEnoughArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector FOR expects, at least, two arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments.cmake
new file mode 100644
index 0000000..81417de
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-NoEnoughArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 1)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..2221cb3
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-FOR-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, '3': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments.cmake
new file mode 100644
index 0000000..80917d6
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-FOR-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER FOR 0 1 2 3)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-stderr.txt
new file mode 100644
index 0000000..31ba939
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-Selector-REGEX-InvalidRegex.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector REGEX failed to compile regex
+ "\^\(alpha\$".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex.cmake
new file mode 100644
index 0000000..56e202b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-InvalidRegex.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER REGEX "^(alpha$")
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-stderr.txt
new file mode 100644
index 0000000..2784785
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at TRANSFORM-Selector-REGEX-NoArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, selector REGEX expects 'regular expression'
+ argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments.cmake
new file mode 100644
index 0000000..f199d0e
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-NoArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER REGEX)
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..db5b1ff
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-Selector-REGEX-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments.cmake
new file mode 100644
index 0000000..4aa1619
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-Selector-REGEX-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER REGEX "^alpha$" "one_too_many")
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..90248ae
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-TOLOWER-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments.cmake
new file mode 100644
index 0000000..1758e19
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOLOWER one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-TOLOWER.cmake b/Tests/RunCMake/list/TRANSFORM-TOLOWER.cmake
new file mode 100644
index 0000000..a2d7348
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOLOWER.cmake
@@ -0,0 +1,48 @@
+set(mylist ALPHA BRAVO CHARLIE DELTA)
+
+list(TRANSFORM mylist TOLOWER OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;bravo;charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"alpha;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;charlie;delta")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;charlie;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER REGEX "(R|T)A" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${output}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOLOWER REGEX "(R|T)A")
+if (NOT mylist STREQUAL "ALPHA;bravo;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOLOWER) is \"${mylist}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-result.txt b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-stderr.txt b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-stderr.txt
new file mode 100644
index 0000000..9da241b
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at TRANSFORM-TOUPPER-TooManyArguments.cmake:2 \(list\):
+ list sub-command TRANSFORM, 'one_too_many': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments.cmake b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments.cmake
new file mode 100644
index 0000000..58d6a8c
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER-TooManyArguments.cmake
@@ -0,0 +1,2 @@
+set(mylist alpha bravo charlie)
+list(TRANSFORM mylist TOUPPER one_too_many)
diff --git a/Tests/RunCMake/list/TRANSFORM-TOUPPER.cmake b/Tests/RunCMake/list/TRANSFORM-TOUPPER.cmake
new file mode 100644
index 0000000..5b1fcb6
--- /dev/null
+++ b/Tests/RunCMake/list/TRANSFORM-TOUPPER.cmake
@@ -0,0 +1,48 @@
+set(mylist alpha bravo charlie delta)
+
+list(TRANSFORM mylist TOUPPER OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;BRAVO;CHARLIE;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"ALPHA;BRAVO;CHARLIE;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER AT 1 3 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER AT 1 -2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER FOR 1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER FOR 1 -1 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;CHARLIE;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;CHARLIE;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER FOR 0 -1 2 OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "ALPHA;bravo;CHARLIE;delta")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"ALPHA;bravo;CHARLIE;delta\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER REGEX "(r|t)a" OUTPUT_VARIABLE output)
+if (NOT output STREQUAL "alpha;BRAVO;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${output}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
+
+unset(output)
+list(TRANSFORM mylist TOUPPER REGEX "(r|t)a")
+if (NOT mylist STREQUAL "alpha;BRAVO;charlie;DELTA")
+ message (FATAL_ERROR "TRANSFORM(TOUPPER) is \"${mylist}\", expected is \"alpha;BRAVO;charlie;DELTA\"")
+endif()
diff --git a/bootstrap b/bootstrap
index 3bcab60..6604f54 100755
--- a/bootstrap
+++ b/bootstrap
@@ -400,6 +400,7 @@ CMAKE_CXX_SOURCES="\
cmState \
cmStateDirectory \
cmStateSnapshot \
+ cmStringReplaceHelper \
cmStringCommand \
cmSubdirCommand \
cmSystemTools \
@@ -570,6 +571,8 @@ Configuration:
--no-system-libarchive use cmake-provided libarchive library (default)
--system-librhash use system-installed librhash library
--no-system-librhash use cmake-provided librhash library (default)
+ --system-libuv use system-installed libuv library
+ --no-system-libuv use cmake-provided libuv library (default)
--qt-gui build the Qt-based GUI (requires Qt >= 4.2)
--no-qt-gui do not build the Qt-based GUI (default)
@@ -804,10 +807,10 @@ while test $# != 0; do
--init=*) cmake_init_file=`cmake_arg "$1"` ;;
--system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=1" ;;
--no-system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=0" ;;
- --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma)
+ --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma|--system-libuv)
lib=`cmake_arg "$1" "--system-"`
cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=1" ;;
- --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma)
+ --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma|--no-system-libuv)
lib=`cmake_arg "$1" "--no-system-"`
cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=0" ;;
--qt-gui) cmake_bootstrap_qt_gui="1" ;;