summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Auxiliary/vim/syntax/cmake.vim2
-rw-r--r--CMakeLists.txt2
-rw-r--r--CompileFlags.cmake2
-rw-r--r--Help/command/file.rst3
-rw-r--r--Help/command/find_package.rst18
-rw-r--r--Help/command/include.rst6
-rw-r--r--Help/manual/cmake-variables.7.rst6
-rw-r--r--Help/release/dev/ExternalProject-http-credentials.rst5
-rw-r--r--Help/release/dev/file-curl-httpheader.rst5
-rw-r--r--Help/release/dev/find_package-dir-sort.rst13
-rw-r--r--Help/variable/CMAKE_COMPILER_IS_GNUCC.rst5
-rw-r--r--Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst5
-rw-r--r--Help/variable/CMAKE_COMPILER_IS_GNUG77.rst5
-rw-r--r--Help/variable/CMAKE_COMPILER_IS_GNULANG.rst15
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst16
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst36
-rw-r--r--Modules/ExternalProject-download.cmake.in1
-rw-r--r--Modules/ExternalProject.cmake17
-rw-r--r--Modules/FeatureSummary.cmake677
-rw-r--r--Modules/FindMatlab.cmake51
-rw-r--r--Modules/FindPythonInterp.cmake2
-rw-r--r--Modules/FindPythonLibs.cmake2
-rw-r--r--Modules/GenerateExportHeader.cmake2
-rw-r--r--Modules/MatlabTestsRedirect.cmake41
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CursesDialog/cmCursesStandardIncludes.h4
-rw-r--r--Source/CursesDialog/form/form.h4
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx5
-rw-r--r--Source/cmFileCommand.cxx36
-rw-r--r--Source/cmFindPackageCommand.cxx118
-rw-r--r--Source/cmFindPackageCommand.h26
-rw-r--r--Source/cmGlobalGenerator.cxx88
-rw-r--r--Source/cmInstallTargetsCommand.cxx17
-rw-r--r--Source/cmMakefile.cxx21
-rw-r--r--Source/cmSystemTools.cxx77
-rw-r--r--Source/cmSystemTools.h10
-rw-r--r--Source/cmTarget.cxx35
-rw-r--r--Source/cmTarget.h26
-rw-r--r--Source/cmake.cxx2
-rw-r--r--Source/cmake.h2
-rw-r--r--Source/kwsys/CMakeLists.txt20
-rw-r--r--Source/kwsys/ConsoleBuf.hxx.in348
-rw-r--r--Source/kwsys/SystemTools.cxx70
-rw-r--r--Source/kwsys/SystemTools.hxx.in9
-rw-r--r--Source/kwsys/testConsoleBuf.cxx609
-rw-r--r--Source/kwsys/testConsoleBuf.hxx24
-rw-r--r--Source/kwsys/testConsoleBufChild.cxx61
-rw-r--r--Source/kwsys/testSystemTools.cxx4
-rw-r--r--Tests/CMakeLib/CMakeLists.txt1
-rw-r--r--Tests/CMakeLib/testFindPackageCommand.cxx76
-rw-r--r--Tests/CMakeLib/testSystemTools.cxx72
-rw-r--r--Tests/FindPackageTest/CMakeLists.txt30
-rw-r--r--Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake2
-rw-r--r--Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake9
-rw-r--r--Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake2
-rw-r--r--Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake9
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt1
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt4
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake1
-rw-r--r--Tests/RunCMake/file/LOCK-lowercase.cmake11
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/file/UPLOAD-httpheader-not-set-result.txt1
-rw-r--r--Tests/RunCMake/file/UPLOAD-httpheader-not-set-stderr.txt4
-rw-r--r--Tests/RunCMake/file/UPLOAD-httpheader-not-set.cmake1
-rw-r--r--Tests/RunCMake/get_filename_component/KnownComponents.cmake12
-rw-r--r--Utilities/Doxygen/CMakeLists.txt2
-rw-r--r--Utilities/Sphinx/CMakeLists.txt2
67 files changed, 2249 insertions, 549 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 715676d..53681a9 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -44,7 +44,7 @@ syn keyword cmakeModule
\ contained
syn keyword cmakeKWExternalProject
- \ ALGO ALWAYS BINARY_DIR BUILD_ALWAYS BUILD_BYPRODUCTS BUILD_COMMAND BUILD_IN_SOURCE BYPRODUCTS CMAKE_ARGS CMAKE_CACHE_ARGS CMAKE_CACHE_DEFAULT_ARGS COMMAND COMMENT CONFIGURE_COMMAND CVS CVSROOT CVS_ CVS_MODULE CVS_REPOSITORY CVS_TAG DEPENDEES DEPENDERS DEPENDS DIRECTORY DOWNLOAD_COMMAND DOWNLOAD_DIR DOWNLOAD_NAME DOWNLOAD_NO_PROGRESS EP_BASE EP_INDEPENDENT_STEP_TARGETS EP_PREFIX EP_STEP_TARGETS EP_UPDATE_DISCONNECTED EXCLUDE_FROM_ALL EXCLUDE_FROM_MAIN FORCE GIT_REMOTE_NAME GIT_REPOSITORY GIT_SUBMODULES GIT_TAG HG_REPOSITORY HG_TAG INDEPENDENT INDEPENDENT_STEP_TARGETS INSTALL_COMMAND INSTALL_DIR JOB_POOLS LIST_SEPARATOR LOG LOG_BUILD LOG_CONFIGURE LOG_DOWNLOAD LOG_INSTALL LOG_TEST LOG_UPDATE NO_DEPENDS PATCH_COMMAND PREFIX PROPERTY SOURCE_DIR STAMP_DIR STEP_TARGETS SVN_ SVN_PASSWORD SVN_REPOSITORY SVN_REVISION SVN_TRUST_CERT SVN_USERNAME TEST_AFTER_INSTALL TEST_BEFORE_INSTALL TEST_COMMAND TEST_EXCLUDE_FROM_MAIN TIMEOUT TLS_CAINFO TLS_VERIFY TMP_DIR UPDATE_COMMAND UPDATE_DISCONNECTED URL URL_HASH USES_TERMINAL USES_TERMINAL_BUILD USES_TERMINAL_CONFIGURE USES_TERMINAL_DOWNLOAD USES_TERMINAL_INSTALL USES_TERMINAL_TEST USES_TERMINAL_UPDATE WORKING_DIRECTORY _COMMAND _DIR
+ \ ALGO ALWAYS BINARY_DIR BUILD_ALWAYS BUILD_BYPRODUCTS BUILD_COMMAND BUILD_IN_SOURCE BYPRODUCTS CMAKE_ARGS CMAKE_CACHE_ARGS CMAKE_CACHE_DEFAULT_ARGS COMMAND COMMENT CONFIGURE_COMMAND CVS CVSROOT CVS_ CVS_MODULE CVS_REPOSITORY CVS_TAG DEPENDEES DEPENDERS DEPENDS DIRECTORY DOWNLOAD_COMMAND DOWNLOAD_DIR DOWNLOAD_NAME DOWNLOAD_NO_PROGRESS EP_BASE EP_INDEPENDENT_STEP_TARGETS EP_PREFIX EP_STEP_TARGETS EP_UPDATE_DISCONNECTED EXCLUDE_FROM_ALL EXCLUDE_FROM_MAIN FORCE GIT_REMOTE_NAME GIT_REPOSITORY GIT_SUBMODULES GIT_TAG HG_REPOSITORY HG_TAG INDEPENDENT INDEPENDENT_STEP_TARGETS INSTALL_COMMAND INSTALL_DIR JOB_POOLS LIST_SEPARATOR LOG LOG_BUILD LOG_CONFIGURE LOG_DOWNLOAD LOG_INSTALL LOG_TEST LOG_UPDATE NO_DEPENDS PATCH_COMMAND PREFIX PROPERTY SOURCE_DIR STAMP_DIR STEP_TARGETS SVN_ SVN_PASSWORD SVN_REPOSITORY SVN_REVISION SVN_TRUST_CERT SVN_USERNAME TEST_AFTER_INSTALL TEST_BEFORE_INSTALL TEST_COMMAND TEST_EXCLUDE_FROM_MAIN TIMEOUT TLS_CAINFO TLS_VERIFY TMP_DIR UPDATE_COMMAND UPDATE_DISCONNECTED URL URL_HASH HTTP_USERNAME HTTP_PASSWORD USES_TERMINAL USES_TERMINAL_BUILD USES_TERMINAL_CONFIGURE USES_TERMINAL_DOWNLOAD USES_TERMINAL_INSTALL USES_TERMINAL_TEST USES_TERMINAL_UPDATE WORKING_DIRECTORY _COMMAND _DIR
\ contained
syn keyword cmakeKWadd_compile_options
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4ef2ca2..c8bd063 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
-cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
+cmake_minimum_required(VERSION 2.8.12.2 FATAL_ERROR)
if(POLICY CMP0025)
cmake_policy(SET CMP0025 NEW)
endif()
diff --git a/CompileFlags.cmake b/CompileFlags.cmake
index 3c053fa..535f68b 100644
--- a/CompileFlags.cmake
+++ b/CompileFlags.cmake
@@ -64,7 +64,7 @@ endif()
# Workaround for short jump tables on PA-RISC
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^parisc")
- if(CMAKE_COMPILER_IS_GNUC)
+ if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-calls")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
diff --git a/Help/command/file.rst b/Help/command/file.rst
index f8727f0..77e9f62 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -225,6 +225,9 @@ Options to both ``DOWNLOAD`` and ``UPLOAD`` are:
``USERPWD <username>:<password>``
Set username and password for operation.
+``HTTPHEADER <HTTP-header>``
+ HTTP header for operation. Suboption can be repeated several times.
+
Additional options to ``DOWNLOAD`` are:
``EXPECTED_HASH ALGO=<value>``
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index c44fe86..2cb1e5f 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -170,11 +170,21 @@ is acceptable the following variables are set:
``<package>_VERSION_COUNT``
number of version components, 0 to 4
-and the corresponding package configuration file is loaded. When
-multiple package configuration files are available whose version files
+and the corresponding package configuration file is loaded.
+When multiple package configuration files are available whose version files
claim compatibility with the version requested it is unspecified which
-one is chosen. No attempt is made to choose a highest or closest
-version number.
+one is chosen: unless the variable :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`
+is set no attempt is made to choose a highest or closest version number.
+
+To control the order in which ``find_package`` checks for compatibiliy use
+the two variables :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` and
+:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION`.
+For instance in order to select the highest version one can set::
+
+ SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
+ SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
+before calling ``find_package``.
Config mode provides an elaborate interface and search procedure.
Much of the interface is provided for completeness and for use
diff --git a/Help/command/include.rst b/Help/command/include.rst
index c391561..eeca4c6 100644
--- a/Help/command/include.rst
+++ b/Help/command/include.rst
@@ -15,10 +15,10 @@ is present, then no error is raised if the file does not exist. If
which has been included or NOTFOUND if it failed.
If a module is specified instead of a file, the file with name
-<modulename>.cmake is searched first in :variable:`CMAKE_MODULE_PATH`,
+``<modulename>.cmake`` is searched first in :variable:`CMAKE_MODULE_PATH`,
then in the CMake module directory. There is one exception to this: if
-the file which calls ``include()`` is located itself in the CMake module
-directory, then first the CMake module directory is searched and
+the file which calls ``include()`` is located itself in the CMake builtin
+module directory, then first the CMake builtin module directory is searched and
:variable:`CMAKE_MODULE_PATH` afterwards. See also policy :policy:`CMP0017`.
See the :command:`cmake_policy` command documentation for discussion of the
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index b14f667..9e0efe9 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -38,6 +38,8 @@ Variables that Provide Information
/variable/CMAKE_EXTRA_GENERATOR
/variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES
/variable/CMAKE_FIND_PACKAGE_NAME
+ /variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION
+ /variable/CMAKE_FIND_PACKAGE_SORT_ORDER
/variable/CMAKE_GENERATOR
/variable/CMAKE_GENERATOR_PLATFORM
/variable/CMAKE_GENERATOR_TOOLSET
@@ -332,7 +334,9 @@ Variables for Languages
.. toctree::
:maxdepth: 1
- /variable/CMAKE_COMPILER_IS_GNULANG
+ /variable/CMAKE_COMPILER_IS_GNUCC
+ /variable/CMAKE_COMPILER_IS_GNUCXX
+ /variable/CMAKE_COMPILER_IS_GNUG77
/variable/CMAKE_C_COMPILE_FEATURES
/variable/CMAKE_C_EXTENSIONS
/variable/CMAKE_C_STANDARD
diff --git a/Help/release/dev/ExternalProject-http-credentials.rst b/Help/release/dev/ExternalProject-http-credentials.rst
new file mode 100644
index 0000000..e3a362a
--- /dev/null
+++ b/Help/release/dev/ExternalProject-http-credentials.rst
@@ -0,0 +1,5 @@
+ExternalProject-http-credentials
+--------------------------------
+
+* The :module:`ExternalProject` module gained ``HTTP_USERNAME`` and
+ ``HTTP_PASSWORD`` options to set http download credentials.
diff --git a/Help/release/dev/file-curl-httpheader.rst b/Help/release/dev/file-curl-httpheader.rst
new file mode 100644
index 0000000..2147d40
--- /dev/null
+++ b/Help/release/dev/file-curl-httpheader.rst
@@ -0,0 +1,5 @@
+file-curl-httpheader
+--------------------
+
+* The :command:`file(DOWNLOAD)` and :command:`file(UPLOAD)` commands
+ gained a ``HTTPHEADER <HTTP-header>`` option.
diff --git a/Help/release/dev/find_package-dir-sort.rst b/Help/release/dev/find_package-dir-sort.rst
new file mode 100644
index 0000000..67b93eb
--- /dev/null
+++ b/Help/release/dev/find_package-dir-sort.rst
@@ -0,0 +1,13 @@
+find_package-dir-sort
+---------------------
+
+* The :command:`find_package` command gained the possibility of
+ sorting compatible libraries by ``NAME`` or by ``NATURAL`` sorting by
+ setting the two new variables :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`
+ and :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION`.
+
+* Variable :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` was added to control
+ the sorting mode of the :command:`find_package` command.
+
+* Variable :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` was added to control
+ the sorting direction the :command:`find_package` command.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst b/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
new file mode 100644
index 0000000..a40667e
--- /dev/null
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
@@ -0,0 +1,5 @@
+CMAKE_COMPILER_IS_GNUCC
+-----------------------
+
+True if the ``C`` compiler is GNU.
+Use :variable:`CMAKE_C_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst b/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
new file mode 100644
index 0000000..f1f5cf7
--- /dev/null
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
@@ -0,0 +1,5 @@
+CMAKE_COMPILER_IS_GNUCXX
+------------------------
+
+True if the C++ (``CXX``) compiler is GNU.
+Use :variable:`CMAKE_CXX_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst b/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
new file mode 100644
index 0000000..3d6dab4
--- /dev/null
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
@@ -0,0 +1,5 @@
+CMAKE_COMPILER_IS_GNUG77
+------------------------
+
+True if the ``Fortran`` compiler is GNU.
+Use :variable:`CMAKE_Fortran_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst b/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst
deleted file mode 100644
index 4b652c0..0000000
--- a/Help/variable/CMAKE_COMPILER_IS_GNULANG.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-CMAKE_COMPILER_IS_GNU<LANG>
----------------------------
-
-True if the compiler is GNU.
-
-If the selected ``<LANG>`` compiler is the GNU compiler then this is ``TRUE``,
-if not it is ``FALSE``. Unlike the other per-language variables, this
-uses the GNU syntax for identifying languages instead of the CMake
-syntax. Recognized values of the ``<LANG>`` suffix are:
-
-::
-
- CC = C compiler
- CXX = C++ compiler
- G77 = Fortran compiler
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
new file mode 100644
index 0000000..99e4ec1
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
@@ -0,0 +1,16 @@
+CMAKE_FIND_PACKAGE_SORT_DIRECTION
+---------------------------------
+
+The sorting direction used by :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`.
+It can assume one of the following values:
+
+``DEC``
+ Default. Ordering is done in descending mode.
+ The highest folder found will be tested first.
+
+``ASC``
+ Ordering is done in ascending mode.
+ The lowest folder found will be tested first.
+
+If :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` is not set or is set to ``NONE``
+this variable has no effect.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
new file mode 100644
index 0000000..ba5f3a8
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
@@ -0,0 +1,36 @@
+CMAKE_FIND_PACKAGE_SORT_ORDER
+-----------------------------
+
+The default order for sorting packages found using :command:`find_package`.
+It can assume one of the following values:
+
+``NONE``
+ Default. No attempt is done to sort packages.
+ The first valid package found will be selected.
+
+``NAME``
+ Sort packages lexicographically before selecting one.
+
+``NATURAL``
+ Sort packages using natural order (see ``strverscmp(3)`` manual),
+ i.e. such that contiguous digits are compared as whole numbers.
+
+Natural sorting can be employed to return the highest version when multiple
+versions of the same library are found by :command:`find_package`. For
+example suppose that the following libraries have been found:
+
+* libX-1.1.0
+* libX-1.2.9
+* libX-1.2.10
+
+By setting ``NATURAL`` order we can select the one with the highest
+version number ``libX-1.2.10``.
+
+.. code-block:: cmake
+
+ set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
+ find_package(libX CONFIG)
+
+The sort direction can be controlled using the
+:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` variable
+(by default decrescent, e.g. lib-B will be tested before lib-A).
diff --git a/Modules/ExternalProject-download.cmake.in b/Modules/ExternalProject-download.cmake.in
index 91d74e0..0e82adb 100644
--- a/Modules/ExternalProject-download.cmake.in
+++ b/Modules/ExternalProject-download.cmake.in
@@ -135,6 +135,7 @@ foreach(i RANGE ${retry_number})
@TIMEOUT_ARGS@
STATUS status
LOG log
+ @USERPWD_ARGS@
)
list(GET status 0 status_code)
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 5ea309f..31fa459 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -75,6 +75,10 @@ Create custom targets to build projects in external trees
Hash of file at URL
``URL_MD5 md5``
Equivalent to URL_HASH MD5=md5
+ ``HTTP_USERNAME <username>``
+ Username for download operation
+ ``HTTP_PASSWORD <username>``
+ Password for download operation
``TLS_VERIFY <bool>``
Should certificate for https be checked
``TLS_CAINFO <file>``
@@ -858,7 +862,7 @@ endif()
endfunction(_ep_write_gitupdate_script)
-function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_progress hash tls_verify tls_cainfo)
+function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_progress hash tls_verify tls_cainfo userpwd)
if(timeout)
set(TIMEOUT_ARGS TIMEOUT ${timeout})
set(TIMEOUT_MSG "${timeout} seconds")
@@ -906,6 +910,12 @@ function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_p
set(TLS_CAINFO_CODE "set(CMAKE_TLS_CAINFO \"${tls_cainfo}\")")
endif()
+ if(userpwd STREQUAL ":")
+ set(USERPWD_ARGS)
+ else()
+ set(USERPWD_ARGS USERPWD "${userpwd}")
+ endif()
+
# Used variables:
# * TLS_VERIFY_CODE
# * TLS_CAINFO_CODE
@@ -916,6 +926,7 @@ function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_p
# * SHOW_PROGRESS
# * TIMEOUT_ARGS
# * TIMEOUT_MSG
+ # * USERPWD_ARGS
configure_file(
"${_ExternalProject_SELF_DIR}/ExternalProject-download.cmake.in"
"${script_filename}"
@@ -1919,8 +1930,10 @@ function(_ep_add_download_command name)
get_property(no_progress TARGET ${name} PROPERTY _EP_DOWNLOAD_NO_PROGRESS)
get_property(tls_verify TARGET ${name} PROPERTY _EP_TLS_VERIFY)
get_property(tls_cainfo TARGET ${name} PROPERTY _EP_TLS_CAINFO)
+ get_property(http_username TARGET ${name} PROPERTY _EP_HTTP_USERNAME)
+ get_property(http_password TARGET ${name} PROPERTY _EP_HTTP_PASSWORD)
set(download_script "${stamp_dir}/download-${name}.cmake")
- _ep_write_downloadfile_script("${download_script}" "${url}" "${file}" "${timeout}" "${no_progress}" "${hash}" "${tls_verify}" "${tls_cainfo}")
+ _ep_write_downloadfile_script("${download_script}" "${url}" "${file}" "${timeout}" "${no_progress}" "${hash}" "${tls_verify}" "${tls_cainfo}" "${http_username}:${http_password}")
set(cmd ${CMAKE_COMMAND} -P "${download_script}"
COMMAND)
if (no_extract)
diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake
index 764a5f7..548d12a 100644
--- a/Modules/FeatureSummary.cmake
+++ b/Modules/FeatureSummary.cmake
@@ -1,268 +1,27 @@
-#.rst:
-# FeatureSummary
-# --------------
-#
-# Macros for generating a summary of enabled/disabled features
-#
-#
-#
-# This module provides the macros feature_summary(),
-# set_package_properties() and add_feature_info(). For compatibility it
-# also still provides set_package_info(), set_feature_info(),
-# print_enabled_features() and print_disabled_features().
-#
-# These macros can be used to generate a summary of enabled and disabled
-# packages and/or feature for a build tree:
-#
-# ::
-#
-# -- The following OPTIONAL packages have been found:
-# LibXml2 (required version >= 2.4), XML processing lib, <http://xmlsoft.org>
-# * Enables HTML-import in MyWordProcessor
-# * Enables odt-export in MyWordProcessor
-# PNG , A PNG image library. , <http://www.libpng.org/pub/png/>
-# * Enables saving screenshots
-# -- The following OPTIONAL packages have not been found:
-# Lua51 , The Lua scripting language. , <http://www.lua.org>
-# * Enables macros in MyWordProcessor
-# Foo , Foo provides cool stuff.
-#
-#
-#
-#
-#
-# ::
-#
-# FEATURE_SUMMARY( [FILENAME <file>]
-# [APPEND]
-# [VAR <variable_name>]
-# [INCLUDE_QUIET_PACKAGES]
-# [FATAL_ON_MISSING_REQUIRED_PACKAGES]
-# [DESCRIPTION "Found packages:"]
-# WHAT (ALL | PACKAGES_FOUND | PACKAGES_NOT_FOUND
-# | ENABLED_FEATURES | DISABLED_FEATURES)
-# )
-#
-#
-#
-# The FEATURE_SUMMARY() macro can be used to print information about
-# enabled or disabled packages or features of a project. By default,
-# only the names of the features/packages will be printed and their
-# required version when one was specified. Use SET_PACKAGE_PROPERTIES()
-# to add more useful information, like e.g. a download URL for the
-# respective package or their purpose in the project.
-#
-# The WHAT option is the only mandatory option. Here you specify what
-# information will be printed:
-#
-# ``ALL``
-# print everything
-# ``ENABLED_FEATURES``
-# the list of all features which are enabled
-# ``DISABLED_FEATURES``
-# the list of all features which are disabled
-# ``PACKAGES_FOUND``
-# the list of all packages which have been found
-# ``PACKAGES_NOT_FOUND``
-# the list of all packages which have not been found
-# ``OPTIONAL_PACKAGES_FOUND``
-# only those packages which have been found which have the type OPTIONAL
-# ``OPTIONAL_PACKAGES_NOT_FOUND``
-# only those packages which have not been found which have the type OPTIONAL
-# ``RECOMMENDED_PACKAGES_FOUND``
-# only those packages which have been found which have the type RECOMMENDED
-# ``RECOMMENDED_PACKAGES_NOT_FOUND``
-# only those packages which have not been found which have the type RECOMMENDED
-# ``REQUIRED_PACKAGES_FOUND``
-# only those packages which have been found which have the type REQUIRED
-# ``REQUIRED_PACKAGES_NOT_FOUND``
-# only those packages which have not been found which have the type REQUIRED
-# ``RUNTIME_PACKAGES_FOUND``
-# only those packages which have been found which have the type RUNTIME
-# ``RUNTIME_PACKAGES_NOT_FOUND``
-# only those packages which have not been found which have the type RUNTIME
-#
-# With the exception of the ``ALL`` value, these values can be combined
-# in order to customize the output. For example:
-#
-# ::
-#
-# feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
-#
-#
-#
-# If a FILENAME is given, the information is printed into this file. If
-# APPEND is used, it is appended to this file, otherwise the file is
-# overwritten if it already existed. If the VAR option is used, the
-# information is "printed" into the specified variable. If FILENAME is
-# not used, the information is printed to the terminal. Using the
-# DESCRIPTION option a description or headline can be set which will be
-# printed above the actual content. If INCLUDE_QUIET_PACKAGES is given,
-# packages which have been searched with find_package(... QUIET) will
-# also be listed. By default they are skipped. If
-# FATAL_ON_MISSING_REQUIRED_PACKAGES is given, CMake will abort if a
-# package which is marked as REQUIRED has not been found.
-#
-# Example 1, append everything to a file:
-#
-# ::
-#
-# feature_summary(WHAT ALL
-# FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND)
-#
-#
-#
-# Example 2, print the enabled features into the variable
-# enabledFeaturesText, including QUIET packages:
-#
-# ::
-#
-# feature_summary(WHAT ENABLED_FEATURES
-# INCLUDE_QUIET_PACKAGES
-# DESCRIPTION "Enabled Features:"
-# VAR enabledFeaturesText)
-# message(STATUS "${enabledFeaturesText}")
-#
-#
-#
-#
-#
-# ::
-#
-# SET_PACKAGE_PROPERTIES(<name> PROPERTIES
-# [ URL <url> ]
-# [ DESCRIPTION <description> ]
-# [ TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED) ]
-# [ PURPOSE <purpose> ]
-# )
-#
-#
-#
-# Use this macro to set up information about the named package, which
-# can then be displayed via FEATURE_SUMMARY(). This can be done either
-# directly in the Find-module or in the project which uses the module
-# after the find_package() call. The features for which information can
-# be set are added automatically by the find_package() command.
-#
-# URL: this should be the homepage of the package, or something similar.
-# Ideally this is set already directly in the Find-module.
-#
-# DESCRIPTION: A short description what that package is, at most one
-# sentence. Ideally this is set already directly in the Find-module.
-#
-# TYPE: What type of dependency has the using project on that package.
-# Default is OPTIONAL. In this case it is a package which can be used
-# by the project when available at buildtime, but it also work without.
-# RECOMMENDED is similar to OPTIONAL, i.e. the project will build if
-# the package is not present, but the functionality of the resulting
-# binaries will be severly limited. If a REQUIRED package is not
-# available at buildtime, the project may not even build. This can be
-# combined with the FATAL_ON_MISSING_REQUIRED_PACKAGES argument for
-# feature_summary(). Last, a RUNTIME package is a package which is
-# actually not used at all during the build, but which is required for
-# actually running the resulting binaries. So if such a package is
-# missing, the project can still be built, but it may not work later on.
-# If set_package_properties() is called multiple times for the same
-# package with different TYPEs, the TYPE is only changed to higher TYPEs
-# ( RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED ), lower TYPEs are
-# ignored. The TYPE property is project-specific, so it cannot be set
-# by the Find-module, but must be set in the project.
-#
-# PURPOSE: This describes which features this package enables in the
-# project, i.e. it tells the user what functionality he gets in the
-# resulting binaries. If set_package_properties() is called multiple
-# times for a package, all PURPOSE properties are appended to a list of
-# purposes of the package in the project. As the TYPE property, also
-# the PURPOSE property is project-specific, so it cannot be set by the
-# Find-module, but must be set in the project.
-#
-#
-#
-# Example for setting the info for a package:
-#
-# ::
-#
-# find_package(LibXml2)
-# set_package_properties(LibXml2 PROPERTIES
-# DESCRIPTION "A XML processing library."
-# URL "http://xmlsoft.org/")
-#
-#
-#
-# ::
-#
-# set_package_properties(LibXml2 PROPERTIES
-# TYPE RECOMMENDED
-# PURPOSE "Enables HTML-import in MyWordProcessor")
-# ...
-# set_package_properties(LibXml2 PROPERTIES
-# TYPE OPTIONAL
-# PURPOSE "Enables odt-export in MyWordProcessor")
-#
-#
-#
-# ::
-#
-# find_package(DBUS)
-# set_package_properties(DBUS PROPERTIES
-# TYPE RUNTIME
-# PURPOSE "Necessary to disable the screensaver during a presentation" )
-#
-#
-#
-# ::
-#
-# ADD_FEATURE_INFO(<name> <enabled> <description>)
-#
-# Use this macro to add information about a feature with the given
-# <name>. <enabled> contains whether this feature is enabled or not,
-# <description> is a text describing the feature. The information can
-# be displayed using feature_summary() for ENABLED_FEATURES and
-# DISABLED_FEATURES respectively.
-#
-# Example for setting the info for a feature:
-#
-# ::
-#
-# option(WITH_FOO "Help for foo" ON)
-# add_feature_info(Foo WITH_FOO "The Foo feature provides very cool stuff.")
-#
-#
-#
-#
-#
-# The following macros are provided for compatibility with previous
-# CMake versions:
-#
-# ::
-#
-# SET_PACKAGE_INFO(<name> <description> [<url> [<purpose>] ] )
-#
-# Use this macro to set up information about the named package, which
-# can then be displayed via FEATURE_SUMMARY(). This can be done either
-# directly in the Find-module or in the project which uses the module
-# after the find_package() call. The features for which information can
-# be set are added automatically by the find_package() command.
-#
-# ::
-#
-# PRINT_ENABLED_FEATURES()
-#
-# Does the same as FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION
-# "Enabled features:")
-#
-# ::
-#
-# PRINT_DISABLED_FEATURES()
-#
-# Does the same as FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION
-# "Disabled features:")
-#
-# ::
-#
-# SET_FEATURE_INFO(<name> <description> [<url>] )
-#
-# Does the same as SET_PACKAGE_INFO(<name> <description> <url> )
+#[=======================================================================[.rst:
+FeatureSummary
+--------------
+
+Functions for generating a summary of enabled/disabled features.
+
+These functions can be used to generate a summary of enabled and disabled
+packages and/or feature for a build tree such as::
+
+ -- The following OPTIONAL packages have been found:
+ LibXml2 (required version >= 2.4), XML processing lib, <http://xmlsoft.org>
+ * Enables HTML-import in MyWordProcessor
+ * Enables odt-export in MyWordProcessor
+ PNG , A PNG image library. , <http://www.libpng.org/pub/png/>
+ * Enables saving screenshots
+ -- The following OPTIONAL packages have not been found:
+ Lua51 , The Lua scripting language. , <http://www.lua.org>
+ * Enables macros in MyWordProcessor
+ Foo , Foo provides cool stuff.
+
+Functions
+^^^^^^^^^
+
+#]=======================================================================]
#=============================================================================
# Copyright 2007-2015 Kitware, Inc.
@@ -280,83 +39,6 @@
include("${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake")
-function(ADD_FEATURE_INFO _name _enabled _desc)
- if (${_enabled})
- set_property(GLOBAL APPEND PROPERTY ENABLED_FEATURES "${_name}")
- else ()
- set_property(GLOBAL APPEND PROPERTY DISABLED_FEATURES "${_name}")
- endif ()
-
- set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" )
-endfunction()
-
-
-
-function(SET_PACKAGE_PROPERTIES _name _props)
- if(NOT "${_props}" STREQUAL "PROPERTIES")
- message(FATAL_ERROR "PROPERTIES keyword is missing in SET_PACKAGE_PROPERTIES() call.")
- endif()
-
- set(options ) # none
- set(oneValueArgs DESCRIPTION URL TYPE PURPOSE )
- set(multiValueArgs ) # none
-
- CMAKE_PARSE_ARGUMENTS(_SPP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
- if(_SPP_UNPARSED_ARGUMENTS)
- message(FATAL_ERROR "Unknown keywords given to SET_PACKAGE_PROPERTIES(): \"${_SPP_UNPARSED_ARGUMENTS}\"")
- endif()
-
- if(_SPP_DESCRIPTION)
- get_property(_info GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION)
- if(_info AND NOT "${_info}" STREQUAL "${_SPP_DESCRIPTION}")
- message(STATUS "Warning: Property DESCRIPTION for package ${_name} already set to \"${_info}\", overriding it with \"${_SPP_DESCRIPTION}\"")
- endif()
-
- set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_SPP_DESCRIPTION}" )
- endif()
-
-
- if(_SPP_URL)
- get_property(_info GLOBAL PROPERTY _CMAKE_${_name}_URL)
- if(_info AND NOT "${_info}" STREQUAL "${_SPP_URL}")
- message(STATUS "Warning: Property URL already set to \"${_info}\", overriding it with \"${_SPP_URL}\"")
- endif()
-
- set_property(GLOBAL PROPERTY _CMAKE_${_name}_URL "${_SPP_URL}" )
- endif()
-
-
- # handle the PURPOSE: use APPEND, since there can be multiple purposes for one package inside a project
- if(_SPP_PURPOSE)
- set_property(GLOBAL APPEND PROPERTY _CMAKE_${_name}_PURPOSE "${_SPP_PURPOSE}" )
- endif()
-
- # handle the TYPE
- if(NOT _SPP_TYPE)
- set(_SPP_TYPE OPTIONAL)
- endif()
-
- # List the supported types, according to their priority
- set(validTypes "RUNTIME" "OPTIONAL" "RECOMMENDED" "REQUIRED" )
- list(FIND validTypes ${_SPP_TYPE} _typeIndexInList)
- if("${_typeIndexInList}" STREQUAL "-1" )
- message(FATAL_ERROR "Bad package property type ${_SPP_TYPE} used in SET_PACKAGE_PROPERTIES(). "
- "Valid types are OPTIONAL, RECOMMENDED, REQUIRED and RUNTIME." )
- endif()
-
- get_property(_previousType GLOBAL PROPERTY _CMAKE_${_name}_TYPE)
- list(FIND validTypes "${_previousType}" _prevTypeIndexInList)
-
- # make sure a previously set TYPE is not overridden with a lower new TYPE:
- if("${_typeIndexInList}" GREATER "${_prevTypeIndexInList}")
- set_property(GLOBAL PROPERTY _CMAKE_${_name}_TYPE "${_SPP_TYPE}" )
- endif()
-
-endfunction()
-
-
-
function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
set(_type "ANY")
@@ -439,6 +121,97 @@ function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
endfunction()
+#[=======================================================================[.rst:
+.. command:: feature_summary
+
+ ::
+
+ feature_summary( [FILENAME <file>]
+ [APPEND]
+ [VAR <variable_name>]
+ [INCLUDE_QUIET_PACKAGES]
+ [FATAL_ON_MISSING_REQUIRED_PACKAGES]
+ [DESCRIPTION "Found packages:"]
+ WHAT (ALL | PACKAGES_FOUND | PACKAGES_NOT_FOUND
+ | ENABLED_FEATURES | DISABLED_FEATURES)
+ )
+
+ The ``feature_summary()`` macro can be used to print information about
+ enabled or disabled packages or features of a project. By default,
+ only the names of the features/packages will be printed and their
+ required version when one was specified. Use ``set_package_properties()``
+ to add more useful information, like e.g. a download URL for the
+ respective package or their purpose in the project.
+
+ The ``WHAT`` option is the only mandatory option. Here you specify what
+ information will be printed:
+
+ ``ALL``
+ print everything
+ ``ENABLED_FEATURES``
+ the list of all features which are enabled
+ ``DISABLED_FEATURES``
+ the list of all features which are disabled
+ ``PACKAGES_FOUND``
+ the list of all packages which have been found
+ ``PACKAGES_NOT_FOUND``
+ the list of all packages which have not been found
+ ``OPTIONAL_PACKAGES_FOUND``
+ only those packages which have been found which have the type OPTIONAL
+ ``OPTIONAL_PACKAGES_NOT_FOUND``
+ only those packages which have not been found which have the type OPTIONAL
+ ``RECOMMENDED_PACKAGES_FOUND``
+ only those packages which have been found which have the type RECOMMENDED
+ ``RECOMMENDED_PACKAGES_NOT_FOUND``
+ only those packages which have not been found which have the type RECOMMENDED
+ ``REQUIRED_PACKAGES_FOUND``
+ only those packages which have been found which have the type REQUIRED
+ ``REQUIRED_PACKAGES_NOT_FOUND``
+ only those packages which have not been found which have the type REQUIRED
+ ``RUNTIME_PACKAGES_FOUND``
+ only those packages which have been found which have the type RUNTIME
+ ``RUNTIME_PACKAGES_NOT_FOUND``
+ only those packages which have not been found which have the type RUNTIME
+
+ With the exception of the ``ALL`` value, these values can be combined
+ in order to customize the output. For example:
+
+ .. code-block:: cmake
+
+ feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
+
+ If a ``FILENAME`` is given, the information is printed into this file. If
+ ``APPEND`` is used, it is appended to this file, otherwise the file is
+ overwritten if it already existed. If the VAR option is used, the
+ information is "printed" into the specified variable. If ``FILENAME`` is
+ not used, the information is printed to the terminal. Using the
+ ``DESCRIPTION`` option a description or headline can be set which will be
+ printed above the actual content. If ``INCLUDE_QUIET_PACKAGES`` is given,
+ packages which have been searched with ``find_package(... QUIET)`` will
+ also be listed. By default they are skipped. If
+ ``FATAL_ON_MISSING_REQUIRED_PACKAGES`` is given, CMake will abort if a
+ package which is marked as ``REQUIRED`` has not been found.
+
+ Example 1, append everything to a file:
+
+ .. code-block:: cmake
+
+ include(FeatureSummary)
+ feature_summary(WHAT ALL
+ FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND)
+
+ Example 2, print the enabled features into the variable
+ enabledFeaturesText, including QUIET packages:
+
+ .. code-block:: cmake
+
+ include(FeatureSummary)
+ feature_summary(WHAT ENABLED_FEATURES
+ INCLUDE_QUIET_PACKAGES
+ DESCRIPTION "Enabled Features:"
+ VAR enabledFeaturesText)
+ message(STATUS "${enabledFeaturesText}")
+#]=======================================================================]
function(FEATURE_SUMMARY)
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
@@ -558,9 +331,198 @@ function(FEATURE_SUMMARY)
endfunction()
+#[=======================================================================[.rst:
+.. command:: set_package_properties
+
+ ::
+
+ set_package_properties(<name> PROPERTIES
+ [ URL <url> ]
+ [ DESCRIPTION <description> ]
+ [ TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED) ]
+ [ PURPOSE <purpose> ]
+ )
+
+ Use this macro to set up information about the named package, which
+ can then be displayed via FEATURE_SUMMARY(). This can be done either
+ directly in the Find-module or in the project which uses the module
+ after the find_package() call. The features for which information can
+ be set are added automatically by the find_package() command.
+
+ ``URL <url>``
+ This should be the homepage of the package, or something similar.
+ Ideally this is set already directly in the Find-module.
+
+ ``DESCRIPTION <description>``
+ A short description what that package is, at most one sentence.
+ Ideally this is set already directly in the Find-module.
+
+ ``TYPE <type>``
+ What type of dependency has the using project on that package.
+ Default is ``OPTIONAL``. In this case it is a package which can be used
+ by the project when available at buildtime, but it also work without.
+ ``RECOMMENDED`` is similar to ``OPTIONAL``, i.e. the project will build if
+ the package is not present, but the functionality of the resulting
+ binaries will be severly limited. If a ``REQUIRED`` package is not
+ available at buildtime, the project may not even build. This can be
+ combined with the ``FATAL_ON_MISSING_REQUIRED_PACKAGES`` argument for
+ ``feature_summary()``. Last, a ``RUNTIME`` package is a package which is
+ actually not used at all during the build, but which is required for
+ actually running the resulting binaries. So if such a package is
+ missing, the project can still be built, but it may not work later on.
+ If ``set_package_properties()`` is called multiple times for the same
+ package with different TYPEs, the ``TYPE`` is only changed to higher
+ TYPEs (``RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED``), lower TYPEs are
+ ignored. The ``TYPE`` property is project-specific, so it cannot be set
+ by the Find-module, but must be set in the project.
+
+
+ ``PURPOSE <purpose>``
+ This describes which features this package enables in the
+ project, i.e. it tells the user what functionality he gets in the
+ resulting binaries. If set_package_properties() is called multiple
+ times for a package, all PURPOSE properties are appended to a list of
+ purposes of the package in the project. As the TYPE property, also
+ the PURPOSE property is project-specific, so it cannot be set by the
+ Find-module, but must be set in the project.
+
+ Example for setting the info for a package:
+
+ .. code-block:: cmake
+
+ find_package(LibXml2)
+ set_package_properties(LibXml2 PROPERTIES
+ DESCRIPTION "A XML processing library."
+ URL "http://xmlsoft.org/")
+ # or
+ set_package_properties(LibXml2 PROPERTIES
+ TYPE RECOMMENDED
+ PURPOSE "Enables HTML-import in MyWordProcessor")
+ # or
+ set_package_properties(LibXml2 PROPERTIES
+ TYPE OPTIONAL
+ PURPOSE "Enables odt-export in MyWordProcessor")
+
+ find_package(DBUS)
+ set_package_properties(DBUS PROPERTIES
+ TYPE RUNTIME
+ PURPOSE "Necessary to disable the screensaver during a presentation")
+#]=======================================================================]
+function(SET_PACKAGE_PROPERTIES _name _props)
+ if(NOT "${_props}" STREQUAL "PROPERTIES")
+ message(FATAL_ERROR "PROPERTIES keyword is missing in SET_PACKAGE_PROPERTIES() call.")
+ endif()
+
+ set(options ) # none
+ set(oneValueArgs DESCRIPTION URL TYPE PURPOSE )
+ set(multiValueArgs ) # none
+
+ CMAKE_PARSE_ARGUMENTS(_SPP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if(_SPP_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown keywords given to SET_PACKAGE_PROPERTIES(): \"${_SPP_UNPARSED_ARGUMENTS}\"")
+ endif()
+
+ if(_SPP_DESCRIPTION)
+ get_property(_info GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION)
+ if(_info AND NOT "${_info}" STREQUAL "${_SPP_DESCRIPTION}")
+ message(STATUS "Warning: Property DESCRIPTION for package ${_name} already set to \"${_info}\", overriding it with \"${_SPP_DESCRIPTION}\"")
+ endif()
+
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_SPP_DESCRIPTION}" )
+ endif()
+
+
+ if(_SPP_URL)
+ get_property(_info GLOBAL PROPERTY _CMAKE_${_name}_URL)
+ if(_info AND NOT "${_info}" STREQUAL "${_SPP_URL}")
+ message(STATUS "Warning: Property URL already set to \"${_info}\", overriding it with \"${_SPP_URL}\"")
+ endif()
+
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_URL "${_SPP_URL}" )
+ endif()
+
+
+ # handle the PURPOSE: use APPEND, since there can be multiple purposes for one package inside a project
+ if(_SPP_PURPOSE)
+ set_property(GLOBAL APPEND PROPERTY _CMAKE_${_name}_PURPOSE "${_SPP_PURPOSE}" )
+ endif()
+
+ # handle the TYPE
+ if(NOT _SPP_TYPE)
+ set(_SPP_TYPE OPTIONAL)
+ endif()
+
+ # List the supported types, according to their priority
+ set(validTypes "RUNTIME" "OPTIONAL" "RECOMMENDED" "REQUIRED" )
+ list(FIND validTypes ${_SPP_TYPE} _typeIndexInList)
+ if("${_typeIndexInList}" STREQUAL "-1" )
+ message(FATAL_ERROR "Bad package property type ${_SPP_TYPE} used in SET_PACKAGE_PROPERTIES(). "
+ "Valid types are OPTIONAL, RECOMMENDED, REQUIRED and RUNTIME." )
+ endif()
+
+ get_property(_previousType GLOBAL PROPERTY _CMAKE_${_name}_TYPE)
+ list(FIND validTypes "${_previousType}" _prevTypeIndexInList)
+
+ # make sure a previously set TYPE is not overridden with a lower new TYPE:
+ if("${_typeIndexInList}" GREATER "${_prevTypeIndexInList}")
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_TYPE "${_SPP_TYPE}" )
+ endif()
+
+endfunction()
+
+#[=======================================================================[.rst:
+.. command:: add_feature_info
+
+ ::
+
+ add_feature_info(<name> <enabled> <description>)
+
+ Use this macro to add information about a feature with the given ``<name>``.
+ ``<enabled>`` contains whether this feature is enabled or not.
+ ``<description>`` is a text describing the feature. The information can
+ be displayed using ``feature_summary()`` for ``ENABLED_FEATURES`` and
+ ``DISABLED_FEATURES`` respectively.
+
+ Example for setting the info for a feature:
+
+ .. code-block:: cmake
+
+ option(WITH_FOO "Help for foo" ON)
+ add_feature_info(Foo WITH_FOO "The Foo feature provides very cool stuff.")
+#]=======================================================================]
+function(ADD_FEATURE_INFO _name _enabled _desc)
+ if (${_enabled})
+ set_property(GLOBAL APPEND PROPERTY ENABLED_FEATURES "${_name}")
+ else ()
+ set_property(GLOBAL APPEND PROPERTY DISABLED_FEATURES "${_name}")
+ endif ()
+
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" )
+endfunction()
+
# The stuff below is only kept for compatibility
+#[=======================================================================[.rst:
+Legacy Macros
+^^^^^^^^^^^^^
+
+The following macros are provided for compatibility with previous
+CMake versions:
+
+.. command:: set_package_info
+
+ ::
+
+ set_package_info(<name> <description> [ <url> [<purpose>] ])
+
+ Use this macro to set up information about the named package, which
+ can then be displayed via ``feature_summary()``. This can be done either
+ directly in the Find-module or in the project which uses the module
+ after the :command:`find_package` call. The features for which information
+ can be set are added automatically by the ``find_package()`` command.
+#]=======================================================================]
function(SET_PACKAGE_INFO _name _desc)
unset(_url)
unset(_purpose)
@@ -579,20 +541,51 @@ function(SET_PACKAGE_INFO _name _desc)
endif()
endfunction()
+#[=======================================================================[.rst:
+.. command:: set_feature_info
+ ::
+ set_feature_info(<name> <description> [<url>])
+
+ Does the same as::
+
+ set_package_info(<name> <description> <url>)
+#]=======================================================================]
function(SET_FEATURE_INFO)
SET_PACKAGE_INFO(${ARGN})
endfunction()
+#[=======================================================================[.rst:
+.. command:: print_enabled_features
+
+ ::
+
+ print_enabled_features()
+ Does the same as
+ .. code-block:: cmake
+
+ feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
+#]=======================================================================]
function(PRINT_ENABLED_FEATURES)
FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
endfunction()
+#[=======================================================================[.rst:
+.. command:: print_disabled_features
+
+ ::
+
+ print_disabled_features()
+
+ Does the same as
+ .. code-block:: cmake
+ feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
+#]=======================================================================]
function(PRINT_DISABLED_FEATURES)
FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
endfunction()
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index b501599..c813f8f 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -635,7 +635,7 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve
set(devnull INPUT_FILE NUL)
endif()
- # timeout set to 30 seconds, in case it does not start
+ # timeout set to 120 seconds, in case it does not start
# note as said before OUTPUT_VARIABLE cannot be used in a platform
# independent manner however, not setting it would flush the output of Matlab
# in the current console (unix variant)
@@ -644,11 +644,18 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve
OUTPUT_VARIABLE _matlab_version_from_cmd_dummy
RESULT_VARIABLE _matlab_result_version_call
ERROR_VARIABLE _matlab_result_version_call_error
- TIMEOUT 30
+ TIMEOUT 120
WORKING_DIRECTORY "${_matlab_temporary_folder}"
${devnull}
)
+ if("${_matlab_result_version_call}" MATCHES "timeout")
+ if(MATLAB_FIND_DEBUG)
+ message(WARNING "[MATLAB] Unable to determine the version of Matlab."
+ " Matlab call timed out after 120 seconds.")
+ endif()
+ return()
+ endif()
if(${_matlab_result_version_call})
if(MATLAB_FIND_DEBUG)
@@ -698,7 +705,6 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve
endfunction()
-
#.rst:
# .. command:: matlab_add_unit_test
#
@@ -720,6 +726,7 @@ endfunction()
# matlab_add_unit_test(
# NAME <name>
# UNITTEST_FILE matlab_file_containing_unittest.m
+# [CUSTOM_MATLAB_COMMAND matlab_command_to_run_as_test]
# [UNITTEST_PRECOMMAND matlab_command_to_run]
# [TIMEOUT timeout]
# [ADDITIONAL_PATH path1 [path2 ...]]
@@ -735,6 +742,11 @@ endfunction()
# ``UNITTEST_FILE``
# the matlab unittest file. Its path will be automatically
# added to the Matlab path.
+# ``CUSTOM_MATLAB_COMMAND``
+# Matlab script command to run as the test.
+# IIf this is not set, then the following is run:
+# "runtests('matlab_file_name'), exit(max([ans(1,:).Failed]))
+# matlab_file_name comes from UNITTEST_FILE without the .m.
# ``UNITTEST_PRECOMMAND``
# Matlab script command to be ran before the file
# containing the test (eg. GPU device initialisation based on CMake
@@ -748,12 +760,18 @@ endfunction()
# ``MATLAB_ADDITIONAL_STARTUP_OPTIONS``
# a list of additional option in order
# to run Matlab from the command line.
+# -nosplash -nodesktop -nodisplay are always added.
# ``TEST_ARGS``
# Additional options provided to the add_test command. These
# options are added to the default options (eg. "CONFIGURATIONS Release")
# ``NO_UNITTEST_FRAMEWORK``
# when set, indicates that the test should not
# use the unittest framework of Matlab (available for versions >= R2013a).
+# ``WORKING_DIRECTORY``
+# This will be the working directory for the test. If specified it will
+# also be the output directory used for the log file of the test run.
+# If not specifed the temporary directory ${CMAKE_BINARY_DIR}/Matlab will
+# be used as the working directory and the log location.
#
function(matlab_add_unit_test)
@@ -762,11 +780,12 @@ function(matlab_add_unit_test)
endif()
set(options NO_UNITTEST_FRAMEWORK)
- set(oneValueArgs NAME UNITTEST_PRECOMMAND UNITTEST_FILE TIMEOUT)
+ set(oneValueArgs NAME UNITTEST_FILE TIMEOUT WORKING_DIRECTORY
+ UNITTEST_PRECOMMAND CUSTOM_TEST_COMMAND)
set(multiValueArgs ADDITIONAL_PATH MATLAB_ADDITIONAL_STARTUP_OPTIONS TEST_ARGS)
set(prefix _matlab_unittest_prefix)
- cmake_parse_arguments(${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+ cmake_parse_arguments(PARSE_ARGV 0 ${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" )
if(NOT ${prefix}_NAME)
message(FATAL_ERROR "[MATLAB] The Matlab test name cannot be empty")
@@ -774,15 +793,17 @@ function(matlab_add_unit_test)
add_test(NAME ${${prefix}_NAME}
COMMAND ${CMAKE_COMMAND}
- -Dtest_name=${${prefix}_NAME}
- -Dadditional_paths=${${prefix}_ADDITIONAL_PATH}
- -Dtest_timeout=${${prefix}_TIMEOUT}
- -Doutput_directory=${_matlab_temporary_folder}
- -DMatlab_PROGRAM=${Matlab_MAIN_PROGRAM}
- -Dno_unittest_framework=${${prefix}_NO_UNITTEST_FRAMEWORK}
- -DMatlab_ADDITIONNAL_STARTUP_OPTIONS=${${prefix}_MATLAB_ADDITIONAL_STARTUP_OPTIONS}
- -Dunittest_file_to_run=${${prefix}_UNITTEST_FILE}
- -Dcmd_to_run_before_test=${${prefix}_UNITTEST_PRECOMMAND}
+ "-Dtest_name=${${prefix}_NAME}"
+ "-Dadditional_paths=${${prefix}_ADDITIONAL_PATH}"
+ "-Dtest_timeout=${${prefix}_TIMEOUT}"
+ "-Doutput_directory=${_matlab_temporary_folder}"
+ "-Dworking_directory=${${prefix}_WORKING_DIRECTORY}"
+ "-DMatlab_PROGRAM=${Matlab_MAIN_PROGRAM}"
+ "-Dno_unittest_framework=${${prefix}_NO_UNITTEST_FRAMEWORK}"
+ "-DMatlab_ADDITIONNAL_STARTUP_OPTIONS=${${prefix}_MATLAB_ADDITIONAL_STARTUP_OPTIONS}"
+ "-Dunittest_file_to_run=${${prefix}_UNITTEST_FILE}"
+ "-Dcustom_Matlab_test_command=${${prefix}_CUSTOM_TEST_COMMAND}"
+ "-Dcmd_to_run_before_test=${${prefix}_UNITTEST_PRECOMMAND}"
-P ${_FindMatlab_SELF_DIR}/MatlabTestsRedirect.cmake
${${prefix}_TEST_ARGS}
${${prefix}_UNPARSED_ARGUMENTS}
@@ -1034,7 +1055,7 @@ function(_Matlab_get_version_from_root matlab_root matlab_known_version matlab_f
if(${list_of_all_versions_length} GREATER 0)
list(GET matlab_list_of_all_versions 0 _matlab_version_tmp)
else()
- set(_matlab_version_tmp "")
+ set(_matlab_version_tmp "unknown")
endif()
# set the version into the cache
diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake
index e194185..4d726f2 100644
--- a/Modules/FindPythonInterp.cmake
+++ b/Modules/FindPythonInterp.cmake
@@ -52,7 +52,7 @@ unset(_Python_NAMES)
set(_PYTHON1_VERSIONS 1.6 1.5)
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-set(_PYTHON3_VERSIONS 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
if(PythonInterp_FIND_VERSION)
if(PythonInterp_FIND_VERSION_COUNT GREATER 1)
diff --git a/Modules/FindPythonLibs.cmake b/Modules/FindPythonLibs.cmake
index ab92f86..d9916a1 100644
--- a/Modules/FindPythonLibs.cmake
+++ b/Modules/FindPythonLibs.cmake
@@ -84,7 +84,7 @@ set(CMAKE_FIND_FRAMEWORK LAST)
set(_PYTHON1_VERSIONS 1.6 1.5)
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
-set(_PYTHON3_VERSIONS 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
+set(_PYTHON3_VERSIONS 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
if(PythonLibs_FIND_VERSION)
if(PythonLibs_FIND_VERSION_COUNT GREATER 1)
diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake
index e33b927..bacf137 100644
--- a/Modules/GenerateExportHeader.cmake
+++ b/Modules/GenerateExportHeader.cmake
@@ -208,7 +208,7 @@ macro(_test_compiler_hidden_visibility)
if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.2")
set(GCC_TOO_OLD TRUE)
- elseif(CMAKE_COMPILER_IS_GNUC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.2")
+ elseif(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.2")
set(GCC_TOO_OLD TRUE)
elseif(CMAKE_CXX_COMPILER_ID MATCHES Intel AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0")
set(_INTEL_TOO_OLD TRUE)
diff --git a/Modules/MatlabTestsRedirect.cmake b/Modules/MatlabTestsRedirect.cmake
index 0ef4c3e..76f9a53 100644
--- a/Modules/MatlabTestsRedirect.cmake
+++ b/Modules/MatlabTestsRedirect.cmake
@@ -23,11 +23,12 @@
# -DMatlab_PROGRAM=matlab_exe_location
# -DMatlab_ADDITIONNAL_STARTUP_OPTIONS=""
# -Dtest_name=name_of_the_test
+# -Dcustom_Matlab_test_command=""
# -Dcmd_to_run_before_test=""
# -Dunittest_file_to_run
# -P FindMatlab_TestsRedirect.cmake
-set(Matlab_UNIT_TESTS_CMD -nosplash -nojvm -nodesktop -nodisplay ${Matlab_ADDITIONNAL_STARTUP_OPTIONS})
+set(Matlab_UNIT_TESTS_CMD -nosplash -nodesktop -nodisplay ${Matlab_ADDITIONNAL_STARTUP_OPTIONS})
if(WIN32)
set(Matlab_UNIT_TESTS_CMD ${Matlab_UNIT_TESTS_CMD} -wait)
endif()
@@ -36,6 +37,13 @@ if(NOT test_timeout)
set(test_timeout 180)
endif()
+# If timeout is -1, then do not put a timeout on the execute_process
+if(test_timeout EQUAL -1)
+ set(test_timeout "")
+else()
+ set(test_timeout TIMEOUT ${test_timeout})
+endif()
+
if(NOT cmd_to_run_before_test)
set(cmd_to_run_before_test)
endif()
@@ -50,16 +58,30 @@ foreach(s IN LISTS additional_paths)
endif()
endforeach()
-set(unittest_to_run "runtests('${unittest_file_to_run_name}'), exit(max([ans(1,:).Failed]))")
+if(custom_Matlab_test_command)
+ set(unittest_to_run "${custom_Matlab_test_command}")
+else()
+ set(unittest_to_run "runtests('${unittest_file_to_run_name}'), exit(max([ans(1,:).Failed]))")
+endif()
+
+
if(no_unittest_framework)
set(unittest_to_run "try, ${unittest_file_to_run_name}, catch err, disp('An exception has been thrown during the execution'), disp(err), disp(err.stack), exit(1), end, exit(0)")
endif()
set(Matlab_SCRIPT_TO_RUN
- "addpath(${concat_string}), path, ${cmd_to_run_before_test}, ${unittest_to_run}"
+ "addpath(${concat_string}); ${cmd_to_run_before_test}; ${unittest_to_run}"
)
+# if the working directory is not specified then default
+# to the output_directory because the log file will go there
+# if the working_directory is specified it will override the
+# output_directory
+if(NOT working_directory)
+ set(working_directory "${output_directory}")
+endif()
-set(Matlab_LOG_FILE "${output_directory}/${test_name}.log")
+string(REPLACE "/" "_" log_file_name "${test_name}.log")
+set(Matlab_LOG_FILE "${working_directory}/${log_file_name}")
set(devnull)
if(UNIX)
@@ -69,11 +91,14 @@ elseif(WIN32)
endif()
execute_process(
- COMMAND "${Matlab_PROGRAM}" ${Matlab_UNIT_TESTS_CMD} -logfile "${test_name}.log" -r "${Matlab_SCRIPT_TO_RUN}"
+ # Do not use a full path to log file. Depend on the fact that the log file
+ # is always going to go in the working_directory. This is because matlab
+ # on unix is a shell script that does not handle spaces in the logfile path.
+ COMMAND "${Matlab_PROGRAM}" ${Matlab_UNIT_TESTS_CMD} -logfile "${log_file_name}" -r "${Matlab_SCRIPT_TO_RUN}"
RESULT_VARIABLE res
- TIMEOUT ${test_timeout}
+ ${test_timeout}
OUTPUT_QUIET # we do not want the output twice
- WORKING_DIRECTORY "${output_directory}"
+ WORKING_DIRECTORY "${working_directory}"
${devnull}
)
@@ -87,5 +112,5 @@ message("Matlab test ${name_of_the_test} output:\n${matlab_log_content}") # if w
if(NOT (res EQUAL 0))
- message( FATAL_ERROR "[MATLAB] TEST FAILED" )
+ message( FATAL_ERROR "[MATLAB] TEST FAILED Matlab returned ${res}" )
endif()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index c61ef42..09f55fa 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 6)
-set(CMake_VERSION_PATCH 20160914)
+set(CMake_VERSION_PATCH 20160916)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CursesDialog/cmCursesStandardIncludes.h b/Source/CursesDialog/cmCursesStandardIncludes.h
index 4929958..1d8d7c6 100644
--- a/Source/CursesDialog/cmCursesStandardIncludes.h
+++ b/Source/CursesDialog/cmCursesStandardIncludes.h
@@ -14,10 +14,6 @@
#include <cmConfigure.h>
-#if defined(__sun__) && defined(__GNUC__)
-#define _MSE_INT_H
-#endif
-
#if defined(__hpux)
#define _BOOL_DEFINED
#include <sys/time.h>
diff --git a/Source/CursesDialog/form/form.h b/Source/CursesDialog/form/form.h
index 1219cb5..b65a3ca 100644
--- a/Source/CursesDialog/form/form.h
+++ b/Source/CursesDialog/form/form.h
@@ -33,10 +33,6 @@
#ifndef FORM_H
#define FORM_H
-#if defined(__sun__) && defined(__GNUC__)
- #define _MSE_INT_H
-#endif
-
#include <cmFormConfigure.h>
/* figure out which curses.h to include */
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index a0aefb8..6c31481 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -77,9 +77,8 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
- cmTarget dummyHead;
- dummyHead.SetType(cmState::EXECUTABLE, "try_compile_dummy_exe");
- dummyHead.SetMakefile(tgt->Target->GetMakefile());
+ cmTarget dummyHead("try_compile_dummy_exe", cmState::EXECUTABLE,
+ cmTarget::VisibilityNormal, tgt->Target->GetMakefile());
cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 2c226cd..c10f426 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2483,6 +2483,8 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
bool showProgress = false;
std::string userpwd;
+ std::list<std::string> curl_headers;
+
while (i != args.end()) {
if (*i == "TIMEOUT") {
++i;
@@ -2572,6 +2574,13 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
return false;
}
userpwd = *i;
+ } else if (*i == "HTTPHEADER") {
+ ++i;
+ if (i == args.end()) {
+ this->SetError("DOWNLOAD missing string for HTTPHEADER.");
+ return false;
+ }
+ curl_headers.push_back(*i);
} else {
// Do not return error for compatibility reason.
std::string err = "Unexpected argument: ";
@@ -2716,8 +2725,17 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
check_curl_result(res, "DOWNLOAD cannot set user password: ");
}
+ struct curl_slist* headers = CM_NULLPTR;
+ for (std::list<std::string>::const_iterator h = curl_headers.begin();
+ h != curl_headers.end(); ++h) {
+ headers = ::curl_slist_append(headers, h->c_str());
+ }
+ ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+
res = ::curl_easy_perform(curl);
+ ::curl_slist_free_all(headers);
+
/* always cleanup */
g_curl.release();
::curl_easy_cleanup(curl);
@@ -2798,6 +2816,8 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
bool showProgress = false;
std::string userpwd;
+ std::list<std::string> curl_headers;
+
while (i != args.end()) {
if (*i == "TIMEOUT") {
++i;
@@ -2838,6 +2858,13 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
return false;
}
userpwd = *i;
+ } else if (*i == "HTTPHEADER") {
+ ++i;
+ if (i == args.end()) {
+ this->SetError("UPLOAD missing string for HTTPHEADER.");
+ return false;
+ }
+ curl_headers.push_back(*i);
} else {
// Do not return error for compatibility reason.
std::string err = "Unexpected argument: ";
@@ -2956,8 +2983,17 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
check_curl_result(res, "UPLOAD cannot set user password: ");
}
+ struct curl_slist* headers = CM_NULLPTR;
+ for (std::list<std::string>::const_iterator h = curl_headers.begin();
+ h != curl_headers.end(); ++h) {
+ headers = ::curl_slist_append(headers, h->c_str());
+ }
+ ::curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+
res = ::curl_easy_perform(curl);
+ ::curl_slist_free_all(headers);
+
/* always cleanup */
g_curl.release();
::curl_easy_cleanup(curl);
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 8338c2a..72b5320 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -12,6 +12,7 @@
#include "cmFindPackageCommand.h"
#include "cmAlgorithms.h"
+#include <cmSystemTools.h>
#include <cmsys/Directory.hxx>
#include <cmsys/Encoding.hxx>
#include <cmsys/RegularExpression.hxx>
@@ -33,6 +34,45 @@ cmFindPackageCommand::PathLabel cmFindPackageCommand::PathLabel::Builds(
cmFindPackageCommand::PathLabel
cmFindPackageCommand::PathLabel::SystemRegistry("SYSTEM_PACKAGE_REGISTRY");
+struct StrverscmpGreater
+{
+ bool operator()(const std::string& lhs, const std::string& rhs) const
+ {
+ return cmSystemTools::strverscmp(lhs, rhs) > 0;
+ }
+};
+
+struct StrverscmpLesser
+{
+ bool operator()(const std::string& lhs, const std::string& rhs) const
+ {
+ return cmSystemTools::strverscmp(lhs, rhs) < 0;
+ }
+};
+
+void cmFindPackageCommand::Sort(std::vector<std::string>::iterator begin,
+ std::vector<std::string>::iterator end,
+ SortOrderType order, SortDirectionType dir)
+{
+ if (order == Name_order) {
+ if (dir == Dec) {
+ std::sort(begin, end, std::greater<std::string>());
+ } else {
+ std::sort(begin, end);
+ }
+ } else if (order == Natural)
+ // natural order uses letters and numbers (contiguous numbers digit are
+ // compared such that e.g. 000 00 < 01 < 010 < 09 < 0 < 1 < 9 < 10
+ {
+ if (dir == Dec) {
+ std::sort(begin, end, StrverscmpGreater());
+ } else {
+ std::sort(begin, end, StrverscmpLesser());
+ }
+ }
+ // else do not sort
+}
+
cmFindPackageCommand::cmFindPackageCommand()
{
this->CMakePathName = "PACKAGE";
@@ -58,7 +98,8 @@ cmFindPackageCommand::cmFindPackageCommand()
this->VersionFoundTweak = 0;
this->VersionFoundCount = 0;
this->RequiredCMakeVersion = 0;
-
+ this->SortOrder = None;
+ this->SortDirection = Asc;
this->AppendSearchPathGroups();
}
@@ -135,6 +176,23 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
this->NoSystemRegistry = true;
}
+ // Check if Sorting should be enabled
+ if (const char* so =
+ this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_ORDER")) {
+
+ if (strcmp(so, "NAME") == 0) {
+ this->SortOrder = Name_order;
+ } else if (strcmp(so, "NATURAL") == 0) {
+ this->SortOrder = Natural;
+ } else {
+ this->SortOrder = None;
+ }
+ }
+ if (const char* sd =
+ this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_DIRECTION")) {
+ this->SortDirection = strcmp(sd, "ASC") == 0 ? Asc : Dec;
+ }
+
// Find the current root path mode.
this->SelectDefaultRootPathMode();
@@ -1666,17 +1724,33 @@ private:
class cmFileListGeneratorProject : public cmFileListGeneratorBase
{
public:
- cmFileListGeneratorProject(std::vector<std::string> const& names)
+ cmFileListGeneratorProject(std::vector<std::string> const& names,
+ cmFindPackageCommand::SortOrderType so,
+ cmFindPackageCommand::SortDirectionType sd)
: cmFileListGeneratorBase()
, Names(names)
{
+ this->SetSort(so, sd);
}
cmFileListGeneratorProject(cmFileListGeneratorProject const& r)
: cmFileListGeneratorBase()
, Names(r.Names)
{
+ this->SetSort(r.SortOrder, r.SortDirection);
+ }
+
+ void SetSort(cmFindPackageCommand::SortOrderType o,
+ cmFindPackageCommand::SortDirectionType d)
+ {
+ SortOrder = o;
+ SortDirection = d;
}
+protected:
+ // sort parameters
+ cmFindPackageCommand::SortOrderType SortOrder;
+ cmFindPackageCommand::SortDirectionType SortDirection;
+
private:
std::vector<std::string> const& Names;
bool Search(std::string const& parent, cmFileList& lister) CM_OVERRIDE
@@ -1698,6 +1772,13 @@ private:
}
}
+ // before testing the matches check if there is a specific sorting order to
+ // perform
+ if (this->SortOrder != cmFindPackageCommand::None) {
+ cmFindPackageCommand::Sort(matches.begin(), matches.end(), SortOrder,
+ SortDirection);
+ }
+
for (std::vector<std::string>::const_iterator i = matches.begin();
i != matches.end(); ++i) {
if (this->Consider(parent + *i, lister)) {
@@ -1895,7 +1976,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names);
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection);
if (lister.Search()) {
return true;
}
@@ -1905,7 +1987,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorCaseInsensitive("cmake");
if (lister.Search()) {
return true;
@@ -1932,7 +2015,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
lister / cmFileListGeneratorFixed(prefix) /
cmFileListGeneratorEnumerate(common) /
cmFileListGeneratorFixed("cmake") /
- cmFileListGeneratorProject(this->Names);
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection);
if (lister.Search()) {
return true;
}
@@ -1943,7 +2027,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names);
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection);
if (lister.Search()) {
return true;
}
@@ -1954,7 +2039,8 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorCaseInsensitive("cmake");
if (lister.Search()) {
return true;
@@ -1965,10 +2051,12 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorEnumerate(common) /
cmFileListGeneratorFixed("cmake") /
- cmFileListGeneratorProject(this->Names);
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection);
if (lister.Search()) {
return true;
}
@@ -1978,9 +2066,11 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names);
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection);
if (lister.Search()) {
return true;
}
@@ -1990,9 +2080,11 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
cmFindPackageFileList lister(this);
lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names) /
+ cmFileListGeneratorProject(this->Names, this->SortOrder,
+ this->SortDirection) /
cmFileListGeneratorCaseInsensitive("cmake");
if (lister.Search()) {
return true;
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 087107e..babdd5a 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -24,6 +24,27 @@ class cmFindPackageFileList;
class cmFindPackageCommand : public cmFindCommon
{
public:
+ /*! A sorting order strategy to be applied to recovered package folders (see
+ * FIND_PACKAGE_SORT_ORDER)*/
+ enum /*class*/ SortOrderType
+ {
+ None,
+ Name_order,
+ Natural
+ };
+ /*! A sorting direction to be applied to recovered package folders (see
+ * FIND_PACKAGE_SORT_DIRECTION)*/
+ enum /*class*/ SortDirectionType
+ {
+ Asc,
+ Dec
+ };
+
+ /*! sorts a given list of string based on the input sort parameters */
+ static void Sort(std::vector<std::string>::iterator begin,
+ std::vector<std::string>::iterator end, SortOrderType order,
+ SortDirectionType dir);
+
cmFindPackageCommand();
/**
@@ -156,6 +177,11 @@ private:
std::vector<std::string> Configs;
std::set<std::string> IgnoredPaths;
+ /*! the selected sortOrder (None by default)*/
+ SortOrderType SortOrder;
+ /*! the selected sortDirection (Asc by default)*/
+ SortDirectionType SortDirection;
+
struct ConfigFileInfo
{
std::string filename;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index ef8266f..e85d80e 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1068,8 +1068,8 @@ void cmGlobalGenerator::Configure()
cmTargets* targets = &(mf->GetTargets());
cmTargets::iterator tit;
for (tit = globalTargets.begin(); tit != globalTargets.end(); ++tit) {
- (*targets)[tit->first] = tit->second;
- (*targets)[tit->first].SetMakefile(mf);
+ targets->insert(
+ cmTargets::value_type(tit->first, tit->second.CopyForDirectory(mf)));
}
}
@@ -2101,9 +2101,12 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
}
}
if (cmSystemTools::FileExists(configFile.c_str())) {
- (*targets)[this->GetPackageTargetName()] = this->CreateGlobalTarget(
- this->GetPackageTargetName(), "Run CPack packaging tool...",
- &cpackCommandLines, depends, workingDir.c_str(), /*uses_terminal*/ true);
+ targets->insert(cmTargets::value_type(
+ this->GetPackageTargetName(),
+ this->CreateGlobalTarget(this->GetPackageTargetName(),
+ "Run CPack packaging tool...",
+ &cpackCommandLines, depends, workingDir.c_str(),
+ /*uses_terminal*/ true)));
}
// CPack source
const char* packageSourceTargetName = this->GetPackageSourceTargetName();
@@ -2122,10 +2125,12 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
if (cmSystemTools::FileExists(configFile.c_str())) {
singleLine.push_back(configFile);
cpackCommandLines.push_back(singleLine);
- (*targets)[packageSourceTargetName] = this->CreateGlobalTarget(
- packageSourceTargetName, "Run CPack packaging tool for source...",
- &cpackCommandLines, depends, workingDir.c_str(),
- /*uses_terminal*/ true);
+ targets->insert(cmTargets::value_type(
+ packageSourceTargetName,
+ this->CreateGlobalTarget(
+ packageSourceTargetName, "Run CPack packaging tool for source...",
+ &cpackCommandLines, depends, workingDir.c_str(),
+ /*uses_terminal*/ true)));
}
}
@@ -2146,10 +2151,11 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
singleLine.push_back("$(ARGS)");
}
cpackCommandLines.push_back(singleLine);
- (*targets)[this->GetTestTargetName()] =
+ targets->insert(cmTargets::value_type(
+ this->GetTestTargetName(),
this->CreateGlobalTarget(this->GetTestTargetName(), "Running tests...",
&cpackCommandLines, depends, CM_NULLPTR,
- /*uses_terminal*/ true);
+ /*uses_terminal*/ true)));
}
// Edit Cache
@@ -2167,18 +2173,22 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
cpackCommandLines.push_back(singleLine);
- (*targets)[editCacheTargetName] = this->CreateGlobalTarget(
- editCacheTargetName, "Running CMake cache editor...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true);
+ targets->insert(cmTargets::value_type(
+ editCacheTargetName,
+ this->CreateGlobalTarget(
+ editCacheTargetName, "Running CMake cache editor...",
+ &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true)));
} else {
singleLine.push_back(cmSystemTools::GetCMakeCommand());
singleLine.push_back("-E");
singleLine.push_back("echo");
singleLine.push_back("No interactive CMake dialog available.");
cpackCommandLines.push_back(singleLine);
- (*targets)[editCacheTargetName] = this->CreateGlobalTarget(
- editCacheTargetName, "No interactive CMake dialog available...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ false);
+ targets->insert(cmTargets::value_type(
+ editCacheTargetName,
+ this->CreateGlobalTarget(
+ editCacheTargetName, "No interactive CMake dialog available...",
+ &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ false)));
}
}
@@ -2193,9 +2203,11 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
cpackCommandLines.push_back(singleLine);
- (*targets)[rebuildCacheTargetName] = this->CreateGlobalTarget(
- rebuildCacheTargetName, "Running CMake to regenerate build system...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true);
+ targets->insert(cmTargets::value_type(
+ rebuildCacheTargetName,
+ this->CreateGlobalTarget(
+ rebuildCacheTargetName, "Running CMake to regenerate build system...",
+ &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true)));
}
// Install
@@ -2219,9 +2231,11 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
ostr << "Only default component available";
}
singleLine.push_back(ostr.str());
- (*targets)["list_install_components"] = this->CreateGlobalTarget(
- "list_install_components", ostr.str().c_str(), &cpackCommandLines,
- depends, CM_NULLPTR, /*uses_terminal*/ false);
+ targets->insert(cmTargets::value_type(
+ "list_install_components",
+ this->CreateGlobalTarget("list_install_components", ostr.str().c_str(),
+ &cpackCommandLines, depends, CM_NULLPTR,
+ /*uses_terminal*/ false)));
}
std::string cmd = cmSystemTools::GetCMakeCommand();
cpackCommandLines.erase(cpackCommandLines.begin(),
@@ -2260,9 +2274,11 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
singleLine.push_back("-P");
singleLine.push_back("cmake_install.cmake");
cpackCommandLines.push_back(singleLine);
- (*targets)[this->GetInstallTargetName()] = this->CreateGlobalTarget(
- this->GetInstallTargetName(), "Install the project...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true);
+ targets->insert(cmTargets::value_type(
+ this->GetInstallTargetName(),
+ this->CreateGlobalTarget(this->GetInstallTargetName(),
+ "Install the project...", &cpackCommandLines,
+ depends, CM_NULLPTR, /*uses_terminal*/ true)));
// install_local
if (const char* install_local = this->GetInstallLocalTargetName()) {
@@ -2274,9 +2290,11 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
cpackCommandLines.end());
cpackCommandLines.push_back(localCmdLine);
- (*targets)[install_local] = this->CreateGlobalTarget(
- install_local, "Installing only the local directory...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true);
+ targets->insert(cmTargets::value_type(
+ install_local,
+ this->CreateGlobalTarget(
+ install_local, "Installing only the local directory...",
+ &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true)));
}
// install_strip
@@ -2290,9 +2308,11 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
cpackCommandLines.end());
cpackCommandLines.push_back(stripCmdLine);
- (*targets)[install_strip] = this->CreateGlobalTarget(
- install_strip, "Installing the project stripped...",
- &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true);
+ targets->insert(cmTargets::value_type(
+ install_strip,
+ this->CreateGlobalTarget(
+ install_strip, "Installing the project stripped...",
+ &cpackCommandLines, depends, CM_NULLPTR, /*uses_terminal*/ true)));
}
}
}
@@ -2332,8 +2352,8 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(
const char* workingDirectory, bool uses_terminal)
{
// Package
- cmTarget target;
- target.SetType(cmState::GLOBAL_TARGET, name);
+ cmTarget target(name, cmState::GLOBAL_TARGET, cmTarget::VisibilityNormal,
+ CM_NULLPTR);
target.SetProperty("EXCLUDE_FROM_ALL", "TRUE");
std::vector<std::string> no_outputs;
diff --git a/Source/cmInstallTargetsCommand.cxx b/Source/cmInstallTargetsCommand.cxx
index 056ea24..6b594b6 100644
--- a/Source/cmInstallTargetsCommand.cxx
+++ b/Source/cmInstallTargetsCommand.cxx
@@ -37,14 +37,17 @@ bool cmInstallTargetsCommand::InitialPass(std::vector<std::string> const& args,
}
runtime_dir = *s;
- } else if (tgts.find(*s) != tgts.end()) {
- tgts[*s].SetInstallPath(args[0].c_str());
- tgts[*s].SetRuntimeInstallPath(runtime_dir.c_str());
- tgts[*s].SetHaveInstallRule(true);
} else {
- std::string str = "Cannot find target: \"" + *s + "\" to install.";
- this->SetError(str);
- return false;
+ cmTargets::iterator ti = tgts.find(*s);
+ if (ti != tgts.end()) {
+ ti->second.SetInstallPath(args[0].c_str());
+ ti->second.SetRuntimeInstallPath(runtime_dir.c_str());
+ ti->second.SetHaveInstallRule(true);
+ } else {
+ std::string str = "Cannot find target: \"" + *s + "\" to install.";
+ this->SetError(str);
+ return false;
+ }
}
}
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index e5a5e6e..508c670 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -979,8 +979,9 @@ void cmMakefile::AddCustomCommandOldStyle(
// then add the source to the target to make sure the rule is
// included.
if (sf && !sf->GetPropertyAsBool("__CMAKE_RULE")) {
- if (this->Targets.find(target) != this->Targets.end()) {
- this->Targets[target].AddSource(sf->GetFullPath());
+ cmTargets::iterator ti = this->Targets.find(target);
+ if (ti != this->Targets.end()) {
+ ti->second.AddSource(sf->GetFullPath());
} else {
cmSystemTools::Error("Attempt to add a custom rule to a target "
"that does not exist yet for target ",
@@ -1924,10 +1925,10 @@ cmTarget* cmMakefile::AddNewTarget(cmState::TargetType type,
const std::string& name)
{
cmTargets::iterator it =
- this->Targets.insert(cmTargets::value_type(name, cmTarget())).first;
- cmTarget& target = it->second;
- target.SetType(type, name);
- target.SetMakefile(this);
+ this->Targets
+ .insert(cmTargets::value_type(
+ name, cmTarget(name, type, cmTarget::VisibilityNormal, this)))
+ .first;
this->GetGlobalGenerator()->IndexTarget(&it->second);
return &it->second;
}
@@ -3709,10 +3710,10 @@ cmTarget* cmMakefile::AddImportedTarget(const std::string& name,
cmState::TargetType type, bool global)
{
// Create the target.
- CM_AUTO_PTR<cmTarget> target(new cmTarget);
- target->SetType(type, name);
- target->MarkAsImported(global);
- target->SetMakefile(this);
+ CM_AUTO_PTR<cmTarget> target(
+ new cmTarget(name, type, global ? cmTarget::VisibilityImportedGlobally
+ : cmTarget::VisibilityImported,
+ this));
// Add to the set of available imported targets.
this->ImportedTargets[name] = target.get();
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 7352217..36ed614 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -2416,6 +2416,83 @@ bool cmSystemTools::VersionCompareGreaterEq(std::string const& lhs,
lhs.c_str(), rhs.c_str());
}
+static size_t cm_strverscmp_find_first_difference_or_end(const char* lhs,
+ const char* rhs)
+{
+ size_t i = 0;
+ /* Step forward until we find a difference or both strings end together.
+ The difference may lie on the null-terminator of one string. */
+ while (lhs[i] == rhs[i] && lhs[i] != 0) {
+ ++i;
+ }
+ return i;
+}
+
+static size_t cm_strverscmp_find_digits_begin(const char* s, size_t i)
+{
+ /* Step back until we are not preceded by a digit. */
+ while (i > 0 && isdigit(s[i - 1])) {
+ --i;
+ }
+ return i;
+}
+
+static size_t cm_strverscmp_find_digits_end(const char* s, size_t i)
+{
+ /* Step forward over digits. */
+ while (isdigit(s[i])) {
+ ++i;
+ }
+ return i;
+}
+
+static size_t cm_strverscmp_count_leading_zeros(const char* s, size_t b)
+{
+ size_t i = b;
+ /* Step forward over zeros that are followed by another digit. */
+ while (s[i] == '0' && isdigit(s[i + 1])) {
+ ++i;
+ }
+ return i - b;
+}
+
+static int cm_strverscmp(const char* lhs, const char* rhs)
+{
+ size_t const i = cm_strverscmp_find_first_difference_or_end(lhs, rhs);
+ if (lhs[i] != rhs[i]) {
+ /* The strings differ starting at 'i'. Check for a digit sequence. */
+ size_t const b = cm_strverscmp_find_digits_begin(lhs, i);
+ if (b != i || (isdigit(lhs[i]) && isdigit(rhs[i]))) {
+ /* A digit sequence starts at 'b', preceding or at 'i'. */
+
+ /* Look for leading zeros, implying a leading decimal point. */
+ size_t const lhs_zeros = cm_strverscmp_count_leading_zeros(lhs, b);
+ size_t const rhs_zeros = cm_strverscmp_count_leading_zeros(rhs, b);
+ if (lhs_zeros != rhs_zeros) {
+ /* The side with more leading zeros orders first. */
+ return rhs_zeros > lhs_zeros ? 1 : -1;
+ }
+ if (lhs_zeros == 0) {
+ /* No leading zeros; compare digit sequence lengths. */
+ size_t const lhs_end = cm_strverscmp_find_digits_end(lhs, i);
+ size_t const rhs_end = cm_strverscmp_find_digits_end(rhs, i);
+ if (lhs_end != rhs_end) {
+ /* The side with fewer digits orders first. */
+ return lhs_end > rhs_end ? 1 : -1;
+ }
+ }
+ }
+ }
+
+ /* Ordering was not decided by digit sequence lengths; compare bytes. */
+ return lhs[i] - rhs[i];
+}
+
+int cmSystemTools::strverscmp(std::string const& lhs, std::string const& rhs)
+{
+ return cm_strverscmp(lhs.c_str(), rhs.c_str());
+}
+
bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
bool* removed)
{
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 3c1a9f4..aecf40e 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -306,6 +306,16 @@ public:
std::string const& rhs);
/**
+ * Compare two ASCII strings using natural versioning order.
+ * Non-numerical characters are compared directly.
+ * Numerical characters are first globbed such that, e.g.
+ * `test000 < test01 < test0 < test1 < test10`.
+ * Return a value less than, equal to, or greater than zero if lhs
+ * precedes, equals, or succeeds rhs in the defined ordering.
+ */
+ static int strverscmp(std::string const& lhs, std::string const& rhs);
+
+ /**
* Determine the file type based on the extension
*/
static FileFormat GetFileFormat(const char* ext);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index d5274cd..d964f00 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -59,28 +59,41 @@ public:
std::vector<cmListFileBacktrace> LinkImplementationPropertyBacktraces;
};
-cmTarget::cmTarget()
+cmTarget::cmTarget(std::string const& name, cmState::TargetType type,
+ Visibility vis, cmMakefile* mf)
{
+ assert(mf || type == cmState::GLOBAL_TARGET);
+ this->Name = name;
+ this->TargetTypeValue = type;
this->Makefile = CM_NULLPTR;
this->HaveInstallRule = false;
this->DLLPlatform = false;
this->IsAndroid = false;
- this->IsImportedTarget = false;
- this->ImportedGloballyVisible = false;
+ this->IsImportedTarget =
+ (vis == VisibilityImported || vis == VisibilityImportedGlobally);
+ this->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
this->BuildInterfaceIncludesAppended = false;
-}
-void cmTarget::SetType(cmState::TargetType type, const std::string& name)
-{
- this->Name = name;
// only add dependency information for library targets
- this->TargetTypeValue = type;
if (this->TargetTypeValue >= cmState::STATIC_LIBRARY &&
this->TargetTypeValue <= cmState::MODULE_LIBRARY) {
this->RecordDependencies = true;
} else {
this->RecordDependencies = false;
}
+
+ if (mf) {
+ this->SetMakefile(mf);
+ }
+}
+
+cmTarget cmTarget::CopyForDirectory(cmMakefile* mf) const
+{
+ assert(this->GetType() == cmState::GLOBAL_TARGET);
+ assert(this->GetMakefile() == CM_NULLPTR);
+ cmTarget result(*this);
+ result.SetMakefile(mf);
+ return result;
}
void cmTarget::SetMakefile(cmMakefile* mf)
@@ -1062,12 +1075,6 @@ void cmTarget::CheckProperty(const std::string& prop,
}
}
-void cmTarget::MarkAsImported(bool global)
-{
- this->IsImportedTarget = true;
- this->ImportedGloballyVisible = global;
-}
-
bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
{
if (this->IsImported()) {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index fc30166..ebc92f3 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -63,7 +63,16 @@ private:
class cmTarget
{
public:
- cmTarget();
+ enum Visibility
+ {
+ VisibilityNormal,
+ VisibilityImported,
+ VisibilityImportedGlobally
+ };
+
+ cmTarget(std::string const& name, cmState::TargetType type, Visibility vis,
+ cmMakefile* mf);
+
enum CustomCommandType
{
PRE_BUILD,
@@ -76,18 +85,13 @@ public:
*/
cmState::TargetType GetType() const { return this->TargetTypeValue; }
- /**
- * Set the target type
- */
- void SetType(cmState::TargetType f, const std::string& name);
-
- void MarkAsImported(bool global = false);
-
///! Set/Get the name of the target
const std::string& GetName() const { return this->Name; }
- ///! Set the cmMakefile that owns this target
- void SetMakefile(cmMakefile* mf);
+ /** Get a copy of this target adapted for the given directory. */
+ cmTarget CopyForDirectory(cmMakefile* mf) const;
+
+ /** Get the cmMakefile that owns this target. */
cmMakefile* GetMakefile() const { return this->Makefile; }
#define DECLARE_TARGET_POLICY(POLICY) \
@@ -279,6 +283,8 @@ public:
};
private:
+ void SetMakefile(cmMakefile* mf);
+
bool HandleLocationPropertyPolicy(cmMakefile* context) const;
const char* GetSuffixVariableInternal(bool implib) const;
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 0d61a3d..18a7894 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -1046,7 +1046,7 @@ const char* cmake::GetHomeOutputDirectory() const
return this->State->GetBinaryDirectory();
}
-std::string cmake::FindCacheFile(const std::string& binaryDir) const
+std::string cmake::FindCacheFile(const std::string& binaryDir)
{
std::string cachePath = binaryDir;
cmSystemTools::ConvertToUnixSlashes(cachePath);
diff --git a/Source/cmake.h b/Source/cmake.h
index 30661d9..6095a59 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -194,7 +194,7 @@ public:
}
///! Return the full path to where the CMakeCache.txt file should be.
- std::string FindCacheFile(const std::string& binaryDir) const;
+ static std::string FindCacheFile(const std::string& binaryDir);
///! Return the global generator assigned to this instance of cmake
void SetGlobalGenerator(cmGlobalGenerator*);
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 87f6048..c4fe5e8 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -123,6 +123,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
SET(KWSYS_USE_FStream 1)
SET(KWSYS_USE_String 1)
SET(KWSYS_USE_SystemInformation 1)
+ SET(KWSYS_USE_ConsoleBuf 1)
ENDIF()
# Enforce component dependencies.
@@ -154,6 +155,9 @@ ENDIF()
IF(KWSYS_USE_FStream)
SET(KWSYS_USE_Encoding 1)
ENDIF()
+IF(KWSYS_USE_ConsoleBuf)
+ SET(KWSYS_USE_Encoding 1)
+ENDIF()
# Setup the large file support default.
IF(KWSYS_LFS_DISABLE)
@@ -673,7 +677,7 @@ SET(KWSYS_HXX_FILES Configure String
# Add selected C++ classes.
SET(cppclasses
Directory DynamicLoader Encoding Glob RegularExpression SystemTools
- CommandLineArguments IOStream FStream SystemInformation
+ CommandLineArguments IOStream FStream SystemInformation ConsoleBuf
)
FOREACH(cpp ${cppclasses})
IF(KWSYS_USE_${cpp})
@@ -926,6 +930,20 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
testFStream
)
ENDIF()
+ IF(KWSYS_USE_ConsoleBuf)
+ ADD_EXECUTABLE(testConsoleBufChild testConsoleBufChild.cxx)
+ SET_PROPERTY(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ TARGET_LINK_LIBRARIES(testConsoleBufChild ${KWSYS_NAMESPACE})
+ SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ testConsoleBuf
+ )
+ IF("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" AND
+ NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.0")
+ set_property(SOURCE testConsoleBuf.cxx testConsoleBufChild.cxx PROPERTY COMPILE_FLAGS /utf-8)
+ ENDIF()
+ SET_PROPERTY(SOURCE testConsoleBuf.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
+ ENDIF()
IF(KWSYS_USE_SystemInformation)
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation)
ENDIF()
diff --git a/Source/kwsys/ConsoleBuf.hxx.in b/Source/kwsys/ConsoleBuf.hxx.in
new file mode 100644
index 0000000..8aeeda1
--- /dev/null
+++ b/Source/kwsys/ConsoleBuf.hxx.in
@@ -0,0 +1,348 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef @KWSYS_NAMESPACE@_ConsoleBuf_hxx
+#define @KWSYS_NAMESPACE@_ConsoleBuf_hxx
+
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+#include <@KWSYS_NAMESPACE@/Encoding.hxx>
+#include <string>
+#include <cstring>
+#include <sstream>
+#include <streambuf>
+#include <iostream>
+#include <stdexcept>
+
+#if defined(_WIN32)
+# include <windows.h>
+# if __cplusplus >= 201103L
+# include <system_error>
+# endif
+#endif
+
+namespace @KWSYS_NAMESPACE@
+{
+#if defined(_WIN32)
+
+ template<class CharT, class Traits = std::char_traits<CharT> >
+ class @KWSYS_NAMESPACE@_EXPORT BasicConsoleBuf :
+ public std::basic_streambuf<CharT, Traits> {
+ public:
+ typedef typename Traits::int_type int_type;
+ typedef typename Traits::char_type char_type;
+
+ class Manager {
+ public:
+ Manager(std::basic_ios<CharT, Traits> &ios, const bool err = false)
+ : m_consolebuf(0)
+ {
+ m_ios = &ios;
+ try {
+ m_consolebuf = new BasicConsoleBuf<CharT, Traits>(err);
+ m_streambuf = m_ios->rdbuf(m_consolebuf);
+ } catch (const std::runtime_error& ex) {
+ std::cerr << "Failed to create ConsoleBuf!" << std::endl
+ << ex.what() << std::endl;
+ };
+ }
+
+ ~Manager()
+ {
+ if (m_consolebuf) {
+ delete m_consolebuf;
+ m_ios->rdbuf(m_streambuf);
+ }
+ }
+
+ private:
+ std::basic_ios<CharT, Traits> *m_ios;
+ std::basic_streambuf<CharT, Traits> *m_streambuf;
+ BasicConsoleBuf<CharT, Traits> *m_consolebuf;
+ };
+
+ BasicConsoleBuf(const bool err = false) :
+ flush_on_newline(true),
+ input_pipe_codepage(0),
+ output_pipe_codepage(0),
+ input_file_codepage(CP_UTF8),
+ output_file_codepage(CP_UTF8),
+ m_consolesCodepage(0)
+ {
+ m_hInput = ::GetStdHandle(STD_INPUT_HANDLE);
+ checkHandle(true, "STD_INPUT_HANDLE");
+ if (!setActiveInputCodepage()) {
+ throw std::runtime_error("setActiveInputCodepage failed!");
+ }
+ m_hOutput = err ? ::GetStdHandle(STD_ERROR_HANDLE) :
+ ::GetStdHandle(STD_OUTPUT_HANDLE);
+ checkHandle(false, err ? "STD_ERROR_HANDLE" : "STD_OUTPUT_HANDLE");
+ if (!setActiveOutputCodepage()) {
+ throw std::runtime_error("setActiveOutputCodepage failed!");
+ }
+ _setg();
+ _setp();
+ }
+
+ ~BasicConsoleBuf() throw()
+ {
+ sync();
+ }
+
+ bool activateCodepageChange()
+ {
+ return setActiveInputCodepage() && setActiveOutputCodepage();
+ }
+
+ protected:
+ virtual int sync() {
+ bool success = true;
+ if (m_hInput && m_isConsoleInput &&
+ ::FlushConsoleInputBuffer(m_hInput) == 0) {
+ success = false;
+ }
+ if (m_hOutput && !m_obuffer.empty()) {
+ const std::wstring wbuffer = getBuffer(m_obuffer);
+ if (m_isConsoleOutput) {
+ DWORD charsWritten;
+ success = ::WriteConsoleW(m_hOutput, wbuffer.c_str(),
+ (DWORD)wbuffer.size(), &charsWritten,
+ NULL) == 0 ? false : true;
+ } else {
+ DWORD bytesWritten;
+ std::string buffer;
+ success = encodeOutputBuffer(wbuffer, buffer);
+ if (success) {
+ success = ::WriteFile(m_hOutput, buffer.c_str(),
+ (DWORD)buffer.size(), &bytesWritten,
+ NULL) == 0 ? false : true;
+ }
+ }
+ }
+ m_ibuffer.clear();
+ m_obuffer.clear();
+ _setg();
+ _setp();
+ return success ? 0 : -1;
+ }
+
+ virtual int_type underflow() {
+ if (this->gptr() >= this->egptr()) {
+ if (!m_hInput) {
+ _setg(true);
+ return Traits::eof();
+ }
+ if (m_isConsoleInput) {
+ wchar_t wbuffer[128];
+ DWORD charsRead;
+ if (::ReadConsoleW(m_hInput, wbuffer, (sizeof(wbuffer) / sizeof(wbuffer[0])) - 1,
+ &charsRead, NULL) == 0 || charsRead == 0) {
+ _setg(true);
+ return Traits::eof();
+ }
+ wbuffer[charsRead] = L'\0';
+ setBuffer(wbuffer, m_ibuffer);
+ } else {
+ std::wstring totalBuffer;
+ std::wstring wbuffer;
+ char buffer[128];
+ DWORD bytesRead;
+ while (::ReadFile(m_hInput, buffer, (sizeof(buffer) / sizeof(buffer[0])) - 1,
+ &bytesRead, NULL) == 0) {
+ if (::GetLastError() == ERROR_MORE_DATA) {
+ buffer[bytesRead] = '\0';
+ if (decodeInputBuffer(buffer, wbuffer)) {
+ totalBuffer += wbuffer;
+ continue;
+ }
+ }
+ _setg(true);
+ return Traits::eof();
+ }
+ buffer[bytesRead] = '\0';
+ if (!decodeInputBuffer(buffer, wbuffer)) {
+ _setg(true);
+ return Traits::eof();
+ }
+ totalBuffer += wbuffer;
+ setBuffer(totalBuffer, m_ibuffer);
+ }
+ _setg();
+ }
+ return Traits::to_int_type(*this->gptr());
+ }
+
+ virtual int_type overflow(int_type ch = Traits::eof()) {
+ if (!Traits::eq_int_type(ch, Traits::eof())) {
+ char_type chr = Traits::to_char_type(ch);
+ m_obuffer += chr;
+ if ((flush_on_newline && Traits::eq(chr, '\n')) ||
+ Traits::eq_int_type(ch, 0x00)) {
+ sync();
+ }
+ return ch;
+ }
+ sync();
+ return Traits::eof();
+ }
+
+ public:
+ bool flush_on_newline;
+ UINT input_pipe_codepage;
+ UINT output_pipe_codepage;
+ UINT input_file_codepage;
+ UINT output_file_codepage;
+
+ private:
+ HANDLE m_hInput;
+ HANDLE m_hOutput;
+ std::basic_string<char_type> m_ibuffer;
+ std::basic_string<char_type> m_obuffer;
+ bool m_isConsoleInput;
+ bool m_isConsoleOutput;
+ UINT m_activeInputCodepage;
+ UINT m_activeOutputCodepage;
+ UINT m_consolesCodepage;
+ void checkHandle(bool input, std::string handleName) {
+ if ((input && m_hInput == INVALID_HANDLE_VALUE) ||
+ (!input && m_hOutput == INVALID_HANDLE_VALUE)) {
+ std::string errmsg = "GetStdHandle(" + handleName +
+ ") returned INVALID_HANDLE_VALUE";
+#if __cplusplus >= 201103L
+ throw std::system_error(::GetLastError(),
+ std::system_category(), errmsg);
+#else
+ throw std::runtime_error(errmsg);
+#endif
+ }
+ }
+ UINT getConsolesCodepage() {
+ if (!m_consolesCodepage) {
+ m_consolesCodepage = GetConsoleCP();
+ if (!m_consolesCodepage) {
+ m_consolesCodepage = GetACP();
+ }
+ }
+ return m_consolesCodepage;
+ }
+ bool setActiveInputCodepage() {
+ m_isConsoleInput = false;
+ switch (GetFileType(m_hInput)) {
+ case FILE_TYPE_DISK:
+ m_activeInputCodepage = input_file_codepage;
+ break;
+ case FILE_TYPE_CHAR:
+ m_isConsoleInput = true;
+ break;
+ case FILE_TYPE_PIPE:
+ m_activeInputCodepage = input_pipe_codepage;
+ break;
+ default:
+ return false;
+ }
+ if (!m_isConsoleInput && m_activeInputCodepage == 0) {
+ m_activeInputCodepage = getConsolesCodepage();
+ }
+ return true;
+ }
+ bool setActiveOutputCodepage() {
+ m_isConsoleOutput = false;
+ switch (GetFileType(m_hOutput)) {
+ case FILE_TYPE_DISK:
+ m_activeOutputCodepage = output_file_codepage;
+ break;
+ case FILE_TYPE_CHAR:
+ m_isConsoleOutput = true;
+ break;
+ case FILE_TYPE_PIPE:
+ m_activeOutputCodepage = output_pipe_codepage;
+ break;
+ default:
+ return false;
+ }
+ if (!m_isConsoleOutput && m_activeOutputCodepage == 0) {
+ m_activeOutputCodepage = getConsolesCodepage();
+ }
+ return true;
+ }
+ void _setg(bool empty = false) {
+ if (!empty) {
+ this->setg((char_type *)m_ibuffer.data(),
+ (char_type *)m_ibuffer.data(),
+ (char_type *)m_ibuffer.data() + m_ibuffer.size());
+ } else {
+ this->setg((char_type *)m_ibuffer.data(),
+ (char_type *)m_ibuffer.data() + m_ibuffer.size(),
+ (char_type *)m_ibuffer.data() + m_ibuffer.size());
+ }
+ }
+ void _setp() {
+ this->setp((char_type *)m_obuffer.data(),
+ (char_type *)m_obuffer.data() + m_obuffer.size());
+ }
+ bool encodeOutputBuffer(const std::wstring wbuffer,
+ std::string &buffer) {
+ const int length = WideCharToMultiByte(m_activeOutputCodepage, 0,
+ wbuffer.c_str(),
+ (int)wbuffer.size(), NULL, 0,
+ NULL, NULL);
+ char *buf = new char[length + 1];
+ const bool success = WideCharToMultiByte(m_activeOutputCodepage, 0,
+ wbuffer.c_str(),
+ (int)wbuffer.size(), buf,
+ length, NULL, NULL) > 0
+ ? true : false;
+ buf[length] = '\0';
+ buffer = buf;
+ delete[] buf;
+ return success;
+ }
+ bool decodeInputBuffer(const char *buffer, std::wstring &wbuffer) {
+ int actualCodepage = m_activeInputCodepage;
+ const char BOM_UTF8[] = { char(0xEF), char(0xBB), char(0xBF) };
+ if (std::memcmp(buffer, BOM_UTF8, sizeof(BOM_UTF8)) == 0) {
+ // PowerShell uses UTF-8 with BOM for pipes
+ actualCodepage = CP_UTF8;
+ buffer += sizeof(BOM_UTF8);
+ }
+ const int wlength = MultiByteToWideChar(actualCodepage, 0, buffer,
+ -1, NULL, 0);
+ wchar_t *wbuf = new wchar_t[wlength];
+ const bool success = MultiByteToWideChar(actualCodepage, 0, buffer,
+ -1, wbuf, wlength) > 0
+ ? true : false;
+ wbuffer = wbuf;
+ delete[] wbuf;
+ return success;
+ }
+ std::wstring getBuffer(const std::basic_string<char> buffer) {
+ return Encoding::ToWide(buffer);
+ }
+ std::wstring getBuffer(const std::basic_string<wchar_t> buffer) {
+ return buffer;
+ }
+ void setBuffer(const std::wstring wbuffer,
+ std::basic_string<char> &target) {
+ target = Encoding::ToNarrow(wbuffer);
+ }
+ void setBuffer(const std::wstring wbuffer,
+ std::basic_string<wchar_t> &target) {
+ target = wbuffer;
+ }
+
+ }; // BasicConsoleBuf class
+
+ typedef BasicConsoleBuf<char> ConsoleBuf;
+ typedef BasicConsoleBuf<wchar_t> WConsoleBuf;
+
+#endif
+} // KWSYS_NAMESPACE
+
+#endif
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 1a73b16..4281c38 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -3982,16 +3982,16 @@ std::string SystemTools::RelativePath(const std::string& local, const std::strin
}
#ifdef _WIN32
-static int GetCasePathName(const std::string & pathIn,
- std::string & casePath)
+static std::string GetCasePathName(std::string const& pathIn)
{
+ std::string casePath;
std::vector<std::string> path_components;
SystemTools::SplitPath(pathIn, path_components);
if(path_components[0].empty()) // First component always exists.
{
// Relative paths cannot be converted.
- casePath = "";
- return 0;
+ casePath = pathIn;
+ return casePath;
}
// Start with root component.
@@ -4015,38 +4015,45 @@ static int GetCasePathName(const std::string & pathIn,
sep = "/";
}
+ // Convert case of all components that exist.
+ bool converting = true;
for(; idx < path_components.size(); idx++)
{
casePath += sep;
sep = "/";
- std::string test_str = casePath;
- test_str += path_components[idx];
-
- // If path component contains wildcards, we skip matching
- // because these filenames are not allowed on windows,
- // and we do not want to match a different file.
- if(path_components[idx].find('*') != std::string::npos ||
- path_components[idx].find('?') != std::string::npos)
- {
- casePath = "";
- return 0;
- }
- WIN32_FIND_DATAW findData;
- HANDLE hFind = ::FindFirstFileW(Encoding::ToWide(test_str).c_str(),
- &findData);
- if (INVALID_HANDLE_VALUE != hFind)
- {
- casePath += Encoding::ToNarrow(findData.cFileName);
- ::FindClose(hFind);
- }
- else
+ if (converting)
{
- casePath = "";
- return 0;
+ // If path component contains wildcards, we skip matching
+ // because these filenames are not allowed on windows,
+ // and we do not want to match a different file.
+ if(path_components[idx].find('*') != std::string::npos ||
+ path_components[idx].find('?') != std::string::npos)
+ {
+ converting = false;
+ }
+ else
+ {
+ std::string test_str = casePath;
+ test_str += path_components[idx];
+ WIN32_FIND_DATAW findData;
+ HANDLE hFind = ::FindFirstFileW(Encoding::ToWide(test_str).c_str(),
+ &findData);
+ if (INVALID_HANDLE_VALUE != hFind)
+ {
+ path_components[idx] = Encoding::ToNarrow(findData.cFileName);
+ ::FindClose(hFind);
+ }
+ else
+ {
+ converting = false;
+ }
+ }
}
+
+ casePath += path_components[idx];
}
- return (int)casePath.size();
+ return casePath;
}
#endif
@@ -4065,11 +4072,10 @@ std::string SystemTools::GetActualCaseForPath(const std::string& p)
{
return i->second;
}
- std::string casePath;
- int len = GetCasePathName(p, casePath);
- if(len == 0 || len > MAX_PATH+1)
+ std::string casePath = GetCasePathName(p);
+ if (casePath.size() > MAX_PATH)
{
- return p;
+ return casePath;
}
(*SystemTools::PathCaseMap)[p] = casePath;
return casePath;
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 28ff0b3..5849145 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -374,10 +374,11 @@ public:
static const char* GetExecutableExtension();
/**
- * Given a path that exists on a windows machine, return the
- * actuall case of the path as it was created. If the file
- * does not exist path is returned unchanged. This does nothing
- * on unix but return path.
+ * Given a path on a Windows machine, return the actual case of
+ * the path as it exists on disk. Path components that do not
+ * exist on disk are returned unchanged. Relative paths are always
+ * returned unchanged. Drive letters are always made upper case.
+ * This does nothing on non-Windows systems but return the path.
*/
static std::string GetActualCaseForPath(const std::string& path);
diff --git a/Source/kwsys/testConsoleBuf.cxx b/Source/kwsys/testConsoleBuf.cxx
new file mode 100644
index 0000000..3dec0973
--- /dev/null
+++ b/Source/kwsys/testConsoleBuf.cxx
@@ -0,0 +1,609 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "kwsysPrivate.h"
+
+// Ignore Windows version levels defined by command-line flags. This
+// source needs access to all APIs available on the host in order for
+// the test to run properly. The test binary is not installed anyway.
+#undef _WIN32_WINNT
+#undef NTDDI_VERSION
+
+#include KWSYS_HEADER(Encoding.hxx)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "Encoding.hxx.in"
+#endif
+
+#if defined(_WIN32)
+
+#include <windows.h>
+#include <string.h>
+#include <wchar.h>
+#include <iostream>
+#include <stdexcept>
+#include "testConsoleBuf.hxx"
+
+#if defined(_MSC_VER) && _MSC_VER >= 1800
+# define KWSYS_WINDOWS_DEPRECATED_GetVersion
+#endif
+// يونيكود
+static const WCHAR UnicodeInputTestString[] = L"\u064A\u0648\u0646\u064A\u0643\u0648\u062F!";
+static UINT TestCodepage = KWSYS_ENCODING_DEFAULT_CODEPAGE;
+
+static const DWORD waitTimeout = 10 * 1000;
+static STARTUPINFO startupInfo;
+static PROCESS_INFORMATION processInfo;
+static HANDLE syncEvent;
+static std::string encodedInputTestString;
+static std::string encodedTestString;
+
+//----------------------------------------------------------------------------
+static bool createProcess(HANDLE hIn, HANDLE hOut, HANDLE hErr)
+{
+ BOOL bInheritHandles = FALSE;
+ DWORD dwCreationFlags = 0;
+ memset(&processInfo, 0, sizeof(processInfo));
+ memset(&startupInfo, 0, sizeof(startupInfo));
+ startupInfo.cb = sizeof(startupInfo);
+ startupInfo.dwFlags = STARTF_USESHOWWINDOW;
+ startupInfo.wShowWindow = SW_HIDE;
+ if (hIn || hOut || hErr) {
+ startupInfo.dwFlags |= STARTF_USESTDHANDLES;
+ startupInfo.hStdInput = hIn;
+ startupInfo.hStdOutput = hOut;
+ startupInfo.hStdError = hErr;
+ bInheritHandles = TRUE;
+ }
+
+ WCHAR cmd[MAX_PATH];
+ if (GetModuleFileNameW(NULL, cmd, MAX_PATH) == 0) {
+ std::cerr << "GetModuleFileName failed!" << std::endl;
+ return false;
+ }
+ WCHAR *p = cmd + wcslen(cmd);
+ while (p > cmd && *p != L'\\') p--;
+ *(p+1) = 0;
+ wcscat(cmd, cmdConsoleBufChild);
+ wcscat(cmd, L".exe");
+
+ bool success = CreateProcessW(NULL, // No module name (use command line)
+ cmd, // Command line
+ NULL, // Process handle not inheritable
+ NULL, // Thread handle not inheritable
+ bInheritHandles, // Set handle inheritance
+ dwCreationFlags,
+ NULL, // Use parent's environment block
+ NULL, // Use parent's starting directory
+ &startupInfo, // Pointer to STARTUPINFO structure
+ &processInfo) != 0; // Pointer to PROCESS_INFORMATION structure
+ if (!success) {
+ DWORD lastError = GetLastError();
+ std::cerr.setf(std::ios::hex, std::ios::basefield);
+ std::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd)
+ << ") failed with error: 0x" << lastError << "!" << std::endl;
+ LPWSTR message;
+ if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ lastError,
+ 0,
+ (LPWSTR)&message, 0,
+ NULL)
+ ) {
+ std::cerr << "Error message: " << kwsys::Encoding::ToNarrow(message) << std::endl;
+ HeapFree(GetProcessHeap(), 0, message);
+ } else {
+ std::cerr << "FormatMessage() failed with error: 0x" << GetLastError() << "!" << std::endl;
+ }
+ std::cerr.unsetf(std::ios::hex);
+ }
+ return success;
+}
+
+//----------------------------------------------------------------------------
+static void finishProcess(bool success)
+{
+ if (success) {
+ success = WaitForSingleObject(processInfo.hProcess, waitTimeout)
+ == WAIT_OBJECT_0;
+ };
+ if (!success) {
+ TerminateProcess(processInfo.hProcess, 1);
+ }
+ CloseHandle(processInfo.hProcess);
+ CloseHandle(processInfo.hThread);
+}
+
+//----------------------------------------------------------------------------
+static bool createPipe(PHANDLE readPipe, PHANDLE writePipe)
+{
+ SECURITY_ATTRIBUTES securityAttributes;
+ securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ securityAttributes.bInheritHandle = TRUE;
+ securityAttributes.lpSecurityDescriptor = NULL;
+ return CreatePipe(readPipe, writePipe, &securityAttributes, 0) == 0
+ ? false : true;
+}
+
+//----------------------------------------------------------------------------
+static void finishPipe(HANDLE readPipe, HANDLE writePipe)
+{
+ if (readPipe != INVALID_HANDLE_VALUE) {
+ CloseHandle(readPipe);
+ }
+ if (writePipe != INVALID_HANDLE_VALUE) {
+ CloseHandle(writePipe);
+ }
+}
+
+//----------------------------------------------------------------------------
+static HANDLE createFile(LPCWSTR fileName)
+{
+ SECURITY_ATTRIBUTES securityAttributes;
+ securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ securityAttributes.bInheritHandle = TRUE;
+ securityAttributes.lpSecurityDescriptor = NULL;
+
+ HANDLE file = CreateFileW(fileName,
+ GENERIC_READ | GENERIC_WRITE,
+ 0, // do not share
+ &securityAttributes,
+ CREATE_ALWAYS, // overwrite existing
+ FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
+ NULL); // no template
+ if (file == INVALID_HANDLE_VALUE) {
+ std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName)
+ << ") failed!" << std::endl;
+ }
+ return file;
+}
+
+//----------------------------------------------------------------------------
+static void finishFile(HANDLE file)
+{
+ if (file != INVALID_HANDLE_VALUE) {
+ CloseHandle(file);
+ }
+}
+
+//----------------------------------------------------------------------------
+
+#ifndef MAPVK_VK_TO_VSC
+# define MAPVK_VK_TO_VSC (0)
+#endif
+
+static void writeInputKeyEvent(INPUT_RECORD inputBuffer[], WCHAR chr)
+{
+ inputBuffer[0].EventType = KEY_EVENT;
+ inputBuffer[0].Event.KeyEvent.bKeyDown = TRUE;
+ inputBuffer[0].Event.KeyEvent.wRepeatCount = 1;
+ SHORT keyCode = VkKeyScanW(chr);
+ if (keyCode == -1) {
+ // Character can't be entered with current keyboard layout
+ // Just set any, it doesn't really matter
+ keyCode = 'K';
+ }
+ inputBuffer[0].Event.KeyEvent.wVirtualKeyCode = LOBYTE(keyCode);
+ inputBuffer[0].Event.KeyEvent.wVirtualScanCode =
+ MapVirtualKey(inputBuffer[0].Event.KeyEvent.wVirtualKeyCode,
+ MAPVK_VK_TO_VSC);
+ inputBuffer[0].Event.KeyEvent.uChar.UnicodeChar = chr;
+ inputBuffer[0].Event.KeyEvent.dwControlKeyState = 0;
+ if ((HIBYTE(keyCode) & 1) == 1) {
+ inputBuffer[0].Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
+ }
+ if ((HIBYTE(keyCode) & 2) == 2) {
+ inputBuffer[0].Event.KeyEvent.dwControlKeyState |= RIGHT_CTRL_PRESSED;
+ }
+ if ((HIBYTE(keyCode) & 4) == 4) {
+ inputBuffer[0].Event.KeyEvent.dwControlKeyState |= RIGHT_ALT_PRESSED;
+ }
+ inputBuffer[1].EventType = inputBuffer[0].EventType;
+ inputBuffer[1].Event.KeyEvent.bKeyDown = FALSE;
+ inputBuffer[1].Event.KeyEvent.wRepeatCount = 1;
+ inputBuffer[1].Event.KeyEvent.wVirtualKeyCode = inputBuffer[0].Event.
+ KeyEvent.wVirtualKeyCode;
+ inputBuffer[1].Event.KeyEvent.wVirtualScanCode = inputBuffer[0].Event.
+ KeyEvent.wVirtualScanCode;
+ inputBuffer[1].Event.KeyEvent.uChar.UnicodeChar = inputBuffer[0].Event.
+ KeyEvent.uChar.UnicodeChar;
+ inputBuffer[1].Event.KeyEvent.dwControlKeyState = 0;
+}
+
+//----------------------------------------------------------------------------
+static int testPipe()
+{
+ int didFail = 1;
+ HANDLE inPipeRead = INVALID_HANDLE_VALUE;
+ HANDLE inPipeWrite = INVALID_HANDLE_VALUE;
+ HANDLE outPipeRead = INVALID_HANDLE_VALUE;
+ HANDLE outPipeWrite = INVALID_HANDLE_VALUE;
+ HANDLE errPipeRead = INVALID_HANDLE_VALUE;
+ HANDLE errPipeWrite = INVALID_HANDLE_VALUE;
+ UINT currentCodepage = GetConsoleCP();
+ char buffer[200];
+ try {
+ if (!createPipe(&inPipeRead, &inPipeWrite) ||
+ !createPipe(&outPipeRead, &outPipeWrite) ||
+ !createPipe(&errPipeRead, &errPipeWrite)) {
+ throw std::runtime_error("createFile failed!");
+ }
+ if (TestCodepage == CP_ACP) {
+ TestCodepage = GetACP();
+ }
+ if (!SetConsoleCP(TestCodepage)) {
+ throw std::runtime_error("SetConsoleCP failed!");
+ }
+
+ DWORD bytesWritten = 0;
+ if (!WriteFile(inPipeWrite, encodedInputTestString.c_str(),
+ (DWORD)encodedInputTestString.size(), &bytesWritten, NULL)
+ || bytesWritten == 0) {
+ throw std::runtime_error("WriteFile failed!");
+ }
+
+ if (createProcess(inPipeRead, outPipeWrite, errPipeWrite)) {
+ try {
+ Sleep(100);
+ if (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) {
+ throw std::runtime_error("WaitForSingleObject failed!");
+ }
+ DWORD bytesRead = 0;
+ if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, NULL)
+ || bytesRead == 0) {
+ throw std::runtime_error("ReadFile failed!");
+ }
+ if ((bytesRead < encodedTestString.size() + 1 + encodedInputTestString.size()
+ && !ReadFile(outPipeRead, buffer + bytesRead,
+ sizeof(buffer) - bytesRead, &bytesRead, NULL))
+ || bytesRead == 0) {
+ throw std::runtime_error("ReadFile failed!");
+ }
+ if (memcmp(buffer, encodedTestString.c_str(),
+ encodedTestString.size()) == 0 &&
+ memcmp(buffer + encodedTestString.size() + 1,
+ encodedInputTestString.c_str(),
+ encodedInputTestString.size()) == 0) {
+ bytesRead = 0;
+ if (!ReadFile(errPipeRead, buffer, sizeof(buffer), &bytesRead, NULL)
+ || bytesRead == 0) {
+ throw std::runtime_error("ReadFile failed!");
+ }
+ buffer[bytesRead - 1] = 0;
+ didFail = encodedTestString.compare(buffer) == 0 ? 0 : 1;
+ }
+ if (didFail != 0) {
+ std::cerr << "Pipe's output didn't match expected output!" << std::endl << std::flush;
+ }
+ } catch (const std::runtime_error &ex) {
+ std::cerr << ex.what() << std::endl << std::flush;
+ }
+ finishProcess(didFail == 0);
+ }
+ } catch (const std::runtime_error &ex) {
+ std::cerr << ex.what() << std::endl << std::flush;
+ }
+ finishPipe(inPipeRead, inPipeWrite);
+ finishPipe(outPipeRead, outPipeWrite);
+ finishPipe(errPipeRead, errPipeWrite);
+ SetConsoleCP(currentCodepage);
+ return didFail;
+}
+
+//----------------------------------------------------------------------------
+static int testFile()
+{
+ int didFail = 1;
+ HANDLE inFile = INVALID_HANDLE_VALUE;
+ HANDLE outFile = INVALID_HANDLE_VALUE;
+ HANDLE errFile = INVALID_HANDLE_VALUE;
+ try {
+ if ((inFile = createFile(L"stdinFile.txt")) == INVALID_HANDLE_VALUE ||
+ (outFile = createFile(L"stdoutFile.txt")) == INVALID_HANDLE_VALUE ||
+ (errFile = createFile(L"stderrFile.txt")) == INVALID_HANDLE_VALUE) {
+ throw std::runtime_error("createFile failed!");
+ }
+ int length = 0;
+ DWORD bytesWritten = 0;
+ char buffer[200];
+
+ if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, -1,
+ buffer, sizeof(buffer),
+ NULL, NULL)) == 0) {
+ throw std::runtime_error("WideCharToMultiByte failed!");
+ }
+ buffer[length - 1] = '\n';
+ if (!WriteFile(inFile, buffer, length, &bytesWritten, NULL)
+ || bytesWritten == 0) {
+ throw std::runtime_error("WriteFile failed!");
+ }
+ if (SetFilePointer(inFile, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
+ throw std::runtime_error("SetFilePointer failed!");
+ }
+
+ if (createProcess(inFile, outFile, errFile)) {
+ DWORD bytesRead = 0;
+ try {
+ Sleep(100);
+ if (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) {
+ throw std::runtime_error("WaitForSingleObject failed!");
+ }
+ if (SetFilePointer(outFile, 0, 0, FILE_BEGIN)
+ == INVALID_SET_FILE_POINTER) {
+ throw std::runtime_error("SetFilePointer failed!");
+ }
+ if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, NULL)
+ || bytesRead == 0) {
+ throw std::runtime_error("ReadFile failed!");
+ }
+ buffer[bytesRead - 1] = 0;
+ if (memcmp(buffer, encodedTestString.c_str(),
+ encodedTestString.size()) == 0 &&
+ memcmp(buffer + encodedTestString.size() + 1,
+ encodedInputTestString.c_str(),
+ encodedInputTestString.size() - 1) == 0) {
+ bytesRead = 0;
+ if (SetFilePointer(errFile, 0, 0, FILE_BEGIN)
+ == INVALID_SET_FILE_POINTER) {
+ throw std::runtime_error("SetFilePointer failed!");
+ }
+ if (!ReadFile(errFile, buffer, sizeof(buffer), &bytesRead, NULL)
+ || bytesRead == 0) {
+ throw std::runtime_error("ReadFile failed!");
+ }
+ buffer[bytesRead - 1] = 0;
+ didFail = encodedTestString.compare(buffer) == 0 ? 0 : 1;
+ }
+ if (didFail != 0) {
+ std::cerr << "File's output didn't match expected output!" << std::endl << std::flush;
+ }
+ } catch (const std::runtime_error &ex) {
+ std::cerr << ex.what() << std::endl << std::flush;
+ }
+ finishProcess(didFail == 0);
+ }
+ } catch (const std::runtime_error &ex) {
+ std::cerr << ex.what() << std::endl << std::flush;
+ }
+ finishFile(inFile);
+ finishFile(outFile);
+ finishFile(errFile);
+ return didFail;
+}
+
+#ifndef _WIN32_WINNT_VISTA
+# define _WIN32_WINNT_VISTA 0x0600
+#endif
+
+//----------------------------------------------------------------------------
+static int testConsole()
+{
+ int didFail = 1;
+ HANDLE parentIn = GetStdHandle(STD_INPUT_HANDLE);
+ HANDLE parentOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ HANDLE parentErr = GetStdHandle(STD_ERROR_HANDLE);
+ HANDLE hIn = parentIn;
+ HANDLE hOut = parentOut;
+ DWORD consoleMode;
+ bool newConsole = false;
+ bool forceNewConsole = false;
+ bool restoreConsole = false;
+ LPCWSTR TestFaceName = L"Lucida Console";
+ const DWORD TestFontFamily = 0x00000036;
+ const DWORD TestFontSize = 0x000c0000;
+ HKEY hConsoleKey;
+ WCHAR FaceName[200];
+ DWORD FaceNameSize = sizeof(FaceName);
+ DWORD FontFamily = TestFontFamily;
+ DWORD FontSize = TestFontSize;
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion
+# pragma warning (push)
+# ifdef __INTEL_COMPILER
+# pragma warning (disable:1478)
+# else
+# pragma warning (disable:4996)
+# endif
+#endif
+ const bool isVistaOrGreater = LOBYTE(LOWORD(GetVersion())) >= HIBYTE(_WIN32_WINNT_VISTA);
+#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion
+# pragma warning (pop)
+#endif
+ if (!isVistaOrGreater) {
+ if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0, KEY_READ | KEY_WRITE,
+ &hConsoleKey) == ERROR_SUCCESS) {
+ DWORD dwordSize = sizeof(DWORD);
+ if (RegQueryValueExW(hConsoleKey, L"FontFamily", NULL, NULL,
+ (LPBYTE)&FontFamily, &dwordSize) == ERROR_SUCCESS) {
+ if (FontFamily != TestFontFamily) {
+ RegQueryValueExW(hConsoleKey, L"FaceName", NULL, NULL,
+ (LPBYTE)FaceName, &FaceNameSize);
+ RegQueryValueExW(hConsoleKey, L"FontSize", NULL, NULL,
+ (LPBYTE)&FontSize, &dwordSize);
+
+ RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD,
+ (BYTE *)&TestFontFamily, sizeof(TestFontFamily));
+ RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ,
+ (BYTE *)TestFaceName, (DWORD)((wcslen(TestFaceName) + 1) * sizeof(WCHAR)));
+ RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD,
+ (BYTE *)&TestFontSize, sizeof(TestFontSize));
+
+ restoreConsole = true;
+ forceNewConsole = true;
+ }
+ } else {
+ std::cerr << "RegGetValueW(FontFamily) failed!" << std::endl << std::flush;
+ }
+ RegCloseKey(hConsoleKey);
+ } else {
+ std::cerr << "RegOpenKeyExW(HKEY_CURRENT_USER\\Console) failed!" << std::endl << std::flush;
+ }
+ }
+ if (forceNewConsole || GetConsoleMode(parentOut, &consoleMode) == 0) {
+ // Not a real console, let's create new one.
+ FreeConsole();
+ if (!AllocConsole()) {
+ std::cerr << "AllocConsole failed!" << std::endl << std::flush;
+ return didFail;
+ }
+ SECURITY_ATTRIBUTES securityAttributes;
+ securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ securityAttributes.bInheritHandle = TRUE;
+ securityAttributes.lpSecurityDescriptor = NULL;
+ hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, 0,
+ &securityAttributes, OPEN_EXISTING, 0, NULL);
+ hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, 0,
+ &securityAttributes, OPEN_EXISTING, 0, NULL);
+ SetStdHandle(STD_INPUT_HANDLE, hIn);
+ SetStdHandle(STD_OUTPUT_HANDLE, hOut);
+ SetStdHandle(STD_ERROR_HANDLE, hOut);
+ newConsole = true;
+ }
+
+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
+ if (isVistaOrGreater) {
+ CONSOLE_FONT_INFOEX consoleFont;
+ memset(&consoleFont, 0, sizeof(consoleFont));
+ consoleFont.cbSize = sizeof(consoleFont);
+ HMODULE kernel32 = LoadLibraryW(L"kernel32.dll");
+ typedef BOOL (WINAPI *GetCurrentConsoleFontExFunc)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
+ typedef BOOL (WINAPI *SetCurrentConsoleFontExFunc)(HANDLE hConsoleOutput, BOOL bMaximumWindow, PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx);
+ GetCurrentConsoleFontExFunc getConsoleFont = (GetCurrentConsoleFontExFunc)GetProcAddress(kernel32, "GetCurrentConsoleFontEx");
+ SetCurrentConsoleFontExFunc setConsoleFont = (SetCurrentConsoleFontExFunc)GetProcAddress(kernel32, "SetCurrentConsoleFontEx");
+ if (getConsoleFont(hOut, FALSE, &consoleFont)) {
+ if (consoleFont.FontFamily != TestFontFamily) {
+ consoleFont.FontFamily = TestFontFamily;
+ wcscpy(consoleFont.FaceName, TestFaceName);
+ if (!setConsoleFont(hOut, FALSE, &consoleFont)) {
+ std::cerr << "SetCurrentConsoleFontEx failed!" << std::endl << std::flush;
+ }
+ }
+ } else {
+ std::cerr << "GetCurrentConsoleFontEx failed!" << std::endl << std::flush;
+ }
+ } else {
+#endif
+ if (restoreConsole && RegOpenKeyExW(HKEY_CURRENT_USER, L"Console", 0,
+ KEY_WRITE, &hConsoleKey) == ERROR_SUCCESS) {
+ RegSetValueExW(hConsoleKey, L"FontFamily", 0, REG_DWORD,
+ (BYTE *)&FontFamily, sizeof(FontFamily));
+ RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ,
+ (BYTE *)FaceName, FaceNameSize);
+ RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD,
+ (BYTE *)&FontSize, sizeof(FontSize));
+ RegCloseKey(hConsoleKey);
+ }
+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
+ }
+#endif
+
+ if (createProcess(NULL, NULL, NULL)) {
+ try {
+ if (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) {
+ throw std::runtime_error("WaitForSingleObject failed!");
+ }
+ INPUT_RECORD inputBuffer[(sizeof(UnicodeInputTestString) /
+ sizeof(UnicodeInputTestString[0])) * 2];
+ memset(&inputBuffer, 0, sizeof(inputBuffer));
+ unsigned int i = 0;
+ for (i = 0; i < (sizeof(UnicodeInputTestString) /
+ sizeof(UnicodeInputTestString[0]) - 1); i++) {
+ writeInputKeyEvent(&inputBuffer[i*2], UnicodeInputTestString[i]);
+ }
+ writeInputKeyEvent(&inputBuffer[i*2], VK_RETURN);
+ DWORD eventsWritten = 0;
+ if (!WriteConsoleInputW(hIn, inputBuffer, sizeof(inputBuffer) /
+ sizeof(inputBuffer[0]),
+ &eventsWritten) || eventsWritten == 0) {
+ throw std::runtime_error("WriteConsoleInput failed!");
+ }
+ if (WaitForSingleObject(syncEvent, waitTimeout) != WAIT_OBJECT_0) {
+ throw std::runtime_error("WaitForSingleObject failed!");
+ }
+ CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
+ if (!GetConsoleScreenBufferInfo(hOut, &screenBufferInfo)) {
+ throw std::runtime_error("GetConsoleScreenBufferInfo failed!");
+ }
+
+ COORD coord;
+ DWORD charsRead = 0;
+ coord.X = 0;
+ coord.Y = screenBufferInfo.dwCursorPosition.Y - 4;
+ WCHAR *outputBuffer = new WCHAR[screenBufferInfo.dwSize.X * 4];
+ if (!ReadConsoleOutputCharacterW(hOut, outputBuffer,
+ screenBufferInfo.dwSize.X * 4, coord, &charsRead)
+ || charsRead == 0) {
+ delete[] outputBuffer;
+ throw std::runtime_error("ReadConsoleOutputCharacter failed!");
+ }
+ std::wstring wideTestString = kwsys::Encoding::ToWide(encodedTestString);
+ std::wstring wideInputTestString = kwsys::Encoding::ToWide(encodedInputTestString);
+ if (memcmp(outputBuffer, wideTestString.c_str(), wideTestString.size()) == 0 &&
+ memcmp(outputBuffer + screenBufferInfo.dwSize.X * 1,
+ wideTestString.c_str(), wideTestString.size()) == 0 &&
+ memcmp(outputBuffer + screenBufferInfo.dwSize.X * 2,
+ UnicodeInputTestString, sizeof(UnicodeInputTestString) -
+ sizeof(WCHAR)) == 0 &&
+ memcmp(outputBuffer + screenBufferInfo.dwSize.X * 3,
+ wideInputTestString.c_str(), wideInputTestString.size() - 1) == 0
+ ) {
+ didFail = 0;
+ } else {
+ std::cerr << "Console's output didn't match expected output!" << std::endl << std::flush;
+ }
+ delete[] outputBuffer;
+ } catch (const std::runtime_error &ex) {
+ std::cerr << ex.what() << std::endl << std::flush;
+ }
+ finishProcess(didFail == 0);
+ }
+ if (newConsole) {
+ SetStdHandle(STD_INPUT_HANDLE, parentIn);
+ SetStdHandle(STD_OUTPUT_HANDLE, parentOut);
+ SetStdHandle(STD_ERROR_HANDLE, parentErr);
+ CloseHandle(hIn);
+ CloseHandle(hOut);
+ FreeConsole();
+ }
+ return didFail;
+}
+
+#endif
+
+//----------------------------------------------------------------------------
+int testConsoleBuf(int, char*[])
+{
+ int ret = 0;
+
+#if defined(_WIN32)
+ syncEvent = CreateEventW(NULL,
+ FALSE, // auto-reset event
+ FALSE, // initial state is nonsignaled
+ SyncEventName); // object name
+ if (!syncEvent) {
+ std::cerr << "CreateEvent failed " << GetLastError() << std::endl;
+ return 1;
+ }
+
+ encodedTestString = kwsys::Encoding::ToNarrow(UnicodeTestString);
+ encodedInputTestString = kwsys::Encoding::ToNarrow(UnicodeInputTestString);
+ encodedInputTestString += "\n";
+
+ ret |= testPipe();
+ ret |= testFile();
+ ret |= testConsole();
+
+ CloseHandle(syncEvent);
+#endif
+
+ return ret;
+}
diff --git a/Source/kwsys/testConsoleBuf.hxx b/Source/kwsys/testConsoleBuf.hxx
new file mode 100644
index 0000000..855028b
--- /dev/null
+++ b/Source/kwsys/testConsoleBuf.hxx
@@ -0,0 +1,24 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#ifndef testConsoleBuf_hxx
+#define testConsoleBuf_hxx
+
+static const wchar_t cmdConsoleBufChild[] = L"testConsoleBufChild";
+
+static const wchar_t SyncEventName[] = L"SyncEvent";
+
+// यूनिकोड είναι здорово!
+static const wchar_t UnicodeTestString[] = L"\u092F\u0942\u0928\u093F\u0915\u094B\u0921 "
+ L"\u03B5\u03AF\u03BD\u03B1\u03B9 "
+ L"\u0437\u0434\u043E\u0440\u043E\u0432\u043E!";
+
+#endif
diff --git a/Source/kwsys/testConsoleBufChild.cxx b/Source/kwsys/testConsoleBufChild.cxx
new file mode 100644
index 0000000..3b9ab71
--- /dev/null
+++ b/Source/kwsys/testConsoleBufChild.cxx
@@ -0,0 +1,61 @@
+/*============================================================================
+ KWSys - Kitware System Library
+ Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "kwsysPrivate.h"
+
+#include KWSYS_HEADER(ConsoleBuf.hxx)
+#include KWSYS_HEADER(Encoding.hxx)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "ConsoleBuf.hxx.in"
+# include "Encoding.hxx.in"
+#endif
+
+#include <iostream>
+#include "testConsoleBuf.hxx"
+
+//----------------------------------------------------------------------------
+int main(int argc, const char* argv[])
+{
+#if defined(_WIN32)
+ kwsys::ConsoleBuf::Manager out(std::cout);
+ kwsys::ConsoleBuf::Manager err(std::cerr, true);
+ kwsys::ConsoleBuf::Manager in(std::cin);
+
+ if (argc > 1) {
+ std::cout << argv[1] << std::endl;
+ std::cerr << argv[1] << std::endl;
+ } else {
+ std::string str = kwsys::Encoding::ToNarrow(UnicodeTestString);
+ std::cout << str << std::endl;
+ std::cerr << str << std::endl;
+ }
+
+ std::string input;
+ HANDLE syncEvent = OpenEventW(EVENT_MODIFY_STATE, FALSE, SyncEventName);
+ if (syncEvent) {
+ SetEvent(syncEvent);
+ }
+
+ std::cin >> input;
+ std::cout << input << std::endl;
+ if (syncEvent) {
+ SetEvent(syncEvent);
+ CloseHandle(syncEvent);
+ }
+#else
+ static_cast<void>(argc);
+ static_cast<void>(argv);
+#endif
+ return 0;
+}
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 9252ea6..880b46e 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -940,7 +940,7 @@ static bool CheckRelativePath(
const std::string& expected)
{
std::string result = kwsys::SystemTools::RelativePath(local, remote);
- if(expected != result)
+ if (!kwsys::SystemTools::ComparePath(expected, result))
{
std::cerr << "RelativePath(" << local << ", " << remote
<< ") yielded " << result << " instead of " << expected << std::endl;
@@ -965,7 +965,7 @@ static bool CheckCollapsePath(
const std::string& expected)
{
std::string result = kwsys::SystemTools::CollapseFullPath(path);
- if(expected != result)
+ if (!kwsys::SystemTools::ComparePath(expected, result))
{
std::cerr << "CollapseFullPath(" << path
<< ") yielded " << result << " instead of " << expected << std::endl;
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index 7ef3c03..405917a 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -11,6 +11,7 @@ set(CMakeLib_TESTS
testUTF8
testXMLParser
testXMLSafe
+ testFindPackageCommand
)
set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/Tests/CMakeLib/testFindPackageCommand.cxx b/Tests/CMakeLib/testFindPackageCommand.cxx
new file mode 100644
index 0000000..1cddb0e
--- /dev/null
+++ b/Tests/CMakeLib/testFindPackageCommand.cxx
@@ -0,0 +1,76 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmFindPackageCommand.h"
+
+#include <iostream>
+#include <string>
+
+#define cmPassed(m) std::cout << "Passed: " << (m) << "\n"
+#define cmFailed(m) \
+ std::cout << "FAILED: " << (m) << "\n"; \
+ failed = 1
+
+int testFindPackageCommand(int /*unused*/, char* /*unused*/ [])
+{
+ int failed = 0;
+
+ // ----------------------------------------------------------------------
+ // Test cmFindPackage::Sort
+ std::vector<std::string> testString;
+ testString.push_back("lib-0.0");
+ testString.push_back("lib-1.2");
+ testString.push_back("lib-2.0");
+ testString.push_back("lib-19.0.1");
+ testString.push_back("lib-20.01.1");
+ testString.push_back("lib-20.2.2a");
+
+ cmFindPackageCommand::Sort(testString.begin(), testString.end(),
+ cmFindPackageCommand::Natural,
+ cmFindPackageCommand::Asc);
+ if (!(testString[0] == "lib-0.0" && testString[1] == "lib-1.2" &&
+ testString[2] == "lib-2.0" && testString[3] == "lib-19.0.1" &&
+ testString[4] == "lib-20.01.1" && testString[5] == "lib-20.2.2a")) {
+ cmFailed("cmSystemTools::Sort fail with Natural ASC");
+ }
+
+ cmFindPackageCommand::Sort(testString.begin(), testString.end(),
+ cmFindPackageCommand::Natural,
+ cmFindPackageCommand::Dec);
+ if (!(testString[5] == "lib-0.0" && testString[4] == "lib-1.2" &&
+ testString[3] == "lib-2.0" && testString[2] == "lib-19.0.1" &&
+ testString[1] == "lib-20.01.1" && testString[0] == "lib-20.2.2a")) {
+ cmFailed("cmSystemTools::Sort fail with Natural ASC");
+ }
+
+ cmFindPackageCommand::Sort(testString.begin(), testString.end(),
+ cmFindPackageCommand::Name_order,
+ cmFindPackageCommand::Dec);
+ if (!(testString[5] == "lib-0.0" && testString[4] == "lib-1.2" &&
+ testString[3] == "lib-19.0.1" && testString[2] == "lib-2.0" &&
+ testString[1] == "lib-20.01.1" && testString[0] == "lib-20.2.2a")) {
+ cmFailed("cmSystemTools::Sort fail with Name DEC");
+ }
+
+ cmFindPackageCommand::Sort(testString.begin(), testString.end(),
+ cmFindPackageCommand::Name_order,
+ cmFindPackageCommand::Asc);
+ if (!(testString[0] == "lib-0.0" && testString[1] == "lib-1.2" &&
+ testString[2] == "lib-19.0.1" && testString[3] == "lib-2.0" &&
+ testString[4] == "lib-20.01.1" && testString[5] == "lib-20.2.2a")) {
+ cmFailed("cmSystemTools::Sort fail with Natural ASC");
+ }
+
+ if (!failed) {
+ cmPassed("cmSystemTools::Sort working");
+ }
+ return failed;
+}
diff --git a/Tests/CMakeLib/testSystemTools.cxx b/Tests/CMakeLib/testSystemTools.cxx
index e834b93..5b5c8d2 100644
--- a/Tests/CMakeLib/testSystemTools.cxx
+++ b/Tests/CMakeLib/testSystemTools.cxx
@@ -19,6 +19,13 @@
std::cout << "FAILED: " << (m) << "\n"; \
failed = 1
+#define cmAssert(exp, m) \
+ if ((exp)) { \
+ cmPassed(m); \
+ } else { \
+ cmFailed(m); \
+ }
+
int testSystemTools(int /*unused*/, char* /*unused*/ [])
{
int failed = 0;
@@ -26,10 +33,67 @@ int testSystemTools(int /*unused*/, char* /*unused*/ [])
// Test cmSystemTools::UpperCase
std::string str = "abc";
std::string strupper = "ABC";
- if (cmSystemTools::UpperCase(str) == strupper) {
- cmPassed("cmSystemTools::UpperCase is working");
- } else {
- cmFailed("cmSystemTools::UpperCase is working");
+ cmAssert(cmSystemTools::UpperCase(str) == strupper,
+ "cmSystemTools::UpperCase");
+
+ // ----------------------------------------------------------------------
+ // Test cmSystemTools::strverscmp
+ cmAssert(cmSystemTools::strverscmp("", "") == 0, "strverscmp empty string");
+ cmAssert(cmSystemTools::strverscmp("abc", "") > 0,
+ "strverscmp string vs empty string");
+ cmAssert(cmSystemTools::strverscmp("abc", "abc") == 0,
+ "strverscmp same string");
+ cmAssert(cmSystemTools::strverscmp("abd", "abc") > 0,
+ "strverscmp character string");
+ cmAssert(cmSystemTools::strverscmp("abc", "abd") < 0,
+ "strverscmp symmetric");
+ cmAssert(cmSystemTools::strverscmp("12345", "12344") > 0,
+ "strverscmp natural numbers");
+ cmAssert(cmSystemTools::strverscmp("100", "99") > 0,
+ "strverscmp natural numbers different digits");
+ cmAssert(cmSystemTools::strverscmp("12345", "00345") > 0,
+ "strverscmp natural against decimal (same length)");
+ cmAssert(cmSystemTools::strverscmp("99999999999999", "99999999999991") > 0,
+ "strverscmp natural overflow");
+ cmAssert(cmSystemTools::strverscmp("00000000000009", "00000000000001") > 0,
+ "strverscmp deciaml precision");
+ cmAssert(cmSystemTools::strverscmp("a.b.c.0", "a.b.c.000") > 0,
+ "strverscmp multiple zeros");
+ cmAssert(cmSystemTools::strverscmp("lib_1.2_10", "lib_1.2_2") > 0,
+ "strverscmp last number ");
+ cmAssert(cmSystemTools::strverscmp("12lib", "2lib") > 0,
+ "strverscmp first number ");
+ cmAssert(cmSystemTools::strverscmp("02lib", "002lib") > 0,
+ "strverscmp first number decimal ");
+ cmAssert(cmSystemTools::strverscmp("10", "9a") > 0,
+ "strverscmp letter filler ");
+ cmAssert(cmSystemTools::strverscmp("000", "0001") > 0,
+ "strverscmp zero and leading zeros ");
+
+ // test sorting using standard strvercmp input
+ std::vector<std::string> testString;
+ testString.push_back("000");
+ testString.push_back("00");
+ testString.push_back("01");
+ testString.push_back("010");
+ testString.push_back("09");
+ testString.push_back("0");
+ testString.push_back("1");
+ testString.push_back("9");
+ testString.push_back("10");
+
+ // test global ordering of input strings
+ for (size_t i = 0; i < testString.size() - 1; i++) {
+ for (size_t j = i + 1; j < testString.size(); j++) {
+ if (cmSystemTools::strverscmp(testString[i], testString[j]) >= 0) {
+ cmFailed("cmSystemTools::strverscmp error in comparing strings " +
+ testString[i] + " " + testString[j]);
+ }
+ }
+ }
+
+ if (!failed) {
+ cmPassed("cmSystemTools::strverscmp working");
}
return failed;
}
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
index 04bbbc6..1a6f204 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -633,3 +633,33 @@ endif()
if(PACKAGE_VERSION_UNSUITABLE)
message(SEND_ERROR "PACKAGE_VERSION_UNSUITABLE set, but must not be !")
endif()
+
+
+############################################################################
+##Test FIND_PACKAGE using sorting
+set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+SET(CMAKE_FIND_PACKAGE_SORT_ORDER NAME)
+SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
+
+set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+FIND_PACKAGE(SortLib CONFIG)
+IF (NOT "${SortLib_VERSION}" STREQUAL "3.1.1")
+ message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Name Asc! ${SortLib_VERSION}")
+endif()
+unset(SortLib_VERSION)
+
+
+set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
+SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+FIND_PACKAGE(SortLib CONFIG)
+IF (NOT "${SortLib_VERSION}" STREQUAL "3.10.1")
+ message(SEND_ERROR "FIND_PACKAGE_SORT_ORDER Natural! Dec ${SortLib_VERSION}")
+endif()
+set(SortLib_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+unset(SortLib_VERSION)
+
+
+unset(CMAKE_FIND_PACKAGE_SORT_ORDER)
+unset(CMAKE_FIND_PACKAGE_SORT_DIRECTION)
+set(CMAKE_PREFIX_PATH )
diff --git a/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake
new file mode 100644
index 0000000..c1f2088
--- /dev/null
+++ b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfig.cmake
@@ -0,0 +1,2 @@
+set(SORT_LIB_VERSION 3.1.1)
+message("SortLib 3.1.1 config reached")
diff --git a/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake
new file mode 100644
index 0000000..fa927c7
--- /dev/null
+++ b/Tests/FindPackageTest/SortLib-3.1.1/SortLibConfigVersion.cmake
@@ -0,0 +1,9 @@
+set(PACKAGE_VERSION 3.1.1)
+if(PACKAGE_FIND_VERSION_MAJOR EQUAL 3)
+ if(PACKAGE_FIND_VERSION_MINOR EQUAL 1)
+ set(PACKAGE_VERSION_COMPATIBLE 1)
+ if(PACKAGE_FIND_VERSION_PATCH EQUAL 1)
+ set(PACKAGE_VERSION_EXACT 1)
+ endif()
+ endif()
+endif()
diff --git a/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake
new file mode 100644
index 0000000..3f3f659
--- /dev/null
+++ b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfig.cmake
@@ -0,0 +1,2 @@
+set(SORT_LIB_VERSION 3.10.1)
+message("SortLib 3.10.1 config reached")
diff --git a/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake
new file mode 100644
index 0000000..6f44c2d
--- /dev/null
+++ b/Tests/FindPackageTest/SortLib-3.10.1/SortLibConfigVersion.cmake
@@ -0,0 +1,9 @@
+set(PACKAGE_VERSION 3.10.1)
+if(PACKAGE_FIND_VERSION_MAJOR EQUAL 3)
+ if(PACKAGE_FIND_VERSION_MINOR EQUAL 10)
+ set(PACKAGE_VERSION_COMPATIBLE 1)
+ if(PACKAGE_FIND_VERSION_PATCH EQUAL 1)
+ set(PACKAGE_VERSION_EXACT 1)
+ endif()
+ endif()
+endif()
diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt
new file mode 100644
index 0000000..247923b
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at DOWNLOAD-httpheader-not-set.cmake:[0-9]+ \(file\):
+ file DOWNLOAD missing string for HTTPHEADER.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake
new file mode 100644
index 0000000..6efc958
--- /dev/null
+++ b/Tests/RunCMake/file/DOWNLOAD-httpheader-not-set.cmake
@@ -0,0 +1 @@
+file(DOWNLOAD "" "" HTTPHEADER "Content-Type: application/x-compressed-tar" HTTPHEADER)
diff --git a/Tests/RunCMake/file/LOCK-lowercase.cmake b/Tests/RunCMake/file/LOCK-lowercase.cmake
new file mode 100644
index 0000000..373afda
--- /dev/null
+++ b/Tests/RunCMake/file/LOCK-lowercase.cmake
@@ -0,0 +1,11 @@
+set(lock "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock")
+
+if(WIN32)
+ string(TOLOWER ${lock} lock)
+endif()
+
+file(LOCK ${lock} TIMEOUT 0)
+file(LOCK ${lock} RELEASE)
+
+file(LOCK ${lock} TIMEOUT 0)
+file(LOCK ${lock} RELEASE)
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index d8e9ce0..48fa757 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -2,8 +2,10 @@ include(RunCMake)
run_cmake(DOWNLOAD-hash-mismatch)
run_cmake(DOWNLOAD-unused-argument)
+run_cmake(DOWNLOAD-httpheader-not-set)
run_cmake(DOWNLOAD-pass-not-set)
run_cmake(UPLOAD-unused-argument)
+run_cmake(UPLOAD-httpheader-not-set)
run_cmake(UPLOAD-pass-not-set)
run_cmake(INSTALL-DIRECTORY)
run_cmake(INSTALL-MESSAGE-bad)
@@ -22,6 +24,7 @@ run_cmake(LOCK-error-no-result-variable)
run_cmake(LOCK-error-no-timeout)
run_cmake(LOCK-error-timeout)
run_cmake(LOCK-error-unknown-option)
+run_cmake(LOCK-lowercase)
run_cmake(GLOB)
run_cmake(GLOB_RECURSE)
# test is valid both for GLOB and GLOB_RECURSE
diff --git a/Tests/RunCMake/file/UPLOAD-httpheader-not-set-result.txt b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file/UPLOAD-httpheader-not-set-stderr.txt b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-stderr.txt
new file mode 100644
index 0000000..341baf5
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-httpheader-not-set-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at UPLOAD-httpheader-not-set.cmake:[0-9]+ \(file\):
+ file UPLOAD missing string for HTTPHEADER.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/UPLOAD-httpheader-not-set.cmake b/Tests/RunCMake/file/UPLOAD-httpheader-not-set.cmake
new file mode 100644
index 0000000..18d43cc
--- /dev/null
+++ b/Tests/RunCMake/file/UPLOAD-httpheader-not-set.cmake
@@ -0,0 +1 @@
+file(UPLOAD "" "" HTTPHEADER "Content-Type: application/x-compressed-tar" HTTPHEADER)
diff --git a/Tests/RunCMake/get_filename_component/KnownComponents.cmake b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
index d822258..7dfb55d 100644
--- a/Tests/RunCMake/get_filename_component/KnownComponents.cmake
+++ b/Tests/RunCMake/get_filename_component/KnownComponents.cmake
@@ -19,12 +19,12 @@ foreach(c DIRECTORY NAME EXT NAME_WE PATH)
endforeach()
# Test Windows paths with DIRECTORY component and an absolute Windows path.
-get_filename_component(test_slashes "c:\\path\\to\\filename.ext.in" DIRECTORY)
-check("DIRECTORY from backslashes" "${test_slashes}" "c:/path/to")
+get_filename_component(test_slashes "C:\\path\\to\\filename.ext.in" DIRECTORY)
+check("DIRECTORY from backslashes" "${test_slashes}" "C:/path/to")
list(APPEND non_cache_vars test_slashes)
-get_filename_component(test_winroot "c:\\filename.ext.in" DIRECTORY)
-check("DIRECTORY in windows root" "${test_winroot}" "c:/")
+get_filename_component(test_winroot "C:\\filename.ext.in" DIRECTORY)
+check("DIRECTORY in windows root" "${test_winroot}" "C:/")
list(APPEND non_cache_vars test_winroot)
# Test finding absolute paths.
@@ -33,8 +33,8 @@ check("ABSOLUTE" "${test_absolute}" "/path/to/filename.ext.in")
get_filename_component(test_absolute "/../path/to/filename.ext.in" ABSOLUTE)
check("ABSOLUTE .. in root" "${test_absolute}" "/path/to/filename.ext.in")
-get_filename_component(test_absolute "c:/../path/to/filename.ext.in" ABSOLUTE)
-check("ABSOLUTE .. in windows root" "${test_absolute}" "c:/path/to/filename.ext.in")
+get_filename_component(test_absolute "C:/../path/to/filename.ext.in" ABSOLUTE)
+check("ABSOLUTE .. in windows root" "${test_absolute}" "C:/path/to/filename.ext.in")
list(APPEND non_cache_vars test_absolute)
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index 6ebf2b4..add5326 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -12,7 +12,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeDeveloperReference_STANDALONE 1)
- cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
+ cmake_minimum_required(VERSION 2.8.12.2 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index 45f79dd..be4850e 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -11,7 +11,7 @@
#=============================================================================
if(NOT CMake_SOURCE_DIR)
set(CMakeHelp_STANDALONE 1)
- cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
+ cmake_minimum_required(VERSION 2.8.12.2 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)