diff options
author | Allen Byrne <50328838+byrnHDF@users.noreply.github.com> | 2023-05-03 16:45:16 (GMT) |
---|---|---|
committer | Jordan Henderson <jhenderson@hdfgroup.org> | 2023-05-03 18:26:57 (GMT) |
commit | 7df92eee39e904bb38e74ce5f7971ebc4886472b (patch) | |
tree | e15ab5693fa57f2a873173f1631d4515b77e6825 | |
parent | c75b4af1a2630ace445da1ec661191601583f79a (diff) | |
download | hdf5-7df92eee39e904bb38e74ce5f7971ebc4886472b.zip hdf5-7df92eee39e904bb38e74ce5f7971ebc4886472b.tar.gz hdf5-7df92eee39e904bb38e74ce5f7971ebc4886472b.tar.bz2 |
Changes to isolate API Test option files and use fetchcontent (#2880)
113 files changed, 89 insertions, 36608 deletions
diff --git a/config/cmake/cacheinit.cmake b/config/cmake/cacheinit.cmake index 4460891..376b28f 100644 --- a/config/cmake/cacheinit.cmake +++ b/config/cmake/cacheinit.cmake @@ -49,6 +49,10 @@ set (HDF5_MINGW_STATIC_GCC_LIBS ON CACHE BOOL "Statically link libgcc/libstdc++" set (HDF5_ALLOW_EXTERNAL_SUPPORT "TGZ" CACHE STRING "Allow External Library Building (NO GIT TGZ)" FORCE) set_property (CACHE HDF5_ALLOW_EXTERNAL_SUPPORT PROPERTY STRINGS NO GIT TGZ) +######################## +# compression options +######################## + set (ZLIB_PACKAGE_NAME "zlib" CACHE STRING "Name of ZLIB package" FORCE) set (ZLIB_TGZ_NAME "ZLib.tar.gz" CACHE STRING "Use HDF5_ZLib from compressed file" FORCE) set (ZLIB_TGZ_ORIGPATH "https://github.com/madler/zlib/releases/download/v1.2.13" CACHE STRING "Use ZLIB from original location" FORCE) @@ -62,6 +66,13 @@ set (LIBAEC_TGZ_ORIGNAME "libaec-v1.0.6.tar.gz" CACHE STRING "Use LIBAEC from or set (LIBAEC_USE_LOCALCONTENT OFF CACHE BOOL "Use local file for LIBAEC FetchContent" FORCE) ######################## +# API test options +######################## +set (KWSYS_TGZ_ORIGPATH "https://gitlab.kitware.com/utils/kwsys/-/archive/master/kwsys-master.tar.gz" CACHE STRING "Use KWSYS from original location" FORCE) +set (KWSYS_TGZ_ORIGNAME "kwsys-master.tar.gz" CACHE STRING "Use KWSYS from original compressed file" FORCE) +set (KWSYS_USE_LOCALCONTENT OFF CACHE BOOL "Use local file for KWSYS FetchContent" FORCE) + +######################## # filter plugin options ######################## diff --git a/doxygen/dox/Overview.dox b/doxygen/dox/Overview.dox index 70974ec..f909d8d 100644 --- a/doxygen/dox/Overview.dox +++ b/doxygen/dox/Overview.dox @@ -23,8 +23,8 @@ documents cover a mix of tasks, concepts, and reference, to help a specific \par Versions Version-specific documentation (see the version in the title area) can be found here: - - <a href="https://docs.hdfgroup.org/hdf5/v1_14/index.html">HDF5 1.14.x (this site)</a> - <a href="https://docs.hdfgroup.org/hdf5/develop/index.html">HDF5 <code>develop</code> branch</a> + - <a href="https://docs.hdfgroup.org/hdf5/v1_14/index.html">HDF5 1.14.x (this site)</a> - <a href="https://docs.hdfgroup.org/hdf5/v1_12/index.html">HDF5 1.12.x</a> - <a href="https://docs.hdfgroup.org/hdf5/v1_10/index.html">HDF5 1.10.x</a> - <a href="https://docs.hdfgroup.org/hdf5/v1_8/index.html">HDF5 1.8.x</a> diff --git a/test/API/CMake/CheckAsan.cmake b/test/API/CMake/CheckAsan.cmake deleted file mode 100644 index 32f4b45..0000000 --- a/test/API/CMake/CheckAsan.cmake +++ /dev/null @@ -1,37 +0,0 @@ -set(ASAN_FLAG "-fsanitize=address") -set(ASAN_C_FLAGS "-O1 -g ${ASAN_FLAG} -fsanitize-address-use-after-scope -fno-omit-frame-pointer -fno-optimize-sibling-calls") -set(ASAN_CXX_FLAGS ${ASAN_C_FLAGS}) - -get_property(ASAN_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) -foreach(lang ${ASAN_LANGUAGES}) - set(ASAN_${lang}_LANG_ENABLED 1) -endforeach() - -if(ASAN_C_LANG_ENABLED) - include(CheckCCompilerFlag) - set(CMAKE_REQUIRED_LINK_OPTIONS ${ASAN_FLAG}) - check_c_compiler_flag(${ASAN_FLAG} ASAN_C_FLAG_SUPPORTED) - if(NOT ASAN_C_FLAG_SUPPORTED) - message(STATUS "Asan flags are not supported by the C compiler.") - else() - if(NOT CMAKE_C_FLAGS_ASAN) - set(CMAKE_C_FLAGS_ASAN ${ASAN_C_FLAGS} CACHE STRING "Flags used by the C compiler during ASAN builds." FORCE) - endif() - endif() - unset(CMAKE_REQUIRED_LINK_OPTIONS) -endif() - -if(ASAN_CXX_LANG_ENABLED) - include(CheckCXXCompilerFlag) - set(CMAKE_REQUIRED_LINK_OPTIONS ${ASAN_FLAG}) - check_cxx_compiler_flag(${ASAN_FLAG} ASAN_CXX_FLAG_SUPPORTED) - if(NOT ASAN_CXX_FLAG_SUPPORTED) - message(STATUS "Asan flags are not supported by the CXX compiler.") - else() - if(NOT CMAKE_CXX_FLAGS_ASAN) - set(CMAKE_CXX_FLAGS_ASAN ${ASAN_CXX_FLAGS} CACHE STRING "Flags used by the CXX compiler during ASAN builds." FORCE) - endif() - endif() - unset(CMAKE_REQUIRED_LINK_OPTIONS) -endif() - diff --git a/test/API/CMake/CheckUbsan.cmake b/test/API/CMake/CheckUbsan.cmake deleted file mode 100644 index f2b9c2c..0000000 --- a/test/API/CMake/CheckUbsan.cmake +++ /dev/null @@ -1,37 +0,0 @@ -set(UBSAN_FLAG "-fsanitize=undefined") -set(UBSAN_C_FLAGS "-O1 -g ${UBSAN_FLAG} -fno-omit-frame-pointer") -set(UBSAN_CXX_FLAGS ${UBSAN_C_FLAGS}) - -get_property(UBSAN_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) -foreach(lang ${UBSAN_LANGUAGES}) - set(UBSAN_${lang}_LANG_ENABLED 1) -endforeach() - -if(UBSAN_C_LANG_ENABLED) - include(CheckCCompilerFlag) - set(CMAKE_REQUIRED_LINK_OPTIONS ${UBSAN_FLAG}) - check_c_compiler_flag(${UBSAN_FLAG} UBSAN_C_FLAG_SUPPORTED) - if(NOT UBSAN_C_FLAG_SUPPORTED) - message(STATUS "Ubsan flags are not supported by the C compiler.") - else() - if(NOT CMAKE_C_FLAGS_UBSAN) - set(CMAKE_C_FLAGS_UBSAN ${UBSAN_C_FLAGS} CACHE STRING "Flags used by the C compiler during UBSAN builds." FORCE) - endif() - endif() - unset(CMAKE_REQUIRED_LINK_OPTIONS) -endif() - -if(UBSAN_CXX_LANG_ENABLED) - include(CheckCXXCompilerFlag) - set(CMAKE_REQUIRED_LINK_OPTIONS ${UBSAN_FLAG}) - check_cxx_compiler_flag(${UBSAN_FLAG} UBSAN_CXX_FLAG_SUPPORTED) - if(NOT UBSAN_CXX_FLAG_SUPPORTED) - message(STATUS "Ubsan flags are not supported by the CXX compiler.") - else() - if(NOT CMAKE_CXX_FLAGS_UBSAN) - set(CMAKE_CXX_FLAGS_UBSAN ${UBSAN_CXX_FLAGS} CACHE STRING "Flags used by the CXX compiler during UBSAN builds." FORCE) - endif() - endif() - unset(CMAKE_REQUIRED_LINK_OPTIONS) -endif() - diff --git a/test/API/CMakeLists.txt b/test/API/CMakeLists.txt index d189d67..c2f95bd 100644 --- a/test/API/CMakeLists.txt +++ b/test/API/CMakeLists.txt @@ -9,26 +9,12 @@ # help@hdfgroup.org. # -#------------------------------------------------------------------------------ -# Set module path -#------------------------------------------------------------------------------ -set(HDF5_TEST_API_CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake") -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${HDF5_TEST_API_CMAKE_MODULE_PATH}) - -# TODO: probably not necessary -#------------------------------------------------------------------------------ -# Setup CMake Environment -#------------------------------------------------------------------------------ -if (WIN32) - message("The HDF5 API test suite is currently not supported on this platform." FATAL_ERROR) -endif () +cmake_minimum_required (VERSION 3.18) +project (HDF5_TEST_API C) #------------------------------------------------------------------------------ # Setup testing configuration file #------------------------------------------------------------------------------ -if (HDF5_TEST_PARALLEL) - set (HDF5_TEST_API_HAVE_PARALLEL 1) -endif () if (HDF5_TEST_API_ENABLE_ASYNC) set (H5_API_TEST_HAVE_ASYNC 1) endif () @@ -46,9 +32,27 @@ if (HDF5_TEST_API_ENABLE_DRIVER) endif () #------------------------------------------------------------------------------ -# Setup for API tests +# Define for API tests #------------------------------------------------------------------------------ +set (HDF5_API_TESTS + attribute + dataset + datatype + file + group + link + misc + object +) + +if (HDF5_TEST_API_ENABLE_ASYNC) + set (HDF5_API_TESTS + ${HDF5_API_TESTS} + async + ) +endif () + # Ported HDF5 tests set (HDF5_API_TESTS_EXTRA testhdf5 diff --git a/test/API/driver/CMakeLists.txt b/test/API/driver/CMakeLists.txt index 2210068..23ba053 100644 --- a/test/API/driver/CMakeLists.txt +++ b/test/API/driver/CMakeLists.txt @@ -1,17 +1,34 @@ -cmake_minimum_required(VERSION 2.8.12.2 FATAL_ERROR) +cmake_minimum_required (VERSION 3.18) project(H5_API_TEST_DRIVER CXX) -include(CheckAsan) -include(CheckUbsan) +if (NOT KWSYS_USE_LOCALCONTENT) + set (KWSYS_URL ${KWSYS_TGZ_ORIGPATH}/${KWSYS_TGZ_ORIGNAME}) +else () + set (KWSYS_URL ${TGZPATH}/${KWSYS_TGZ_ORIGNAME}) +endif () +# Only tgz files +FetchContent_Declare (KWSYS + URL ${KWSYS_URL} + URL_HASH "" +) +FetchContent_GetProperties(KWSYS) +if(NOT kwsys_POPULATED) + FetchContent_Populate(KWSYS) -set(CMAKE_CXX_STANDARD 11) + # Copy an additional/replacement files into the populated source + #file(COPY ${HDF_RESOURCES_DIR}/KWSYS/CMakeLists.txt DESTINATION ${hdf5_kwsys_SOURCE_DIR}) -set(KWSYS_NAMESPACE h5_api_test_sys) -set(KWSYS_USE_SystemTools 1) -set(KWSYS_USE_Process 1) -set(KWSYS_USE_RegularExpression 1) -add_subdirectory(kwsys) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/kwsys) + set(CMAKE_CXX_STANDARD 11) + + set(KWSYS_NAMESPACE h5_api_test_sys) + set(KWSYS_USE_SystemTools 1) + set(KWSYS_USE_Process 1) + set(KWSYS_USE_RegularExpression 1) + + add_subdirectory(${hdf5_kwsysb_SOURCE_DIR} ${hdf5_kwsys_BINARY_DIR}) +endif() + +include_directories(${hdf5_kwsys_BINARY_DIR}) add_executable(h5_api_test_driver h5_api_test_driver.cxx) target_link_libraries(h5_api_test_driver h5_api_test_sys) diff --git a/test/API/driver/kwsys/.clang-format b/test/API/driver/kwsys/.clang-format deleted file mode 100644 index 588b790..0000000 --- a/test/API/driver/kwsys/.clang-format +++ /dev/null @@ -1,22 +0,0 @@ ---- -# This configuration requires clang-format version 6.0 exactly. -BasedOnStyle: Mozilla -AlignOperands: false -AllowShortFunctionsOnASingleLine: InlineOnly -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -BinPackArguments: true -BinPackParameters: true -BraceWrapping: - AfterClass: true - AfterEnum: true - AfterFunction: true - AfterStruct: true - AfterUnion: true -BreakBeforeBraces: Custom -ColumnLimit: 79 -IndentPPDirectives: AfterHash -SortUsingDeclarations: false -SpaceAfterTemplateKeyword: true -Standard: Cpp03 -... diff --git a/test/API/driver/kwsys/.hooks-config b/test/API/driver/kwsys/.hooks-config deleted file mode 100644 index 739cdd2..0000000 --- a/test/API/driver/kwsys/.hooks-config +++ /dev/null @@ -1,2 +0,0 @@ -[hooks "chain"] - pre-commit = GitSetup/pre-commit diff --git a/test/API/driver/kwsys/Base64.c b/test/API/driver/kwsys/Base64.c deleted file mode 100644 index bf876f2..0000000 --- a/test/API/driver/kwsys/Base64.c +++ /dev/null @@ -1,225 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Base64.h) - -/* Work-around CMake dependency scanning limitation. This must - duplicate the above list of headers. */ -#if 0 -# include "Base64.h.in" -#endif - -static const unsigned char kwsysBase64EncodeTable[65] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - -static const unsigned char kwsysBase64DecodeTable[256] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, - 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - /*------------------------------------*/ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -}; - -static unsigned char kwsysBase64EncodeChar(int c) -{ - return kwsysBase64EncodeTable[(unsigned char)c]; -} - -static unsigned char kwsysBase64DecodeChar(unsigned char c) -{ - return kwsysBase64DecodeTable[c]; -} - -/* Encode 3 bytes into a 4 byte string. */ -void kwsysBase64_Encode3(const unsigned char* src, unsigned char* dest) -{ - dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F); - dest[1] = - kwsysBase64EncodeChar(((src[0] << 4) & 0x30) | ((src[1] >> 4) & 0x0F)); - dest[2] = - kwsysBase64EncodeChar(((src[1] << 2) & 0x3C) | ((src[2] >> 6) & 0x03)); - dest[3] = kwsysBase64EncodeChar(src[2] & 0x3F); -} - -/* Encode 2 bytes into a 4 byte string. */ -void kwsysBase64_Encode2(const unsigned char* src, unsigned char* dest) -{ - dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F); - dest[1] = - kwsysBase64EncodeChar(((src[0] << 4) & 0x30) | ((src[1] >> 4) & 0x0F)); - dest[2] = kwsysBase64EncodeChar(((src[1] << 2) & 0x3C)); - dest[3] = '='; -} - -/* Encode 1 bytes into a 4 byte string. */ -void kwsysBase64_Encode1(const unsigned char* src, unsigned char* dest) -{ - dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F); - dest[1] = kwsysBase64EncodeChar(((src[0] << 4) & 0x30)); - dest[2] = '='; - dest[3] = '='; -} - -/* Encode 'length' bytes from the input buffer and store the - encoded stream into the output buffer. Return the length of the encoded - buffer (output). Note that the output buffer must be allocated by the caller - (length * 1.5 should be a safe estimate). If 'mark_end' is true than an - extra set of 4 bytes is added to the end of the stream if the input is a - multiple of 3 bytes. These bytes are invalid chars and therefore they will - stop the decoder thus enabling the caller to decode a stream without - actually knowing how much data to expect (if the input is not a multiple of - 3 bytes then the extra padding needed to complete the encode 4 bytes will - stop the decoding anyway). */ -size_t kwsysBase64_Encode(const unsigned char* input, size_t length, - unsigned char* output, int mark_end) -{ - const unsigned char* ptr = input; - const unsigned char* end = input + length; - unsigned char* optr = output; - - /* Encode complete triplet */ - - while ((end - ptr) >= 3) { - kwsysBase64_Encode3(ptr, optr); - ptr += 3; - optr += 4; - } - - /* Encodes a 2-byte ending into 3 bytes and 1 pad byte and writes. */ - - if (end - ptr == 2) { - kwsysBase64_Encode2(ptr, optr); - optr += 4; - } - - /* Encodes a 1-byte ending into 2 bytes and 2 pad bytes */ - - else if (end - ptr == 1) { - kwsysBase64_Encode1(ptr, optr); - optr += 4; - } - - /* Do we need to mark the end */ - - else if (mark_end) { - optr[0] = optr[1] = optr[2] = optr[3] = '='; - optr += 4; - } - - return (size_t)(optr - output); -} - -/* Decode 4 bytes into a 3 byte string. */ -int kwsysBase64_Decode3(const unsigned char* src, unsigned char* dest) -{ - unsigned char d0, d1, d2, d3; - - d0 = kwsysBase64DecodeChar(src[0]); - d1 = kwsysBase64DecodeChar(src[1]); - d2 = kwsysBase64DecodeChar(src[2]); - d3 = kwsysBase64DecodeChar(src[3]); - - /* Make sure all characters were valid */ - - if (d0 == 0xFF || d1 == 0xFF || d2 == 0xFF || d3 == 0xFF) { - return 0; - } - - /* Decode the 3 bytes */ - - dest[0] = (unsigned char)(((d0 << 2) & 0xFC) | ((d1 >> 4) & 0x03)); - dest[1] = (unsigned char)(((d1 << 4) & 0xF0) | ((d2 >> 2) & 0x0F)); - dest[2] = (unsigned char)(((d2 << 6) & 0xC0) | ((d3 >> 0) & 0x3F)); - - /* Return the number of bytes actually decoded */ - - if (src[2] == '=') { - return 1; - } - if (src[3] == '=') { - return 2; - } - return 3; -} - -/* Decode bytes from the input buffer and store the decoded stream - into the output buffer until 'length' bytes have been decoded. Return the - real length of the decoded stream (which should be equal to 'length'). Note - that the output buffer must be allocated by the caller. If - 'max_input_length' is not null, then it specifies the number of encoded - bytes that should be at most read from the input buffer. In that case the - 'length' parameter is ignored. This enables the caller to decode a stream - without actually knowing how much decoded data to expect (of course, the - buffer must be large enough). */ -size_t kwsysBase64_Decode(const unsigned char* input, size_t length, - unsigned char* output, size_t max_input_length) -{ - const unsigned char* ptr = input; - unsigned char* optr = output; - - /* Decode complete triplet */ - - if (max_input_length) { - const unsigned char* end = input + max_input_length; - while (ptr < end) { - int len = kwsysBase64_Decode3(ptr, optr); - optr += len; - if (len < 3) { - return (size_t)(optr - output); - } - ptr += 4; - } - } else { - unsigned char* oend = output + length; - while ((oend - optr) >= 3) { - int len = kwsysBase64_Decode3(ptr, optr); - optr += len; - if (len < 3) { - return (size_t)(optr - output); - } - ptr += 4; - } - - /* Decode the last triplet */ - - if (oend - optr == 2) { - unsigned char temp[3]; - int len = kwsysBase64_Decode3(ptr, temp); - if (len >= 2) { - optr[0] = temp[0]; - optr[1] = temp[1]; - optr += 2; - } else if (len > 0) { - optr[0] = temp[0]; - optr += 1; - } - } else if (oend - optr == 1) { - unsigned char temp[3]; - int len = kwsysBase64_Decode3(ptr, temp); - if (len > 0) { - optr[0] = temp[0]; - optr += 1; - } - } - } - - return (size_t)(optr - output); -} diff --git a/test/API/driver/kwsys/Base64.h.in b/test/API/driver/kwsys/Base64.h.in deleted file mode 100644 index 729f972..0000000 --- a/test/API/driver/kwsys/Base64.h.in +++ /dev/null @@ -1,110 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_Base64_h -#define @KWSYS_NAMESPACE@_Base64_h - -#include <@KWSYS_NAMESPACE@/Configure.h> - -#include <stddef.h> /* size_t */ - -/* Redefine all public interface symbol names to be in the proper - namespace. These macros are used internally to kwsys only, and are - not visible to user code. Use kwsysHeaderDump.pl to reproduce - these macros after making changes to the interface. */ -#if !defined(KWSYS_NAMESPACE) -# define kwsys_ns(x) @KWSYS_NAMESPACE@##x -# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT -#endif -#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# define kwsysBase64 kwsys_ns(Base64) -# define kwsysBase64_Decode kwsys_ns(Base64_Decode) -# define kwsysBase64_Decode3 kwsys_ns(Base64_Decode3) -# define kwsysBase64_Encode kwsys_ns(Base64_Encode) -# define kwsysBase64_Encode1 kwsys_ns(Base64_Encode1) -# define kwsysBase64_Encode2 kwsys_ns(Base64_Encode2) -# define kwsysBase64_Encode3 kwsys_ns(Base64_Encode3) -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -/** - * Encode 3 bytes into a 4 byte string. - */ -kwsysEXPORT void kwsysBase64_Encode3(const unsigned char* src, - unsigned char* dest); - -/** - * Encode 2 bytes into a 4 byte string. - */ -kwsysEXPORT void kwsysBase64_Encode2(const unsigned char* src, - unsigned char* dest); - -/** - * Encode 1 bytes into a 4 byte string. - */ -kwsysEXPORT void kwsysBase64_Encode1(const unsigned char* src, - unsigned char* dest); - -/** - * Encode 'length' bytes from the input buffer and store the encoded - * stream into the output buffer. Return the length of the encoded - * buffer (output). Note that the output buffer must be allocated by - * the caller (length * 1.5 should be a safe estimate). If 'mark_end' - * is true than an extra set of 4 bytes is added to the end of the - * stream if the input is a multiple of 3 bytes. These bytes are - * invalid chars and therefore they will stop the decoder thus - * enabling the caller to decode a stream without actually knowing how - * much data to expect (if the input is not a multiple of 3 bytes then - * the extra padding needed to complete the encode 4 bytes will stop - * the decoding anyway). - */ -kwsysEXPORT size_t kwsysBase64_Encode(const unsigned char* input, - size_t length, unsigned char* output, - int mark_end); - -/** - * Decode 4 bytes into a 3 byte string. Returns the number of bytes - * actually decoded. - */ -kwsysEXPORT int kwsysBase64_Decode3(const unsigned char* src, - unsigned char* dest); - -/** - * Decode bytes from the input buffer and store the decoded stream - * into the output buffer until 'length' bytes have been decoded. - * Return the real length of the decoded stream (which should be equal - * to 'length'). Note that the output buffer must be allocated by the - * caller. If 'max_input_length' is not null, then it specifies the - * number of encoded bytes that should be at most read from the input - * buffer. In that case the 'length' parameter is ignored. This - * enables the caller to decode a stream without actually knowing how - * much decoded data to expect (of course, the buffer must be large - * enough). - */ -kwsysEXPORT size_t kwsysBase64_Decode(const unsigned char* input, - size_t length, unsigned char* output, - size_t max_input_length); - -#if defined(__cplusplus) -} /* extern "C" */ -#endif - -/* If we are building a kwsys .c or .cxx file, let it use these macros. - Otherwise, undefine them to keep the namespace clean. */ -#if !defined(KWSYS_NAMESPACE) -# undef kwsys_ns -# undef kwsysEXPORT -# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# undef kwsysBase64 -# undef kwsysBase64_Decode -# undef kwsysBase64_Decode3 -# undef kwsysBase64_Encode -# undef kwsysBase64_Encode1 -# undef kwsysBase64_Encode2 -# undef kwsysBase64_Encode3 -# endif -#endif - -#endif diff --git a/test/API/driver/kwsys/CMakeLists.txt b/test/API/driver/kwsys/CMakeLists.txt deleted file mode 100644 index 09bcdb9..0000000 --- a/test/API/driver/kwsys/CMakeLists.txt +++ /dev/null @@ -1,1260 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing#kwsys for details. - -# The Kitware System Library is intended to be included in other -# projects. It is completely configurable in that the library's -# namespace can be configured and the components that are included can -# be selected invididually. - -# Typical usage is to import the kwsys directory tree into a -# subdirectory under a parent project and enable the classes that will -# be used. All classes are disabled by default. The CMake listfile -# above this one configures the library as follows: -# -# SET(KWSYS_NAMESPACE foosys) -# SET(KWSYS_USE_Directory 1) # Enable Directory class. -# SUBDIRS(kwsys) -# -# Optional settings are as follows: -# -# KWSYS_HEADER_ROOT = The directory into which to generate the kwsys headers. -# A directory called "${KWSYS_NAMESPACE}" will be -# created under this root directory to hold the files. -# KWSYS_SPLIT_OBJECTS_FROM_INTERFACE -# = Instead of creating a single ${KWSYS_NAMESPACE} library -# target, create three separate targets: -# ${KWSYS_NAMESPACE} -# - An INTERFACE library only containing usage -# requirements. -# ${KWSYS_NAMESPACE}_objects -# - An OBJECT library for the built kwsys objects. -# Note: This is omitted from the install rules -# ${KWSYS_NAMESPACE}_private -# - An INTERFACE library combining both that is -# appropriate for use with PRIVATE linking in -# target_link_libraries. Because of how interface -# properties propagate, this target is not suitable -# for use with PUBLIC or INTERFACE linking. -# KWSYS_ALIAS_TARGET = The name of an alias target to create to the actual target. -# -# Example: -# -# SET(KWSYS_HEADER_ROOT ${PROJECT_BINARY_DIR}) -# INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}) -# -# KWSYS_CXX_STANDARD = A value for CMAKE_CXX_STANDARD within KWSys. -# Set to empty string to use no default value. -# KWSYS_CXX_COMPILE_FEATURES = target_compile_features arguments for KWSys. -# -# Optional settings to setup install rules are as follows: -# -# KWSYS_INSTALL_BIN_DIR = The installation target directories into -# KWSYS_INSTALL_LIB_DIR which the libraries and headers from -# KWSYS_INSTALL_INCLUDE_DIR kwsys should be installed by a "make install". -# The values should be specified relative to -# the installation prefix and NOT start with '/'. -# KWSYS_INSTALL_DOC_DIR = The installation target directory for documentation -# such as copyright information. -# -# KWSYS_INSTALL_COMPONENT_NAME_RUNTIME = Name of runtime and development -# KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT installation components. -# If not given the install rules -# will not be in any component. -# -# KWSYS_INSTALL_EXPORT_NAME = The EXPORT option value for install(TARGETS) calls. -# -# Example: -# -# SET(KWSYS_INSTALL_BIN_DIR bin) -# SET(KWSYS_INSTALL_LIB_DIR lib) -# SET(KWSYS_INSTALL_INCLUDE_DIR include) -# SET(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME Runtime) -# SET(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT Development) - -# Once configured, kwsys should be used as follows from C or C++ code: -# -# #include <foosys/Directory.hxx> -# ... -# foosys::Directory directory; -# - -# NOTE: This library is intended for internal use by Kitware-driven -# projects. In order to keep it simple no attempt will be made to -# maintain backward compatibility when changes are made to KWSys. -# When an incompatible change is made Kitware's projects that use -# KWSys will be fixed, but no notification will necessarily be sent to -# any outside mailing list and no documentation of the change will be -# written. - -CMAKE_MINIMUM_REQUIRED(VERSION 3.1 FATAL_ERROR) -FOREACH(p - CMP0056 # CMake 3.2, Honor link flags in try_compile() source-file signature. - CMP0063 # CMake 3.3, Honor visibility properties for all target types. - CMP0067 # CMake 3.8, Honor language standard in try_compile source-file signature. - CMP0069 # CMake 3.9, INTERPROCEDURAL_OPTIMIZATION is enforced when enabled. - ) - IF(POLICY ${p}) - CMAKE_POLICY(SET ${p} NEW) - ENDIF() -ENDFOREACH() - -#----------------------------------------------------------------------------- -# If a namespace is not specified, use "kwsys" and enable testing. -# This should be the case only when kwsys is not included inside -# another project and is being tested. -IF(NOT KWSYS_NAMESPACE) - SET(KWSYS_NAMESPACE "kwsys") - SET(KWSYS_STANDALONE 1) -ENDIF() - -#----------------------------------------------------------------------------- -# The project name is that of the specified namespace. -PROJECT(${KWSYS_NAMESPACE}) - -# Tell CMake how to follow dependencies of sources in this directory. -SET_PROPERTY(DIRECTORY - PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM - "KWSYS_HEADER(%)=<${KWSYS_NAMESPACE}/%>" - ) - -if(KWSYS_CXX_STANDARD) - set(CMAKE_CXX_STANDARD "${KWSYS_CXX_STANDARD}") -elseif(NOT DEFINED CMAKE_CXX_STANDARD AND NOT DEFINED KWSYS_CXX_STANDARD) - if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" - AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC" - AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" - ) - set(CMAKE_CXX_STANDARD 14) - else() - set(CMAKE_CXX_STANDARD 11) - endif() -endif() - -# Select library components. -IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) - SET(KWSYS_ENABLE_C 1) - # Enable all components. - SET(KWSYS_USE_Base64 1) - SET(KWSYS_USE_Directory 1) - SET(KWSYS_USE_DynamicLoader 1) - SET(KWSYS_USE_Encoding 1) - SET(KWSYS_USE_Glob 1) - SET(KWSYS_USE_MD5 1) - SET(KWSYS_USE_Process 1) - SET(KWSYS_USE_RegularExpression 1) - SET(KWSYS_USE_System 1) - SET(KWSYS_USE_SystemTools 1) - SET(KWSYS_USE_CommandLineArguments 1) - SET(KWSYS_USE_Terminal 1) - SET(KWSYS_USE_IOStream 1) - SET(KWSYS_USE_FStream 1) - SET(KWSYS_USE_String 1) - SET(KWSYS_USE_SystemInformation 1) - SET(KWSYS_USE_ConsoleBuf 1) -ENDIF() - -# Enforce component dependencies. -IF(KWSYS_USE_SystemTools) - SET(KWSYS_USE_Directory 1) - SET(KWSYS_USE_FStream 1) - SET(KWSYS_USE_Encoding 1) -ENDIF() -IF(KWSYS_USE_Glob) - SET(KWSYS_USE_Directory 1) - SET(KWSYS_USE_SystemTools 1) - SET(KWSYS_USE_RegularExpression 1) - SET(KWSYS_USE_FStream 1) - SET(KWSYS_USE_Encoding 1) -ENDIF() -IF(KWSYS_USE_Process) - SET(KWSYS_USE_System 1) - SET(KWSYS_USE_Encoding 1) -ENDIF() -IF(KWSYS_USE_SystemInformation) - SET(KWSYS_USE_Process 1) -ENDIF() -IF(KWSYS_USE_System) - SET(KWSYS_USE_Encoding 1) -ENDIF() -IF(KWSYS_USE_Directory) - SET(KWSYS_USE_Encoding 1) -ENDIF() -IF(KWSYS_USE_DynamicLoader) - SET(KWSYS_USE_Encoding 1) -ENDIF() -IF(KWSYS_USE_FStream) - SET(KWSYS_USE_Encoding 1) -ENDIF() -IF(KWSYS_USE_ConsoleBuf) - SET(KWSYS_USE_Encoding 1) -ENDIF() - -# Specify default 8 bit encoding for Windows -IF(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE) - SET(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_ACP) -ENDIF() - -# Enable testing if building standalone. -IF(KWSYS_STANDALONE) - INCLUDE(Dart) - MARK_AS_ADVANCED(BUILD_TESTING DART_ROOT TCL_TCLSH) - IF(BUILD_TESTING) - ENABLE_TESTING() - ENDIF() -ENDIF() - -# Choose default shared/static build if not specified. -IF(NOT DEFINED KWSYS_BUILD_SHARED) - SET(KWSYS_BUILD_SHARED ${BUILD_SHARED_LIBS}) -ENDIF() - -# Include helper macros. -INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformTests.cmake) -INCLUDE(CheckTypeSize) - -# Do full dependency headers. -INCLUDE_REGULAR_EXPRESSION("^.*$") - -# Use new KWSYS_INSTALL_*_DIR variable names to control installation. -# Take defaults from the old names. Note that there was no old name -# for the bin dir, so we take the old lib dir name so DLLs will be -# installed in a compatible way for old code. -IF(NOT KWSYS_INSTALL_INCLUDE_DIR) - STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR - "${KWSYS_HEADER_INSTALL_DIR}") -ENDIF() -IF(NOT KWSYS_INSTALL_LIB_DIR) - STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR - "${KWSYS_LIBRARY_INSTALL_DIR}") -ENDIF() -IF(NOT KWSYS_INSTALL_BIN_DIR) - STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR - "${KWSYS_LIBRARY_INSTALL_DIR}") -ENDIF() - -# Setup header install rules. -SET(KWSYS_INSTALL_INCLUDE_OPTIONS) -IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) - SET(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS} - COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT} - ) -ENDIF() - -# Setup library install rules. -SET(KWSYS_INSTALL_LIBRARY_RULE) -SET(KWSYS_INSTALL_NAMELINK_RULE) -IF(KWSYS_INSTALL_LIB_DIR) - IF(KWSYS_INSTALL_EXPORT_NAME) - LIST(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME}) - ENDIF() - # Install the shared library to the lib directory. - SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} NAMELINK_SKIP - ) - # Assign the shared library to the runtime component. - IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) - SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} - ) - ENDIF() - IF(KWSYS_BUILD_SHARED) - SET(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE} - LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} NAMELINK_ONLY - ) - # Assign the namelink to the development component. - IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) - SET(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE} - COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT} - ) - ENDIF() - ENDIF() - - # Install the archive to the lib directory. - SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - ARCHIVE DESTINATION ${KWSYS_INSTALL_LIB_DIR} - ) - # Assign the archive to the development component. - IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) - SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT} - ) - ENDIF() -ENDIF() -IF(KWSYS_INSTALL_BIN_DIR) - # Install the runtime library to the bin directory. - SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - RUNTIME DESTINATION ${KWSYS_INSTALL_BIN_DIR} - ) - # Assign the runtime library to the runtime component. - IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) - SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} - COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} - ) - ENDIF() -ENDIF() - -# Do not support old KWSYS_*a_INSTALL_DIR variable names. -SET(KWSYS_HEADER_INSTALL_DIR) -SET(KWSYS_LIBRARY_INSTALL_DIR) - -# Generated source files will need this header. -STRING(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}" - KWSYS_IN_SOURCE_BUILD) -IF(NOT KWSYS_IN_SOURCE_BUILD) - CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsysPrivate.h - ${PROJECT_BINARY_DIR}/kwsysPrivate.h COPYONLY IMMEDIATE) -ENDIF() - -# Select plugin module file name convention. -IF(NOT KWSYS_DynamicLoader_PREFIX) - SET(KWSYS_DynamicLoader_PREFIX ${CMAKE_SHARED_MODULE_PREFIX}) -ENDIF() -IF(NOT KWSYS_DynamicLoader_SUFFIX) - SET(KWSYS_DynamicLoader_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX}) -ENDIF() - -#----------------------------------------------------------------------------- -# We require ANSI support from the C compiler. Add any needed flags. -IF(CMAKE_ANSI_CFLAGS) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}") -ENDIF() - -#----------------------------------------------------------------------------- -# Adjust compiler flags for some platforms. -IF(NOT CMAKE_COMPILER_IS_GNUCXX) - IF(CMAKE_SYSTEM MATCHES "OSF1-V.*") - STRING(REGEX MATCH "-timplicit_local" - KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL "${CMAKE_CXX_FLAGS}") - STRING(REGEX MATCH "-no_implicit_include" - KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE "${CMAKE_CXX_FLAGS}") - IF(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local") - ENDIF() - IF(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no_implicit_include") - ENDIF() - ENDIF() - IF(CMAKE_SYSTEM MATCHES "HP-UX") - SET(KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS "+p") - IF(CMAKE_CXX_COMPILER_ID MATCHES "HP") - # it is known that version 3.85 fails and 6.25 works without these flags - IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4) - # use new C++ library and improved template support - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98") - ENDIF() - ENDIF() - ENDIF() -ENDIF() -IF(KWSYS_STANDALONE) - IF(CMAKE_CXX_COMPILER_ID STREQUAL SunPro) - IF(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03") - ELSE() - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4") - ENDIF() - ENDIF() -ENDIF() - -#----------------------------------------------------------------------------- -# Configure the standard library header wrappers based on compiler's -# capabilities and parent project's request. Enforce 0/1 as only -# possible values for configuration into Configure.hxx. - -# Check existence and uniqueness of long long and __int64. -KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_LONG_LONG - "Checking whether C++ compiler has 'long long'" DIRECT) -KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS___INT64 - "Checking whether C++ compiler has '__int64'" DIRECT) -IF(KWSYS_CXX_HAS___INT64) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_AND___INT64 - "Checking whether long and __int64 are the same type" DIRECT) - IF(KWSYS_CXX_HAS_LONG_LONG) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_LONG_AND___INT64 - "Checking whether long long and __int64 are the same type" DIRECT) - ENDIF() -ENDIF() - -# Enable the "long long" type if it is available. It is standard in -# C99 and C++03 but not in earlier standards. -IF(KWSYS_CXX_HAS_LONG_LONG) - SET(KWSYS_USE_LONG_LONG 1) -ELSE() - SET(KWSYS_USE_LONG_LONG 0) -ENDIF() - -# Enable the "__int64" type if it is available and unique. It is not -# standard. -SET(KWSYS_USE___INT64 0) -IF(KWSYS_CXX_HAS___INT64) - IF(NOT KWSYS_CXX_SAME_LONG_AND___INT64) - IF(NOT KWSYS_CXX_SAME_LONG_LONG_AND___INT64) - SET(KWSYS_USE___INT64 1) - ENDIF() - ENDIF() -ENDIF() - -IF(KWSYS_USE_Encoding) - # Look for type size helper macros. - KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_WSTRING - "Checking whether wstring is available" DIRECT) -ENDIF() - -IF(KWSYS_USE_IOStream) - # Determine whether iostreams support long long. - IF(KWSYS_CXX_HAS_LONG_LONG) - KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM_LONG_LONG - "Checking if istream supports long long" DIRECT) - KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM_LONG_LONG - "Checking if ostream supports long long" DIRECT) - ELSE() - SET(KWSYS_IOS_HAS_ISTREAM_LONG_LONG 0) - SET(KWSYS_IOS_HAS_OSTREAM_LONG_LONG 0) - ENDIF() - IF(KWSYS_CXX_HAS___INT64) - KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM___INT64 - "Checking if istream supports __int64" DIRECT) - KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM___INT64 - "Checking if ostream supports __int64" DIRECT) - ELSE() - SET(KWSYS_IOS_HAS_ISTREAM___INT64 0) - SET(KWSYS_IOS_HAS_OSTREAM___INT64 0) - ENDIF() -ENDIF() - -IF(KWSYS_NAMESPACE MATCHES "^kwsys$") - SET(KWSYS_NAME_IS_KWSYS 1) -ELSE() - SET(KWSYS_NAME_IS_KWSYS 0) -ENDIF() - -IF(KWSYS_BUILD_SHARED) - SET(KWSYS_BUILD_SHARED 1) - SET(KWSYS_LIBRARY_TYPE SHARED) -ELSE() - SET(KWSYS_BUILD_SHARED 0) - SET(KWSYS_LIBRARY_TYPE STATIC) -ENDIF() - -if(NOT DEFINED KWSYS_BUILD_PIC) - set(KWSYS_BUILD_PIC 0) -endif() - -#----------------------------------------------------------------------------- -# Configure some implementation details. - -KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_PTRDIFF_T - "Checking whether C compiler has ptrdiff_t in stddef.h" DIRECT) -KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_SSIZE_T - "Checking whether C compiler has ssize_t in unistd.h" DIRECT) -IF(KWSYS_USE_Process) - KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC - "Checking whether C compiler has clock_gettime" DIRECT) -ENDIF() - -SET_SOURCE_FILES_PROPERTIES(ProcessUNIX.c System.c PROPERTIES - COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T} -DKWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC=${KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC}" - ) - -IF(DEFINED KWSYS_PROCESS_USE_SELECT) - GET_PROPERTY(ProcessUNIX_FLAGS SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS) - SET_PROPERTY(SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS "${ProcessUNIX_FLAGS} -DKWSYSPE_USE_SELECT=${KWSYSPE_USE_SELECT}") -ENDIF() - -IF(KWSYS_USE_DynamicLoader) - GET_PROPERTY(KWSYS_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS) - IF(KWSYS_SUPPORTS_SHARED_LIBS) - SET(KWSYS_SUPPORTS_SHARED_LIBS 1) - ELSE() - SET(KWSYS_SUPPORTS_SHARED_LIBS 0) - ENDIF() - SET_PROPERTY(SOURCE DynamicLoader.cxx APPEND PROPERTY COMPILE_DEFINITIONS - KWSYS_SUPPORTS_SHARED_LIBS=${KWSYS_SUPPORTS_SHARED_LIBS}) -ENDIF() - -IF(KWSYS_USE_SystemTools) - if (NOT DEFINED KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP) - set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 1) - endif () - if (KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP) - set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 1) - else () - set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 0) - endif () - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_SETENV - "Checking whether CXX compiler has setenv" DIRECT) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UNSETENV - "Checking whether CXX compiler has unsetenv" DIRECT) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H - "Checking whether CXX compiler has environ in stdlib.h" DIRECT) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UTIMES - "Checking whether CXX compiler has utimes" DIRECT) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UTIMENSAT - "Checking whether CXX compiler has utimensat" DIRECT) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_STAT_HAS_ST_MTIM - "Checking whether CXX compiler struct stat has st_mtim member" DIRECT) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_STAT_HAS_ST_MTIMESPEC - "Checking whether CXX compiler struct stat has st_mtimespec member" DIRECT) - SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS - KWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV} - KWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV} - KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H} - KWSYS_CXX_HAS_UTIMES=${KWSYS_CXX_HAS_UTIMES} - KWSYS_CXX_HAS_UTIMENSAT=${KWSYS_CXX_HAS_UTIMENSAT} - KWSYS_CXX_STAT_HAS_ST_MTIM=${KWSYS_CXX_STAT_HAS_ST_MTIM} - KWSYS_CXX_STAT_HAS_ST_MTIMESPEC=${KWSYS_CXX_STAT_HAS_ST_MTIMESPEC} - ) - IF(NOT WIN32) - IF(KWSYS_STANDALONE) - OPTION(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES "If true, Windows paths will be supported on Unix as well" ON) - ENDIF() - IF(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES) - SET_PROPERTY(SOURCE SystemTools.cxx testSystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS - KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES - ) - ENDIF() - ENDIF() - - # Disable getpwnam for static linux builds since it depends on shared glibc - GET_PROPERTY(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS) - IF(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT SHARED_LIBS_SUPPORTED) - SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS - HAVE_GETPWNAM=0 - ) - ENDIF() -ENDIF() - -IF(KWSYS_USE_SystemInformation) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P}) - IF(NOT CYGWIN) - INCLUDE(CheckIncludeFiles) - CHECK_INCLUDE_FILES("sys/types.h;ifaddrs.h" KWSYS_SYS_HAS_IFADDRS_H) - IF(KWSYS_SYS_HAS_IFADDRS_H) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_SYS_HAS_IFADDRS_H=1) - ENDIF() - ENDIF() - IF(WIN32) - INCLUDE(CheckSymbolExists) - SET(CMAKE_REQUIRED_LIBRARIES Psapi) - CHECK_SYMBOL_EXISTS(GetProcessMemoryInfo "windows.h;psapi.h" KWSYS_SYS_HAS_PSAPI) - UNSET(CMAKE_REQUIRED_LIBRARIES) - IF(KWSYS_SYS_HAS_PSAPI) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_SYS_HAS_PSAPI=1) - IF(MSVC70 OR MSVC71) - # Suppress LNK4089: all references to 'PSAPI.DLL' discarded by /OPT:REF - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /IGNORE:4089") - ENDIF() - ENDIF() - ENDIF() - IF(CMAKE_SYSTEM MATCHES "HP-UX") - CHECK_INCLUDE_FILES("sys/mpctl.h" KWSYS_SYS_HAS_MPCTL_H) - IF(KWSYS_SYS_HAS_MPCTL_H) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_SYS_HAS_MPCTL_H=1) - ENDIF() - ENDIF() - IF(CMAKE_SYSTEM MATCHES "BSD") - CHECK_INCLUDE_FILES("machine/cpu.h" KWSYS_SYS_HAS_MACHINE_CPU_H) - IF(KWSYS_SYS_HAS_MACHINE_CPU_H) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_SYS_HAS_MACHINE_CPU_H=1) - ENDIF() - ENDIF() - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_RLIMIT64 - "Checking whether CXX compiler has rlimit64" DIRECT) - SET(KWSYS_PLATFORM_CXX_TEST_DEFINES) - IF(KWSYS_CXX_HAS_RLIMIT64) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_CXX_HAS_RLIMIT64=1) - ENDIF() - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOL - "Checking whether CXX compiler has atol" DIRECT) - IF(KWSYS_CXX_HAS_ATOL) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOL=1) - ENDIF() - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOLL - "Checking whether CXX compiler has atoll" DIRECT) - IF(KWSYS_CXX_HAS_ATOLL) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOLL=1) - ENDIF() - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS__ATOI64 - "Checking whether CXX compiler has _atoi64" DIRECT) - IF(KWSYS_CXX_HAS__ATOI64) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_CXX_HAS__ATOI64=1) - ENDIF() - IF(UNIX) - INCLUDE(CheckIncludeFileCXX) - # check for simple stack trace - # usually it's in libc but on FreeBSD - # it's in libexecinfo - FIND_LIBRARY(EXECINFO_LIB "execinfo") - MARK_AS_ADVANCED(EXECINFO_LIB) - IF (NOT EXECINFO_LIB) - SET(EXECINFO_LIB "") - ENDIF() - CHECK_INCLUDE_FILE_CXX("execinfo.h" KWSYS_CXX_HAS_EXECINFOH) - IF (KWSYS_CXX_HAS_EXECINFOH) - # we have the backtrace header check if it - # can be used with this compiler - SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${EXECINFO_LIB}) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BACKTRACE - "Checking whether backtrace works with this C++ compiler" DIRECT) - SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES) - IF (KWSYS_CXX_HAS_BACKTRACE) - # backtrace is supported by this system and compiler. - # now check for the more advanced capabilities. - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE=1) - # check for symbol lookup using dladdr - CHECK_INCLUDE_FILE_CXX("dlfcn.h" KWSYS_CXX_HAS_DLFCNH) - IF (KWSYS_CXX_HAS_DLFCNH) - # we have symbol lookup libraries and headers - # check if they can be used with this compiler - SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${CMAKE_DL_LIBS}) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_DLADDR - "Checking whether dladdr works with this C++ compiler" DIRECT) - SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES) - IF (KWSYS_CXX_HAS_DLADDR) - # symbol lookup is supported by this system - # and compiler. - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP=1) - ENDIF() - ENDIF() - # c++ demangling support - # check for cxxabi headers - CHECK_INCLUDE_FILE_CXX("cxxabi.h" KWSYS_CXX_HAS_CXXABIH) - IF (KWSYS_CXX_HAS_CXXABIH) - # check if cxxabi can be used with this - # system and compiler. - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_CXXABI - "Checking whether cxxabi works with this C++ compiler" DIRECT) - IF (KWSYS_CXX_HAS_CXXABI) - # c++ demangle using cxxabi is supported with - # this system and compiler - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE=1) - ENDIF() - ENDIF() - # basic backtrace works better with release build - # don't bother with advanced features for release - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS_DEBUG KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD=1) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS_RELWITHDEBINFO KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD=1) - ENDIF() - ENDIF() - ENDIF() - IF(BORLAND) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM - "Checking whether Borland CXX compiler supports assembler instructions" DIRECT) - IF(KWSYS_CXX_HAS_BORLAND_ASM) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM=1) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM_CPUID - "Checking whether Borland CXX compiler supports CPUID assembler instruction" DIRECT) - IF(KWSYS_CXX_HAS_BORLAND_ASM_CPUID) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM_CPUID=1) - ENDIF() - ENDIF() - ENDIF() - IF(KWSYS_USE___INT64) - SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_USE___INT64=1) - ENDIF() - IF(KWSYS_USE_LONG_LONG) - SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_USE_LONG_LONG=1) - ENDIF() - IF(KWSYS_IOS_HAS_OSTREAM_LONG_LONG) - SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM_LONG_LONG=1) - ENDIF() - IF(KWSYS_IOS_HAS_OSTREAM___INT64) - SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM___INT64=1) - ENDIF() - IF(KWSYS_BUILD_SHARED) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1) - ENDIF() - - IF(UNIX AND NOT CYGWIN) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_GETLOADAVG - "Checking whether CXX compiler has getloadavg" DIRECT) - IF(KWSYS_CXX_HAS_GETLOADAVG) - SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY - COMPILE_DEFINITIONS KWSYS_CXX_HAS_GETLOADAVG=1) - ENDIF() - ENDIF() -ENDIF() - -IF(KWSYS_USE_FStream) - KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H - "Checking whether <ext/stdio_filebuf.h> is available" DIRECT) -ENDIF() - -#----------------------------------------------------------------------------- -# Choose a directory for the generated headers. -IF(NOT KWSYS_HEADER_ROOT) - SET(KWSYS_HEADER_ROOT "${PROJECT_BINARY_DIR}") -ENDIF() -SET(KWSYS_HEADER_DIR "${KWSYS_HEADER_ROOT}/${KWSYS_NAMESPACE}") -INCLUDE_DIRECTORIES(${KWSYS_HEADER_ROOT}) - -#----------------------------------------------------------------------------- -IF(KWSYS_INSTALL_DOC_DIR) - # Assign the license to the runtime component since it must be - # distributed with binary forms of this software. - IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) - SET(KWSYS_INSTALL_LICENSE_OPTIONS ${KWSYS_INSTALL_LICENSE_OPTIONS} - COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} - ) - ENDIF() - - # Install the license under the documentation directory. - INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt - DESTINATION ${KWSYS_INSTALL_DOC_DIR}/${KWSYS_NAMESPACE} - ${KWSYS_INSTALL_LICENSE_OPTIONS}) -ENDIF() - -#----------------------------------------------------------------------------- -# Build a list of classes and headers we need to implement the -# selected components. Initialize with required components. -SET(KWSYS_CLASSES) -SET(KWSYS_H_FILES Configure SharedForward) -SET(KWSYS_HXX_FILES Configure String) - -IF(NOT CMake_SOURCE_DIR) - SET(KWSYS_HXX_FILES ${KWSYS_HXX_FILES} - hashtable hash_fun hash_map hash_set - ) -ENDIF() - -# Add selected C++ classes. -SET(cppclasses - Directory DynamicLoader Encoding Glob RegularExpression SystemTools - CommandLineArguments IOStream FStream SystemInformation ConsoleBuf - ) -FOREACH(cpp ${cppclasses}) - IF(KWSYS_USE_${cpp}) - # Use the corresponding class. - SET(KWSYS_CLASSES ${KWSYS_CLASSES} ${cpp}) - - # Load component-specific CMake code. - IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake) - INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake) - ENDIF() - ENDIF() -ENDFOREACH() - -# Add selected C components. -FOREACH(c - Process Base64 Encoding MD5 Terminal System String - ) - IF(KWSYS_USE_${c}) - # Use the corresponding header file. - SET(KWSYS_H_FILES ${KWSYS_H_FILES} ${c}) - - # Load component-specific CMake code. - IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake) - INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${c}.cmake) - ENDIF() - ENDIF() -ENDFOREACH() - -#----------------------------------------------------------------------------- -# Build a list of sources for the library based on components that are -# included. -SET(KWSYS_C_SRCS) -SET(KWSYS_CXX_SRCS) - -# Add the proper sources for this platform's Process implementation. -IF(KWSYS_USE_Process) - IF(NOT UNIX) - # Use the Windows implementation. - SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c) - ELSE() - # Use the UNIX implementation. - SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c) - ENDIF() -ENDIF() - -# Add selected C sources. -FOREACH(c Base64 Encoding MD5 Terminal System String) - IF(KWSYS_USE_${c}) - IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c) - LIST(APPEND KWSYS_C_SRCS ${c}C.c) - ELSE() - LIST(APPEND KWSYS_C_SRCS ${c}.c) - ENDIF() - ENDIF() -ENDFOREACH() - -# Configure headers of C++ classes and construct the list of sources. -FOREACH(c ${KWSYS_CLASSES}) - # Add this source to the list of source files for the library. - IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx) - LIST(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx) - ELSEIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}.cxx) - LIST(APPEND KWSYS_CXX_SRCS ${c}.cxx) - ENDIF() - - # Configure the header for this class. - CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${c}.hxx.in ${KWSYS_HEADER_DIR}/${c}.hxx - @ONLY IMMEDIATE) - SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${c}.hxx) - - # Create an install target for the header. - IF(KWSYS_INSTALL_INCLUDE_DIR) - INSTALL(FILES ${KWSYS_HEADER_DIR}/${c}.hxx - DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE} - ${KWSYS_INSTALL_INCLUDE_OPTIONS}) - ENDIF() -ENDFOREACH() - -# Configure C headers. -FOREACH(h ${KWSYS_H_FILES}) - # Configure the header into the given directory. - CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.h.in ${KWSYS_HEADER_DIR}/${h}.h - @ONLY IMMEDIATE) - SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${KWSYS_HEADER_DIR}/${h}.h) - - # Create an install target for the header. - IF(KWSYS_INSTALL_INCLUDE_DIR) - INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.h - DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE} - ${KWSYS_INSTALL_INCLUDE_OPTIONS}) - ENDIF() -ENDFOREACH() - -# Configure other C++ headers. -FOREACH(h ${KWSYS_HXX_FILES}) - # Configure the header into the given directory. - CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.hxx.in ${KWSYS_HEADER_DIR}/${h}.hxx - @ONLY IMMEDIATE) - SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${h}.hxx) - - # Create an install target for the header. - IF(KWSYS_INSTALL_INCLUDE_DIR) - INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.hxx - DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE} - ${KWSYS_INSTALL_INCLUDE_OPTIONS}) - ENDIF() -ENDFOREACH() - -#----------------------------------------------------------------------------- -# Add the library with the configured name and list of sources. -IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS) - IF(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE) - SET(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE}) - SET(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE}_objects) - SET(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE}_private) - SET(KWSYS_TARGET_INSTALL ${KWSYS_TARGET_INTERFACE} ${KWSYS_TARGET_LINK}) - SET(KWSYS_LINK_DEPENDENCY INTERFACE) - ADD_LIBRARY(${KWSYS_TARGET_OBJECT} OBJECT - ${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS}) - IF(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC) - SET_PROPERTY(TARGET ${KWSYS_TARGET_OBJECT} PROPERTY - POSITION_INDEPENDENT_CODE TRUE) - ENDIF() - ADD_LIBRARY(${KWSYS_TARGET_INTERFACE} INTERFACE) - ADD_LIBRARY(${KWSYS_TARGET_LINK} INTERFACE) - TARGET_LINK_LIBRARIES(${KWSYS_TARGET_LINK} INTERFACE - ${KWSYS_TARGET_INTERFACE}) - TARGET_SOURCES(${KWSYS_TARGET_LINK} INTERFACE - $<TARGET_OBJECTS:${KWSYS_TARGET_OBJECT}>) - target_compile_features(${KWSYS_TARGET_OBJECT} PRIVATE ${KWSYS_CXX_COMPILE_FEATURES}) - target_compile_features(${KWSYS_TARGET_INTERFACE} INTERFACE ${KWSYS_CXX_COMPILE_FEATURES}) - ELSE() - SET(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE}) - SET(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE}) - SET(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE}) - set(KWSYS_TARGET_INSTALL ${KWSYS_TARGET_LINK}) - SET(KWSYS_LINK_DEPENDENCY PUBLIC) - ADD_LIBRARY(${KWSYS_TARGET_INTERFACE} ${KWSYS_LIBRARY_TYPE} - ${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS}) - target_compile_features(${KWSYS_TARGET_INTERFACE} PUBLIC ${KWSYS_CXX_COMPILE_FEATURES}) - ENDIF() - if (KWSYS_ALIAS_TARGET) - add_library(${KWSYS_ALIAS_TARGET} ALIAS ${KWSYS_TARGET_INTERFACE}) - endif () - SET_TARGET_PROPERTIES(${KWSYS_TARGET_OBJECT} PROPERTIES - C_CLANG_TIDY "" - CXX_CLANG_TIDY "" - C_INCLUDE_WHAT_YOU_USE "" - CXX_INCLUDE_WHAT_YOU_USE "" - LABELS "${KWSYS_LABELS_LIB}") - IF(KWSYS_USE_DynamicLoader) - IF(UNIX) - TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} - ${CMAKE_DL_LIBS}) - ENDIF() - ENDIF() - - IF(KWSYS_USE_SystemInformation) - IF(WIN32) - TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} ws2_32) - # link in dbghelp.dll for symbol lookup if MSVC 1800 or later - # Note that the dbghelp runtime is part of MS Windows OS - IF(MSVC_VERSION AND NOT MSVC_VERSION VERSION_LESS 1800) - TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} dbghelp) - ENDIF() - IF(KWSYS_SYS_HAS_PSAPI) - TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} - Psapi) - ENDIF() - ELSEIF(UNIX) - IF (EXECINFO_LIB AND KWSYS_CXX_HAS_BACKTRACE) - # backtrace on FreeBSD is not in libc - TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} - ${EXECINFO_LIB}) - ENDIF() - IF (KWSYS_CXX_HAS_DLADDR) - # for symbol lookup using dladdr - TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} - ${CMAKE_DL_LIBS}) - ENDIF() - IF (CMAKE_SYSTEM_NAME STREQUAL "SunOS") - TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} - socket) - ENDIF() - ENDIF() - ENDIF() - - # Apply user-defined target properties to the library. - IF(KWSYS_PROPERTIES_CXX) - SET_TARGET_PROPERTIES(${KWSYS_TARGET_INTERFACE} PROPERTIES - ${KWSYS_PROPERTIES_CXX}) - ENDIF() - - # Set up include usage requirement - IF(COMMAND TARGET_INCLUDE_DIRECTORIES) - TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_INTERFACE} INTERFACE - $<BUILD_INTERFACE:${KWSYS_HEADER_ROOT}>) - IF(KWSYS_INSTALL_INCLUDE_DIR) - TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_INTERFACE} INTERFACE - $<INSTALL_INTERFACE:${KWSYS_INSTALL_INCLUDE_DIR}>) - ENDIF() - ENDIF() - - # Create an install target for the library. - IF(KWSYS_INSTALL_LIBRARY_RULE) - INSTALL(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_LIBRARY_RULE}) - ENDIF() - IF(KWSYS_INSTALL_NAMELINK_RULE) - INSTALL(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_NAMELINK_RULE}) - ENDIF() -ENDIF() - -# Add a C-only library if requested. -IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS) - IF(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE) - SET(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c) - SET(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c_objects) - SET(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c_private) - SET(KWSYS_TARGET_C_INSTALL - ${KWSYS_TARGET_C_INTERFACE} ${KWSYS_TARGET_C_LINK}) - SET(KWSYS_LINK_DEPENDENCY INTERFACE) - ADD_LIBRARY(${KWSYS_TARGET_C_OBJECT} OBJECT ${KWSYS_C_SRCS}) - IF(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC) - SET_PROPERTY(TARGET ${KWSYS_TARGET_C_OBJECT} PROPERTY - POSITION_INDEPENDENT_CODE TRUE) - ENDIF() - ADD_LIBRARY(${KWSYS_TARGET_C_INTERFACE} INTERFACE) - ADD_LIBRARY(${KWSYS_TARGET_C_LINK} INTERFACE) - TARGET_LINK_LIBRARIES(${KWSYS_TARGET_C_LINK} INTERFACE - ${KWSYS_TARGET_C_INTERFACE}) - TARGET_SOURCES(${KWSYS_TARGET_C_LINK} INTERFACE - $<TARGET_OBJECTS:${KWSYS_TARGET_C_OBJECT}>) - ELSE() - SET(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c) - SET(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c) - SET(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c) - SET(KWSYS_TARGET_C_INSTALL ${KWSYS_TARGET_C_LINK}) - SET(KWSYS_LINK_DEPENDENCY PUBLIC) - ADD_LIBRARY(${KWSYS_TARGET_C_INTERFACE} ${KWSYS_LIBRARY_TYPE} - ${KWSYS_C_SRCS}) - ENDIF() - SET_TARGET_PROPERTIES(${KWSYS_TARGET_C_OBJECT} PROPERTIES - LABELS "${KWSYS_LABELS_LIB}") - - # Apply user-defined target properties to the library. - IF(KWSYS_PROPERTIES_C) - SET_TARGET_PROPERTIES(${KWSYS_TARGET_C_INTERFACE} PROPERTIES - ${KWSYS_PROPERTIES_C}) - ENDIF() - - # Set up include usage requirement - IF(COMMAND TARGET_INCLUDE_DIRECTORIES) - TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_C_INTERFACE} INTERFACE - $<BUILD_INTERFACE:${KWSYS_HEADER_ROOT}>) - IF(KWSYS_INSTALL_INCLUDE_DIR) - TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_C_INTERFACE} INTERFACE - $<INSTALL_INTERFACE:${KWSYS_INSTALL_INCLUDE_DIR}>) - ENDIF() - ENDIF() - - # Create an install target for the library. - IF(KWSYS_INSTALL_LIBRARY_RULE) - INSTALL(TARGETS ${KWSYS_TARGET_C_INSTALL}) - ENDIF() -ENDIF() - -# For building kwsys itself, we use a macro defined on the command -# line to configure the namespace in the C and C++ source files. -ADD_DEFINITIONS("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}") - -# Disable deprecation warnings for standard C functions. -IF(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "Intel" OR - (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")))) - ADD_DEFINITIONS( - -D_CRT_NONSTDC_NO_DEPRECATE - -D_CRT_SECURE_NO_DEPRECATE - -D_CRT_SECURE_NO_WARNINGS - -D_SCL_SECURE_NO_DEPRECATE - ) -ENDIF() - -IF(WIN32) - # Help enforce the use of wide Windows apis. - ADD_DEFINITIONS(-DUNICODE -D_UNICODE) -ENDIF() - -IF(KWSYS_USE_String) - # Activate code in "String.c". See the comment in the source. - SET_SOURCE_FILES_PROPERTIES(String.c PROPERTIES - COMPILE_FLAGS "-DKWSYS_STRING_C") -ENDIF() - -IF(KWSYS_USE_Encoding) - # Set default 8 bit encoding in "EndcodingC.c". - SET_PROPERTY(SOURCE EncodingC.c EncodingCXX.cxx APPEND PROPERTY COMPILE_DEFINITIONS - KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE}) -ENDIF() - -#----------------------------------------------------------------------------- -# Setup testing if not being built as part of another project. -IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) - IF(BUILD_TESTING) - # Compute the location of executables. - SET(EXEC_DIR "${CMAKE_CURRENT_BINARY_DIR}") - IF(EXECUTABLE_OUTPUT_PATH) - SET(EXEC_DIR "${EXECUTABLE_OUTPUT_PATH}") - ENDIF() - - # C tests - SET(KWSYS_C_TESTS - testEncode.c - testTerminal.c - ) - IF(KWSYS_STANDALONE) - SET(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail.c) - ENDIF() - CREATE_TEST_SOURCELIST( - KWSYS_C_TEST_SRCS ${KWSYS_NAMESPACE}TestsC.c - ${KWSYS_C_TESTS} - ) - ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS}) - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE}) - TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsC ${KWSYS_TARGET_C_LINK}) - FOREACH(testfile ${KWSYS_C_TESTS}) - get_filename_component(test "${testfile}" NAME_WE) - ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}}) - SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST}) - ENDFOREACH() - - # C++ tests - IF(NOT WATCOM AND NOT CMake_SOURCE_DIR) - SET(KWSYS_CXX_TESTS - testHashSTL.cxx - ) - ENDIF() - SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} - testConfigure.cxx - testSystemTools.cxx - testCommandLineArguments.cxx - testCommandLineArguments1.cxx - testDirectory.cxx - ) - IF(KWSYS_STL_HAS_WSTRING) - SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} - testEncoding.cxx - ) - ENDIF() - IF(KWSYS_USE_FStream) - SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} - testFStream.cxx - ) - ENDIF() - IF(KWSYS_USE_ConsoleBuf) - ADD_EXECUTABLE(testConsoleBufChild testConsoleBufChild.cxx) - SET_PROPERTY(TARGET testConsoleBufChild PROPERTY C_CLANG_TIDY "") - SET_PROPERTY(TARGET testConsoleBufChild PROPERTY CXX_CLANG_TIDY "") - SET_PROPERTY(TARGET testConsoleBufChild PROPERTY C_INCLUDE_WHAT_YOU_USE "") - SET_PROPERTY(TARGET testConsoleBufChild PROPERTY CXX_INCLUDE_WHAT_YOU_USE "") - SET_PROPERTY(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE}) - TARGET_LINK_LIBRARIES(testConsoleBufChild ${KWSYS_TARGET_LINK}) - SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} - testConsoleBuf.cxx - ) - IF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND - CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "19.0.23506") - 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.cxx) - ENDIF() - IF(KWSYS_USE_DynamicLoader) - SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testDynamicLoader.cxx) - # If kwsys contains the DynamicLoader, need extra library - ADD_LIBRARY(${KWSYS_NAMESPACE}TestDynload MODULE testDynload.c) - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB}) - ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestDynload ${KWSYS_TARGET_INTERFACE}) - - if (WIN32) - # Windows tests supported flags. - add_library(${KWSYS_NAMESPACE}TestDynloadImpl SHARED testDynloadImpl.c) - set_property(TARGET ${KWSYS_NAMESPACE}TestDynloadImpl PROPERTY LABELS ${KWSYS_LABELS_LIB}) - set_property(TARGET ${KWSYS_NAMESPACE}TestDynloadImpl PROPERTY DEFINE_SYMBOL BUILDING_TestDynloadImpl) - set_property(TARGET ${KWSYS_NAMESPACE}TestDynloadImpl PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dynloaddir") - add_dependencies(${KWSYS_NAMESPACE}TestDynloadImpl ${KWSYS_TARGET_INTERFACE}) - add_library(${KWSYS_NAMESPACE}TestDynloadUse MODULE testDynloadUse.c) - set_property(TARGET ${KWSYS_NAMESPACE}TestDynloadUse PROPERTY LABELS ${KWSYS_LABELS_LIB}) - set_property(TARGET ${KWSYS_NAMESPACE}TestDynloadUse PROPERTY LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/dynloaddir") - add_dependencies(${KWSYS_NAMESPACE}TestDynloadUse ${KWSYS_TARGET_INTERFACE}) - target_link_libraries(${KWSYS_NAMESPACE}TestDynloadUse PRIVATE ${KWSYS_NAMESPACE}TestDynloadImpl) - endif () - ENDIF() - CREATE_TEST_SOURCELIST( - KWSYS_CXX_TEST_SRCS ${KWSYS_NAMESPACE}TestsCxx.cxx - ${KWSYS_CXX_TESTS} - ) - ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS}) - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_CLANG_TIDY "") - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_CLANG_TIDY "") - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_INCLUDE_WHAT_YOU_USE "") - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_INCLUDE_WHAT_YOU_USE "") - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE}) - TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_TARGET_LINK}) - - SET(TEST_SYSTEMTOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") - SET(TEST_SYSTEMTOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") - CONFIGURE_FILE( - ${PROJECT_SOURCE_DIR}/testSystemTools.h.in - ${PROJECT_BINARY_DIR}/testSystemTools.h) - INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR}) - - IF(CTEST_TEST_KWSYS) - CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/ExtraTest.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake") - SET_DIRECTORY_PROPERTIES(PROPERTIES TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake") - ENDIF() - - SET(KWSYS_TEST_ARGS_testCommandLineArguments - --another-bool-variable - --long3=opt - --set-bool-arg1 - -SSS ken brad bill andy - --some-bool-variable=true - --some-double-variable12.5 - --some-int-variable 14 - "--some-string-variable=test string with space" - --some-multi-argument 5 1 8 3 7 1 3 9 7 1 - -N 12.5 -SS=andy -N 1.31 -N 22 - -SS=bill -BBtrue -SS=brad - -BBtrue - -BBfalse - -SS=ken - -A - -C=test - --long2 hello - ) - SET(KWSYS_TEST_ARGS_testCommandLineArguments1 - --ignored - -n 24 - --second-ignored - "-m=test value" - third-ignored - -p - some junk at the end - ) - FOREACH(testfile ${KWSYS_CXX_TESTS}) - get_filename_component(test "${testfile}" NAME_WE) - ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}}) - SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST}) - ENDFOREACH() - - # Process tests. - ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestProcess testProcess.c) - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE}) - TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestProcess ${KWSYS_TARGET_C_LINK}) - IF(NOT CYGWIN) - SET(KWSYS_TEST_PROCESS_7 7) - ENDIF() - FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10) - ADD_TEST(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n}) - SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST}) - SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120) - ENDFOREACH() - - SET(testProcess_COMPILE_FLAGS "") - # Some Apple compilers produce bad optimizations in this source. - IF(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$") - SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -O0") - ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "XL") - # Tell IBM XL not to warn about our test infinite loop - IF(CMAKE_SYSTEM MATCHES "Linux.*ppc64le" - AND CMAKE_C_COMPILER_VERSION VERSION_LESS "16.1.0" - AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS "13.1.1") - # v13.1.[1-6] on Linux ppc64le is clang based and does not accept - # the -qsuppress option, so just suppress all warnings. - SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -w") - ELSE() - SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -qsuppress=1500-010") - ENDIF() - ENDIF() - IF(CMAKE_C_FLAGS MATCHES "-fsanitize=") - SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -DCRASH_USING_ABORT") - ENDIF() - SET_PROPERTY(SOURCE testProcess.c PROPERTY COMPILE_FLAGS "${testProcess_COMPILE_FLAGS}") - - # Test SharedForward - CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/testSharedForward.c.in - ${PROJECT_BINARY_DIR}/testSharedForward.c @ONLY IMMEDIATE) - ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestSharedForward - ${PROJECT_BINARY_DIR}/testSharedForward.c) - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestSharedForward PROPERTY LABELS ${KWSYS_LABELS_EXE}) - ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestSharedForward ${KWSYS_TARGET_C_LINK}) - ADD_TEST(kwsys.testSharedForward ${EXEC_DIR}/${KWSYS_NAMESPACE}TestSharedForward 1) - SET_PROPERTY(TEST kwsys.testSharedForward PROPERTY LABELS ${KWSYS_LABELS_TEST}) - - # Configure some test properties. - IF(KWSYS_STANDALONE) - # We expect test to fail - SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES WILL_FAIL ON) - GET_TEST_PROPERTY(kwsys.testFail WILL_FAIL wfv) - SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value") - MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}") - ENDIF() - - # Set up ctest custom configuration file. - CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/CTestCustom.cmake.in - ${PROJECT_BINARY_DIR}/CTestCustom.cmake @ONLY) - - # Suppress known consistent failures on buggy systems. - IF(KWSYS_TEST_BOGUS_FAILURES) - SET_TESTS_PROPERTIES(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON) - ENDIF() - - ENDIF() -ENDIF() diff --git a/test/API/driver/kwsys/CONTRIBUTING.rst b/test/API/driver/kwsys/CONTRIBUTING.rst deleted file mode 100644 index 32e7b83..0000000 --- a/test/API/driver/kwsys/CONTRIBUTING.rst +++ /dev/null @@ -1,49 +0,0 @@ -Contributing to KWSys -********************* - -Patches -======= - -KWSys is kept in its own Git repository and shared by several projects -via copies in their source trees. Changes to KWSys should not be made -directly in a host project, except perhaps in maintenance branches. - -KWSys uses `Kitware's GitLab Instance`_ to manage development and code review. -To contribute patches: - -#. Fork the upstream `KWSys Repository`_ into a personal account. -#. Base all new work on the upstream ``master`` branch. -#. Run ``./SetupForDevelopment.sh`` in new local work trees. -#. Create commits making incremental, distinct, logically complete changes. -#. Push a topic branch to a personal repository fork on GitLab. -#. Create a GitLab Merge Request targeting the upstream ``master`` branch. - -Once changes are reviewed, tested, and integrated to KWSys upstream then -copies of KWSys within dependent projects can be updated to get the changes. - -.. _`Kitware's GitLab Instance`: https://gitlab.kitware.com -.. _`KWSys Repository`: https://gitlab.kitware.com/utils/kwsys - -Code Style -========== - -We use `clang-format`_ version **6.0** to define our style for C++ code in -the KWSys source tree. See the `.clang-format`_ configuration file for -our style settings. Use the `clang-format.bash`_ script to format source -code. It automatically runs ``clang-format`` on the set of source files -for which we enforce style. The script also has options to format only -a subset of files, such as those that are locally modified. - -.. _`clang-format`: http://clang.llvm.org/docs/ClangFormat.html -.. _`.clang-format`: .clang-format -.. _`clang-format.bash`: clang-format.bash - -License -======= - -We do not require any formal copyright assignment or contributor license -agreement. Any contributions intentionally sent upstream are presumed -to be offered under terms of the OSI-approved BSD 3-clause License. -See `Copyright.txt`_ for details. - -.. _`Copyright.txt`: Copyright.txt diff --git a/test/API/driver/kwsys/CTestConfig.cmake b/test/API/driver/kwsys/CTestConfig.cmake deleted file mode 100644 index 1339ffc..0000000 --- a/test/API/driver/kwsys/CTestConfig.cmake +++ /dev/null @@ -1,9 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing#kwsys for details. - -set(CTEST_PROJECT_NAME "KWSys") -set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") -set(CTEST_DROP_METHOD "http") -set(CTEST_DROP_SITE "open.cdash.org") -set(CTEST_DROP_LOCATION "/submit.php?project=KWSys") -set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/test/API/driver/kwsys/CTestCustom.cmake.in b/test/API/driver/kwsys/CTestCustom.cmake.in deleted file mode 100644 index 760221b..0000000 --- a/test/API/driver/kwsys/CTestCustom.cmake.in +++ /dev/null @@ -1,14 +0,0 @@ -# kwsys.testProcess-10 involves sending SIGINT to a child process, which then -# exits abnormally via a call to _exit(). (On Windows, a call to ExitProcess). -# Naturally, this results in plenty of memory being "leaked" by this child -# process - the memory check results are not meaningful in this case. -# -# kwsys.testProcess-9 also tests sending SIGINT to a child process. However, -# normal operation of that test involves the child process timing out, and the -# host process kills (SIGKILL) it as a result. Since it was SIGKILL'ed, the -# resulting memory leaks are not logged by valgrind anyway. Therefore, we -# don't have to exclude it. - -list(APPEND CTEST_CUSTOM_MEMCHECK_IGNORE - kwsys.testProcess-10 - ) diff --git a/test/API/driver/kwsys/CommandLineArguments.cxx b/test/API/driver/kwsys/CommandLineArguments.cxx deleted file mode 100644 index 3fd1955..0000000 --- a/test/API/driver/kwsys/CommandLineArguments.cxx +++ /dev/null @@ -1,768 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(CommandLineArguments.hxx) - -#include KWSYS_HEADER(Configure.hxx) -#include KWSYS_HEADER(String.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "CommandLineArguments.hxx.in" -# include "Configure.hxx.in" -# include "String.hxx.in" -#endif - -#include <iostream> -#include <map> -#include <set> -#include <sstream> -#include <vector> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef _MSC_VER -# pragma warning(disable : 4786) -#endif - -#if defined(__sgi) && !defined(__GNUC__) -# pragma set woff 1375 /* base class destructor not virtual */ -#endif - -#if 0 -# define CommandLineArguments_DEBUG(x) \ - std::cout << __LINE__ << " CLA: " << x << std::endl -#else -# define CommandLineArguments_DEBUG(x) -#endif - -namespace KWSYS_NAMESPACE { - -struct CommandLineArgumentsCallbackStructure -{ - const char* Argument; - int ArgumentType; - CommandLineArguments::CallbackType Callback; - void* CallData; - void* Variable; - int VariableType; - const char* Help; -}; - -class CommandLineArgumentsVectorOfStrings : public std::vector<kwsys::String> -{ -}; -class CommandLineArgumentsSetOfStrings : public std::set<kwsys::String> -{ -}; -class CommandLineArgumentsMapOfStrucs - : public std::map<kwsys::String, CommandLineArgumentsCallbackStructure> -{ -}; - -class CommandLineArgumentsInternal -{ -public: - CommandLineArgumentsInternal() - : UnknownArgumentCallback{ nullptr } - , ClientData{ nullptr } - , LastArgument{ 0 } - { - } - - typedef CommandLineArgumentsVectorOfStrings VectorOfStrings; - typedef CommandLineArgumentsMapOfStrucs CallbacksMap; - typedef kwsys::String String; - typedef CommandLineArgumentsSetOfStrings SetOfStrings; - - VectorOfStrings Argv; - String Argv0; - CallbacksMap Callbacks; - - CommandLineArguments::ErrorCallbackType UnknownArgumentCallback; - void* ClientData; - - VectorOfStrings::size_type LastArgument; - - VectorOfStrings UnusedArguments; -}; - -CommandLineArguments::CommandLineArguments() -{ - this->Internals = new CommandLineArguments::Internal; - this->Help = ""; - this->LineLength = 80; - this->StoreUnusedArgumentsFlag = false; -} - -CommandLineArguments::~CommandLineArguments() -{ - delete this->Internals; -} - -void CommandLineArguments::Initialize(int argc, const char* const argv[]) -{ - int cc; - - this->Initialize(); - this->Internals->Argv0 = argv[0]; - for (cc = 1; cc < argc; cc++) { - this->ProcessArgument(argv[cc]); - } -} - -void CommandLineArguments::Initialize(int argc, char* argv[]) -{ - this->Initialize(argc, static_cast<const char* const*>(argv)); -} - -void CommandLineArguments::Initialize() -{ - this->Internals->Argv.clear(); - this->Internals->LastArgument = 0; -} - -void CommandLineArguments::ProcessArgument(const char* arg) -{ - this->Internals->Argv.push_back(arg); -} - -bool CommandLineArguments::GetMatchedArguments( - std::vector<std::string>* matches, const std::string& arg) -{ - matches->clear(); - CommandLineArguments::Internal::CallbacksMap::iterator it; - - // Does the argument match to any we know about? - for (it = this->Internals->Callbacks.begin(); - it != this->Internals->Callbacks.end(); it++) { - const CommandLineArguments::Internal::String& parg = it->first; - CommandLineArgumentsCallbackStructure* cs = &it->second; - if (cs->ArgumentType == CommandLineArguments::NO_ARGUMENT || - cs->ArgumentType == CommandLineArguments::SPACE_ARGUMENT) { - if (arg == parg) { - matches->push_back(parg); - } - } else if (arg.find(parg) == 0) { - matches->push_back(parg); - } - } - return !matches->empty(); -} - -int CommandLineArguments::Parse() -{ - std::vector<std::string>::size_type cc; - std::vector<std::string> matches; - if (this->StoreUnusedArgumentsFlag) { - this->Internals->UnusedArguments.clear(); - } - for (cc = 0; cc < this->Internals->Argv.size(); cc++) { - const std::string& arg = this->Internals->Argv[cc]; - CommandLineArguments_DEBUG("Process argument: " << arg); - this->Internals->LastArgument = cc; - if (this->GetMatchedArguments(&matches, arg)) { - // Ok, we found one or more arguments that match what user specified. - // Let's find the longest one. - CommandLineArguments::Internal::VectorOfStrings::size_type kk; - CommandLineArguments::Internal::VectorOfStrings::size_type maxidx = 0; - CommandLineArguments::Internal::String::size_type maxlen = 0; - for (kk = 0; kk < matches.size(); kk++) { - if (matches[kk].size() > maxlen) { - maxlen = matches[kk].size(); - maxidx = kk; - } - } - // So, the longest one is probably the right one. Now see if it has any - // additional value - CommandLineArgumentsCallbackStructure* cs = - &this->Internals->Callbacks[matches[maxidx]]; - const std::string& sarg = matches[maxidx]; - if (cs->Argument != sarg) { - abort(); - } - switch (cs->ArgumentType) { - case NO_ARGUMENT: - // No value - if (!this->PopulateVariable(cs, nullptr)) { - return 0; - } - break; - case SPACE_ARGUMENT: - if (cc == this->Internals->Argv.size() - 1) { - this->Internals->LastArgument--; - return 0; - } - CommandLineArguments_DEBUG("This is a space argument: " - << arg << " value: " - << this->Internals->Argv[cc + 1]); - // Value is the next argument - if (!this->PopulateVariable(cs, - this->Internals->Argv[cc + 1].c_str())) { - return 0; - } - cc++; - break; - case EQUAL_ARGUMENT: - if (arg.size() == sarg.size() || arg.at(sarg.size()) != '=') { - this->Internals->LastArgument--; - return 0; - } - // Value is everythng followed the '=' sign - if (!this->PopulateVariable(cs, arg.c_str() + sarg.size() + 1)) { - return 0; - } - break; - case CONCAT_ARGUMENT: - // Value is whatever follows the argument - if (!this->PopulateVariable(cs, arg.c_str() + sarg.size())) { - return 0; - } - break; - case MULTI_ARGUMENT: - // Suck in all the rest of the arguments - CommandLineArguments_DEBUG("This is a multi argument: " << arg); - for (cc++; cc < this->Internals->Argv.size(); ++cc) { - const std::string& marg = this->Internals->Argv[cc]; - CommandLineArguments_DEBUG( - " check multi argument value: " << marg); - if (this->GetMatchedArguments(&matches, marg)) { - CommandLineArguments_DEBUG("End of multi argument " - << arg << " with value: " << marg); - break; - } - CommandLineArguments_DEBUG( - " populate multi argument value: " << marg); - if (!this->PopulateVariable(cs, marg.c_str())) { - return 0; - } - } - if (cc != this->Internals->Argv.size()) { - CommandLineArguments_DEBUG("Again End of multi argument " << arg); - cc--; - continue; - } - break; - default: - std::cerr << "Got unknown argument type: \"" << cs->ArgumentType - << "\"" << std::endl; - this->Internals->LastArgument--; - return 0; - } - } else { - // Handle unknown arguments - if (this->Internals->UnknownArgumentCallback) { - if (!this->Internals->UnknownArgumentCallback( - arg.c_str(), this->Internals->ClientData)) { - this->Internals->LastArgument--; - return 0; - } - return 1; - } else if (this->StoreUnusedArgumentsFlag) { - CommandLineArguments_DEBUG("Store unused argument " << arg); - this->Internals->UnusedArguments.push_back(arg); - } else { - std::cerr << "Got unknown argument: \"" << arg << "\"" << std::endl; - this->Internals->LastArgument--; - return 0; - } - } - } - return 1; -} - -void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv) -{ - CommandLineArguments::Internal::VectorOfStrings::size_type size = - this->Internals->Argv.size() - this->Internals->LastArgument + 1; - CommandLineArguments::Internal::VectorOfStrings::size_type cc; - - // Copy Argv0 as the first argument - char** args = new char*[size]; - args[0] = new char[this->Internals->Argv0.size() + 1]; - strcpy(args[0], this->Internals->Argv0.c_str()); - int cnt = 1; - - // Copy everything after the LastArgument, since that was not parsed. - for (cc = this->Internals->LastArgument + 1; - cc < this->Internals->Argv.size(); cc++) { - args[cnt] = new char[this->Internals->Argv[cc].size() + 1]; - strcpy(args[cnt], this->Internals->Argv[cc].c_str()); - cnt++; - } - *argc = cnt; - *argv = args; -} - -void CommandLineArguments::GetUnusedArguments(int* argc, char*** argv) -{ - CommandLineArguments::Internal::VectorOfStrings::size_type size = - this->Internals->UnusedArguments.size() + 1; - CommandLineArguments::Internal::VectorOfStrings::size_type cc; - - // Copy Argv0 as the first argument - char** args = new char*[size]; - args[0] = new char[this->Internals->Argv0.size() + 1]; - strcpy(args[0], this->Internals->Argv0.c_str()); - int cnt = 1; - - // Copy everything after the LastArgument, since that was not parsed. - for (cc = 0; cc < this->Internals->UnusedArguments.size(); cc++) { - kwsys::String& str = this->Internals->UnusedArguments[cc]; - args[cnt] = new char[str.size() + 1]; - strcpy(args[cnt], str.c_str()); - cnt++; - } - *argc = cnt; - *argv = args; -} - -void CommandLineArguments::DeleteRemainingArguments(int argc, char*** argv) -{ - int cc; - for (cc = 0; cc < argc; ++cc) { - delete[](*argv)[cc]; - } - delete[] * argv; -} - -void CommandLineArguments::AddCallback(const char* argument, - ArgumentTypeEnum type, - CallbackType callback, void* call_data, - const char* help) -{ - CommandLineArgumentsCallbackStructure s; - s.Argument = argument; - s.ArgumentType = type; - s.Callback = callback; - s.CallData = call_data; - s.VariableType = CommandLineArguments::NO_VARIABLE_TYPE; - s.Variable = nullptr; - s.Help = help; - - this->Internals->Callbacks[argument] = s; - this->GenerateHelp(); -} - -void CommandLineArguments::AddArgument(const char* argument, - ArgumentTypeEnum type, - VariableTypeEnum vtype, void* variable, - const char* help) -{ - CommandLineArgumentsCallbackStructure s; - s.Argument = argument; - s.ArgumentType = type; - s.Callback = nullptr; - s.CallData = nullptr; - s.VariableType = vtype; - s.Variable = variable; - s.Help = help; - - this->Internals->Callbacks[argument] = s; - this->GenerateHelp(); -} - -#define CommandLineArgumentsAddArgumentMacro(type, ctype) \ - void CommandLineArguments::AddArgument(const char* argument, \ - ArgumentTypeEnum type, \ - ctype* variable, const char* help) \ - { \ - this->AddArgument(argument, type, CommandLineArguments::type##_TYPE, \ - variable, help); \ - } - -/* clang-format off */ -CommandLineArgumentsAddArgumentMacro(BOOL, bool) -CommandLineArgumentsAddArgumentMacro(INT, int) -CommandLineArgumentsAddArgumentMacro(DOUBLE, double) -CommandLineArgumentsAddArgumentMacro(STRING, char*) -CommandLineArgumentsAddArgumentMacro(STL_STRING, std::string) - -CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, std::vector<bool>) -CommandLineArgumentsAddArgumentMacro(VECTOR_INT, std::vector<int>) -CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE, std::vector<double>) -CommandLineArgumentsAddArgumentMacro(VECTOR_STRING, std::vector<char*>) -CommandLineArgumentsAddArgumentMacro(VECTOR_STL_STRING, - std::vector<std::string>) -#ifdef HELP_CLANG_FORMAT -; -#endif -/* clang-format on */ - -#define CommandLineArgumentsAddBooleanArgumentMacro(type, ctype) \ - void CommandLineArguments::AddBooleanArgument( \ - const char* argument, ctype* variable, const char* help) \ - { \ - this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT, \ - CommandLineArguments::type##_TYPE, variable, help); \ - } - -/* clang-format off */ -CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool) -CommandLineArgumentsAddBooleanArgumentMacro(INT, int) -CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE, double) -CommandLineArgumentsAddBooleanArgumentMacro(STRING, char*) -CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, std::string) -#ifdef HELP_CLANG_FORMAT -; -#endif -/* clang-format on */ - -void CommandLineArguments::SetClientData(void* client_data) -{ - this->Internals->ClientData = client_data; -} - -void CommandLineArguments::SetUnknownArgumentCallback( - CommandLineArguments::ErrorCallbackType callback) -{ - this->Internals->UnknownArgumentCallback = callback; -} - -const char* CommandLineArguments::GetHelp(const char* arg) -{ - CommandLineArguments::Internal::CallbacksMap::iterator it = - this->Internals->Callbacks.find(arg); - if (it == this->Internals->Callbacks.end()) { - return nullptr; - } - - // Since several arguments may point to the same argument, find the one this - // one point to if this one is pointing to another argument. - CommandLineArgumentsCallbackStructure* cs = &(it->second); - for (;;) { - CommandLineArguments::Internal::CallbacksMap::iterator hit = - this->Internals->Callbacks.find(cs->Help); - if (hit == this->Internals->Callbacks.end()) { - break; - } - cs = &(hit->second); - } - return cs->Help; -} - -void CommandLineArguments::SetLineLength(unsigned int ll) -{ - if (ll < 9 || ll > 1000) { - return; - } - this->LineLength = ll; - this->GenerateHelp(); -} - -const char* CommandLineArguments::GetArgv0() -{ - return this->Internals->Argv0.c_str(); -} - -unsigned int CommandLineArguments::GetLastArgument() -{ - return static_cast<unsigned int>(this->Internals->LastArgument + 1); -} - -void CommandLineArguments::GenerateHelp() -{ - std::ostringstream str; - - // Collapse all arguments into the map of vectors of all arguments that do - // the same thing. - CommandLineArguments::Internal::CallbacksMap::iterator it; - typedef std::map<CommandLineArguments::Internal::String, - CommandLineArguments::Internal::SetOfStrings> - MapArgs; - MapArgs mp; - MapArgs::iterator mpit, smpit; - for (it = this->Internals->Callbacks.begin(); - it != this->Internals->Callbacks.end(); it++) { - CommandLineArgumentsCallbackStructure* cs = &(it->second); - mpit = mp.find(cs->Help); - if (mpit != mp.end()) { - mpit->second.insert(it->first); - mp[it->first].insert(it->first); - } else { - mp[it->first].insert(it->first); - } - } - for (it = this->Internals->Callbacks.begin(); - it != this->Internals->Callbacks.end(); it++) { - CommandLineArgumentsCallbackStructure* cs = &(it->second); - mpit = mp.find(cs->Help); - if (mpit != mp.end()) { - mpit->second.insert(it->first); - smpit = mp.find(it->first); - CommandLineArguments::Internal::SetOfStrings::iterator sit; - for (sit = smpit->second.begin(); sit != smpit->second.end(); sit++) { - mpit->second.insert(*sit); - } - mp.erase(smpit); - } else { - mp[it->first].insert(it->first); - } - } - - // Find the length of the longest string - CommandLineArguments::Internal::String::size_type maxlen = 0; - for (mpit = mp.begin(); mpit != mp.end(); mpit++) { - CommandLineArguments::Internal::SetOfStrings::iterator sit; - for (sit = mpit->second.begin(); sit != mpit->second.end(); sit++) { - CommandLineArguments::Internal::String::size_type clen = sit->size(); - switch (this->Internals->Callbacks[*sit].ArgumentType) { - case CommandLineArguments::NO_ARGUMENT: - clen += 0; - break; - case CommandLineArguments::CONCAT_ARGUMENT: - clen += 3; - break; - case CommandLineArguments::SPACE_ARGUMENT: - clen += 4; - break; - case CommandLineArguments::EQUAL_ARGUMENT: - clen += 4; - break; - } - if (clen > maxlen) { - maxlen = clen; - } - } - } - - CommandLineArguments::Internal::String::size_type maxstrlen = maxlen; - maxlen += 4; // For the space before and after the option - - // Print help for each option - for (mpit = mp.begin(); mpit != mp.end(); mpit++) { - CommandLineArguments::Internal::SetOfStrings::iterator sit; - for (sit = mpit->second.begin(); sit != mpit->second.end(); sit++) { - str << std::endl; - std::string argument = *sit; - switch (this->Internals->Callbacks[*sit].ArgumentType) { - case CommandLineArguments::NO_ARGUMENT: - break; - case CommandLineArguments::CONCAT_ARGUMENT: - argument += "opt"; - break; - case CommandLineArguments::SPACE_ARGUMENT: - argument += " opt"; - break; - case CommandLineArguments::EQUAL_ARGUMENT: - argument += "=opt"; - break; - case CommandLineArguments::MULTI_ARGUMENT: - argument += " opt opt ..."; - break; - } - str << " " << argument.substr(0, maxstrlen) << " "; - } - const char* ptr = this->Internals->Callbacks[mpit->first].Help; - size_t len = strlen(ptr); - int cnt = 0; - while (len > 0) { - // If argument with help is longer than line length, split it on previous - // space (or tab) and continue on the next line - CommandLineArguments::Internal::String::size_type cc; - for (cc = 0; ptr[cc]; cc++) { - if (*ptr == ' ' || *ptr == '\t') { - ptr++; - len--; - } - } - if (cnt > 0) { - for (cc = 0; cc < maxlen; cc++) { - str << " "; - } - } - CommandLineArguments::Internal::String::size_type skip = len; - if (skip > this->LineLength - maxlen) { - skip = this->LineLength - maxlen; - for (cc = skip - 1; cc > 0; cc--) { - if (ptr[cc] == ' ' || ptr[cc] == '\t') { - break; - } - } - if (cc != 0) { - skip = cc; - } - } - str.write(ptr, static_cast<std::streamsize>(skip)); - str << std::endl; - ptr += skip; - len -= skip; - cnt++; - } - } - /* - // This can help debugging help string - str << endl; - unsigned int cc; - for ( cc = 0; cc < this->LineLength; cc ++ ) - { - str << cc % 10; - } - str << endl; - */ - this->Help = str.str(); -} - -void CommandLineArguments::PopulateVariable(bool* variable, - const std::string& value) -{ - if (value == "1" || value == "ON" || value == "on" || value == "On" || - value == "TRUE" || value == "true" || value == "True" || - value == "yes" || value == "Yes" || value == "YES") { - *variable = true; - } else { - *variable = false; - } -} - -void CommandLineArguments::PopulateVariable(int* variable, - const std::string& value) -{ - char* res = nullptr; - *variable = static_cast<int>(strtol(value.c_str(), &res, 10)); - // if ( res && *res ) - // { - // Can handle non-int - // } -} - -void CommandLineArguments::PopulateVariable(double* variable, - const std::string& value) -{ - char* res = nullptr; - *variable = strtod(value.c_str(), &res); - // if ( res && *res ) - // { - // Can handle non-double - // } -} - -void CommandLineArguments::PopulateVariable(char** variable, - const std::string& value) -{ - delete[] * variable; - *variable = new char[value.size() + 1]; - strcpy(*variable, value.c_str()); -} - -void CommandLineArguments::PopulateVariable(std::string* variable, - const std::string& value) -{ - *variable = value; -} - -void CommandLineArguments::PopulateVariable(std::vector<bool>* variable, - const std::string& value) -{ - bool val = false; - if (value == "1" || value == "ON" || value == "on" || value == "On" || - value == "TRUE" || value == "true" || value == "True" || - value == "yes" || value == "Yes" || value == "YES") { - val = true; - } - variable->push_back(val); -} - -void CommandLineArguments::PopulateVariable(std::vector<int>* variable, - const std::string& value) -{ - char* res = nullptr; - variable->push_back(static_cast<int>(strtol(value.c_str(), &res, 10))); - // if ( res && *res ) - // { - // Can handle non-int - // } -} - -void CommandLineArguments::PopulateVariable(std::vector<double>* variable, - const std::string& value) -{ - char* res = nullptr; - variable->push_back(strtod(value.c_str(), &res)); - // if ( res && *res ) - // { - // Can handle non-int - // } -} - -void CommandLineArguments::PopulateVariable(std::vector<char*>* variable, - const std::string& value) -{ - char* var = new char[value.size() + 1]; - strcpy(var, value.c_str()); - variable->push_back(var); -} - -void CommandLineArguments::PopulateVariable(std::vector<std::string>* variable, - const std::string& value) -{ - variable->push_back(value); -} - -bool CommandLineArguments::PopulateVariable( - CommandLineArgumentsCallbackStructure* cs, const char* value) -{ - // Call the callback - if (cs->Callback) { - if (!cs->Callback(cs->Argument, value, cs->CallData)) { - this->Internals->LastArgument--; - return 0; - } - } - CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to " - << value); - if (cs->Variable) { - std::string var = "1"; - if (value) { - var = value; - } - switch (cs->VariableType) { - case CommandLineArguments::INT_TYPE: - this->PopulateVariable(static_cast<int*>(cs->Variable), var); - break; - case CommandLineArguments::DOUBLE_TYPE: - this->PopulateVariable(static_cast<double*>(cs->Variable), var); - break; - case CommandLineArguments::STRING_TYPE: - this->PopulateVariable(static_cast<char**>(cs->Variable), var); - break; - case CommandLineArguments::STL_STRING_TYPE: - this->PopulateVariable(static_cast<std::string*>(cs->Variable), var); - break; - case CommandLineArguments::BOOL_TYPE: - this->PopulateVariable(static_cast<bool*>(cs->Variable), var); - break; - case CommandLineArguments::VECTOR_BOOL_TYPE: - this->PopulateVariable(static_cast<std::vector<bool>*>(cs->Variable), - var); - break; - case CommandLineArguments::VECTOR_INT_TYPE: - this->PopulateVariable(static_cast<std::vector<int>*>(cs->Variable), - var); - break; - case CommandLineArguments::VECTOR_DOUBLE_TYPE: - this->PopulateVariable(static_cast<std::vector<double>*>(cs->Variable), - var); - break; - case CommandLineArguments::VECTOR_STRING_TYPE: - this->PopulateVariable(static_cast<std::vector<char*>*>(cs->Variable), - var); - break; - case CommandLineArguments::VECTOR_STL_STRING_TYPE: - this->PopulateVariable( - static_cast<std::vector<std::string>*>(cs->Variable), var); - break; - default: - std::cerr << "Got unknown variable type: \"" << cs->VariableType - << "\"" << std::endl; - this->Internals->LastArgument--; - return 0; - } - } - return 1; -} - -} // namespace KWSYS_NAMESPACE diff --git a/test/API/driver/kwsys/CommandLineArguments.hxx.in b/test/API/driver/kwsys/CommandLineArguments.hxx.in deleted file mode 100644 index 7db9015..0000000 --- a/test/API/driver/kwsys/CommandLineArguments.hxx.in +++ /dev/null @@ -1,270 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_CommandLineArguments_hxx -#define @KWSYS_NAMESPACE@_CommandLineArguments_hxx - -#include <@KWSYS_NAMESPACE@/Configure.h> -#include <@KWSYS_NAMESPACE@/Configure.hxx> - -#include <string> -#include <vector> - -namespace @KWSYS_NAMESPACE@ { - -class CommandLineArgumentsInternal; -struct CommandLineArgumentsCallbackStructure; - -/** \class CommandLineArguments - * \brief Command line arguments processing code. - * - * Find specified arguments with optional options and execute specified methods - * or set given variables. - * - * The two interfaces it knows are callback based and variable based. For - * callback based, you have to register callback for particular argument using - * AddCallback method. When that argument is passed, the callback will be - * called with argument, value, and call data. For boolean (NO_ARGUMENT) - * arguments, the value is "1". If the callback returns 0 the argument parsing - * will stop with an error. - * - * For the variable interface you associate variable with each argument. When - * the argument is specified, the variable is set to the specified value casted - * to the appropriate type. For boolean (NO_ARGUMENT), the value is "1". - * - * Both interfaces can be used at the same time. - * - * Possible argument types are: - * NO_ARGUMENT - The argument takes no value : --A - * CONCAT_ARGUMENT - The argument takes value after no space : --Aval - * SPACE_ARGUMENT - The argument takes value after space : --A val - * EQUAL_ARGUMENT - The argument takes value after equal : --A=val - * MULTI_ARGUMENT - The argument takes values after space : --A val1 val2 - * val3 ... - * - * Example use: - * - * kwsys::CommandLineArguments arg; - * arg.Initialize(argc, argv); - * typedef kwsys::CommandLineArguments argT; - * arg.AddArgument("--something", argT::EQUAL_ARGUMENT, &some_variable, - * "This is help string for --something"); - * if ( !arg.Parse() ) - * { - * std::cerr << "Problem parsing arguments" << std::endl; - * res = 1; - * } - * - */ - -class @KWSYS_NAMESPACE@_EXPORT CommandLineArguments -{ -public: - CommandLineArguments(); - ~CommandLineArguments(); - - CommandLineArguments(const CommandLineArguments&) = delete; - CommandLineArguments& operator=(const CommandLineArguments&) = delete; - - /** - * Various argument types. - */ - enum ArgumentTypeEnum - { - NO_ARGUMENT, - CONCAT_ARGUMENT, - SPACE_ARGUMENT, - EQUAL_ARGUMENT, - MULTI_ARGUMENT - }; - - /** - * Various variable types. When using the variable interface, this specifies - * what type the variable is. - */ - enum VariableTypeEnum - { - NO_VARIABLE_TYPE = 0, // The variable is not specified - INT_TYPE, // The variable is integer (int) - BOOL_TYPE, // The variable is boolean (bool) - DOUBLE_TYPE, // The variable is float (double) - STRING_TYPE, // The variable is string (char*) - STL_STRING_TYPE, // The variable is string (char*) - VECTOR_INT_TYPE, // The variable is integer (int) - VECTOR_BOOL_TYPE, // The variable is boolean (bool) - VECTOR_DOUBLE_TYPE, // The variable is float (double) - VECTOR_STRING_TYPE, // The variable is string (char*) - VECTOR_STL_STRING_TYPE, // The variable is string (char*) - LAST_VARIABLE_TYPE - }; - - /** - * Prototypes for callbacks for callback interface. - */ - typedef int (*CallbackType)(const char* argument, const char* value, - void* call_data); - typedef int (*ErrorCallbackType)(const char* argument, void* client_data); - - /** - * Initialize internal data structures. This should be called before parsing. - */ - void Initialize(int argc, const char* const argv[]); - void Initialize(int argc, char* argv[]); - - /** - * Initialize internal data structure and pass arguments one by one. This is - * convenience method for use from scripting languages where argc and argv - * are not available. - */ - void Initialize(); - void ProcessArgument(const char* arg); - - /** - * This method will parse arguments and call appropriate methods. - */ - int Parse(); - - /** - * This method will add a callback for a specific argument. The arguments to - * it are argument, argument type, callback method, and call data. The - * argument help specifies the help string used with this option. The - * callback and call_data can be skipped. - */ - void AddCallback(const char* argument, ArgumentTypeEnum type, - CallbackType callback, void* call_data, const char* help); - - /** - * Add handler for argument which is going to set the variable to the - * specified value. If the argument is specified, the option is casted to the - * appropriate type. - */ - void AddArgument(const char* argument, ArgumentTypeEnum type, bool* variable, - const char* help); - void AddArgument(const char* argument, ArgumentTypeEnum type, int* variable, - const char* help); - void AddArgument(const char* argument, ArgumentTypeEnum type, - double* variable, const char* help); - void AddArgument(const char* argument, ArgumentTypeEnum type, - char** variable, const char* help); - void AddArgument(const char* argument, ArgumentTypeEnum type, - std::string* variable, const char* help); - - /** - * Add handler for argument which is going to set the variable to the - * specified value. If the argument is specified, the option is casted to the - * appropriate type. This will handle the multi argument values. - */ - void AddArgument(const char* argument, ArgumentTypeEnum type, - std::vector<bool>* variable, const char* help); - void AddArgument(const char* argument, ArgumentTypeEnum type, - std::vector<int>* variable, const char* help); - void AddArgument(const char* argument, ArgumentTypeEnum type, - std::vector<double>* variable, const char* help); - void AddArgument(const char* argument, ArgumentTypeEnum type, - std::vector<char*>* variable, const char* help); - void AddArgument(const char* argument, ArgumentTypeEnum type, - std::vector<std::string>* variable, const char* help); - - /** - * Add handler for boolean argument. The argument does not take any option - * and if it is specified, the value of the variable is true/1, otherwise it - * is false/0. - */ - void AddBooleanArgument(const char* argument, bool* variable, - const char* help); - void AddBooleanArgument(const char* argument, int* variable, - const char* help); - void AddBooleanArgument(const char* argument, double* variable, - const char* help); - void AddBooleanArgument(const char* argument, char** variable, - const char* help); - void AddBooleanArgument(const char* argument, std::string* variable, - const char* help); - - /** - * Set the callbacks for error handling. - */ - void SetClientData(void* client_data); - void SetUnknownArgumentCallback(ErrorCallbackType callback); - - /** - * Get remaining arguments. It allocates space for argv, so you have to call - * delete[] on it. - */ - void GetRemainingArguments(int* argc, char*** argv); - void DeleteRemainingArguments(int argc, char*** argv); - - /** - * If StoreUnusedArguments is set to true, then all unknown arguments will be - * stored and the user can access the modified argc, argv without known - * arguments. - */ - void StoreUnusedArguments(bool val) { this->StoreUnusedArgumentsFlag = val; } - void GetUnusedArguments(int* argc, char*** argv); - - /** - * Return string containing help. If the argument is specified, only return - * help for that argument. - */ - const char* GetHelp() { return this->Help.c_str(); } - const char* GetHelp(const char* arg); - - /** - * Get / Set the help line length. This length is used when generating the - * help page. Default length is 80. - */ - void SetLineLength(unsigned int); - unsigned int GetLineLength(); - - /** - * Get the executable name (argv0). This is only available when using - * Initialize with argc/argv. - */ - const char* GetArgv0(); - - /** - * Get index of the last argument parsed. This is the last argument that was - * parsed ok in the original argc/argv list. - */ - unsigned int GetLastArgument(); - -protected: - void GenerateHelp(); - - //! This is internal method that registers variable with argument - void AddArgument(const char* argument, ArgumentTypeEnum type, - VariableTypeEnum vtype, void* variable, const char* help); - - bool GetMatchedArguments(std::vector<std::string>* matches, - const std::string& arg); - - //! Populate individual variables - bool PopulateVariable(CommandLineArgumentsCallbackStructure* cs, - const char* value); - - //! Populate individual variables of type ... - void PopulateVariable(bool* variable, const std::string& value); - void PopulateVariable(int* variable, const std::string& value); - void PopulateVariable(double* variable, const std::string& value); - void PopulateVariable(char** variable, const std::string& value); - void PopulateVariable(std::string* variable, const std::string& value); - void PopulateVariable(std::vector<bool>* variable, const std::string& value); - void PopulateVariable(std::vector<int>* variable, const std::string& value); - void PopulateVariable(std::vector<double>* variable, - const std::string& value); - void PopulateVariable(std::vector<char*>* variable, - const std::string& value); - void PopulateVariable(std::vector<std::string>* variable, - const std::string& value); - - typedef CommandLineArgumentsInternal Internal; - Internal* Internals; - std::string Help; - - unsigned int LineLength; - - bool StoreUnusedArgumentsFlag; -}; - -} // namespace @KWSYS_NAMESPACE@ - -#endif diff --git a/test/API/driver/kwsys/Configure.h.in b/test/API/driver/kwsys/Configure.h.in deleted file mode 100644 index 5323c57..0000000 --- a/test/API/driver/kwsys/Configure.h.in +++ /dev/null @@ -1,89 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_Configure_h -#define @KWSYS_NAMESPACE@_Configure_h - -/* If we are building a kwsys .c or .cxx file, let it use the kwsys - namespace. When not building a kwsys source file these macros are - temporarily defined inside the headers that use them. */ -#if defined(KWSYS_NAMESPACE) -# define kwsys_ns(x) @KWSYS_NAMESPACE@##x -# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT -#endif - -/* Disable some warnings inside kwsys source files. */ -#if defined(KWSYS_NAMESPACE) -# if defined(__BORLANDC__) -# pragma warn - 8027 /* function not inlined. */ -# endif -# if defined(__INTEL_COMPILER) -# pragma warning(disable : 1572) /* floating-point equality test */ -# endif -# if defined(__sgi) && !defined(__GNUC__) -# pragma set woff 3970 /* pointer to int conversion */ -# pragma set woff 3968 /* 64 bit conversion */ -# endif -#endif - -/* Whether kwsys namespace is "kwsys". */ -#define @KWSYS_NAMESPACE@_NAME_IS_KWSYS @KWSYS_NAME_IS_KWSYS@ - -/* Setup the export macro. */ -#if @KWSYS_BUILD_SHARED@ -# if defined(_WIN32) || defined(__CYGWIN__) -# if defined(@KWSYS_NAMESPACE@_EXPORTS) -# define @KWSYS_NAMESPACE@_EXPORT __declspec(dllexport) -# else -# define @KWSYS_NAMESPACE@_EXPORT __declspec(dllimport) -# endif -# elif __GNUC__ >= 4 -# define @KWSYS_NAMESPACE@_EXPORT __attribute__((visibility("default"))) -# else -# define @KWSYS_NAMESPACE@_EXPORT -# endif -#else -# define @KWSYS_NAMESPACE@_EXPORT -#endif - -/* Enable warnings that are off by default but are useful. */ -#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_ENABLE) -# if defined(_MSC_VER) -# pragma warning(default : 4263) /* no override, call convention differs \ - */ -# endif -#endif - -/* Disable warnings that are on by default but occur in valid code. */ -#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_DISABLE) -# if defined(_MSC_VER) -# pragma warning(disable : 4097) /* typedef is synonym for class */ -# pragma warning(disable : 4127) /* conditional expression is constant */ -# pragma warning(disable : 4244) /* possible loss in conversion */ -# pragma warning(disable : 4251) /* missing DLL-interface */ -# pragma warning(disable : 4305) /* truncation from type1 to type2 */ -# pragma warning(disable : 4309) /* truncation of constant value */ -# pragma warning(disable : 4514) /* unreferenced inline function */ -# pragma warning(disable : 4706) /* assignment in conditional expression \ - */ -# pragma warning(disable : 4710) /* function not inlined */ -# pragma warning(disable : 4786) /* identifier truncated in debug info */ -# endif -# if defined(__BORLANDC__) && !defined(__cplusplus) -/* Code has no effect; raised by winnt.h in C (not C++) when ignoring an - unused parameter using "(param)" syntax (i.e. no cast to void). */ -# pragma warn - 8019 -# endif -#endif - -/* MSVC 6.0 in release mode will warn about code it produces with its - optimizer. Disable the warnings specifically for this - configuration. Real warnings will be revealed by a debug build or - by other compilers. */ -#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_DISABLE_BOGUS) -# if defined(_MSC_VER) && (_MSC_VER < 1300) && defined(NDEBUG) -# pragma warning(disable : 4701) /* Variable may be used uninitialized. */ -# pragma warning(disable : 4702) /* Unreachable code. */ -# endif -#endif - -#endif diff --git a/test/API/driver/kwsys/Configure.hxx.in b/test/API/driver/kwsys/Configure.hxx.in deleted file mode 100644 index 29a2dd1..0000000 --- a/test/API/driver/kwsys/Configure.hxx.in +++ /dev/null @@ -1,65 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_Configure_hxx -#define @KWSYS_NAMESPACE@_Configure_hxx - -/* Include C configuration. */ -#include <@KWSYS_NAMESPACE@/Configure.h> - -/* Whether wstring is available. */ -#define @KWSYS_NAMESPACE@_STL_HAS_WSTRING @KWSYS_STL_HAS_WSTRING@ -/* Whether <ext/stdio_filebuf.h> is available. */ -#define @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H \ - @KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@ -/* Whether the translation map is available or not. */ -#define @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP \ - @KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP@ - -#if defined(__SUNPRO_CC) && __SUNPRO_CC > 0x5130 && defined(__has_attribute) -# define @KWSYS_NAMESPACE@__has_cpp_attribute(x) __has_attribute(x) -#elif defined(__has_cpp_attribute) -# define @KWSYS_NAMESPACE@__has_cpp_attribute(x) __has_cpp_attribute(x) -#else -# define @KWSYS_NAMESPACE@__has_cpp_attribute(x) 0 -#endif - -#if __cplusplus >= 201103L -# define @KWSYS_NAMESPACE@_NULLPTR nullptr -#else -# define @KWSYS_NAMESPACE@_NULLPTR 0 -#endif - -#ifndef @KWSYS_NAMESPACE@_FALLTHROUGH -# if __cplusplus >= 201703L && \ - @KWSYS_NAMESPACE@__has_cpp_attribute(fallthrough) -# define @KWSYS_NAMESPACE@_FALLTHROUGH [[fallthrough]] -# elif __cplusplus >= 201103L && \ - @KWSYS_NAMESPACE@__has_cpp_attribute(gnu::fallthrough) -# define @KWSYS_NAMESPACE@_FALLTHROUGH [[gnu::fallthrough]] -# elif __cplusplus >= 201103L && \ - @KWSYS_NAMESPACE@__has_cpp_attribute(clang::fallthrough) -# define @KWSYS_NAMESPACE@_FALLTHROUGH [[clang::fallthrough]] -# endif -#endif -#ifndef @KWSYS_NAMESPACE@_FALLTHROUGH -# define @KWSYS_NAMESPACE@_FALLTHROUGH static_cast<void>(0) -#endif - -#undef @KWSYS_NAMESPACE@__has_cpp_attribute - -/* If building a C++ file in kwsys itself, give the source file - access to the macros without a configured namespace. */ -#if defined(KWSYS_NAMESPACE) -# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# define kwsys @KWSYS_NAMESPACE@ -# endif -# define KWSYS_NAME_IS_KWSYS @KWSYS_NAMESPACE@_NAME_IS_KWSYS -# define KWSYS_STL_HAS_WSTRING @KWSYS_NAMESPACE@_STL_HAS_WSTRING -# define KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H \ - @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H -# define KWSYS_FALLTHROUGH @KWSYS_NAMESPACE@_FALLTHROUGH -# define KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP \ - @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP -#endif - -#endif diff --git a/test/API/driver/kwsys/ConsoleBuf.hxx.in b/test/API/driver/kwsys/ConsoleBuf.hxx.in deleted file mode 100644 index 49dbdf7..0000000 --- a/test/API/driver/kwsys/ConsoleBuf.hxx.in +++ /dev/null @@ -1,398 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_ConsoleBuf_hxx -#define @KWSYS_NAMESPACE@_ConsoleBuf_hxx - -#include <@KWSYS_NAMESPACE@/Configure.hxx> - -#include <@KWSYS_NAMESPACE@/Encoding.hxx> - -#include <cstring> -#include <iostream> -#include <sstream> -#include <stdexcept> -#include <streambuf> -#include <string> - -#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 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; - }; - } - - BasicConsoleBuf<CharT, Traits>* GetConsoleBuf() { return m_consolebuf; } - - void SetUTF8Pipes() - { - if (m_consolebuf) { - m_consolebuf->input_pipe_codepage = CP_UTF8; - m_consolebuf->output_pipe_codepage = CP_UTF8; - m_consolebuf->activateCodepageChange(); - } - } - - ~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, nullptr) == 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, nullptr) == 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) { - // ReadConsole doesn't tell if there's more input available - // don't support reading more characters than this - wchar_t wbuffer[8192]; - DWORD charsRead; - if (ReadConsoleW(m_hInput, wbuffer, - (sizeof(wbuffer) / sizeof(wbuffer[0])), &charsRead, - nullptr) == 0 || - charsRead == 0) { - _setg(true); - return Traits::eof(); - } - setBuffer(std::wstring(wbuffer, charsRead), m_ibuffer); - } else { - std::wstring wbuffer; - std::string strbuffer; - DWORD bytesRead; - LARGE_INTEGER size; - if (GetFileSizeEx(m_hInput, &size) == 0) { - _setg(true); - return Traits::eof(); - } - char* buffer = new char[size.LowPart]; - while (ReadFile(m_hInput, buffer, size.LowPart, &bytesRead, nullptr) == - 0) { - if (GetLastError() == ERROR_MORE_DATA) { - strbuffer += std::string(buffer, bytesRead); - continue; - } - _setg(true); - delete[] buffer; - return Traits::eof(); - } - if (bytesRead > 0) { - strbuffer += std::string(buffer, bytesRead); - } - delete[] buffer; - if (!decodeInputBuffer(strbuffer, wbuffer)) { - _setg(true); - return Traits::eof(); - } - setBuffer(wbuffer, 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: - // Check for actual console. - DWORD consoleMode; - m_isConsoleInput = - GetConsoleMode(m_hInput, &consoleMode) == 0 ? false : true; - if (m_isConsoleInput) { - break; - } - @KWSYS_NAMESPACE@_FALLTHROUGH; - 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: - // Check for actual console. - DWORD consoleMode; - m_isConsoleOutput = - GetConsoleMode(m_hOutput, &consoleMode) == 0 ? false : true; - if (m_isConsoleOutput) { - break; - } - @KWSYS_NAMESPACE@_FALLTHROUGH; - 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) - { - if (wbuffer.size() == 0) { - buffer = std::string(); - return true; - } - const int length = - WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(), - (int)wbuffer.size(), nullptr, 0, nullptr, nullptr); - char* buf = new char[length]; - const bool success = - WideCharToMultiByte(m_activeOutputCodepage, 0, wbuffer.c_str(), - (int)wbuffer.size(), buf, length, nullptr, - nullptr) > 0 - ? true - : false; - buffer = std::string(buf, length); - delete[] buf; - return success; - } - bool decodeInputBuffer(const std::string buffer, std::wstring& wbuffer) - { - size_t length = buffer.length(); - if (length == 0) { - wbuffer = std::wstring(); - return true; - } - int actualCodepage = m_activeInputCodepage; - const char BOM_UTF8[] = { char(0xEF), char(0xBB), char(0xBF) }; - const char* data = buffer.data(); - const size_t BOMsize = sizeof(BOM_UTF8); - if (length >= BOMsize && std::memcmp(data, BOM_UTF8, BOMsize) == 0) { - // PowerShell uses UTF-8 with BOM for pipes - actualCodepage = CP_UTF8; - data += BOMsize; - length -= BOMsize; - } - const size_t wlength = static_cast<size_t>(MultiByteToWideChar( - actualCodepage, 0, data, static_cast<int>(length), nullptr, 0)); - wchar_t* wbuf = new wchar_t[wlength]; - const bool success = - MultiByteToWideChar(actualCodepage, 0, data, static_cast<int>(length), - wbuf, static_cast<int>(wlength)) > 0 - ? true - : false; - wbuffer = std::wstring(wbuf, wlength); - 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/test/API/driver/kwsys/Copyright.txt b/test/API/driver/kwsys/Copyright.txt deleted file mode 100644 index 33d7fb4..0000000 --- a/test/API/driver/kwsys/Copyright.txt +++ /dev/null @@ -1,38 +0,0 @@ -KWSys - Kitware System Library -Copyright 2000-2016 Kitware, Inc. and Contributors -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -* Neither the name of Kitware, Inc. nor the names of Contributors - may be used to endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ------------------------------------------------------------------------------- - -The following individuals and institutions are among the Contributors: - -* Insight Software Consortium <insightsoftwareconsortium.org> - -See version control history for details of individual contributions. diff --git a/test/API/driver/kwsys/Directory.cxx b/test/API/driver/kwsys/Directory.cxx deleted file mode 100644 index e379182..0000000 --- a/test/API/driver/kwsys/Directory.cxx +++ /dev/null @@ -1,236 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Directory.hxx) - -#include KWSYS_HEADER(Configure.hxx) - -#include KWSYS_HEADER(Encoding.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Configure.hxx.in" -# include "Directory.hxx.in" -# include "Encoding.hxx.in" -#endif - -#include <string> -#include <vector> - -namespace KWSYS_NAMESPACE { - -class DirectoryInternals -{ -public: - // Array of Files - std::vector<std::string> Files; - - // Path to Open'ed directory - std::string Path; -}; - -Directory::Directory() -{ - this->Internal = new DirectoryInternals; -} - -Directory::~Directory() -{ - delete this->Internal; -} - -unsigned long Directory::GetNumberOfFiles() const -{ - return static_cast<unsigned long>(this->Internal->Files.size()); -} - -const char* Directory::GetFile(unsigned long dindex) const -{ - if (dindex >= this->Internal->Files.size()) { - return nullptr; - } - return this->Internal->Files[dindex].c_str(); -} - -const char* Directory::GetPath() const -{ - return this->Internal->Path.c_str(); -} - -void Directory::Clear() -{ - this->Internal->Path.resize(0); - this->Internal->Files.clear(); -} - -} // namespace KWSYS_NAMESPACE - -// First Windows platforms - -#if defined(_WIN32) && !defined(__CYGWIN__) -# include <windows.h> - -# include <ctype.h> -# include <fcntl.h> -# include <io.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# include <sys/stat.h> -# include <sys/types.h> - -// Wide function names can vary depending on compiler: -# ifdef __BORLANDC__ -# define _wfindfirst_func __wfindfirst -# define _wfindnext_func __wfindnext -# else -# define _wfindfirst_func _wfindfirst -# define _wfindnext_func _wfindnext -# endif - -namespace KWSYS_NAMESPACE { - -bool Directory::Load(const std::string& name) -{ - this->Clear(); -# if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__) - // Older Visual C++ and Embarcadero compilers. - long srchHandle; -# else // Newer Visual C++ - intptr_t srchHandle; -# endif - char* buf; - size_t n = name.size(); - if (name.back() == '/' || name.back() == '\\') { - buf = new char[n + 1 + 1]; - sprintf(buf, "%s*", name.c_str()); - } else { - // Make sure the slashes in the wildcard suffix are consistent with the - // rest of the path - buf = new char[n + 2 + 1]; - if (name.find('\\') != std::string::npos) { - sprintf(buf, "%s\\*", name.c_str()); - } else { - sprintf(buf, "%s/*", name.c_str()); - } - } - struct _wfinddata_t data; // data of current file - - // Now put them into the file array - srchHandle = _wfindfirst_func( - (wchar_t*)Encoding::ToWindowsExtendedPath(buf).c_str(), &data); - delete[] buf; - - if (srchHandle == -1) { - return 0; - } - - // Loop through names - do { - this->Internal->Files.push_back(Encoding::ToNarrow(data.name)); - } while (_wfindnext_func(srchHandle, &data) != -1); - this->Internal->Path = name; - return _findclose(srchHandle) != -1; -} - -unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name) -{ -# if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__) - // Older Visual C++ and Embarcadero compilers. - long srchHandle; -# else // Newer Visual C++ - intptr_t srchHandle; -# endif - char* buf; - size_t n = name.size(); - if (name.back() == '/') { - buf = new char[n + 1 + 1]; - sprintf(buf, "%s*", name.c_str()); - } else { - buf = new char[n + 2 + 1]; - sprintf(buf, "%s/*", name.c_str()); - } - struct _wfinddata_t data; // data of current file - - // Now put them into the file array - srchHandle = - _wfindfirst_func((wchar_t*)Encoding::ToWide(buf).c_str(), &data); - delete[] buf; - - if (srchHandle == -1) { - return 0; - } - - // Loop through names - unsigned long count = 0; - do { - count++; - } while (_wfindnext_func(srchHandle, &data) != -1); - _findclose(srchHandle); - return count; -} - -} // namespace KWSYS_NAMESPACE - -#else - -// Now the POSIX style directory access - -# include <sys/types.h> - -# include <dirent.h> - -// PGI with glibc has trouble with dirent and large file support: -// http://www.pgroup.com/userforum/viewtopic.php? -// p=1992&sid=f16167f51964f1a68fe5041b8eb213b6 -// Work around the problem by mapping dirent the same way as readdir. -# if defined(__PGI) && defined(__GLIBC__) -# define kwsys_dirent_readdir dirent -# define kwsys_dirent_readdir64 dirent64 -# define kwsys_dirent kwsys_dirent_lookup(readdir) -# define kwsys_dirent_lookup(x) kwsys_dirent_lookup_delay(x) -# define kwsys_dirent_lookup_delay(x) kwsys_dirent_##x -# else -# define kwsys_dirent dirent -# endif - -namespace KWSYS_NAMESPACE { - -bool Directory::Load(const std::string& name) -{ - this->Clear(); - - DIR* dir = opendir(name.c_str()); - - if (!dir) { - return 0; - } - - for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) { - this->Internal->Files.push_back(d->d_name); - } - this->Internal->Path = name; - closedir(dir); - return 1; -} - -unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name) -{ - DIR* dir = opendir(name.c_str()); - - if (!dir) { - return 0; - } - - unsigned long count = 0; - for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) { - count++; - } - closedir(dir); - return count; -} - -} // namespace KWSYS_NAMESPACE - -#endif diff --git a/test/API/driver/kwsys/Directory.hxx.in b/test/API/driver/kwsys/Directory.hxx.in deleted file mode 100644 index ad8c51b..0000000 --- a/test/API/driver/kwsys/Directory.hxx.in +++ /dev/null @@ -1,72 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_Directory_hxx -#define @KWSYS_NAMESPACE@_Directory_hxx - -#include <@KWSYS_NAMESPACE@/Configure.h> - -#include <string> - -namespace @KWSYS_NAMESPACE@ { - -class DirectoryInternals; - -/** \class Directory - * \brief Portable directory/filename traversal. - * - * Directory provides a portable way of finding the names of the files - * in a system directory. - * - * Directory currently works with Windows and Unix operating systems. - */ -class @KWSYS_NAMESPACE@_EXPORT Directory -{ -public: - Directory(); - ~Directory(); - - /** - * Load the specified directory and load the names of the files - * in that directory. 0 is returned if the directory can not be - * opened, 1 if it is opened. - */ - bool Load(const std::string&); - - /** - * Return the number of files in the current directory. - */ - unsigned long GetNumberOfFiles() const; - - /** - * Return the number of files in the specified directory. - * A higher performance static method. - */ - static unsigned long GetNumberOfFilesInDirectory(const std::string&); - - /** - * Return the file at the given index, the indexing is 0 based - */ - const char* GetFile(unsigned long) const; - - /** - * Return the path to Open'ed directory - */ - const char* GetPath() const; - - /** - * Clear the internal structure. Used internally at beginning of Load(...) - * to clear the cache. - */ - void Clear(); - -private: - // Private implementation details. - DirectoryInternals* Internal; - - Directory(const Directory&); // Not implemented. - void operator=(const Directory&); // Not implemented. -}; // End Class: Directory - -} // namespace @KWSYS_NAMESPACE@ - -#endif diff --git a/test/API/driver/kwsys/DynamicLoader.cxx b/test/API/driver/kwsys/DynamicLoader.cxx deleted file mode 100644 index a4b8641..0000000 --- a/test/API/driver/kwsys/DynamicLoader.cxx +++ /dev/null @@ -1,495 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#if defined(_WIN32) -# define NOMINMAX // hide min,max to not conflict with <limits> -#endif - -#include "kwsysPrivate.h" -#include KWSYS_HEADER(DynamicLoader.hxx) - -#include KWSYS_HEADER(Configure.hxx) -#include KWSYS_HEADER(Encoding.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Configure.hxx.in" -# include "DynamicLoader.hxx.in" -#endif - -// This file actually contains several different implementations: -// * NOOP for environments without dynamic libs -// * HP machines which uses shl_load -// * Mac OS X 10.2.x and earlier which uses NSLinkModule -// * Windows which uses LoadLibrary -// * BeOS / Haiku -// * FreeMiNT for Atari -// * Default implementation for *NIX systems (including Mac OS X 10.3 and -// later) which use dlopen -// -// Each part of the ifdef contains a complete implementation for -// the static methods of DynamicLoader. - -#define CHECK_OPEN_FLAGS(var, supported, ret) \ - do { \ - /* Check for unknown flags. */ \ - if ((var & AllOpenFlags) != var) { \ - return ret; \ - } \ - \ - /* Check for unsupported flags. */ \ - if ((var & (supported)) != var) { \ - return ret; \ - } \ - } while (0) - -namespace KWSYS_NAMESPACE { - -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( - const std::string& libname) -{ - return DynamicLoader::OpenLibrary(libname, 0); -} -} - -#if !KWSYS_SUPPORTS_SHARED_LIBS -// Implementation for environments without dynamic libs -# include <string.h> // for strerror() - -namespace KWSYS_NAMESPACE { - -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( - const std::string& libname, int flags) -{ - return 0; -} - -int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) -{ - if (!lib) { - return 0; - } - - return 1; -} - -DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const std::string& sym) -{ - return 0; -} - -const char* DynamicLoader::LastError() -{ - return "General error"; -} - -} // namespace KWSYS_NAMESPACE - -#elif defined(__hpux) -// Implementation for HPUX machines -# include <dl.h> -# include <errno.h> - -namespace KWSYS_NAMESPACE { - -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( - const std::string& libname, int flags) -{ - CHECK_OPEN_FLAGS(flags, 0, 0); - - return shl_load(libname.c_str(), BIND_DEFERRED | DYNAMIC_PATH, 0L); -} - -int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) -{ - if (!lib) { - return 0; - } - return !shl_unload(lib); -} - -DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const std::string& sym) -{ - void* addr; - int status; - - /* TYPE_PROCEDURE Look for a function or procedure. (This used to be default) - * TYPE_DATA Look for a symbol in the data segment (for example, - * variables). - * TYPE_UNDEFINED Look for any symbol. - */ - status = shl_findsym(&lib, sym.c_str(), TYPE_UNDEFINED, &addr); - void* result = (status < 0) ? (void*)0 : addr; - - // Hack to cast pointer-to-data to pointer-to-function. - return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result); -} - -const char* DynamicLoader::LastError() -{ - // TODO: Need implementation with errno/strerror - /* If successful, shl_findsym returns an integer (int) value zero. If - * shl_findsym cannot find sym, it returns -1 and sets errno to zero. - * If any other errors occur, shl_findsym returns -1 and sets errno to one - * of these values (defined in <errno.h>): - * ENOEXEC - * A format error was detected in the specified library. - * ENOSYM - * A symbol on which sym depends could not be found. - * EINVAL - * The specified handle is invalid. - */ - - if (errno == ENOEXEC || errno == ENOSYM || errno == EINVAL) { - return strerror(errno); - } - // else - return 0; -} - -} // namespace KWSYS_NAMESPACE - -#elif defined(__APPLE__) && (MAC_OS_X_VERSION_MAX_ALLOWED < 1030) -// Implementation for Mac OS X 10.2.x and earlier -# include <mach-o/dyld.h> -# include <string.h> // for strlen - -namespace KWSYS_NAMESPACE { - -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( - const std::string& libname, int flags) -{ - CHECK_OPEN_FLAGS(flags, 0, 0); - - NSObjectFileImageReturnCode rc; - NSObjectFileImage image = 0; - - rc = NSCreateObjectFileImageFromFile(libname.c_str(), &image); - // rc == NSObjectFileImageInappropriateFile when trying to load a dylib file - if (rc != NSObjectFileImageSuccess) { - return 0; - } - NSModule handle = NSLinkModule(image, libname.c_str(), - NSLINKMODULE_OPTION_BINDNOW | - NSLINKMODULE_OPTION_RETURN_ON_ERROR); - NSDestroyObjectFileImage(image); - return handle; -} - -int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) -{ - // NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED - // With this option the memory for the module is not deallocated - // allowing pointers into the module to still be valid. - // You should use this option instead if your code experience some problems - // reported against Panther 10.3.9 (fixed in Tiger 10.4.2 and up) - bool success = NSUnLinkModule(lib, NSUNLINKMODULE_OPTION_NONE); - return success; -} - -DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const std::string& sym) -{ - void* result = 0; - // Need to prepend symbols with '_' on Apple-gcc compilers - std::string rsym = '_' + sym; - - NSSymbol symbol = NSLookupSymbolInModule(lib, rsym.c_str()); - if (symbol) { - result = NSAddressOfSymbol(symbol); - } - - // Hack to cast pointer-to-data to pointer-to-function. - return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result); -} - -const char* DynamicLoader::LastError() -{ - return 0; -} - -} // namespace KWSYS_NAMESPACE - -#elif defined(_WIN32) && !defined(__CYGWIN__) -// Implementation for Windows win32 code but not cygwin -# include <windows.h> - -# include <stdio.h> - -namespace KWSYS_NAMESPACE { - -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( - const std::string& libname, int flags) -{ - CHECK_OPEN_FLAGS(flags, SearchBesideLibrary, nullptr); - - DWORD llFlags = 0; - if (flags & SearchBesideLibrary) { - llFlags |= LOAD_WITH_ALTERED_SEARCH_PATH; - } - - return LoadLibraryExW(Encoding::ToWindowsExtendedPath(libname).c_str(), - nullptr, llFlags); -} - -int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) -{ - return (int)FreeLibrary(lib); -} - -DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const std::string& sym) -{ - // TODO: The calling convention affects the name of the symbol. We - // should have a tool to help get the symbol with the desired - // calling convention. Currently we assume cdecl. - // - // Borland: - // __cdecl = "_func" (default) - // __fastcall = "@_func" - // __stdcall = "func" - // - // Watcom: - // __cdecl = "_func" - // __fastcall = "@_func@X" - // __stdcall = "_func@X" - // __watcall = "func_" (default) - // - // MSVC: - // __cdecl = "func" (default) - // __fastcall = "@_func@X" - // __stdcall = "_func@X" - // - // Note that the "@X" part of the name above is the total size (in - // bytes) of the arguments on the stack. - void* result; -# if defined(__BORLANDC__) || defined(__WATCOMC__) - // Need to prepend symbols with '_' - std::string ssym = '_' + sym; - const char* rsym = ssym.c_str(); -# else - const char* rsym = sym.c_str(); -# endif - result = (void*)GetProcAddress(lib, rsym); -// Hack to cast pointer-to-data to pointer-to-function. -# ifdef __WATCOMC__ - return *(DynamicLoader::SymbolPointer*)(&result); -# else - return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result); -# endif -} - -# define DYNLOAD_ERROR_BUFFER_SIZE 1024 - -const char* DynamicLoader::LastError() -{ - wchar_t lpMsgBuf[DYNLOAD_ERROR_BUFFER_SIZE + 1]; - - DWORD error = GetLastError(); - DWORD length = FormatMessageW( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - lpMsgBuf, DYNLOAD_ERROR_BUFFER_SIZE, nullptr); - - static char str[DYNLOAD_ERROR_BUFFER_SIZE + 1]; - - if (length < 1) { - /* FormatMessage failed. Use a default message. */ - _snprintf(str, DYNLOAD_ERROR_BUFFER_SIZE, - "DynamicLoader encountered error 0x%X. " - "FormatMessage failed with error 0x%X", - error, GetLastError()); - return str; - } - - if (!WideCharToMultiByte(CP_UTF8, 0, lpMsgBuf, -1, str, - DYNLOAD_ERROR_BUFFER_SIZE, nullptr, nullptr)) { - /* WideCharToMultiByte failed. Use a default message. */ - _snprintf(str, DYNLOAD_ERROR_BUFFER_SIZE, - "DynamicLoader encountered error 0x%X. " - "WideCharToMultiByte failed with error 0x%X", - error, GetLastError()); - } - - return str; -} - -} // namespace KWSYS_NAMESPACE - -#elif defined(__BEOS__) -// Implementation for BeOS / Haiku -# include <string.h> // for strerror() - -# include <be/kernel/image.h> -# include <be/support/Errors.h> - -namespace KWSYS_NAMESPACE { - -static image_id last_dynamic_err = B_OK; - -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( - const std::string& libname, int flags) -{ - CHECK_OPEN_FLAGS(flags, 0, 0); - - // image_id's are integers, errors are negative. Add one just in case we - // get a valid image_id of zero (is that even possible?). - image_id rc = load_add_on(libname.c_str()); - if (rc < 0) { - last_dynamic_err = rc; - return 0; - } - - return rc + 1; -} - -int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) -{ - if (!lib) { - last_dynamic_err = B_BAD_VALUE; - return 0; - } else { - // The function dlclose() returns 0 on success, and non-zero on error. - status_t rc = unload_add_on(lib - 1); - if (rc != B_OK) { - last_dynamic_err = rc; - return 0; - } - } - - return 1; -} - -DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const std::string& sym) -{ - // Hack to cast pointer-to-data to pointer-to-function. - union - { - void* pvoid; - DynamicLoader::SymbolPointer psym; - } result; - - result.psym = nullptr; - - if (!lib) { - last_dynamic_err = B_BAD_VALUE; - } else { - // !!! FIXME: BeOS can do function-only lookups...does this ever - // !!! FIXME: actually _want_ a data symbol lookup, or was this union - // !!! FIXME: a leftover of dlsym()? (s/ANY/TEXT for functions only). - status_t rc = - get_image_symbol(lib - 1, sym.c_str(), B_SYMBOL_TYPE_ANY, &result.pvoid); - if (rc != B_OK) { - last_dynamic_err = rc; - result.psym = nullptr; - } - } - return result.psym; -} - -const char* DynamicLoader::LastError() -{ - const char* retval = strerror(last_dynamic_err); - last_dynamic_err = B_OK; - return retval; -} - -} // namespace KWSYS_NAMESPACE - -#elif defined(__MINT__) -// Implementation for FreeMiNT on Atari -# define _GNU_SOURCE /* for program_invocation_name */ -# include <dld.h> -# include <errno.h> -# include <malloc.h> -# include <string.h> - -namespace KWSYS_NAMESPACE { - -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( - const std::string& libname, int flags) -{ - CHECK_OPEN_FLAGS(flags, 0, nullptr); - - char* name = (char*)calloc(1, libname.size() + 1); - dld_init(program_invocation_name); - strncpy(name, libname.c_str(), libname.size()); - dld_link(libname.c_str()); - return (void*)name; -} - -int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) -{ - dld_unlink_by_file((char*)lib, 0); - free(lib); - return 0; -} - -DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const std::string& sym) -{ - // Hack to cast pointer-to-data to pointer-to-function. - union - { - void* pvoid; - DynamicLoader::SymbolPointer psym; - } result; - result.pvoid = dld_get_symbol(sym.c_str()); - return result.psym; -} - -const char* DynamicLoader::LastError() -{ - return dld_strerror(dld_errno); -} - -} // namespace KWSYS_NAMESPACE - -#else -// Default implementation for *NIX systems (including Mac OS X 10.3 and -// later) which use dlopen -# include <dlfcn.h> - -namespace KWSYS_NAMESPACE { - -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary( - const std::string& libname, int flags) -{ - CHECK_OPEN_FLAGS(flags, 0, nullptr); - - return dlopen(libname.c_str(), RTLD_LAZY); -} - -int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) -{ - if (lib) { - // The function dlclose() returns 0 on success, and non-zero on error. - return !dlclose(lib); - } - // else - return 0; -} - -DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const std::string& sym) -{ - // Hack to cast pointer-to-data to pointer-to-function. - union - { - void* pvoid; - DynamicLoader::SymbolPointer psym; - } result; - result.pvoid = dlsym(lib, sym.c_str()); - return result.psym; -} - -const char* DynamicLoader::LastError() -{ - return dlerror(); -} - -} // namespace KWSYS_NAMESPACE -#endif diff --git a/test/API/driver/kwsys/DynamicLoader.hxx.in b/test/API/driver/kwsys/DynamicLoader.hxx.in deleted file mode 100644 index 539c742..0000000 --- a/test/API/driver/kwsys/DynamicLoader.hxx.in +++ /dev/null @@ -1,106 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_DynamicLoader_hxx -#define @KWSYS_NAMESPACE@_DynamicLoader_hxx - -#include <@KWSYS_NAMESPACE@/Configure.hxx> - -#include <string> - -#if defined(__hpux) -# include <dl.h> -#elif defined(_WIN32) && !defined(__CYGWIN__) -# include <windows.h> -#elif defined(__APPLE__) -# include <AvailabilityMacros.h> -# if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 -# include <mach-o/dyld.h> -# endif -#elif defined(__BEOS__) -# include <be/kernel/image.h> -#endif - -namespace @KWSYS_NAMESPACE@ { -/** \class DynamicLoader - * \brief Portable loading of dynamic libraries or dll's. - * - * DynamicLoader provides a portable interface to loading dynamic - * libraries or dll's into a process. - * - * Directory currently works with Windows, Apple, HP-UX and Unix (POSIX) - * operating systems - * - * \warning dlopen on *nix system works the following way: - * If filename contains a slash ("/"), then it is interpreted as a (relative - * or absolute) pathname. Otherwise, the dynamic linker searches for the - * library as follows : see ld.so(8) for further details): - * Whereas this distinction does not exist on Win32. Therefore ideally you - * should be doing full path to guarantee to have a consistent way of dealing - * with dynamic loading of shared library. - * - * \warning the Cygwin implementation do not use the Win32 HMODULE. Put extra - * condition so that we can include the correct declaration (POSIX) - */ - -class @KWSYS_NAMESPACE@_EXPORT DynamicLoader -{ -public: -// Ugly stuff for library handles -// They are different on several different OS's -#if defined(__hpux) - typedef shl_t LibraryHandle; -#elif defined(_WIN32) && !defined(__CYGWIN__) - typedef HMODULE LibraryHandle; -#elif defined(__APPLE__) -# if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 - typedef NSModule LibraryHandle; -# else - typedef void* LibraryHandle; -# endif -#elif defined(__BEOS__) - typedef image_id LibraryHandle; -#else // POSIX - typedef void* LibraryHandle; -#endif - - // Return type from DynamicLoader::GetSymbolAddress. - typedef void (*SymbolPointer)(); - - enum OpenFlags - { - // Search for dependent libraries beside the library being loaded. - // - // This is currently only supported on Windows. - SearchBesideLibrary = 0x00000001, - - AllOpenFlags = SearchBesideLibrary - }; - - /** Load a dynamic library into the current process. - * The returned LibraryHandle can be used to access the symbols in the - * library. The optional second argument is a set of flags to use when - * opening the library. If unrecognized or unsupported flags are specified, - * the library is not opened. */ - static LibraryHandle OpenLibrary(const std::string&); - static LibraryHandle OpenLibrary(const std::string&, int); - - /** Attempt to detach a dynamic library from the - * process. A value of true is returned if it is successful. */ - static int CloseLibrary(LibraryHandle); - - /** Find the address of the symbol in the given library. */ - static SymbolPointer GetSymbolAddress(LibraryHandle, const std::string&); - - /** Return the default module prefix for the current platform. */ - static const char* LibPrefix() { return "@KWSYS_DynamicLoader_PREFIX@"; } - - /** Return the default module suffix for the current platform. */ - static const char* LibExtension() { return "@KWSYS_DynamicLoader_SUFFIX@"; } - - /** Return the last error produced from a calls made on this class. */ - static const char* LastError(); -}; // End Class: DynamicLoader - -} // namespace @KWSYS_NAMESPACE@ - -#endif diff --git a/test/API/driver/kwsys/Encoding.h.in b/test/API/driver/kwsys/Encoding.h.in deleted file mode 100644 index 86a2669..0000000 --- a/test/API/driver/kwsys/Encoding.h.in +++ /dev/null @@ -1,69 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_Encoding_h -#define @KWSYS_NAMESPACE@_Encoding_h - -#include <@KWSYS_NAMESPACE@/Configure.h> - -#include <wchar.h> - -/* Redefine all public interface symbol names to be in the proper - namespace. These macros are used internally to kwsys only, and are - not visible to user code. Use kwsysHeaderDump.pl to reproduce - these macros after making changes to the interface. */ -#if !defined(KWSYS_NAMESPACE) -# define kwsys_ns(x) @KWSYS_NAMESPACE@##x -# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT -#endif -#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# define kwsysEncoding kwsys_ns(Encoding) -# define kwsysEncoding_mbstowcs kwsys_ns(Encoding_mbstowcs) -# define kwsysEncoding_DupToWide kwsys_ns(Encoding_DupToWide) -# define kwsysEncoding_wcstombs kwsys_ns(Encoding_wcstombs) -# define kwsysEncoding_DupToNarrow kwsys_ns(Encoding_DupToNarrow) -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Convert a narrow string to a wide string. - On Windows, UTF-8 is assumed, and on other platforms, - the current locale is assumed. - */ -kwsysEXPORT size_t kwsysEncoding_mbstowcs(wchar_t* dest, const char* src, - size_t n); - -/* Convert a narrow string to a wide string. - This can return NULL if the conversion fails. */ -kwsysEXPORT wchar_t* kwsysEncoding_DupToWide(const char* src); - -/* Convert a wide string to a narrow string. - On Windows, UTF-8 is assumed, and on other platforms, - the current locale is assumed. */ -kwsysEXPORT size_t kwsysEncoding_wcstombs(char* dest, const wchar_t* src, - size_t n); - -/* Convert a wide string to a narrow string. - This can return NULL if the conversion fails. */ -kwsysEXPORT char* kwsysEncoding_DupToNarrow(const wchar_t* str); - -#if defined(__cplusplus) -} /* extern "C" */ -#endif - -/* If we are building a kwsys .c or .cxx file, let it use these macros. - Otherwise, undefine them to keep the namespace clean. */ -#if !defined(KWSYS_NAMESPACE) -# undef kwsys_ns -# undef kwsysEXPORT -# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# undef kwsysEncoding -# undef kwsysEncoding_mbstowcs -# undef kwsysEncoding_DupToWide -# undef kwsysEncoding_wcstombs -# undef kwsysEncoding_DupToNarrow -# endif -#endif - -#endif diff --git a/test/API/driver/kwsys/Encoding.hxx.in b/test/API/driver/kwsys/Encoding.hxx.in deleted file mode 100644 index 75a2d4d..0000000 --- a/test/API/driver/kwsys/Encoding.hxx.in +++ /dev/null @@ -1,80 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_Encoding_hxx -#define @KWSYS_NAMESPACE@_Encoding_hxx - -#include <@KWSYS_NAMESPACE@/Configure.hxx> - -#include <string> -#include <vector> - -namespace @KWSYS_NAMESPACE@ { -class @KWSYS_NAMESPACE@_EXPORT Encoding -{ -public: - // Container class for argc/argv. - class @KWSYS_NAMESPACE@_EXPORT CommandLineArguments - { - public: - // On Windows, get the program command line arguments - // in this Encoding module's 8 bit encoding. - // On other platforms the given argc/argv is used, and - // to be consistent, should be the argc/argv from main(). - static CommandLineArguments Main(int argc, char const* const* argv); - - // Construct CommandLineArguments with the given - // argc/argv. It is assumed that the string is already - // in the encoding used by this module. - CommandLineArguments(int argc, char const* const* argv); - - // Construct CommandLineArguments with the given - // argc and wide argv. This is useful if wmain() is used. - CommandLineArguments(int argc, wchar_t const* const* argv); - ~CommandLineArguments(); - CommandLineArguments(const CommandLineArguments&); - CommandLineArguments& operator=(const CommandLineArguments&); - - int argc() const; - char const* const* argv() const; - - protected: - std::vector<char*> argv_; - }; - - /** - * Convert between char and wchar_t - */ - -#if @KWSYS_NAMESPACE@_STL_HAS_WSTRING - - // Convert a narrow string to a wide string. - // On Windows, UTF-8 is assumed, and on other platforms, - // the current locale is assumed. - static std::wstring ToWide(const std::string& str); - static std::wstring ToWide(const char* str); - - // Convert a wide string to a narrow string. - // On Windows, UTF-8 is assumed, and on other platforms, - // the current locale is assumed. - static std::string ToNarrow(const std::wstring& str); - static std::string ToNarrow(const wchar_t* str); - -# if defined(_WIN32) - /** - * Convert the path to an extended length path to avoid MAX_PATH length - * limitations on Windows. If the input is a local path the result will be - * prefixed with \\?\; if the input is instead a network path, the result - * will be prefixed with \\?\UNC\. All output will also be converted to - * absolute paths with Windows-style backslashes. - **/ - static std::wstring ToWindowsExtendedPath(std::string const&); - static std::wstring ToWindowsExtendedPath(const char* source); - static std::wstring ToWindowsExtendedPath(std::wstring const& wsource); -# endif - -#endif // @KWSYS_NAMESPACE@_STL_HAS_WSTRING - -}; // class Encoding -} // namespace @KWSYS_NAMESPACE@ - -#endif diff --git a/test/API/driver/kwsys/EncodingC.c b/test/API/driver/kwsys/EncodingC.c deleted file mode 100644 index e12236a..0000000 --- a/test/API/driver/kwsys/EncodingC.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Encoding.h) - -/* Work-around CMake dependency scanning limitation. This must - duplicate the above list of headers. */ -#if 0 -# include "Encoding.h.in" -#endif - -#include <stdlib.h> - -#ifdef _WIN32 -# include <windows.h> -#endif - -size_t kwsysEncoding_mbstowcs(wchar_t* dest, const char* str, size_t n) -{ - if (str == 0) { - return (size_t)-1; - } -#ifdef _WIN32 - return MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str, -1, dest, - (int)n) - - 1; -#else - return mbstowcs(dest, str, n); -#endif -} - -wchar_t* kwsysEncoding_DupToWide(const char* str) -{ - wchar_t* ret = NULL; - size_t length = kwsysEncoding_mbstowcs(NULL, str, 0) + 1; - if (length > 0) { - ret = (wchar_t*)malloc((length) * sizeof(wchar_t)); - if (ret) { - ret[0] = 0; - kwsysEncoding_mbstowcs(ret, str, length); - } - } - return ret; -} - -size_t kwsysEncoding_wcstombs(char* dest, const wchar_t* str, size_t n) -{ - if (str == 0) { - return (size_t)-1; - } -#ifdef _WIN32 - return WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str, -1, dest, - (int)n, NULL, NULL) - - 1; -#else - return wcstombs(dest, str, n); -#endif -} - -char* kwsysEncoding_DupToNarrow(const wchar_t* str) -{ - char* ret = NULL; - size_t length = kwsysEncoding_wcstombs(0, str, 0) + 1; - if (length > 0) { - ret = (char*)malloc(length); - if (ret) { - ret[0] = 0; - kwsysEncoding_wcstombs(ret, str, length); - } - } - return ret; -} diff --git a/test/API/driver/kwsys/EncodingCXX.cxx b/test/API/driver/kwsys/EncodingCXX.cxx deleted file mode 100644 index 5cad934..0000000 --- a/test/API/driver/kwsys/EncodingCXX.cxx +++ /dev/null @@ -1,288 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifdef __osf__ -# define _OSF_SOURCE -# define _POSIX_C_SOURCE 199506L -# define _XOPEN_SOURCE_EXTENDED -#endif - -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Encoding.hxx) -#include KWSYS_HEADER(Encoding.h) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Encoding.h.in" -# include "Encoding.hxx.in" -#endif - -#include <stdlib.h> -#include <string.h> -#include <vector> - -#ifdef _MSC_VER -# pragma warning(disable : 4786) -#endif - -// Windows API. -#if defined(_WIN32) -# include <windows.h> - -# include <ctype.h> -# include <shellapi.h> -#endif - -namespace KWSYS_NAMESPACE { - -Encoding::CommandLineArguments Encoding::CommandLineArguments::Main( - int argc, char const* const* argv) -{ -#ifdef _WIN32 - (void)argc; - (void)argv; - - int ac; - LPWSTR* w_av = CommandLineToArgvW(GetCommandLineW(), &ac); - - std::vector<std::string> av1(ac); - std::vector<char const*> av2(ac); - for (int i = 0; i < ac; i++) { - av1[i] = ToNarrow(w_av[i]); - av2[i] = av1[i].c_str(); - } - LocalFree(w_av); - return CommandLineArguments(ac, &av2[0]); -#else - return CommandLineArguments(argc, argv); -#endif -} - -Encoding::CommandLineArguments::CommandLineArguments(int ac, - char const* const* av) -{ - this->argv_.resize(ac + 1); - for (int i = 0; i < ac; i++) { - this->argv_[i] = strdup(av[i]); - } - this->argv_[ac] = nullptr; -} - -Encoding::CommandLineArguments::CommandLineArguments(int ac, - wchar_t const* const* av) -{ - this->argv_.resize(ac + 1); - for (int i = 0; i < ac; i++) { - this->argv_[i] = kwsysEncoding_DupToNarrow(av[i]); - } - this->argv_[ac] = nullptr; -} - -Encoding::CommandLineArguments::~CommandLineArguments() -{ - for (size_t i = 0; i < this->argv_.size(); i++) { - free(argv_[i]); - } -} - -Encoding::CommandLineArguments::CommandLineArguments( - const CommandLineArguments& other) -{ - this->argv_.resize(other.argv_.size()); - for (size_t i = 0; i < this->argv_.size(); i++) { - this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : nullptr; - } -} - -Encoding::CommandLineArguments& Encoding::CommandLineArguments::operator=( - const CommandLineArguments& other) -{ - if (this != &other) { - size_t i; - for (i = 0; i < this->argv_.size(); i++) { - free(this->argv_[i]); - } - - this->argv_.resize(other.argv_.size()); - for (i = 0; i < this->argv_.size(); i++) { - this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : nullptr; - } - } - - return *this; -} - -int Encoding::CommandLineArguments::argc() const -{ - return static_cast<int>(this->argv_.size() - 1); -} - -char const* const* Encoding::CommandLineArguments::argv() const -{ - return &this->argv_[0]; -} - -#if KWSYS_STL_HAS_WSTRING - -std::wstring Encoding::ToWide(const std::string& str) -{ - std::wstring wstr; -# if defined(_WIN32) - const int wlength = - MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(), - int(str.size()), nullptr, 0); - if (wlength > 0) { - wchar_t* wdata = new wchar_t[wlength]; - int r = MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(), - int(str.size()), wdata, wlength); - if (r > 0) { - wstr = std::wstring(wdata, wlength); - } - delete[] wdata; - } -# else - size_t pos = 0; - size_t nullPos = 0; - do { - if (pos < str.size() && str.at(pos) != '\0') { - wstr += ToWide(str.c_str() + pos); - } - nullPos = str.find('\0', pos); - if (nullPos != std::string::npos) { - pos = nullPos + 1; - wstr += wchar_t('\0'); - } - } while (nullPos != std::string::npos); -# endif - return wstr; -} - -std::string Encoding::ToNarrow(const std::wstring& str) -{ - std::string nstr; -# if defined(_WIN32) - int length = - WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(), - int(str.size()), nullptr, 0, nullptr, nullptr); - if (length > 0) { - char* data = new char[length]; - int r = - WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(), - int(str.size()), data, length, nullptr, nullptr); - if (r > 0) { - nstr = std::string(data, length); - } - delete[] data; - } -# else - size_t pos = 0; - size_t nullPos = 0; - do { - if (pos < str.size() && str.at(pos) != '\0') { - nstr += ToNarrow(str.c_str() + pos); - } - nullPos = str.find(wchar_t('\0'), pos); - if (nullPos != std::string::npos) { - pos = nullPos + 1; - nstr += '\0'; - } - } while (nullPos != std::string::npos); -# endif - return nstr; -} - -std::wstring Encoding::ToWide(const char* cstr) -{ - std::wstring wstr; - size_t length = kwsysEncoding_mbstowcs(nullptr, cstr, 0) + 1; - if (length > 0) { - std::vector<wchar_t> wchars(length); - if (kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0) { - wstr = &wchars[0]; - } - } - return wstr; -} - -std::string Encoding::ToNarrow(const wchar_t* wcstr) -{ - std::string str; - size_t length = kwsysEncoding_wcstombs(nullptr, wcstr, 0) + 1; - if (length > 0) { - std::vector<char> chars(length); - if (kwsysEncoding_wcstombs(&chars[0], wcstr, length) > 0) { - str = &chars[0]; - } - } - return str; -} - -# if defined(_WIN32) -// Convert local paths to UNC style paths -std::wstring Encoding::ToWindowsExtendedPath(std::string const& source) -{ - return ToWindowsExtendedPath(ToWide(source)); -} - -// Convert local paths to UNC style paths -std::wstring Encoding::ToWindowsExtendedPath(const char* source) -{ - return ToWindowsExtendedPath(ToWide(source)); -} - -// Convert local paths to UNC style paths -std::wstring Encoding::ToWindowsExtendedPath(std::wstring const& wsource) -{ - // Resolve any relative paths - DWORD wfull_len; - - /* The +3 is a workaround for a bug in some versions of GetFullPathNameW that - * won't return a large enough buffer size if the input is too small */ - wfull_len = GetFullPathNameW(wsource.c_str(), 0, nullptr, nullptr) + 3; - std::vector<wchar_t> wfull(wfull_len); - GetFullPathNameW(wsource.c_str(), wfull_len, &wfull[0], nullptr); - - /* This should get the correct size without any extra padding from the - * previous size workaround. */ - wfull_len = static_cast<DWORD>(wcslen(&wfull[0])); - - if (wfull_len >= 2 && isalpha(wfull[0]) && - wfull[1] == L':') { /* C:\Foo\bar\FooBar.txt */ - return L"\\\\?\\" + std::wstring(&wfull[0]); - } else if (wfull_len >= 2 && wfull[0] == L'\\' && - wfull[1] == L'\\') { /* Starts with \\ */ - if (wfull_len >= 4 && wfull[2] == L'?' && - wfull[3] == L'\\') { /* Starts with \\?\ */ - if (wfull_len >= 8 && wfull[4] == L'U' && wfull[5] == L'N' && - wfull[6] == L'C' && - wfull[7] == L'\\') { /* \\?\UNC\Foo\bar\FooBar.txt */ - return std::wstring(&wfull[0]); - } else if (wfull_len >= 6 && isalpha(wfull[4]) && - wfull[5] == L':') { /* \\?\C:\Foo\bar\FooBar.txt */ - return std::wstring(&wfull[0]); - } else if (wfull_len >= 5) { /* \\?\Foo\bar\FooBar.txt */ - return L"\\\\?\\UNC\\" + std::wstring(&wfull[4]); - } - } else if (wfull_len >= 4 && wfull[2] == L'.' && - wfull[3] == L'\\') { /* Starts with \\.\ a device name */ - if (wfull_len >= 6 && isalpha(wfull[4]) && - wfull[5] == L':') { /* \\.\C:\Foo\bar\FooBar.txt */ - return L"\\\\?\\" + std::wstring(&wfull[4]); - } else if (wfull_len >= - 5) { /* \\.\Foo\bar\ Device name is left unchanged */ - return std::wstring(&wfull[0]); - } - } else if (wfull_len >= 3) { /* \\Foo\bar\FooBar.txt */ - return L"\\\\?\\UNC\\" + std::wstring(&wfull[2]); - } - } - - // If this case has been reached, then the path is invalid. Leave it - // unchanged - return wsource; -} -# endif - -#endif // KWSYS_STL_HAS_WSTRING - -} // namespace KWSYS_NAMESPACE diff --git a/test/API/driver/kwsys/ExtraTest.cmake.in b/test/API/driver/kwsys/ExtraTest.cmake.in deleted file mode 100644 index e8c0a1c..0000000 --- a/test/API/driver/kwsys/ExtraTest.cmake.in +++ /dev/null @@ -1 +0,0 @@ -MESSAGE("*** This message is generated by message inside a file that is included in DartTestfile.txt ***") diff --git a/test/API/driver/kwsys/FStream.cxx b/test/API/driver/kwsys/FStream.cxx deleted file mode 100644 index 5e4133a..0000000 --- a/test/API/driver/kwsys/FStream.cxx +++ /dev/null @@ -1,55 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(FStream.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "FStream.hxx.in" -#endif - -namespace KWSYS_NAMESPACE { -namespace FStream { - -BOM ReadBOM(std::istream& in) -{ - if (!in.good()) { - return BOM_None; - } - unsigned long orig = in.tellg(); - unsigned char bom[4]; - in.read(reinterpret_cast<char*>(bom), 2); - if (!in.good()) { - in.clear(); - in.seekg(orig); - return BOM_None; - } - if (bom[0] == 0xEF && bom[1] == 0xBB) { - in.read(reinterpret_cast<char*>(bom + 2), 1); - if (in.good() && bom[2] == 0xBF) { - return BOM_UTF8; - } - } else if (bom[0] == 0xFE && bom[1] == 0xFF) { - return BOM_UTF16BE; - } else if (bom[0] == 0x00 && bom[1] == 0x00) { - in.read(reinterpret_cast<char*>(bom + 2), 2); - if (in.good() && bom[2] == 0xFE && bom[3] == 0xFF) { - return BOM_UTF32BE; - } - } else if (bom[0] == 0xFF && bom[1] == 0xFE) { - unsigned long p = in.tellg(); - in.read(reinterpret_cast<char*>(bom + 2), 2); - if (in.good() && bom[2] == 0x00 && bom[3] == 0x00) { - return BOM_UTF32LE; - } - in.seekg(p); - return BOM_UTF16LE; - } - in.clear(); - in.seekg(orig); - return BOM_None; -} - -} // FStream namespace -} // KWSYS_NAMESPACE diff --git a/test/API/driver/kwsys/FStream.hxx.in b/test/API/driver/kwsys/FStream.hxx.in deleted file mode 100644 index d79bbdf..0000000 --- a/test/API/driver/kwsys/FStream.hxx.in +++ /dev/null @@ -1,278 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_FStream_hxx -#define @KWSYS_NAMESPACE@_FStream_hxx - -#include <@KWSYS_NAMESPACE@/Configure.hxx> - -#include <@KWSYS_NAMESPACE@/Encoding.hxx> - -#include <fstream> -#if defined(_WIN32) -# if !defined(_MSC_VER) && @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H -# include <ext/stdio_filebuf.h> -# endif -#endif - -namespace @KWSYS_NAMESPACE@ { -#if defined(_WIN32) && \ - (defined(_MSC_VER) || @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H) -# if defined(_NOEXCEPT) -# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT -# else -# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT -# endif - -# if defined(_MSC_VER) - -template <typename CharType, typename Traits> -class basic_filebuf : public std::basic_filebuf<CharType, Traits> -{ -# if _MSC_VER >= 1400 -public: - typedef std::basic_filebuf<CharType, Traits> my_base_type; - basic_filebuf* open(char const* s, std::ios_base::openmode mode) - { - const std::wstring wstr = Encoding::ToWindowsExtendedPath(s); - return static_cast<basic_filebuf*>(my_base_type::open(wstr.c_str(), mode)); - } -# endif -}; - -# else - -inline std::wstring getcmode(const std::ios_base::openmode mode) -{ - std::wstring cmode; - bool plus = false; - if (mode & std::ios_base::app) { - cmode += L"a"; - plus = mode & std::ios_base::in ? true : false; - } else if (mode & std::ios_base::trunc || - (mode & std::ios_base::out && (mode & std::ios_base::in) == 0)) { - cmode += L"w"; - plus = mode & std::ios_base::in ? true : false; - } else { - cmode += L"r"; - plus = mode & std::ios_base::out ? true : false; - } - if (plus) { - cmode += L"+"; - } - if (mode & std::ios_base::binary) { - cmode += L"b"; - } else { - cmode += L"t"; - } - return cmode; -}; - -# endif - -template <typename CharType, typename Traits = std::char_traits<CharType> > -class basic_efilebuf -{ -public: -# if defined(_MSC_VER) - typedef basic_filebuf<CharType, Traits> internal_buffer_type; -# else - typedef __gnu_cxx::stdio_filebuf<CharType, Traits> internal_buffer_type; -# endif - - basic_efilebuf() - : file_(0) - { - buf_ = 0; - } - - bool _open(char const* file_name, std::ios_base::openmode mode) - { - if (is_open() || file_) { - return false; - } -# if defined(_MSC_VER) - const bool success = buf_->open(file_name, mode) != 0; -# else - const std::wstring wstr = Encoding::ToWindowsExtendedPath(file_name); - bool success = false; - std::wstring cmode = getcmode(mode); - file_ = _wfopen(wstr.c_str(), cmode.c_str()); - if (file_) { - if (buf_) { - delete buf_; - } - buf_ = new internal_buffer_type(file_, mode); - success = true; - } -# endif - return success; - } - - bool is_open() - { - if (!buf_) { - return false; - } - return buf_->is_open(); - } - - bool is_open() const - { - if (!buf_) { - return false; - } - return buf_->is_open(); - } - - bool _close() - { - bool success = false; - if (buf_) { - success = buf_->close() != 0; -# if !defined(_MSC_VER) - if (file_) { - success = fclose(file_) == 0 ? success : false; - file_ = 0; - } -# endif - } - return success; - } - - static void _set_state(bool success, std::basic_ios<CharType, Traits>* ios, - basic_efilebuf* efilebuf) - { -# if !defined(_MSC_VER) - ios->rdbuf(efilebuf->buf_); -# else - static_cast<void>(efilebuf); -# endif - if (!success) { - ios->setstate(std::ios_base::failbit); - } else { - ios->clear(); - } - } - - ~basic_efilebuf() - { - if (buf_) { - delete buf_; - } - } - -protected: - internal_buffer_type* buf_; - FILE* file_; -}; - -template <typename CharType, typename Traits = std::char_traits<CharType> > -class basic_ifstream - : public std::basic_istream<CharType, Traits> - , public basic_efilebuf<CharType, Traits> -{ -public: - typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type - internal_buffer_type; - typedef std::basic_istream<CharType, Traits> internal_stream_type; - - basic_ifstream() - : internal_stream_type(new internal_buffer_type()) - { - this->buf_ = - static_cast<internal_buffer_type*>(internal_stream_type::rdbuf()); - } - explicit basic_ifstream(char const* file_name, - std::ios_base::openmode mode = std::ios_base::in) - : internal_stream_type(new internal_buffer_type()) - { - this->buf_ = - static_cast<internal_buffer_type*>(internal_stream_type::rdbuf()); - open(file_name, mode); - } - - void open(char const* file_name, - std::ios_base::openmode mode = std::ios_base::in) - { - mode = mode | std::ios_base::in; - this->_set_state(this->_open(file_name, mode), this, this); - } - - void close() { this->_set_state(this->_close(), this, this); } - - using basic_efilebuf<CharType, Traits>::is_open; - - internal_buffer_type* rdbuf() const { return this->buf_; } - - ~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { close(); } -}; - -template <typename CharType, typename Traits = std::char_traits<CharType> > -class basic_ofstream - : public std::basic_ostream<CharType, Traits> - , public basic_efilebuf<CharType, Traits> -{ - using basic_efilebuf<CharType, Traits>::is_open; - -public: - typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type - internal_buffer_type; - typedef std::basic_ostream<CharType, Traits> internal_stream_type; - - basic_ofstream() - : internal_stream_type(new internal_buffer_type()) - { - this->buf_ = - static_cast<internal_buffer_type*>(internal_stream_type::rdbuf()); - } - explicit basic_ofstream(char const* file_name, - std::ios_base::openmode mode = std::ios_base::out) - : internal_stream_type(new internal_buffer_type()) - { - this->buf_ = - static_cast<internal_buffer_type*>(internal_stream_type::rdbuf()); - open(file_name, mode); - } - void open(char const* file_name, - std::ios_base::openmode mode = std::ios_base::out) - { - mode = mode | std::ios_base::out; - this->_set_state(this->_open(file_name, mode), this, this); - } - - void close() { this->_set_state(this->_close(), this, this); } - - internal_buffer_type* rdbuf() const { return this->buf_; } - - ~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { close(); } -}; - -typedef basic_ifstream<char> ifstream; -typedef basic_ofstream<char> ofstream; - -# undef @KWSYS_NAMESPACE@_FStream_NOEXCEPT -#else -using std::ofstream; -using std::ifstream; -#endif - -namespace FStream { -enum BOM -{ - BOM_None, - BOM_UTF8, - BOM_UTF16BE, - BOM_UTF16LE, - BOM_UTF32BE, - BOM_UTF32LE -}; - -// Read a BOM, if one exists. -// If a BOM exists, the stream is advanced to after the BOM. -// This function requires a seekable stream (but not a relative -// seekable stream). -@KWSYS_NAMESPACE@_EXPORT BOM ReadBOM(std::istream& in); -} -} - -#endif diff --git a/test/API/driver/kwsys/GitSetup/.gitattributes b/test/API/driver/kwsys/GitSetup/.gitattributes deleted file mode 100644 index e96d1f8..0000000 --- a/test/API/driver/kwsys/GitSetup/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -.git* export-ignore - -config* eol=lf whitespace=indent-with-non-tab -git-* eol=lf whitespace=indent-with-non-tab -tips eol=lf whitespace=indent-with-non-tab -setup-* eol=lf whitespace=indent-with-non-tab diff --git a/test/API/driver/kwsys/GitSetup/LICENSE b/test/API/driver/kwsys/GitSetup/LICENSE deleted file mode 100644 index d645695..0000000 --- a/test/API/driver/kwsys/GitSetup/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/test/API/driver/kwsys/GitSetup/NOTICE b/test/API/driver/kwsys/GitSetup/NOTICE deleted file mode 100644 index 0d32c02..0000000 --- a/test/API/driver/kwsys/GitSetup/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Kitware Local Git Setup Scripts -Copyright 2010-2012 Kitware, Inc. - -This product includes software developed at Kitware, Inc. -(http://www.kitware.com/). diff --git a/test/API/driver/kwsys/GitSetup/README b/test/API/driver/kwsys/GitSetup/README deleted file mode 100644 index 2f9f1ec..0000000 --- a/test/API/driver/kwsys/GitSetup/README +++ /dev/null @@ -1,87 +0,0 @@ -Kitware Local Git Setup Scripts - - -Introduction ------------- - -This is a collection of local Git development setup scripts meant for -inclusion in project source trees to aid their development workflow. -Project-specific information needed by the scripts may be configured -in a "config" file added next to them in the project. - - -Import ------- - -A project may import these scripts into their source tree by -initializing a subtree merge. Bring up a Git prompt and set the -current working directory inside a clone of the target project. -Fetch the "setup" branch from the GitSetup repository: - - $ git fetch ../GitSetup setup:setup - -Prepare to merge the branch but place the content in a subdirectory. -Any prefix (with trailing '/') may be chosen so long as it is used -consistently within a project through the rest of these instructions: - - $ git merge -s ours --no-commit setup - $ git read-tree -u --prefix=Utilities/GitSetup/ setup - -Commit the merge with an informative message: - - $ git commit - ------------------------------------------------------------------------ - Merge branch 'setup' - - Add Utilities/GitSetup/ directory using subtree merge from - the general GitSetup repository "setup" branch. - ------------------------------------------------------------------------ - -Optionally add to the project ".gitattributes" file the line - - /Utilities/GitSetup export-ignore - -to exclude the GitSetup directory from inclusion by "git archive" -since it does not make sense in source tarballs. - - -Configuration -------------- - -Read the "Project configuration instructions" comment in each script. -Add a "config" file next to the scripts with desired configuration -(optionally copy and modify "config.sample"). For example, to -configure the "setup-hooks" script: - - $ git config -f Utilities/GitSetup/config hooks.url "$url" - -where "$url" is the project repository publishing the "hooks" branch. -When finished, add and commit the configuration file: - - $ git add Utilities/GitSetup/config - $ git commit - - -Update ------- - -A project may update these scripts from the GitSetup repository. -Bring up a Git prompt and set the current working directory inside a -clone of the target project. Fetch the "setup" branch from the -GitSetup repository: - - $ git fetch ../GitSetup setup:setup - -Merge the "setup" branch into the subtree: - - $ git merge -X subtree=Utilities/GitSetup setup - -where "Utilities/GitSetup" is the same prefix used during the import -setup, but without a trailing '/'. - - -License -------- - -Distributed under the Apache License 2.0. -See LICENSE and NOTICE for details. diff --git a/test/API/driver/kwsys/GitSetup/config b/test/API/driver/kwsys/GitSetup/config deleted file mode 100644 index cba4c14..0000000 --- a/test/API/driver/kwsys/GitSetup/config +++ /dev/null @@ -1,4 +0,0 @@ -[hooks] - url = https://gitlab.kitware.com/utils/gitsetup.git -[upstream] - url = https://gitlab.kitware.com/utils/kwsys.git diff --git a/test/API/driver/kwsys/GitSetup/config.sample b/test/API/driver/kwsys/GitSetup/config.sample deleted file mode 100644 index eeb468b..0000000 --- a/test/API/driver/kwsys/GitSetup/config.sample +++ /dev/null @@ -1,32 +0,0 @@ -# Kitware Local Git Setup Scripts - Sample Project Configuration -# -# Copy to "config" and edit as necessary. - -[hooks] - url = http://public.kitware.com/GitSetup.git - #branch = hooks - -[ssh] - host = public.kitware.com - key = id_git_public - request-url = https://www.kitware.com/Admin/SendPassword.cgi - -[stage] - #url = git://public.kitware.com/stage/Project.git - #pushurl = git@public.kitware.com:stage/Project.git - -[gerrit] - #project = Project - site = http://review.source.kitware.com - # pushurl placeholder "$username" is literal - pushurl = $username@review.source.kitware.com:Project - -[upstream] - url = git://public.kitware.com/Project.git - -[gitlab] - host = gitlab.kitware.com - group-path = group - group-name = Group - project-path = project - project-name = Project diff --git a/test/API/driver/kwsys/GitSetup/git-gerrit-push b/test/API/driver/kwsys/GitSetup/git-gerrit-push deleted file mode 100644 index b46f753..0000000 --- a/test/API/driver/kwsys/GitSetup/git-gerrit-push +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env bash -#============================================================================= -# Copyright 2010-2015 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -USAGE="[<remote>] [--no-topic] [--dry-run] [--]" -OPTIONS_SPEC= -SUBDIRECTORY_OK=Yes -. "$(git --exec-path)/git-sh-setup" - -#----------------------------------------------------------------------------- - -remote='' -refspecs='' -no_topic='' -dry_run='' - -# Parse the command line options. -while test $# != 0; do - case "$1" in - --no-topic) no_topic=1 ;; - --dry-run) dry_run=--dry-run ;; - --) shift; break ;; - -*) usage ;; - *) test -z "$remote" || usage ; remote="$1" ;; - esac - shift -done -test $# = 0 || usage - -# Default remote. -test -n "$remote" || remote="gerrit" - -if test -z "$no_topic"; then - # Identify and validate the topic branch name. - head="$(git symbolic-ref HEAD)" && topic="${head#refs/heads/}" || topic='' - if test -z "$topic" -o "$topic" = "master"; then - die 'Please name your topic: - git checkout -b descriptive-name' - fi - # The topic branch will be pushed by name. - refspecs="HEAD:refs/for/master/$topic $refspecs" -fi - -# Fetch the current upstream master branch head. -# This helps computation of a minimal pack to push. -echo "Fetching $remote master" -fetch_out=$(git fetch "$remote" master 2>&1) || die "$fetch_out" - -# Exit early if we have nothing to push. -if test -z "$refspecs"; then - echo 'Nothing to push!' - exit 0 -fi - -# Push. Save output and exit code. -echo "Pushing to $remote" -push_stdout=$(git push --porcelain $dry_run "$remote" $refspecs); push_exit=$? -echo "$push_stdout" - -# Reproduce the push exit code. -exit $push_exit diff --git a/test/API/driver/kwsys/GitSetup/git-gitlab-push b/test/API/driver/kwsys/GitSetup/git-gitlab-push deleted file mode 100644 index 768f853..0000000 --- a/test/API/driver/kwsys/GitSetup/git-gitlab-push +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env bash -#============================================================================= -# Copyright 2010-2015 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -USAGE='[<remote>] [<options>...] [--] - -OPTIONS - ---dry-run - Show what would be pushed without actually updating the destination - --f,--force - Force-push the topic HEAD to rewrite the destination branch - ---no-default - Do not push the default branch (e.g. master) - ---no-topic - Do not push the topic HEAD. -' -OPTIONS_SPEC= -SUBDIRECTORY_OK=Yes -. "$(git --exec-path)/git-sh-setup" - -egrep-q() { - egrep "$@" >/dev/null 2>/dev/null -} - -# Load the project configuration. -gitlab_upstream='' && -gitlab_configured='' && -config="${BASH_SOURCE%/*}/config" && -protocol=$(git config -f "$config" --get gitlab.protocol || - echo "https") && -host=$(git config -f "$config" --get gitlab.host) && -site=$(git config -f "$config" --get gitlab.site || - echo "$protocol://$host") && -group_path=$(git config -f "$config" --get gitlab.group-path) && -project_path=$(git config -f "$config" --get gitlab.project-path) && -gitlab_upstream="$site/$group_path/$project_path.git" && -gitlab_pushurl=$(git config --get remote.gitlab.pushurl || - git config --get remote.gitlab.url) && -gitlab_configured=1 - -#----------------------------------------------------------------------------- - -remote='' -refspecs='' -force='' -lease=false -lease_flag='' -no_topic='' -no_default='' -dry_run='' - -# Parse the command line options. -while test $# != 0; do - case "$1" in - -f|--force) force='+'; lease=true ;; - --no-topic) no_topic=1 ;; - --dry-run) dry_run=--dry-run ;; - --no-default) no_default=1 ;; - --) shift; break ;; - -*) usage ;; - *) test -z "$remote" || usage ; remote="$1" ;; - esac - shift -done -test $# = 0 || usage - -# Default remote. -test -n "$remote" || remote="gitlab" - -if test -z "$no_topic"; then - # Identify and validate the topic branch name. - head="$(git symbolic-ref HEAD)" && topic="${head#refs/heads/}" || topic='' - if test -z "$topic" -o "$topic" = "master"; then - die 'Please name your topic: - git checkout -b descriptive-name' - fi - - if $lease; then - have_ref=false - remoteref="refs/remotes/$remote/$topic" - if git rev-parse --verify -q "$remoteref"; then - have_ref=true - else - die "It seems that a local ref for the branch is -missing; forcing a push is dangerous and may overwrite -previous work. Fetch from the $remote remote first or -push without '-f' or '--force'." - fi - - have_lease_flag=false - if git push -h | egrep-q -e '--force-with-lease'; then - have_lease_flag=true - fi - - if $have_lease_flag && $have_ref; then - # Set the lease flag. - lease_flag="--force-with-lease=$topic:$remoteref" - # Clear the force string. - force='' - fi - fi - - # The topic branch will be pushed by name. - refspecs="${force}HEAD:refs/heads/$topic $refspecs" -fi - -# Fetch the current remote master branch head. -# This helps computation of a minimal pack to push. -echo "Fetching $remote master" -fetch_out=$(git fetch "$remote" master 2>&1) || die "$fetch_out" -gitlab_head=$(git rev-parse FETCH_HEAD) || exit - -# Fetch the current upstream master branch head. -if origin_fetchurl=$(git config --get remote.origin.url) && - test "$origin_fetchurl" = "$gitlab_upstream"; then - upstream_remote='origin' -else - upstream_remote="$gitlab_upstream" -fi -echo "Fetching $upstream_remote master" -fetch_out=$(git fetch "$upstream_remote" master 2>&1) || die "$fetch_out" -upstream_head=$(git rev-parse FETCH_HEAD) || exit - -# Add a refspec to keep the remote master up to date if possible. -if test -z "$no_default" && - base=$(git merge-base "$gitlab_head" "$upstream_head") && - test "$base" = "$gitlab_head"; then - refspecs="$upstream_head:refs/heads/master $refspecs" -fi - -# Exit early if we have nothing to push. -if test -z "$refspecs"; then - echo 'Nothing to push!' - exit 0 -fi - -# Push. Save output and exit code. -echo "Pushing to $remote" -push_config='-c advice.pushUpdateRejected=false' -push_stdout=$(git $push_config push $lease_flag --porcelain $dry_run "$remote" $refspecs); push_exit=$? -echo "$push_stdout" - -if test "$push_exit" -ne 0 && test -z "$force"; then - # Advise the user to fetch if needed. - if echo "$push_stdout" | egrep-q 'stale info'; then - echo " -You have pushed to your branch from another machine; you may be overwriting -commits unintentionally. Fetch from the $remote remote and check that you are -not pushing an outdated branch." - fi - - # Advise the user to force-push if needed. - if echo "$push_stdout" | egrep-q 'non-fast-forward'; then - echo ' -Add "-f" or "--force" to push a rewritten topic.' - fi -fi - -# Reproduce the push exit code. -exit $push_exit diff --git a/test/API/driver/kwsys/GitSetup/pre-commit b/test/API/driver/kwsys/GitSetup/pre-commit deleted file mode 100644 index 1f1d3f5..0000000 --- a/test/API/driver/kwsys/GitSetup/pre-commit +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -egrep-q() { - egrep "$@" >/dev/null 2>/dev/null -} - -die() { - echo 'pre-commit hook failure' 1>&2 - echo '-----------------------' 1>&2 - echo '' 1>&2 - echo "$@" 1>&2 - exit 1 -} - -#----------------------------------------------------------------------------- - -# Check that developmer setup is up-to-date. -lastSetupForDevelopment=$(git config --get hooks.SetupForDevelopment || echo 0) -eval $(grep '^SetupForDevelopment_VERSION=' "${BASH_SOURCE%/*}/../SetupForDevelopment.sh") -test -n "$SetupForDevelopment_VERSION" || SetupForDevelopment_VERSION=0 -if test $lastSetupForDevelopment -lt $SetupForDevelopment_VERSION; then - die 'Developer setup in this work tree is out of date. Please re-run - - ./SetupForDevelopment.sh -' -fi diff --git a/test/API/driver/kwsys/GitSetup/setup-aliases b/test/API/driver/kwsys/GitSetup/setup-aliases deleted file mode 100644 index 98810ad..0000000 --- a/test/API/driver/kwsys/GitSetup/setup-aliases +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -echo "Adding 'git prepush' alias" && -git config alias.prepush 'log --graph --stat origin/master..' && -gerrit_disabled="KWSys no longer uses Gerrit. Please use GitLab." && -git config alias.gerrit-push '!sh -c "echo '"${gerrit_disabled}"'"' && -true diff --git a/test/API/driver/kwsys/GitSetup/setup-gerrit b/test/API/driver/kwsys/GitSetup/setup-gerrit deleted file mode 100644 index 6d46e3c..0000000 --- a/test/API/driver/kwsys/GitSetup/setup-gerrit +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env bash -#============================================================================= -# Copyright 2010-2012 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -# Run this script to set up the local Git repository to push to -# a Gerrit Code Review instance for this project. - -# Project configuration instructions: -# -# - Run a Gerrit Code Review server -# -# - Populate adjacent "config" file with: -# gerrit.site = Top Gerrit URL (not project-specific) -# gerrit.project = Name of project in Gerrit -# gerrit.pushurl = Review site push URL with "$username" placeholder -# gerrit.remote = Gerrit remote name, if not "gerrit" -# gerrit.url = Gerrit project URL, if not "$site/p/$project" -# optionally with "$username" placeholder - -die() { - echo 1>&2 "$@" ; exit 1 -} - -# Make sure we are inside the repository. -cd "${BASH_SOURCE%/*}" && - -# Load the project configuration. -site=$(git config -f config --get gerrit.site) && -project=$(git config -f config --get gerrit.project) && -remote=$(git config -f config --get gerrit.remote || - echo "gerrit") && -fetchurl_=$(git config -f config --get gerrit.url || - echo "$site/p/$project") && -pushurl_=$(git config -f config --get gerrit.pushurl || - git config -f config --get gerrit.url) || -die 'This project is not configured to use Gerrit.' - -# Get current gerrit push URL. -pushurl=$(git config --get remote."$remote".pushurl || - git config --get remote."$remote".url || echo '') && - -# Tell user about current configuration. -if test -n "$pushurl"; then - echo 'Remote "'"$remote"'" is currently configured to push to - - '"$pushurl"' -' && - read -ep 'Reconfigure Gerrit? [y/N]: ' ans && - if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then - setup=1 - else - setup='' - fi -else - echo 'Remote "'"$remote"'" is not yet configured. - -'"$project"' changes must be pushed to our Gerrit Code Review site: - - '"$site/p/$project"' - -Register a Gerrit account and select a username (used below). -You will need an OpenID: - - http://openid.net/get-an-openid/ -' && - read -ep 'Configure Gerrit? [Y/n]: ' ans && - if [ "$ans" == "n" ] || [ "$ans" == "N" ]; then - exit 0 - else - setup=1 - fi -fi && - -# Perform setup if necessary. -if test -n "$setup"; then - echo 'Sign-in to Gerrit to get/set your username at - - '"$site"'/#/settings - -Add your SSH public keys at - - '"$site"'/#/settings/ssh-keys -' && - read -ep "Gerrit username? [$USER]: " gu && - if test -z "$gu"; then - gu="$USER" - fi && - fetchurl="${fetchurl_/\$username/$gu}" && - if test -z "$pushurl"; then - git remote add "$remote" "$fetchurl" - else - git config remote."$remote".url "$fetchurl" - fi && - pushurl="${pushurl_/\$username/$gu}" && - if test "$pushurl" != "$fetchurl"; then - git config remote."$remote".pushurl "$pushurl" - fi && - echo 'Remote "'"$remote"'" is now configured to push to - - '"$pushurl"' -' -fi && - -# Optionally test Gerrit access. -if test -n "$pushurl"; then - read -ep 'Test access to Gerrit (SSH)? [y/N]: ' ans && - if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then - echo -n 'Testing Gerrit access by SSH...' - if git ls-remote --heads "$pushurl" >/dev/null; then - echo 'passed.' - else - echo 'failed.' && - die 'Could not access Gerrit. Add your SSH public keys at - - '"$site"'/#/settings/ssh-keys -' - fi - fi -fi && - -# Set up GerritId hook. -hook=$(git config --get hooks.GerritId || echo '') && -if test -z "$hook"; then - echo ' -Enabling GerritId hook to add a "Change-Id" footer to commit -messages for interaction with Gerrit. Run - - git config hooks.GerritId false - -to disable this feature (but you will be on your own).' && - git config hooks.GerritId true -else - echo 'GerritId hook already configured to "'"$hook"'".' -fi diff --git a/test/API/driver/kwsys/GitSetup/setup-gitlab b/test/API/driver/kwsys/GitSetup/setup-gitlab deleted file mode 100644 index 9c7574d..0000000 --- a/test/API/driver/kwsys/GitSetup/setup-gitlab +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env bash -#============================================================================= -# Copyright 2010-2015 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -# Run this script to set up the local Git repository to push to -# a personal fork for this project in GitLab. - -# Project configuration instructions: -# -# - Run a GitLab server -# -# - Populate adjacent "config" file with: -# gitlab.protocol = Top GitLab protocol, if not 'https' -# gitlab.host = Top GitLab fully qualified host name -# gitlab.site = Top GitLab URL, if not "<protocol>://<host>" -# gitlab.group-name = Name of group containing project in GitLab -# gitlab.group-path = Path of group containing project in GitLab -# gitlab.project-name = Name of project within GitLab group -# gitlab.project-path = Path of project within GitLab group -# gitlab.url = GitLab push URL with "$username" placeholder, -# if not "<site>/$username/<project-path>.git" -# gitlab.pushurl = GitLab push URL with "$username" placeholder, -# if not "git@<host>:$username/<project-path>.git" -# gitlab.remote = GitLab remote name, if not "gitlab" - -die() { - echo 1>&2 "$@" ; exit 1 -} - -# Make sure we are inside the repository. -cd "${BASH_SOURCE%/*}" && - -# Load the project configuration. -protocol=$(git config -f config --get gitlab.protocol || - echo "https") && -host=$(git config -f config --get gitlab.host) && -site=$(git config -f config --get gitlab.site || - echo "$protocol://$host") && -group_path=$(git config -f config --get gitlab.group-path) && -group_name=$(git config -f config --get gitlab.group-name) && -project_name=$(git config -f config --get gitlab.project-name) && -project_path=$(git config -f config --get gitlab.project-path) && -pushurl_=$(git config -f config --get gitlab.pushurl || - echo "git@$host:\$username/$project_path.git") && -remote=$(git config -f config --get gitlab.remote || - echo "gitlab") && -fetchurl_=$(git config -f config --get gitlab.url || - echo "$site/\$username/$project_path.git") || -die 'This project is not configured to use GitLab.' - -# Get current gitlab push URL. -pushurl=$(git config --get remote."$remote".pushurl || - git config --get remote."$remote".url || echo '') && - -# Tell user about current configuration. -if test -n "$pushurl"; then - echo 'Remote "'"$remote"'" is currently configured to push to - - '"$pushurl"' -' && - read -ep 'Reconfigure GitLab? [y/N]: ' ans && - if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then - setup=1 - else - setup='' - fi -else - echo 'Remote "'"$remote"'" is not yet configured. -' && - read -ep 'Configure GitLab to contribute to '"$project_name"'? [Y/n]: ' ans && - if [ "$ans" == "n" ] || [ "$ans" == "N" ]; then - exit 0 - else - setup=1 - fi -fi && - -setup_instructions='Add your SSH public keys at - - '"$site"'/profile/keys - -Then visit the main repository at: - - '"$site/$group_path/$project_path"' - -and use the Fork button in the upper right. -' - -# Perform setup if necessary. -if test -n "$setup"; then - echo 'Sign-in to GitLab to get/set your username at - - '"$site/profile/account"' - -'"$setup_instructions" && - read -ep "GitLab username? [$USER]: " gu && - if test -z "$gu"; then - gu="$USER" - fi && - fetchurl="${fetchurl_/\$username/$gu}" && - if test -z "$pushurl"; then - git remote add "$remote" "$fetchurl" - else - git config remote."$remote".url "$fetchurl" - fi && - pushurl="${pushurl_/\$username/$gu}" && - git config remote."$remote".pushurl "$pushurl" && - echo 'Remote "'"$remote"'" is now configured to push to - - '"$pushurl"' -' -fi && - -# Optionally test GitLab access. -if test -n "$pushurl"; then - read -ep 'Test access to GitLab (SSH)? [y/N]: ' ans && - if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then - echo -n 'Testing GitLab access by SSH...' - if git ls-remote --heads "$pushurl" >/dev/null; then - echo 'passed.' - else - echo 'failed.' && - die 'Could not access your GitLab fork of this project. -'"$setup_instructions" - fi - fi -fi diff --git a/test/API/driver/kwsys/GitSetup/setup-hooks b/test/API/driver/kwsys/GitSetup/setup-hooks deleted file mode 100644 index ca07712..0000000 --- a/test/API/driver/kwsys/GitSetup/setup-hooks +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env bash -#============================================================================= -# Copyright 2010-2012 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -# Run this script to set up local Git hooks for this project. - -# Project configuration instructions: -# -# - Publish a "hooks" branch in the project repository such that -# clones will have "refs/remotes/origin/hooks". -# -# - Populate adjacent "config" file with: -# hooks.url = Repository URL publishing "hooks" branch -# hooks.branch = Repository branch instead of "hooks" - -egrep-q() { - egrep "$@" >/dev/null 2>/dev/null -} - -die() { - echo 1>&2 "$@" ; exit 1 -} - -# Make sure we are inside the repository. -cd "${BASH_SOURCE%/*}" && - -# Select a hooks branch. -if url=$(git config --get hooks.url); then - # Fetch hooks from locally configured repository. - branch=$(git config hooks.branch || echo hooks) -elif git for-each-ref refs/remotes/origin/hooks 2>/dev/null | - egrep-q 'refs/remotes/origin/hooks$'; then - # Use hooks cloned from origin. - url=.. && branch=remotes/origin/hooks -elif url=$(git config -f config --get hooks.url); then - # Fetch hooks from project-configured repository. - branch=$(git config -f config hooks.branch || echo hooks) -else - die 'This project is not configured to install local hooks.' -fi && - -# Populate ".git/hooks". -echo 'Setting up git hooks...' && -git_dir=$(git rev-parse --git-dir) && -mkdir -p "$git_dir/hooks" && -cd "$git_dir/hooks" && -if ! test -e .git; then - git init -q || die 'Could not run git init for hooks.' -fi && -git fetch -q "$url" "$branch" && -git reset -q --hard FETCH_HEAD || die 'Failed to install hooks' diff --git a/test/API/driver/kwsys/GitSetup/setup-ssh b/test/API/driver/kwsys/GitSetup/setup-ssh deleted file mode 100644 index 8920a5b..0000000 --- a/test/API/driver/kwsys/GitSetup/setup-ssh +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env bash -#============================================================================= -# Copyright 2010-2012 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -# Run this script to set up ssh push access to the repository host. - -# Project configuration instructions: -# -# - Populate adjacent "config" file with: -# ssh.host = Repository host name -# ssh.user = Username on host, if not "git" -# ssh.key = Local ssh key name -# ssh.request-url = Web page URL to request ssh access - -egrep-q() { - egrep "$@" >/dev/null 2>/dev/null -} - -die() { - echo 1>&2 "$@" ; exit 1 -} - -# Make sure we are inside the repository. -cd "${BASH_SOURCE%/*}" && - -# Load the project configuration. -host=$(git config -f config --get ssh.host) && -user=$(git config -f config --get ssh.user || echo git) && -key=$(git config -f config --get ssh.key) && -request_url=$(git config -f config --get ssh.request-url) || -die 'This project is not configured for ssh push access.' - -# Check for existing configuration. -if test -r ~/.ssh/config && - egrep-q 'Host[= ]'"${host//\./\\.}" ~/.ssh/config; then - echo 'Host "'"$host"'" is already in ~/.ssh/config' && - setup= && - question='Test' -else - echo 'Host "'"$host"'" not found in ~/.ssh/config' && - setup=1 && - question='Setup and test' -fi && - -# Ask the user whether to make changes. -echo '' && -read -ep "${question} push access by ssh to $user@$host? [y/N]: " access && -if test "$access" != "y" -a "$access" != "Y"; then - exit 0 -fi && - -# Setup host configuration if necessary. -if test -n "$setup"; then - if ! test -d ~/.ssh; then - mkdir -p ~/.ssh && - chmod 700 ~/.ssh - fi && - if ! test -f ~/.ssh/config; then - touch ~/.ssh/config && - chmod 600 ~/.ssh/config - fi && - ssh_config='Host='"$host"' - IdentityFile ~/.ssh/'"$key" && - echo "Adding to ~/.ssh/config: - -$ssh_config -" && - echo "$ssh_config" >> ~/.ssh/config && - if ! test -e ~/.ssh/"$key"; then - if test -f ~/.ssh/id_rsa; then - # Take care of the common case. - ln -s id_rsa ~/.ssh/"$key" - echo ' -Assuming ~/.ssh/id_rsa is the private key corresponding to the public key for - - '"$user@$host"' - -If this is incorrect place private key at "~/.ssh/'"$key"'".' - else - echo ' -Place the private key corresponding to the public key registered for - - '"$user@$host"' - -at "~/.ssh/'"$key"'".' - fi - read -e -n 1 -p 'Press any key to continue...' - fi -fi || exit 1 - -# Test access configuration. -echo 'Testing ssh push access to "'"$user@$host"'"...' && -if ! ssh "$user@$host" info; then - die 'No ssh push access to "'"$user@$host"'". You may need to request access at - - '"$request_url"' -' -fi diff --git a/test/API/driver/kwsys/GitSetup/setup-stage b/test/API/driver/kwsys/GitSetup/setup-stage deleted file mode 100644 index ce6ec45..0000000 --- a/test/API/driver/kwsys/GitSetup/setup-stage +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env bash -#============================================================================= -# Copyright 2010-2012 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -# Run this script to set up the topic stage for pushing changes. - -# Project configuration instructions: -# -# - Run a Topic Stage repository next to the main project repository. -# -# - Populate adjacent "config" file with: -# stage.url = Topic Stage repository URL -# stage.pushurl = Topic Stage push URL if not "$url" - -egrep-q() { - egrep "$@" >/dev/null 2>/dev/null -} - -die() { - echo 1>&2 "$@" ; exit 1 -} - -# Make sure we are inside the repository. -cd "${BASH_SOURCE%/*}" && - -# Load the project configuration. -fetchurl_=$(git config -f config --get stage.url) && -pushurl_=$(git config -f config --get stage.pushurl || echo "$fetchurl_") && -remote=$(git config -f config --get stage.remote || echo 'stage') || -die 'This project is not configured to use a topic stage.' - -# Get current stage push URL. -pushurl=$(git config --get remote."$remote".pushurl || - git config --get remote."$remote".url || echo '') && - -# Tell user about current configuration. -if test -n "$pushurl"; then - echo 'Remote "'"$remote"'" is currently configured to push to - - '"$pushurl"' -' && - read -ep 'Reconfigure Topic Stage? [y/N]: ' ans && - if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then - setup=1 - else - setup='' - fi -else - setup=1 -fi - -# Perform setup if necessary. -if test -n "$setup"; then - echo 'Setting up the topic stage...' && - fetchurl="${fetchurl_}" && - if test -z "$pushurl"; then - git remote add "$remote" "$fetchurl" - else - git config remote."$remote".url "$fetchurl" - fi && - pushurl="${pushurl_}" && - if test "$pushurl" != "$fetchurl"; then - git config remote."$remote".pushurl "$pushurl" - fi && - echo 'Remote "'"$remote"'" is now configured to push to - - '"$pushurl"' -' -fi || die 'Could not configure the topic stage remote.' diff --git a/test/API/driver/kwsys/GitSetup/setup-upstream b/test/API/driver/kwsys/GitSetup/setup-upstream deleted file mode 100644 index 92ce1da..0000000 --- a/test/API/driver/kwsys/GitSetup/setup-upstream +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env bash -#============================================================================= -# Copyright 2010-2015 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -# Run this script to set up the local Git repository to use the -# preferred upstream repository URLs. - -# Project configuration instructions: -# -# - Populate adjacent "config" file with: -# upstream.url = Preferred fetch url for upstream remote -# upstream.remote = Preferred name for upstream remote, if not "origin" - -die() { - echo 1>&2 "$@" ; exit 1 -} - -# Make sure we are inside the repository. -cd "${BASH_SOURCE%/*}" && - -# Load the project configuration. -url=$(git config -f config --get upstream.url) && -remote=$(git config -f config --get upstream.remote || - echo 'origin') || -die 'This project is not configured to use a preferred upstream repository.' - -# Get current upstream URLs. -fetchurl=$(git config --get remote."$remote".url || echo '') && -pushurl=$(git config --get remote."$remote".pushurl || echo '') && - -if test "$fetchurl" = "$url"; then - echo 'Remote "'"$remote"'" already uses recommended upstream repository.' - exit 0 -fi - -upstream_recommend=' -We recommended configuring the "'"$remote"'" remote to fetch from upstream at - - '"$url"' -' - -# Tell user about current configuration. -if test -n "$fetchurl"; then - echo 'Remote "'"$remote"'" is currently configured to fetch from - - '"$fetchurl"' -' && - if test -n "$pushurl"; then - echo 'and push to - - '"$pushurl" - fi && - echo "$upstream_recommend" && - if test -n "$pushurl"; then - echo 'and to never push to it directly. -' - fi && - - read -ep 'Reconfigure "'"$remote"'" remote as recommended? [y/N]: ' ans && - if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then - setup=1 - else - setup='' - fi -else - echo 'Remote "'"$remote"'" is not yet configured.' && - echo "$upstream_recommend" && - read -ep 'Configure "'"$remote"'" remote as recommended? [Y/n]: ' ans && - if [ "$ans" == "n" ] || [ "$ans" == "N" ]; then - exit 0 - else - setup=1 - fi -fi && - -# Perform setup if necessary. -if test -n "$setup"; then - if test -z "$fetchurl"; then - git remote add "$remote" "$url" - else - git config remote."$remote".url "$url" && - if old=$(git config --get remote."$remote".pushurl); then - git config --unset remote."$remote".pushurl || - echo 'Warning: failed to unset remote.'"$remote"'.pushurl' - fi - fi && - echo 'Remote "'"$remote"'" is now configured to fetch from - - '"$url"' -' -fi diff --git a/test/API/driver/kwsys/GitSetup/setup-user b/test/API/driver/kwsys/GitSetup/setup-user deleted file mode 100644 index 1af439c..0000000 --- a/test/API/driver/kwsys/GitSetup/setup-user +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash -#============================================================================= -# Copyright 2010-2012 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -# Run this script to configure Git user info in this repository. - -# Project configuration instructions: NONE - -for (( ; ; )); do - user_name=$(git config user.name || echo '') && - user_email=$(git config user.email || echo '') && - if test -n "$user_name" -a -n "$user_email"; then - echo 'Your commits will record as Author: - - '"$user_name <$user_email>"' -' && - read -ep 'Is the author name and email address above correct? [Y/n] ' correct && - if test "$correct" != "n" -a "$correct" != "N"; then - break - fi - fi && - read -ep 'Enter your full name e.g. "John Doe": ' name && - read -ep 'Enter your email address e.g. "john@gmail.com": ' email && - git config user.name "$name" && - git config user.email "$email" -done diff --git a/test/API/driver/kwsys/GitSetup/tips b/test/API/driver/kwsys/GitSetup/tips deleted file mode 100644 index 784e1ed..0000000 --- a/test/API/driver/kwsys/GitSetup/tips +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash -#============================================================================= -# Copyright 2010-2012 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -# This script makes optional suggestions for working with Git. - -# Project configuration instructions: NONE - -egrep-q() { - egrep "$@" >/dev/null 2>/dev/null -} - -# Suggest color configuration. -if test -z "$(git config --get color.ui)"; then - echo ' -One may enable color output from Git commands with - - git config --global color.ui auto -' -fi - -# Suggest bash completion. -if ! bash -i -c 'echo $PS1' | egrep-q '__git_ps1'; then - echo ' -A dynamic, informative Git shell prompt can be obtained by sourcing -the git bash-completion script in your "~/.bashrc". Set the PS1 -environmental variable as suggested in the comments at the top of the -bash-completion script. You may need to install the bash-completion -package from your distribution to obtain it. -' -fi - -# Suggest merge tool. -if test -z "$(git config --get merge.tool)"; then - echo ' -One may configure Git to load a merge tool with - - git config merge.tool <toolname> - -See "git help mergetool" for more information. -' -fi diff --git a/test/API/driver/kwsys/Glob.cxx b/test/API/driver/kwsys/Glob.cxx deleted file mode 100644 index 34bb0d0..0000000 --- a/test/API/driver/kwsys/Glob.cxx +++ /dev/null @@ -1,448 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Glob.hxx) - -#include KWSYS_HEADER(Configure.hxx) - -#include KWSYS_HEADER(RegularExpression.hxx) -#include KWSYS_HEADER(SystemTools.hxx) -#include KWSYS_HEADER(Directory.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Configure.hxx.in" -# include "Directory.hxx.in" -# include "Glob.hxx.in" -# include "RegularExpression.hxx.in" -# include "SystemTools.hxx.in" -#endif - -#include <algorithm> -#include <string> -#include <vector> - -#include <ctype.h> -#include <stdio.h> -#include <string.h> -namespace KWSYS_NAMESPACE { -#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__) -// On Windows and Apple, no difference between lower and upper case -# define KWSYS_GLOB_CASE_INDEPENDENT -#endif - -#if defined(_WIN32) || defined(__CYGWIN__) -// Handle network paths -# define KWSYS_GLOB_SUPPORT_NETWORK_PATHS -#endif - -class GlobInternals -{ -public: - std::vector<std::string> Files; - std::vector<kwsys::RegularExpression> Expressions; -}; - -Glob::Glob() -{ - this->Internals = new GlobInternals; - this->Recurse = false; - this->Relative = ""; - - this->RecurseThroughSymlinks = true; - // RecurseThroughSymlinks is true by default for backwards compatibility, - // not because it's a good idea... - this->FollowedSymlinkCount = 0; - - // Keep separate variables for directory listing for back compatibility - this->ListDirs = true; - this->RecurseListDirs = false; -} - -Glob::~Glob() -{ - delete this->Internals; -} - -std::vector<std::string>& Glob::GetFiles() -{ - return this->Internals->Files; -} - -std::string Glob::PatternToRegex(const std::string& pattern, - bool require_whole_string, bool preserve_case) -{ - // Incrementally build the regular expression from the pattern. - std::string regex = require_whole_string ? "^" : ""; - std::string::const_iterator pattern_first = pattern.begin(); - std::string::const_iterator pattern_last = pattern.end(); - for (std::string::const_iterator i = pattern_first; i != pattern_last; ++i) { - int c = *i; - if (c == '*') { - // A '*' (not between brackets) matches any string. - // We modify this to not match slashes since the original glob - // pattern documentation was meant for matching file name - // components separated by slashes. - regex += "[^/]*"; - } else if (c == '?') { - // A '?' (not between brackets) matches any single character. - // We modify this to not match slashes since the original glob - // pattern documentation was meant for matching file name - // components separated by slashes. - regex += "[^/]"; - } else if (c == '[') { - // Parse out the bracket expression. It begins just after the - // opening character. - std::string::const_iterator bracket_first = i + 1; - std::string::const_iterator bracket_last = bracket_first; - - // The first character may be complementation '!' or '^'. - if (bracket_last != pattern_last && - (*bracket_last == '!' || *bracket_last == '^')) { - ++bracket_last; - } - - // If the next character is a ']' it is included in the brackets - // because the bracket string may not be empty. - if (bracket_last != pattern_last && *bracket_last == ']') { - ++bracket_last; - } - - // Search for the closing ']'. - while (bracket_last != pattern_last && *bracket_last != ']') { - ++bracket_last; - } - - // Check whether we have a complete bracket string. - if (bracket_last == pattern_last) { - // The bracket string did not end, so it was opened simply by - // a '[' that is supposed to be matched literally. - regex += "\\["; - } else { - // Convert the bracket string to its regex equivalent. - std::string::const_iterator k = bracket_first; - - // Open the regex block. - regex += "["; - - // A regex range complement uses '^' instead of '!'. - if (k != bracket_last && *k == '!') { - regex += "^"; - ++k; - } - - // Convert the remaining characters. - for (; k != bracket_last; ++k) { - // Backslashes must be escaped. - if (*k == '\\') { - regex += "\\"; - } - - // Store this character. - regex += *k; - } - - // Close the regex block. - regex += "]"; - - // Jump to the end of the bracket string. - i = bracket_last; - } - } else { - // A single character matches itself. - int ch = c; - if (!(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || - ('0' <= ch && ch <= '9'))) { - // Escape the non-alphanumeric character. - regex += "\\"; - } -#if defined(KWSYS_GLOB_CASE_INDEPENDENT) - else { - // On case-insensitive systems file names are converted to lower - // case before matching. - if (!preserve_case) { - ch = tolower(ch); - } - } -#endif - (void)preserve_case; - // Store the character. - regex.append(1, static_cast<char>(ch)); - } - } - - if (require_whole_string) { - regex += "$"; - } - return regex; -} - -bool Glob::RecurseDirectory(std::string::size_type start, - const std::string& dir, GlobMessages* messages) -{ - kwsys::Directory d; - if (!d.Load(dir)) { - return true; - } - unsigned long cc; - std::string realname; - std::string fname; - for (cc = 0; cc < d.GetNumberOfFiles(); cc++) { - fname = d.GetFile(cc); - if (fname == "." || fname == "..") { - continue; - } - - if (start == 0) { - realname = dir + fname; - } else { - realname = dir + "/" + fname; - } - -#if defined(KWSYS_GLOB_CASE_INDEPENDENT) - // On Windows and Apple, no difference between lower and upper case - fname = kwsys::SystemTools::LowerCase(fname); -#endif - - bool isDir = kwsys::SystemTools::FileIsDirectory(realname); - bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname); - - if (isDir && (!isSymLink || this->RecurseThroughSymlinks)) { - if (isSymLink) { - ++this->FollowedSymlinkCount; - std::string realPathErrorMessage; - std::string canonicalPath( - SystemTools::GetRealPath(dir, &realPathErrorMessage)); - - if (!realPathErrorMessage.empty()) { - if (messages) { - messages->push_back( - Message(Glob::error, - "Canonical path generation from path '" + dir + - "' failed! Reason: '" + realPathErrorMessage + "'")); - } - return false; - } - - if (std::find(this->VisitedSymlinks.begin(), - this->VisitedSymlinks.end(), - canonicalPath) == this->VisitedSymlinks.end()) { - if (this->RecurseListDirs) { - // symlinks are treated as directories - this->AddFile(this->Internals->Files, realname); - } - - this->VisitedSymlinks.push_back(canonicalPath); - if (!this->RecurseDirectory(start + 1, realname, messages)) { - this->VisitedSymlinks.pop_back(); - - return false; - } - this->VisitedSymlinks.pop_back(); - } - // else we have already visited this symlink - prevent cyclic recursion - else if (messages) { - std::string message; - for (std::vector<std::string>::const_iterator pathIt = - std::find(this->VisitedSymlinks.begin(), - this->VisitedSymlinks.end(), canonicalPath); - pathIt != this->VisitedSymlinks.end(); ++pathIt) { - message += *pathIt + "\n"; - } - message += canonicalPath + "/" + fname; - messages->push_back(Message(Glob::cyclicRecursion, message)); - } - } else { - if (this->RecurseListDirs) { - this->AddFile(this->Internals->Files, realname); - } - if (!this->RecurseDirectory(start + 1, realname, messages)) { - return false; - } - } - } else { - if (!this->Internals->Expressions.empty() && - this->Internals->Expressions.back().find(fname)) { - this->AddFile(this->Internals->Files, realname); - } - } - } - - return true; -} - -void Glob::ProcessDirectory(std::string::size_type start, - const std::string& dir, GlobMessages* messages) -{ - // std::cout << "ProcessDirectory: " << dir << std::endl; - bool last = (start == this->Internals->Expressions.size() - 1); - if (last && this->Recurse) { - this->RecurseDirectory(start, dir, messages); - return; - } - - if (start >= this->Internals->Expressions.size()) { - return; - } - - kwsys::Directory d; - if (!d.Load(dir)) { - return; - } - unsigned long cc; - std::string realname; - std::string fname; - for (cc = 0; cc < d.GetNumberOfFiles(); cc++) { - fname = d.GetFile(cc); - if (fname == "." || fname == "..") { - continue; - } - - if (start == 0) { - realname = dir + fname; - } else { - realname = dir + "/" + fname; - } - -#if defined(KWSYS_GLOB_CASE_INDEPENDENT) - // On case-insensitive file systems convert to lower case for matching. - fname = kwsys::SystemTools::LowerCase(fname); -#endif - - // std::cout << "Look at file: " << fname << std::endl; - // std::cout << "Match: " - // << this->Internals->TextExpressions[start].c_str() << std::endl; - // std::cout << "Real name: " << realname << std::endl; - - if ((!last && !kwsys::SystemTools::FileIsDirectory(realname)) || - (!this->ListDirs && last && - kwsys::SystemTools::FileIsDirectory(realname))) { - continue; - } - - if (this->Internals->Expressions[start].find(fname)) { - if (last) { - this->AddFile(this->Internals->Files, realname); - } else { - this->ProcessDirectory(start + 1, realname, messages); - } - } - } -} - -bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages) -{ - std::string cexpr; - std::string::size_type cc; - std::string expr = inexpr; - - this->Internals->Expressions.clear(); - this->Internals->Files.clear(); - - if (!kwsys::SystemTools::FileIsFullPath(expr)) { - expr = kwsys::SystemTools::GetCurrentWorkingDirectory(); - expr += "/" + inexpr; - } - std::string fexpr = expr; - - std::string::size_type skip = 0; - std::string::size_type last_slash = 0; - for (cc = 0; cc < expr.size(); cc++) { - if (cc > 0 && expr[cc] == '/' && expr[cc - 1] != '\\') { - last_slash = cc; - } - if (cc > 0 && (expr[cc] == '[' || expr[cc] == '?' || expr[cc] == '*') && - expr[cc - 1] != '\\') { - break; - } - } - if (last_slash > 0) { - // std::cout << "I can skip: " << fexpr.substr(0, last_slash) - // << std::endl; - skip = last_slash; - } - if (skip == 0) { -#if defined(KWSYS_GLOB_SUPPORT_NETWORK_PATHS) - // Handle network paths - if (expr[0] == '/' && expr[1] == '/') { - int cnt = 0; - for (cc = 2; cc < expr.size(); cc++) { - if (expr[cc] == '/') { - cnt++; - if (cnt == 2) { - break; - } - } - } - skip = int(cc + 1); - } else -#endif - // Handle drive letters on Windows - if (expr[1] == ':' && expr[0] != '/') { - skip = 2; - } - } - - if (skip > 0) { - expr = expr.substr(skip); - } - - cexpr = ""; - for (cc = 0; cc < expr.size(); cc++) { - int ch = expr[cc]; - if (ch == '/') { - if (!cexpr.empty()) { - this->AddExpression(cexpr); - } - cexpr = ""; - } else { - cexpr.append(1, static_cast<char>(ch)); - } - } - if (!cexpr.empty()) { - this->AddExpression(cexpr); - } - - // Handle network paths - if (skip > 0) { - this->ProcessDirectory(0, fexpr.substr(0, skip) + "/", messages); - } else { - this->ProcessDirectory(0, "/", messages); - } - return true; -} - -void Glob::AddExpression(const std::string& expr) -{ - this->Internals->Expressions.push_back( - kwsys::RegularExpression(this->PatternToRegex(expr))); -} - -void Glob::SetRelative(const char* dir) -{ - if (!dir) { - this->Relative = ""; - return; - } - this->Relative = dir; -} - -const char* Glob::GetRelative() -{ - if (this->Relative.empty()) { - return nullptr; - } - return this->Relative.c_str(); -} - -void Glob::AddFile(std::vector<std::string>& files, const std::string& file) -{ - if (!this->Relative.empty()) { - files.push_back(kwsys::SystemTools::RelativePath(this->Relative, file)); - } else { - files.push_back(file); - } -} - -} // namespace KWSYS_NAMESPACE diff --git a/test/API/driver/kwsys/Glob.hxx.in b/test/API/driver/kwsys/Glob.hxx.in deleted file mode 100644 index 170766f..0000000 --- a/test/API/driver/kwsys/Glob.hxx.in +++ /dev/null @@ -1,134 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_Glob_hxx -#define @KWSYS_NAMESPACE@_Glob_hxx - -#include <@KWSYS_NAMESPACE@/Configure.h> -#include <@KWSYS_NAMESPACE@/Configure.hxx> - -#include <string> -#include <vector> - -namespace @KWSYS_NAMESPACE@ { - -class GlobInternals; - -/** \class Glob - * \brief Portable globbing searches. - * - * Globbing expressions are much simpler than regular - * expressions. This class will search for files using - * globbing expressions. - * - * Finds all files that match a given globbing expression. - */ -class @KWSYS_NAMESPACE@_EXPORT Glob -{ -public: - enum MessageType - { - error, - cyclicRecursion - }; - - struct Message - { - MessageType type; - std::string content; - - Message(MessageType t, const std::string& c) - : type(t) - , content(c) - { - } - ~Message() = default; - Message(const Message& msg) = default; - Message& operator=(Message const& msg) = default; - }; - - typedef std::vector<Message> GlobMessages; - typedef std::vector<Message>::iterator GlobMessagesIterator; - -public: - Glob(); - ~Glob(); - - //! Find all files that match the pattern. - bool FindFiles(const std::string& inexpr, GlobMessages* messages = nullptr); - - //! Return the list of files that matched. - std::vector<std::string>& GetFiles(); - - //! Set recurse to true to match subdirectories. - void RecurseOn() { this->SetRecurse(true); } - void RecurseOff() { this->SetRecurse(false); } - void SetRecurse(bool i) { this->Recurse = i; } - bool GetRecurse() { return this->Recurse; } - - //! Set recurse through symlinks to true if recursion should traverse the - // linked-to directories - void RecurseThroughSymlinksOn() { this->SetRecurseThroughSymlinks(true); } - void RecurseThroughSymlinksOff() { this->SetRecurseThroughSymlinks(false); } - void SetRecurseThroughSymlinks(bool i) { this->RecurseThroughSymlinks = i; } - bool GetRecurseThroughSymlinks() { return this->RecurseThroughSymlinks; } - - //! Get the number of symlinks followed through recursion - unsigned int GetFollowedSymlinkCount() { return this->FollowedSymlinkCount; } - - //! Set relative to true to only show relative path to files. - void SetRelative(const char* dir); - const char* GetRelative(); - - /** Convert the given globbing pattern to a regular expression. - There is no way to quote meta-characters. The - require_whole_string argument specifies whether the regex is - automatically surrounded by "^" and "$" to match the whole - string. This is on by default because patterns always match - whole strings, but may be disabled to support concatenating - expressions more easily (regex1|regex2|etc). */ - static std::string PatternToRegex(const std::string& pattern, - bool require_whole_string = true, - bool preserve_case = false); - - /** Getters and setters for enabling and disabling directory - listing in recursive and non recursive globbing mode. - If listing is enabled in recursive mode it also lists - directory symbolic links even if follow symlinks is enabled. */ - void SetListDirs(bool list) { this->ListDirs = list; } - bool GetListDirs() const { return this->ListDirs; } - void SetRecurseListDirs(bool list) { this->RecurseListDirs = list; } - bool GetRecurseListDirs() const { return this->RecurseListDirs; } - -protected: - //! Process directory - void ProcessDirectory(std::string::size_type start, const std::string& dir, - GlobMessages* messages); - - //! Process last directory, but only when recurse flags is on. That is - // effectively like saying: /path/to/file/**/file - bool RecurseDirectory(std::string::size_type start, const std::string& dir, - GlobMessages* messages); - - //! Add regular expression - void AddExpression(const std::string& expr); - - //! Add a file to the list - void AddFile(std::vector<std::string>& files, const std::string& file); - - GlobInternals* Internals; - bool Recurse; - std::string Relative; - bool RecurseThroughSymlinks; - unsigned int FollowedSymlinkCount; - std::vector<std::string> VisitedSymlinks; - bool ListDirs; - bool RecurseListDirs; - -private: - Glob(const Glob&); // Not implemented. - void operator=(const Glob&); // Not implemented. -}; - -} // namespace @KWSYS_NAMESPACE@ - -#endif diff --git a/test/API/driver/kwsys/IOStream.cxx b/test/API/driver/kwsys/IOStream.cxx deleted file mode 100644 index e21f87d..0000000 --- a/test/API/driver/kwsys/IOStream.cxx +++ /dev/null @@ -1,255 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Configure.hxx) - -// Include the streams library. -#include <iostream> -#include KWSYS_HEADER(IOStream.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Configure.hxx.in" -# include "IOStream.hxx.in" -#endif - -// Implement the rest of this file only if it is needed. -#if KWSYS_IOS_NEED_OPERATORS_LL - -# include <stdio.h> // sscanf, sprintf -# include <string.h> // memchr - -# if defined(_MAX_INT_DIG) -# define KWSYS_IOS_INT64_MAX_DIG _MAX_INT_DIG -# else -# define KWSYS_IOS_INT64_MAX_DIG 32 -# endif - -namespace KWSYS_NAMESPACE { - -// Scan an input stream for an integer value. -static int IOStreamScanStream(std::istream& is, char* buffer) -{ - // Prepare to write to buffer. - char* out = buffer; - char* end = buffer + KWSYS_IOS_INT64_MAX_DIG - 1; - - // Look for leading sign. - if (is.peek() == '+') { - *out++ = '+'; - is.ignore(); - } else if (is.peek() == '-') { - *out++ = '-'; - is.ignore(); - } - - // Determine the base. If not specified in the stream, try to - // detect it from the input. A leading 0x means hex, and a leading - // 0 alone means octal. - int base = 0; - int flags = is.flags() & std::ios_base::basefield; - if (flags == std::ios_base::oct) { - base = 8; - } else if (flags == std::ios_base::dec) { - base = 10; - } else if (flags == std::ios_base::hex) { - base = 16; - } - bool foundDigit = false; - bool foundNonZero = false; - if (is.peek() == '0') { - foundDigit = true; - is.ignore(); - if ((is.peek() == 'x' || is.peek() == 'X') && (base == 0 || base == 16)) { - base = 16; - foundDigit = false; - is.ignore(); - } else if (base == 0) { - base = 8; - } - } - - // Determine the range of digits allowed for this number. - const char* digits = "0123456789abcdefABCDEF"; - int maxDigitIndex = 10; - if (base == 8) { - maxDigitIndex = 8; - } else if (base == 16) { - maxDigitIndex = 10 + 6 + 6; - } - - // Scan until an invalid digit is found. - for (; is.peek() != EOF; is.ignore()) { - if (memchr(digits, *out = (char)is.peek(), maxDigitIndex) != 0) { - if ((foundNonZero || *out != '0') && out < end) { - ++out; - foundNonZero = true; - } - foundDigit = true; - } else { - break; - } - } - - // Correct the buffer contents for degenerate cases. - if (foundDigit && !foundNonZero) { - *out++ = '0'; - } else if (!foundDigit) { - out = buffer; - } - - // Terminate the string in the buffer. - *out = '\0'; - - return base; -} - -// Read an integer value from an input stream. -template <class T> -std::istream& IOStreamScanTemplate(std::istream& is, T& value, char type) -{ - int state = std::ios_base::goodbit; - - // Skip leading whitespace. - std::istream::sentry okay(is); - - if (okay) { - try { - // Copy the string to a buffer and construct the format string. - char buffer[KWSYS_IOS_INT64_MAX_DIG]; -# if defined(_MSC_VER) - char format[] = "%I64_"; - const int typeIndex = 4; -# else - char format[] = "%ll_"; - const int typeIndex = 3; -# endif - switch (IOStreamScanStream(is, buffer)) { - case 8: - format[typeIndex] = 'o'; - break; - case 0: // Default to decimal if not told otherwise. - case 10: - format[typeIndex] = type; - break; - case 16: - format[typeIndex] = 'x'; - break; - }; - - // Use sscanf to parse the number from the buffer. - T result; - int success = (sscanf(buffer, format, &result) == 1) ? 1 : 0; - - // Set flags for resulting state. - if (is.peek() == EOF) { - state |= std::ios_base::eofbit; - } - if (!success) { - state |= std::ios_base::failbit; - } else { - value = result; - } - } catch (...) { - state |= std::ios_base::badbit; - } - } - - is.setstate(std::ios_base::iostate(state)); - return is; -} - -// Print an integer value to an output stream. -template <class T> -std::ostream& IOStreamPrintTemplate(std::ostream& os, T value, char type) -{ - std::ostream::sentry okay(os); - if (okay) { - try { - // Construct the format string. - char format[8]; - char* f = format; - *f++ = '%'; - if (os.flags() & std::ios_base::showpos) { - *f++ = '+'; - } - if (os.flags() & std::ios_base::showbase) { - *f++ = '#'; - } -# if defined(_MSC_VER) - *f++ = 'I'; - *f++ = '6'; - *f++ = '4'; -# else - *f++ = 'l'; - *f++ = 'l'; -# endif - long bflags = os.flags() & std::ios_base::basefield; - if (bflags == std::ios_base::oct) { - *f++ = 'o'; - } else if (bflags != std::ios_base::hex) { - *f++ = type; - } else if (os.flags() & std::ios_base::uppercase) { - *f++ = 'X'; - } else { - *f++ = 'x'; - } - *f = '\0'; - - // Use sprintf to print to a buffer and then write the - // buffer to the stream. - char buffer[2 * KWSYS_IOS_INT64_MAX_DIG]; - sprintf(buffer, format, value); - os << buffer; - } catch (...) { - os.clear(os.rdstate() | std::ios_base::badbit); - } - } - return os; -} - -# if !KWSYS_IOS_HAS_ISTREAM_LONG_LONG -// Implement input stream operator for IOStreamSLL. -std::istream& IOStreamScan(std::istream& is, IOStreamSLL& value) -{ - return IOStreamScanTemplate(is, value, 'd'); -} - -// Implement input stream operator for IOStreamULL. -std::istream& IOStreamScan(std::istream& is, IOStreamULL& value) -{ - return IOStreamScanTemplate(is, value, 'u'); -} -# endif - -# if !KWSYS_IOS_HAS_OSTREAM_LONG_LONG -// Implement output stream operator for IOStreamSLL. -std::ostream& IOStreamPrint(std::ostream& os, IOStreamSLL value) -{ - return IOStreamPrintTemplate(os, value, 'd'); -} - -// Implement output stream operator for IOStreamULL. -std::ostream& IOStreamPrint(std::ostream& os, IOStreamULL value) -{ - return IOStreamPrintTemplate(os, value, 'u'); -} -# endif - -} // namespace KWSYS_NAMESPACE - -#else - -namespace KWSYS_NAMESPACE { - -// Create one public symbol in this object file to avoid warnings from -// archivers. -void IOStreamSymbolToAvoidWarning(); -void IOStreamSymbolToAvoidWarning() -{ -} - -} // namespace KWSYS_NAMESPACE - -#endif // KWSYS_IOS_NEED_OPERATORS_LL diff --git a/test/API/driver/kwsys/IOStream.hxx.in b/test/API/driver/kwsys/IOStream.hxx.in deleted file mode 100644 index db8a23e..0000000 --- a/test/API/driver/kwsys/IOStream.hxx.in +++ /dev/null @@ -1,126 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_IOStream_hxx -#define @KWSYS_NAMESPACE@_IOStream_hxx - -#include <iosfwd> - -/* Define these macros temporarily to keep the code readable. */ -#if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT -#endif - -/* Whether istream supports long long. */ -#define @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG \ - @KWSYS_IOS_HAS_ISTREAM_LONG_LONG@ - -/* Whether ostream supports long long. */ -#define @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG \ - @KWSYS_IOS_HAS_OSTREAM_LONG_LONG@ - -/* Determine whether we need to define the streaming operators for - long long or __int64. */ -#if @KWSYS_USE_LONG_LONG@ -# if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG || \ - !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG -# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1 -namespace @KWSYS_NAMESPACE@ { -typedef long long IOStreamSLL; -typedef unsigned long long IOStreamULL; -} -# endif -#elif defined(_MSC_VER) && _MSC_VER < 1300 -# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1 -namespace @KWSYS_NAMESPACE@ { -typedef __int64 IOStreamSLL; -typedef unsigned __int64 IOStreamULL; -} -#endif -#if !defined(@KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL) -# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 0 -#endif - -#if @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL -# if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG - -/* Input stream operator implementation functions. */ -namespace @KWSYS_NAMESPACE@ { -kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamSLL&); -kwsysEXPORT std::istream& IOStreamScan(std::istream&, IOStreamULL&); -} - -/* Provide input stream operator for long long. */ -# if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_LONG_LONG) && \ - !defined(KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED) -# define KWSYS_IOS_ISTREAM_LONG_LONG_DEFINED -# define @KWSYS_NAMESPACE@_IOS_ISTREAM_LONG_LONG_DEFINED -inline std::istream& operator>>(std::istream& is, - @KWSYS_NAMESPACE@::IOStreamSLL& value) -{ - return @KWSYS_NAMESPACE@::IOStreamScan(is, value); -} -# endif - -/* Provide input stream operator for unsigned long long. */ -# if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_UNSIGNED_LONG_LONG) && \ - !defined(KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED) -# define KWSYS_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED -# define @KWSYS_NAMESPACE@_IOS_ISTREAM_UNSIGNED_LONG_LONG_DEFINED -inline std::istream& operator>>(std::istream& is, - @KWSYS_NAMESPACE@::IOStreamULL& value) -{ - return @KWSYS_NAMESPACE@::IOStreamScan(is, value); -} -# endif -# endif /* !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG */ - -# if !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG - -/* Output stream operator implementation functions. */ -namespace @KWSYS_NAMESPACE@ { -kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamSLL); -kwsysEXPORT std::ostream& IOStreamPrint(std::ostream&, IOStreamULL); -} - -/* Provide output stream operator for long long. */ -# if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_LONG_LONG) && \ - !defined(KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED) -# define KWSYS_IOS_OSTREAM_LONG_LONG_DEFINED -# define @KWSYS_NAMESPACE@_IOS_OSTREAM_LONG_LONG_DEFINED -inline std::ostream& operator<<(std::ostream& os, - @KWSYS_NAMESPACE@::IOStreamSLL value) -{ - return @KWSYS_NAMESPACE@::IOStreamPrint(os, value); -} -# endif - -/* Provide output stream operator for unsigned long long. */ -# if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_UNSIGNED_LONG_LONG) && \ - !defined(KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED) -# define KWSYS_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED -# define @KWSYS_NAMESPACE@_IOS_OSTREAM_UNSIGNED_LONG_LONG_DEFINED -inline std::ostream& operator<<(std::ostream& os, - @KWSYS_NAMESPACE@::IOStreamULL value) -{ - return @KWSYS_NAMESPACE@::IOStreamPrint(os, value); -} -# endif -# endif /* !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG */ -#endif /* @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL */ - -/* Undefine temporary macros. */ -#if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# undef kwsysEXPORT -#endif - -/* If building a C++ file in kwsys itself, give the source file - access to the macros without a configured namespace. */ -#if defined(KWSYS_NAMESPACE) -# define KWSYS_IOS_HAS_ISTREAM_LONG_LONG \ - @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG -# define KWSYS_IOS_HAS_OSTREAM_LONG_LONG \ - @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG -# define KWSYS_IOS_NEED_OPERATORS_LL @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL -#endif - -#endif diff --git a/test/API/driver/kwsys/MD5.c b/test/API/driver/kwsys/MD5.c deleted file mode 100644 index 97cf9ba..0000000 --- a/test/API/driver/kwsys/MD5.c +++ /dev/null @@ -1,494 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(MD5.h) - -/* Work-around CMake dependency scanning limitation. This must - duplicate the above list of headers. */ -#if 0 -# include "MD5.h.in" -#endif - -#include <stddef.h> /* size_t */ -#include <stdlib.h> /* malloc, free */ -#include <string.h> /* memcpy, strlen */ - -/* This MD5 implementation has been taken from a third party. Slight - modifications to the arrangement of the code have been made to put - it in a single source file instead of a separate header and - implementation file. */ - -#if defined(__clang__) && !defined(__INTEL_COMPILER) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wcast-align" -#endif - -/* - Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.c is L. Peter Deutsch - <ghost@aladdin.com>. Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include <string.h> - in library. - 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. - 2002-02-21 lpd Added missing #include <stdio.h> in test program. - 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -/* - * This package supports both compile-time and run-time determination of CPU - * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be - * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is - * defined as non-zero, the code will be compiled to run only on big-endian - * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to - * run on either big- or little-endian CPUs, but will run slightly less - * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. - */ - -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ - -/* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s -{ - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ -} md5_state_t; - -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ -#ifdef ARCH_IS_BIG_ENDIAN -# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) -#else -# define BYTE_ORDER 0 -#endif - -#define T_MASK ((md5_word_t)~0) -#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) -#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -#define T3 0x242070db -#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) -#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -#define T6 0x4787c62a -#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) -#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -#define T9 0x698098d8 -#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) -#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) -#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -#define T13 0x6b901122 -#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) -#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -#define T16 0x49b40821 -#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) -#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -#define T19 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) -#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -#define T22 0x02441453 -#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) -#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -#define T25 0x21e1cde6 -#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) -#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -#define T28 0x455a14ed -#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) -#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -#define T31 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) -#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) -#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -#define T35 0x6d9d6122 -#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) -#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -#define T38 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) -#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -#define T41 0x289b7ec6 -#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) -#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -#define T44 0x04881d05 -#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) -#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -#define T47 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) -#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -#define T50 0x432aff97 -#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) -#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -#define T53 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) -#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) -#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -#define T57 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) -#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -#define T60 0x4e0811a1 -#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) -#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -#define T63 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) - -static void md5_process(md5_state_t* pms, const md5_byte_t* data /*[64]*/) -{ - md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], - d = pms->abcd[3]; - md5_word_t t; -#if BYTE_ORDER > 0 - /* Define storage only for big-endian CPUs. */ - md5_word_t X[16]; -#else - /* Define storage for little-endian or both types of CPUs. */ - md5_word_t xbuf[16]; - const md5_word_t* X; -#endif - - { -#if BYTE_ORDER == 0 - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; - - if (*((const md5_byte_t*)&w)) /* dynamic little-endian */ -#endif -#if BYTE_ORDER <= 0 /* little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if (!((data - (const md5_byte_t*)0) & 3)) { - /* data are properly aligned */ - X = (const md5_word_t*)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } - } -#endif -#if BYTE_ORDER == 0 - else /* dynamic big-endian */ -#endif -#if BYTE_ORDER >= 0 /* big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const md5_byte_t* xp = data; - int i; - -# if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ -# else -# define xbuf X /* (static only) */ -# endif - for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = - (md5_word_t)(xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24)); - } -#endif - } - -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - -/* Round 1. */ -/* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti) \ - t = a + F(b, c, d) + X[k] + (Ti); \ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); - SET(c, d, a, b, 10, 17, T11); - SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); - SET(d, a, b, c, 13, 12, T14); - SET(c, d, a, b, 14, 17, T15); - SET(b, c, d, a, 15, 22, T16); -#undef SET - -/* Round 2. */ -/* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti) \ - t = a + G(b, c, d) + X[k] + (Ti); \ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); - SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); - SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); - SET(b, c, d, a, 12, 20, T32); -#undef SET - -/* Round 3. */ -/* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti) \ - t = a + H(b, c, d) + X[k] + (Ti); \ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); - SET(c, d, a, b, 11, 16, T35); - SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); - SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); - SET(d, a, b, c, 12, 11, T46); - SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); -#undef SET - -/* Round 4. */ -/* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti) \ - t = a + I(b, c, d) + X[k] + (Ti); \ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); - SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); - SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); - SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); - SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); - SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); -#undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -/* Initialize the algorithm. */ -static void md5_init(md5_state_t* pms) -{ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; -} - -/* Append a string to the message. */ -static void md5_append(md5_state_t* pms, const md5_byte_t* data, size_t nbytes) -{ - const md5_byte_t* p = data; - size_t left = nbytes; - size_t offset = (pms->count[0] >> 3) & 63; - md5_word_t nbits = (md5_word_t)(nbytes << 3); - - if (nbytes <= 0) - return; - - /* Update the message length. */ - pms->count[1] += (md5_word_t)(nbytes >> 29); - pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; - - /* Process an initial partial block. */ - if (offset) { - size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); - - /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); -} - -/* Finish the message and return the digest. */ -static void md5_finish(md5_state_t* pms, md5_byte_t digest[16]) -{ - static const md5_byte_t pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -} - -#if defined(__clang__) && !defined(__INTEL_COMPILER) -# pragma clang diagnostic pop -#endif - -/* Wrap up the MD5 state in our opaque structure. */ -struct kwsysMD5_s -{ - md5_state_t md5_state; -}; - -kwsysMD5* kwsysMD5_New(void) -{ - /* Allocate a process control structure. */ - kwsysMD5* md5 = (kwsysMD5*)malloc(sizeof(kwsysMD5)); - if (!md5) { - return 0; - } - return md5; -} - -void kwsysMD5_Delete(kwsysMD5* md5) -{ - /* Make sure we have an instance. */ - if (!md5) { - return; - } - - /* Free memory. */ - free(md5); -} - -void kwsysMD5_Initialize(kwsysMD5* md5) -{ - md5_init(&md5->md5_state); -} - -void kwsysMD5_Append(kwsysMD5* md5, unsigned char const* data, int length) -{ - size_t dlen; - if (length < 0) { - dlen = strlen((char const*)data); - } else { - dlen = (size_t)length; - } - md5_append(&md5->md5_state, (md5_byte_t const*)data, dlen); -} - -void kwsysMD5_Finalize(kwsysMD5* md5, unsigned char digest[16]) -{ - md5_finish(&md5->md5_state, (md5_byte_t*)digest); -} - -void kwsysMD5_FinalizeHex(kwsysMD5* md5, char buffer[32]) -{ - unsigned char digest[16]; - kwsysMD5_Finalize(md5, digest); - kwsysMD5_DigestToHex(digest, buffer); -} - -void kwsysMD5_DigestToHex(unsigned char const digest[16], char buffer[32]) -{ - /* Map from 4-bit index to hexadecimal representation. */ - static char const hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - - /* Map each 4-bit block separately. */ - char* out = buffer; - int i; - for (i = 0; i < 16; ++i) { - *out++ = hex[digest[i] >> 4]; - *out++ = hex[digest[i] & 0xF]; - } -} diff --git a/test/API/driver/kwsys/MD5.h.in b/test/API/driver/kwsys/MD5.h.in deleted file mode 100644 index 7646f12..0000000 --- a/test/API/driver/kwsys/MD5.h.in +++ /dev/null @@ -1,97 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_MD5_h -#define @KWSYS_NAMESPACE@_MD5_h - -#include <@KWSYS_NAMESPACE@/Configure.h> - -/* Redefine all public interface symbol names to be in the proper - namespace. These macros are used internally to kwsys only, and are - not visible to user code. Use kwsysHeaderDump.pl to reproduce - these macros after making changes to the interface. */ -#if !defined(KWSYS_NAMESPACE) -# define kwsys_ns(x) @KWSYS_NAMESPACE@##x -# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT -#endif -#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# define kwsysMD5 kwsys_ns(MD5) -# define kwsysMD5_s kwsys_ns(MD5_s) -# define kwsysMD5_New kwsys_ns(MD5_New) -# define kwsysMD5_Delete kwsys_ns(MD5_Delete) -# define kwsysMD5_Initialize kwsys_ns(MD5_Initialize) -# define kwsysMD5_Append kwsys_ns(MD5_Append) -# define kwsysMD5_Finalize kwsys_ns(MD5_Finalize) -# define kwsysMD5_FinalizeHex kwsys_ns(MD5_FinalizeHex) -# define kwsysMD5_DigestToHex kwsys_ns(MD5_DigestToHex) -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -/** - * MD5 state data structure. - */ -typedef struct kwsysMD5_s kwsysMD5; - -/** - * Create a new MD5 instance. The returned instance is not initialized. - */ -kwsysEXPORT kwsysMD5* kwsysMD5_New(void); - -/** - * Delete an old MD5 instance. - */ -kwsysEXPORT void kwsysMD5_Delete(kwsysMD5* md5); - -/** - * Initialize a new MD5 digest. - */ -kwsysEXPORT void kwsysMD5_Initialize(kwsysMD5* md5); - -/** - * Append data to an MD5 digest. If the given length is negative, - * data will be read up to but not including a terminating null. - */ -kwsysEXPORT void kwsysMD5_Append(kwsysMD5* md5, unsigned char const* data, - int length); - -/** - * Finalize a MD5 digest and get the 16-byte hash value. - */ -kwsysEXPORT void kwsysMD5_Finalize(kwsysMD5* md5, unsigned char digest[16]); - -/** - * Finalize a MD5 digest and get the 32-bit hexadecimal representation. - */ -kwsysEXPORT void kwsysMD5_FinalizeHex(kwsysMD5* md5, char buffer[32]); - -/** - * Convert a MD5 digest 16-byte value to a 32-byte hexadecimal representation. - */ -kwsysEXPORT void kwsysMD5_DigestToHex(unsigned char const digest[16], - char buffer[32]); - -#if defined(__cplusplus) -} /* extern "C" */ -#endif - -/* If we are building a kwsys .c or .cxx file, let it use these macros. - Otherwise, undefine them to keep the namespace clean. */ -#if !defined(KWSYS_NAMESPACE) -# undef kwsys_ns -# undef kwsysEXPORT -# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# undef kwsysMD5 -# undef kwsysMD5_s -# undef kwsysMD5_New -# undef kwsysMD5_Delete -# undef kwsysMD5_Initialize -# undef kwsysMD5_Append -# undef kwsysMD5_Finalize -# undef kwsysMD5_FinalizeHex -# undef kwsysMD5_DigestToHex -# endif -#endif - -#endif diff --git a/test/API/driver/kwsys/Process.h.in b/test/API/driver/kwsys/Process.h.in deleted file mode 100644 index 73ea9db..0000000 --- a/test/API/driver/kwsys/Process.h.in +++ /dev/null @@ -1,544 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_Process_h -#define @KWSYS_NAMESPACE@_Process_h - -#include <@KWSYS_NAMESPACE@/Configure.h> - -/* Redefine all public interface symbol names to be in the proper - namespace. These macros are used internally to kwsys only, and are - not visible to user code. Use kwsysHeaderDump.pl to reproduce - these macros after making changes to the interface. */ -#if !defined(KWSYS_NAMESPACE) -# define kwsys_ns(x) @KWSYS_NAMESPACE@##x -# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT -#endif -#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# define kwsysProcess kwsys_ns(Process) -# define kwsysProcess_s kwsys_ns(Process_s) -# define kwsysProcess_New kwsys_ns(Process_New) -# define kwsysProcess_Delete kwsys_ns(Process_Delete) -# define kwsysProcess_SetCommand kwsys_ns(Process_SetCommand) -# define kwsysProcess_AddCommand kwsys_ns(Process_AddCommand) -# define kwsysProcess_SetTimeout kwsys_ns(Process_SetTimeout) -# define kwsysProcess_SetWorkingDirectory \ - kwsys_ns(Process_SetWorkingDirectory) -# define kwsysProcess_SetPipeFile kwsys_ns(Process_SetPipeFile) -# define kwsysProcess_SetPipeNative kwsys_ns(Process_SetPipeNative) -# define kwsysProcess_SetPipeShared kwsys_ns(Process_SetPipeShared) -# define kwsysProcess_Option_Detach kwsys_ns(Process_Option_Detach) -# define kwsysProcess_Option_HideWindow kwsys_ns(Process_Option_HideWindow) -# define kwsysProcess_Option_MergeOutput kwsys_ns(Process_Option_MergeOutput) -# define kwsysProcess_Option_Verbatim kwsys_ns(Process_Option_Verbatim) -# define kwsysProcess_Option_CreateProcessGroup \ - kwsys_ns(Process_Option_CreateProcessGroup) -# define kwsysProcess_GetOption kwsys_ns(Process_GetOption) -# define kwsysProcess_SetOption kwsys_ns(Process_SetOption) -# define kwsysProcess_Option_e kwsys_ns(Process_Option_e) -# define kwsysProcess_State_Starting kwsys_ns(Process_State_Starting) -# define kwsysProcess_State_Error kwsys_ns(Process_State_Error) -# define kwsysProcess_State_Exception kwsys_ns(Process_State_Exception) -# define kwsysProcess_State_Executing kwsys_ns(Process_State_Executing) -# define kwsysProcess_State_Exited kwsys_ns(Process_State_Exited) -# define kwsysProcess_State_Expired kwsys_ns(Process_State_Expired) -# define kwsysProcess_State_Killed kwsys_ns(Process_State_Killed) -# define kwsysProcess_State_Disowned kwsys_ns(Process_State_Disowned) -# define kwsysProcess_State_e kwsys_ns(Process_State_e) -# define kwsysProcess_Exception_None kwsys_ns(Process_Exception_None) -# define kwsysProcess_Exception_Fault kwsys_ns(Process_Exception_Fault) -# define kwsysProcess_Exception_Illegal kwsys_ns(Process_Exception_Illegal) -# define kwsysProcess_Exception_Interrupt \ - kwsys_ns(Process_Exception_Interrupt) -# define kwsysProcess_Exception_Numerical \ - kwsys_ns(Process_Exception_Numerical) -# define kwsysProcess_Exception_Other kwsys_ns(Process_Exception_Other) -# define kwsysProcess_Exception_e kwsys_ns(Process_Exception_e) -# define kwsysProcess_GetState kwsys_ns(Process_GetState) -# define kwsysProcess_GetExitException kwsys_ns(Process_GetExitException) -# define kwsysProcess_GetExitCode kwsys_ns(Process_GetExitCode) -# define kwsysProcess_GetExitValue kwsys_ns(Process_GetExitValue) -# define kwsysProcess_GetErrorString kwsys_ns(Process_GetErrorString) -# define kwsysProcess_GetExceptionString kwsys_ns(Process_GetExceptionString) -# define kwsysProcess_GetStateByIndex kwsys_ns(Process_GetStateByIndex) -# define kwsysProcess_GetExitExceptionByIndex \ - kwsys_ns(Process_GetExitExceptionByIndex) -# define kwsysProcess_GetExitCodeByIndex kwsys_ns(Process_GetExitCodeByIndex) -# define kwsysProcess_GetExitValueByIndex \ - kwsys_ns(Process_GetExitValueByIndex) -# define kwsysProcess_GetExceptionStringByIndex \ - kwsys_ns(Process_GetExceptionStringByIndex) -# define kwsysProcess_GetExitCodeByIndex kwsys_ns(Process_GetExitCodeByIndex) -# define kwsysProcess_Execute kwsys_ns(Process_Execute) -# define kwsysProcess_Disown kwsys_ns(Process_Disown) -# define kwsysProcess_WaitForData kwsys_ns(Process_WaitForData) -# define kwsysProcess_Pipes_e kwsys_ns(Process_Pipes_e) -# define kwsysProcess_Pipe_None kwsys_ns(Process_Pipe_None) -# define kwsysProcess_Pipe_STDIN kwsys_ns(Process_Pipe_STDIN) -# define kwsysProcess_Pipe_STDOUT kwsys_ns(Process_Pipe_STDOUT) -# define kwsysProcess_Pipe_STDERR kwsys_ns(Process_Pipe_STDERR) -# define kwsysProcess_Pipe_Timeout kwsys_ns(Process_Pipe_Timeout) -# define kwsysProcess_Pipe_Handle kwsys_ns(Process_Pipe_Handle) -# define kwsysProcess_WaitForExit kwsys_ns(Process_WaitForExit) -# define kwsysProcess_Interrupt kwsys_ns(Process_Interrupt) -# define kwsysProcess_Kill kwsys_ns(Process_Kill) -# define kwsysProcess_KillPID kwsys_ns(Process_KillPID) -# define kwsysProcess_ResetStartTime kwsys_ns(Process_ResetStartTime) -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -/** - * Process control data structure. - */ -typedef struct kwsysProcess_s kwsysProcess; - -/* Platform-specific pipe handle type. */ -#if defined(_WIN32) && !defined(__CYGWIN__) -typedef void* kwsysProcess_Pipe_Handle; -#else -typedef int kwsysProcess_Pipe_Handle; -#endif - -/** - * Create a new Process instance. - */ -kwsysEXPORT kwsysProcess* kwsysProcess_New(void); - -/** - * Delete an existing Process instance. If the instance is currently - * executing a process, this blocks until the process terminates. - */ -kwsysEXPORT void kwsysProcess_Delete(kwsysProcess* cp); - -/** - * Set the command line to be executed. Argument is an array of - * pointers to the command and each argument. The array must end with - * a NULL pointer. Any previous command lines are removed. Returns - * 1 for success and 0 otherwise. - */ -kwsysEXPORT int kwsysProcess_SetCommand(kwsysProcess* cp, - char const* const* command); - -/** - * Add a command line to be executed. Argument is an array of - * pointers to the command and each argument. The array must end with - * a NULL pointer. If this is not the first command added, its - * standard input will be connected to the standard output of the - * previous command. Returns 1 for success and 0 otherwise. - */ -kwsysEXPORT int kwsysProcess_AddCommand(kwsysProcess* cp, - char const* const* command); - -/** - * Set the timeout in seconds for the child process. The timeout - * period begins when the child is executed. If the child has not - * terminated when the timeout expires, it will be killed. A - * non-positive (<= 0) value will disable the timeout. - */ -kwsysEXPORT void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout); - -/** - * Set the working directory for the child process. The working - * directory can be absolute or relative to the current directory. - * Returns 1 for success and 0 for failure. - */ -kwsysEXPORT int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, - const char* dir); - -/** - * Set the name of a file to be attached to the given pipe. Returns 1 - * for success and 0 for failure. - */ -kwsysEXPORT int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, - const char* file); - -/** - * Set whether the given pipe in the child is shared with the parent - * process. The default is no for Pipe_STDOUT and Pipe_STDERR and yes - * for Pipe_STDIN. - */ -kwsysEXPORT void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, - int shared); - -/** - * Specify a platform-specific native pipe for use as one of the child - * interface pipes. The native pipe is specified by an array of two - * descriptors or handles. The first entry in the array (index 0) - * should be the read end of the pipe. The second entry in the array - * (index 1) should be the write end of the pipe. If a null pointer - * is given the option will be disabled. - * - * For Pipe_STDIN the native pipe is connected to the first child in - * the pipeline as its stdin. After the children are created the - * write end of the pipe will be closed in the child process and the - * read end will be closed in the parent process. - * - * For Pipe_STDOUT and Pipe_STDERR the pipe is connected to the last - * child as its stdout or stderr. After the children are created the - * write end of the pipe will be closed in the parent process and the - * read end will be closed in the child process. - */ -kwsysEXPORT void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, - kwsysProcess_Pipe_Handle p[2]); - -/** - * Get/Set a possibly platform-specific option. Possible options are: - * - * kwsysProcess_Option_Detach = Whether to detach the process. - * 0 = No (default) - * 1 = Yes - * - * kwsysProcess_Option_HideWindow = Whether to hide window on Windows. - * 0 = No (default) - * 1 = Yes - * - * kwsysProcess_Option_MergeOutput = Whether to merge stdout/stderr. - * No content will be returned as stderr. - * Any actual stderr will be on stdout. - * 0 = No (default) - * 1 = Yes - * - * kwsysProcess_Option_Verbatim = Whether SetCommand and AddCommand - * should treat the first argument - * as a verbatim command line - * and ignore the rest of the arguments. - * 0 = No (default) - * 1 = Yes - * - * kwsysProcess_Option_CreateProcessGroup = Whether to place the process in a - * new process group. This is - * useful if you want to send Ctrl+C - * to the process. On UNIX, also - * places the process in a new - * session. - * 0 = No (default) - * 1 = Yes - */ -kwsysEXPORT int kwsysProcess_GetOption(kwsysProcess* cp, int optionId); -kwsysEXPORT void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, - int value); -enum kwsysProcess_Option_e -{ - kwsysProcess_Option_HideWindow, - kwsysProcess_Option_Detach, - kwsysProcess_Option_MergeOutput, - kwsysProcess_Option_Verbatim, - kwsysProcess_Option_CreateProcessGroup -}; - -/** - * Get the current state of the Process instance. Possible states are: - * - * kwsysProcess_State_Starting = Execute has not yet been called. - * kwsysProcess_State_Error = Error administrating the child process. - * kwsysProcess_State_Exception = Child process exited abnormally. - * kwsysProcess_State_Executing = Child process is currently running. - * kwsysProcess_State_Exited = Child process exited normally. - * kwsysProcess_State_Expired = Child process's timeout expired. - * kwsysProcess_State_Killed = Child process terminated by Kill method. - * kwsysProcess_State_Disowned = Child is no longer managed by this object. - */ -kwsysEXPORT int kwsysProcess_GetState(kwsysProcess* cp); -enum kwsysProcess_State_e -{ - kwsysProcess_State_Starting, - kwsysProcess_State_Error, - kwsysProcess_State_Exception, - kwsysProcess_State_Executing, - kwsysProcess_State_Exited, - kwsysProcess_State_Expired, - kwsysProcess_State_Killed, - kwsysProcess_State_Disowned -}; - -/** - * When GetState returns "Exception", this method returns a - * platform-independent description of the exceptional behavior that - * caused the child to terminate abnormally. Possible exceptions are: - * - * kwsysProcess_Exception_None = No exceptional behavior occurred. - * kwsysProcess_Exception_Fault = Child crashed with a memory fault. - * kwsysProcess_Exception_Illegal = Child crashed with an illegal - * instruction. - * kwsysProcess_Exception_Interrupt = Child was interrupted by user - * (Cntl-C/Break). - * kwsysProcess_Exception_Numerical = Child crashed with a numerical - * exception. - * kwsysProcess_Exception_Other = Child terminated for another reason. - */ -kwsysEXPORT int kwsysProcess_GetExitException(kwsysProcess* cp); -enum kwsysProcess_Exception_e -{ - kwsysProcess_Exception_None, - kwsysProcess_Exception_Fault, - kwsysProcess_Exception_Illegal, - kwsysProcess_Exception_Interrupt, - kwsysProcess_Exception_Numerical, - kwsysProcess_Exception_Other -}; - -/** - * When GetState returns "Exited" or "Exception", this method returns - * the platform-specific raw exit code of the process. UNIX platforms - * should use WIFEXITED/WEXITSTATUS and WIFSIGNALED/WTERMSIG to access - * this value. Windows users should compare the value to the various - * EXCEPTION_* values. - * - * If GetState returns "Exited", use GetExitValue to get the - * platform-independent child return value. - */ -kwsysEXPORT int kwsysProcess_GetExitCode(kwsysProcess* cp); - -/** - * When GetState returns "Exited", this method returns the child's - * platform-independent exit code (such as the value returned by the - * child's main). - */ -kwsysEXPORT int kwsysProcess_GetExitValue(kwsysProcess* cp); - -/** - * When GetState returns "Error", this method returns a string - * describing the problem. Otherwise, it returns NULL. - */ -kwsysEXPORT const char* kwsysProcess_GetErrorString(kwsysProcess* cp); - -/** - * When GetState returns "Exception", this method returns a string - * describing the problem. Otherwise, it returns NULL. - */ -kwsysEXPORT const char* kwsysProcess_GetExceptionString(kwsysProcess* cp); - -/** - * Get the current state of the Process instance. Possible states are: - * - * kwsysProcess_StateByIndex_Starting = Execute has not yet been called. - * kwsysProcess_StateByIndex_Exception = Child process exited abnormally. - * kwsysProcess_StateByIndex_Exited = Child process exited normally. - * kwsysProcess_StateByIndex_Error = Error getting the child return code. - */ -kwsysEXPORT int kwsysProcess_GetStateByIndex(kwsysProcess* cp, int idx); -enum kwsysProcess_StateByIndex_e -{ - kwsysProcess_StateByIndex_Starting = kwsysProcess_State_Starting, - kwsysProcess_StateByIndex_Exception = kwsysProcess_State_Exception, - kwsysProcess_StateByIndex_Exited = kwsysProcess_State_Exited, - kwsysProcess_StateByIndex_Error = kwsysProcess_State_Error -}; - -/** - * When GetState returns "Exception", this method returns a - * platform-independent description of the exceptional behavior that - * caused the child to terminate abnormally. Possible exceptions are: - * - * kwsysProcess_Exception_None = No exceptional behavior occurred. - * kwsysProcess_Exception_Fault = Child crashed with a memory fault. - * kwsysProcess_Exception_Illegal = Child crashed with an illegal - * instruction. - * kwsysProcess_Exception_Interrupt = Child was interrupted by user - * (Cntl-C/Break). - * kwsysProcess_Exception_Numerical = Child crashed with a numerical - * exception. - * kwsysProcess_Exception_Other = Child terminated for another reason. - */ -kwsysEXPORT int kwsysProcess_GetExitExceptionByIndex(kwsysProcess* cp, - int idx); - -/** - * When GetState returns "Exited" or "Exception", this method returns - * the platform-specific raw exit code of the process. UNIX platforms - * should use WIFEXITED/WEXITSTATUS and WIFSIGNALED/WTERMSIG to access - * this value. Windows users should compare the value to the various - * EXCEPTION_* values. - * - * If GetState returns "Exited", use GetExitValue to get the - * platform-independent child return value. - */ -kwsysEXPORT int kwsysProcess_GetExitCodeByIndex(kwsysProcess* cp, int idx); - -/** - * When GetState returns "Exited", this method returns the child's - * platform-independent exit code (such as the value returned by the - * child's main). - */ -kwsysEXPORT int kwsysProcess_GetExitValueByIndex(kwsysProcess* cp, int idx); - -/** - * When GetState returns "Exception", this method returns a string - * describing the problem. Otherwise, it returns NULL. - */ -kwsysEXPORT const char* kwsysProcess_GetExceptionStringByIndex( - kwsysProcess* cp, int idx); - -/** - * Start executing the child process. - */ -kwsysEXPORT void kwsysProcess_Execute(kwsysProcess* cp); - -/** - * Stop management of a detached child process. This closes any pipes - * being read. If the child was not created with the - * kwsysProcess_Option_Detach option, this method does nothing. This - * is because disowning a non-detached process will cause the child - * exit signal to be left unhandled until this process exits. - */ -kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp); - -/** - * Block until data are available on a pipe, a timeout expires, or the - * child process terminates. Arguments are as follows: - * - * data = If data are read, the pointer to which this points is - * set to point to the data. - * length = If data are read, the integer to which this points is - * set to the length of the data read. - * timeout = Specifies the maximum time this call may block. Upon - * return after reading data, the time elapsed is subtracted - * from the timeout value. If this timeout expires, the - * value is set to 0. A NULL pointer passed for this argument - * indicates no timeout for the call. A negative or zero - * value passed for this argument may be used for polling - * and will always return immediately. - * - * Return value will be one of: - * - * Pipe_None = No more data will be available from the child process, - * ( == 0) or no process has been executed. WaitForExit should - * be called to wait for the process to terminate. - * Pipe_STDOUT = Data have been read from the child's stdout pipe. - * Pipe_STDERR = Data have been read from the child's stderr pipe. - * Pipe_Timeout = No data available within timeout specified for the - * call. Time elapsed has been subtracted from timeout - * argument. - */ -kwsysEXPORT int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, - int* length, double* timeout); -enum kwsysProcess_Pipes_e -{ - kwsysProcess_Pipe_None, - kwsysProcess_Pipe_STDIN, - kwsysProcess_Pipe_STDOUT, - kwsysProcess_Pipe_STDERR, - kwsysProcess_Pipe_Timeout = 255 -}; - -/** - * Block until the child process terminates or the given timeout - * expires. If no process is running, returns immediately. The - * argument is: - * - * timeout = Specifies the maximum time this call may block. Upon - * returning due to child termination, the elapsed time - * is subtracted from the given value. A NULL pointer - * passed for this argument indicates no timeout for the - * call. - * - * Return value will be one of: - * - * 0 = Child did not terminate within timeout specified for - * the call. Time elapsed has been subtracted from timeout - * argument. - * 1 = Child has terminated or was not running. - */ -kwsysEXPORT int kwsysProcess_WaitForExit(kwsysProcess* cp, double* timeout); - -/** - * Interrupt the process group for the child process that is currently - * running by sending it the appropriate operating-system specific signal. - * The caller should call WaitForExit after this returns to wait for the - * child to terminate. - * - * WARNING: If you didn't specify kwsysProcess_Option_CreateProcessGroup, - * you will interrupt your own process group. - */ -kwsysEXPORT void kwsysProcess_Interrupt(kwsysProcess* cp); - -/** - * Forcefully terminate the child process that is currently running. - * The caller should call WaitForExit after this returns to wait for - * the child to terminate. - */ -kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp); - -/** - * Same as kwsysProcess_Kill using process ID to locate process to - * terminate. - * @see kwsysProcess_Kill(kwsysProcess* cp) - */ -kwsysEXPORT void kwsysProcess_KillPID(unsigned long); - -/** - * Reset the start time of the child process to the current time. - */ -kwsysEXPORT void kwsysProcess_ResetStartTime(kwsysProcess* cp); - -#if defined(__cplusplus) -} /* extern "C" */ -#endif - -/* If we are building a kwsys .c or .cxx file, let it use these macros. - Otherwise, undefine them to keep the namespace clean. */ -#if !defined(KWSYS_NAMESPACE) -# undef kwsys_ns -# undef kwsysEXPORT -# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# undef kwsysProcess -# undef kwsysProcess_s -# undef kwsysProcess_New -# undef kwsysProcess_Delete -# undef kwsysProcess_SetCommand -# undef kwsysProcess_AddCommand -# undef kwsysProcess_SetTimeout -# undef kwsysProcess_SetWorkingDirectory -# undef kwsysProcess_SetPipeFile -# undef kwsysProcess_SetPipeNative -# undef kwsysProcess_SetPipeShared -# undef kwsysProcess_Option_Detach -# undef kwsysProcess_Option_HideWindow -# undef kwsysProcess_Option_MergeOutput -# undef kwsysProcess_Option_Verbatim -# undef kwsysProcess_Option_CreateProcessGroup -# undef kwsysProcess_GetOption -# undef kwsysProcess_SetOption -# undef kwsysProcess_Option_e -# undef kwsysProcess_State_Starting -# undef kwsysProcess_State_Error -# undef kwsysProcess_State_Exception -# undef kwsysProcess_State_Executing -# undef kwsysProcess_State_Exited -# undef kwsysProcess_State_Expired -# undef kwsysProcess_State_Killed -# undef kwsysProcess_State_Disowned -# undef kwsysProcess_GetState -# undef kwsysProcess_State_e -# undef kwsysProcess_Exception_None -# undef kwsysProcess_Exception_Fault -# undef kwsysProcess_Exception_Illegal -# undef kwsysProcess_Exception_Interrupt -# undef kwsysProcess_Exception_Numerical -# undef kwsysProcess_Exception_Other -# undef kwsysProcess_GetExitException -# undef kwsysProcess_Exception_e -# undef kwsysProcess_GetExitCode -# undef kwsysProcess_GetExitValue -# undef kwsysProcess_GetErrorString -# undef kwsysProcess_GetExceptionString -# undef kwsysProcess_Execute -# undef kwsysProcess_Disown -# undef kwsysProcess_WaitForData -# undef kwsysProcess_Pipes_e -# undef kwsysProcess_Pipe_None -# undef kwsysProcess_Pipe_STDIN -# undef kwsysProcess_Pipe_STDOUT -# undef kwsysProcess_Pipe_STDERR -# undef kwsysProcess_Pipe_Timeout -# undef kwsysProcess_Pipe_Handle -# undef kwsysProcess_WaitForExit -# undef kwsysProcess_Interrupt -# undef kwsysProcess_Kill -# undef kwsysProcess_ResetStartTime -# endif -#endif - -#endif diff --git a/test/API/driver/kwsys/ProcessUNIX.c b/test/API/driver/kwsys/ProcessUNIX.c deleted file mode 100644 index 100eddc..0000000 --- a/test/API/driver/kwsys/ProcessUNIX.c +++ /dev/null @@ -1,2920 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Process.h) -#include KWSYS_HEADER(System.h) - -/* Work-around CMake dependency scanning limitation. This must - duplicate the above list of headers. */ -#if 0 -# include "Process.h.in" -# include "System.h.in" -#endif - -/* - -Implementation for UNIX - -On UNIX, a child process is forked to exec the program. Three output -pipes are read by the parent process using a select call to block -until data are ready. Two of the pipes are stdout and stderr for the -child. The third is a special pipe populated by a signal handler to -indicate that a child has terminated. This is used in conjunction -with the timeout on the select call to implement a timeout for program -even when it closes stdout and stderr and at the same time avoiding -races. - -*/ - -/* - -TODO: - -We cannot create the pipeline of processes in suspended states. How -do we cleanup processes already started when one fails to load? Right -now we are just killing them, which is probably not the right thing to -do. - -*/ - -#if defined(__CYGWIN__) -/* Increase the file descriptor limit for select() before including - related system headers. (Default: 64) */ -# define FD_SETSIZE 16384 -#endif - -#include <assert.h> /* assert */ -#include <ctype.h> /* isspace */ -#include <dirent.h> /* DIR, dirent */ -#include <errno.h> /* errno */ -#include <fcntl.h> /* fcntl */ -#include <signal.h> /* sigaction */ -#include <stddef.h> /* ptrdiff_t */ -#include <stdio.h> /* snprintf */ -#include <stdlib.h> /* malloc, free */ -#include <string.h> /* strdup, strerror, memset */ -#include <sys/stat.h> /* open mode */ -#include <sys/time.h> /* struct timeval */ -#include <sys/types.h> /* pid_t, fd_set */ -#include <sys/wait.h> /* waitpid */ -#include <time.h> /* gettimeofday */ -#include <unistd.h> /* pipe, close, fork, execvp, select, _exit */ - -#if defined(__VMS) -# define KWSYSPE_VMS_NONBLOCK , O_NONBLOCK -#else -# define KWSYSPE_VMS_NONBLOCK -#endif - -#if defined(KWSYS_C_HAS_PTRDIFF_T) && KWSYS_C_HAS_PTRDIFF_T -typedef ptrdiff_t kwsysProcess_ptrdiff_t; -#else -typedef int kwsysProcess_ptrdiff_t; -#endif - -#if defined(KWSYS_C_HAS_SSIZE_T) && KWSYS_C_HAS_SSIZE_T -typedef ssize_t kwsysProcess_ssize_t; -#else -typedef int kwsysProcess_ssize_t; -#endif - -#if defined(__BEOS__) && !defined(__ZETA__) -/* BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. */ -# include <be/kernel/OS.h> -static inline void kwsysProcess_usleep(unsigned int msec) -{ - snooze(msec); -} -#else -# define kwsysProcess_usleep usleep -#endif - -/* - * BeOS's select() works like WinSock: it's for networking only, and - * doesn't work with Unix file handles...socket and file handles are - * different namespaces (the same descriptor means different things in - * each context!) - * - * So on Unix-like systems where select() is flakey, we'll set the - * pipes' file handles to be non-blocking and just poll them directly - * without select(). - */ -#if !defined(__BEOS__) && !defined(__VMS) && !defined(__MINT__) && \ - !defined(KWSYSPE_USE_SELECT) -# define KWSYSPE_USE_SELECT 1 -#endif - -/* Some platforms do not have siginfo on their signal handlers. */ -#if defined(SA_SIGINFO) && !defined(__BEOS__) -# define KWSYSPE_USE_SIGINFO 1 -#endif - -/* The number of pipes for the child's output. The standard stdout - and stderr pipes are the first two. One more pipe is used to - detect when the child process has terminated. The third pipe is - not given to the child process, so it cannot close it until it - terminates. */ -#define KWSYSPE_PIPE_COUNT 3 -#define KWSYSPE_PIPE_STDOUT 0 -#define KWSYSPE_PIPE_STDERR 1 -#define KWSYSPE_PIPE_SIGNAL 2 - -/* The maximum amount to read from a pipe at a time. */ -#define KWSYSPE_PIPE_BUFFER_SIZE 1024 - -/* Keep track of times using a signed representation. Switch to the - native (possibly unsigned) representation only when calling native - functions. */ -typedef struct timeval kwsysProcessTimeNative; -typedef struct kwsysProcessTime_s kwsysProcessTime; -struct kwsysProcessTime_s -{ - long tv_sec; - long tv_usec; -}; - -typedef struct kwsysProcessCreateInformation_s -{ - int StdIn; - int StdOut; - int StdErr; - int ErrorPipe[2]; -} kwsysProcessCreateInformation; - -static void kwsysProcessVolatileFree(volatile void* p); -static int kwsysProcessInitialize(kwsysProcess* cp); -static void kwsysProcessCleanup(kwsysProcess* cp, int error); -static void kwsysProcessCleanupDescriptor(int* pfd); -static void kwsysProcessClosePipes(kwsysProcess* cp); -static int kwsysProcessSetNonBlocking(int fd); -static int kwsysProcessCreate(kwsysProcess* cp, int prIndex, - kwsysProcessCreateInformation* si); -static void kwsysProcessDestroy(kwsysProcess* cp); -static int kwsysProcessSetupOutputPipeFile(int* p, const char* name); -static int kwsysProcessSetupOutputPipeNative(int* p, int des[2]); -static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, - kwsysProcessTime* timeoutTime); -static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime, - double* userTimeout, - kwsysProcessTimeNative* timeoutLength, - int zeroIsExpired); -static kwsysProcessTime kwsysProcessTimeGetCurrent(void); -static double kwsysProcessTimeToDouble(kwsysProcessTime t); -static kwsysProcessTime kwsysProcessTimeFromDouble(double d); -static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2); -static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, - kwsysProcessTime in2); -static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, - kwsysProcessTime in2); -static void kwsysProcessSetExitExceptionByIndex(kwsysProcess* cp, int sig, - int idx); -static void kwsysProcessChildErrorExit(int errorPipe); -static void kwsysProcessRestoreDefaultSignalHandlers(void); -static pid_t kwsysProcessFork(kwsysProcess* cp, - kwsysProcessCreateInformation* si); -static void kwsysProcessKill(pid_t process_id); -#if defined(__VMS) -static int kwsysProcessSetVMSFeature(const char* name, int value); -#endif -static int kwsysProcessesAdd(kwsysProcess* cp); -static void kwsysProcessesRemove(kwsysProcess* cp); -#if KWSYSPE_USE_SIGINFO -static void kwsysProcessesSignalHandler(int signum, siginfo_t* info, - void* ucontext); -#else -static void kwsysProcessesSignalHandler(int signum); -#endif - -/* A structure containing results data for each process. */ -typedef struct kwsysProcessResults_s kwsysProcessResults; -struct kwsysProcessResults_s -{ - /* The status of the child process. */ - int State; - - /* The exceptional behavior that terminated the process, if any. */ - int ExitException; - - /* The process exit code. */ - int ExitCode; - - /* The process return code, if any. */ - int ExitValue; - - /* Description for the ExitException. */ - char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE + 1]; -}; - -/* Structure containing data used to implement the child's execution. */ -struct kwsysProcess_s -{ - /* The command lines to execute. */ - char*** Commands; - volatile int NumberOfCommands; - - /* Descriptors for the read ends of the child's output pipes and - the signal pipe. */ - int PipeReadEnds[KWSYSPE_PIPE_COUNT]; - - /* Descriptors for the child's ends of the pipes. - Used temporarily during process creation. */ - int PipeChildStd[3]; - - /* Write descriptor for child termination signal pipe. */ - int SignalPipe; - - /* Buffer for pipe data. */ - char PipeBuffer[KWSYSPE_PIPE_BUFFER_SIZE]; - - /* Process IDs returned by the calls to fork. Everything is volatile - because the signal handler accesses them. You must be very careful - when reaping PIDs or modifying this array to avoid race conditions. */ - volatile pid_t* volatile ForkPIDs; - - /* Flag for whether the children were terminated by a failed select. */ - int SelectError; - - /* The timeout length. */ - double Timeout; - - /* The working directory for the process. */ - char* WorkingDirectory; - - /* Whether to create the child as a detached process. */ - int OptionDetach; - - /* Whether the child was created as a detached process. */ - int Detached; - - /* Whether to treat command lines as verbatim. */ - int Verbatim; - - /* Whether to merge stdout/stderr of the child. */ - int MergeOutput; - - /* Whether to create the process in a new process group. */ - volatile sig_atomic_t CreateProcessGroup; - - /* Time at which the child started. Negative for no timeout. */ - kwsysProcessTime StartTime; - - /* Time at which the child will timeout. Negative for no timeout. */ - kwsysProcessTime TimeoutTime; - - /* Flag for whether the timeout expired. */ - int TimeoutExpired; - - /* The number of pipes left open during execution. */ - int PipesLeft; - -#if KWSYSPE_USE_SELECT - /* File descriptor set for call to select. */ - fd_set PipeSet; -#endif - - /* The number of children still executing. */ - int CommandsLeft; - - /* The status of the process structure. Must be atomic because - the signal handler checks this to avoid a race. */ - volatile sig_atomic_t State; - - /* Whether the process was killed. */ - volatile sig_atomic_t Killed; - - /* Buffer for error message in case of failure. */ - char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE + 1]; - - /* process results. */ - kwsysProcessResults* ProcessResults; - - /* The exit codes of each child process in the pipeline. */ - int* CommandExitCodes; - - /* Name of files to which stdin and stdout pipes are attached. */ - char* PipeFileSTDIN; - char* PipeFileSTDOUT; - char* PipeFileSTDERR; - - /* Whether each pipe is shared with the parent process. */ - int PipeSharedSTDIN; - int PipeSharedSTDOUT; - int PipeSharedSTDERR; - - /* Native pipes provided by the user. */ - int PipeNativeSTDIN[2]; - int PipeNativeSTDOUT[2]; - int PipeNativeSTDERR[2]; - - /* The real working directory of this process. */ - int RealWorkingDirectoryLength; - char* RealWorkingDirectory; -}; - -kwsysProcess* kwsysProcess_New(void) -{ - /* Allocate a process control structure. */ - kwsysProcess* cp = (kwsysProcess*)malloc(sizeof(kwsysProcess)); - if (!cp) { - return 0; - } - memset(cp, 0, sizeof(kwsysProcess)); - - /* Share stdin with the parent process by default. */ - cp->PipeSharedSTDIN = 1; - - /* No native pipes by default. */ - cp->PipeNativeSTDIN[0] = -1; - cp->PipeNativeSTDIN[1] = -1; - cp->PipeNativeSTDOUT[0] = -1; - cp->PipeNativeSTDOUT[1] = -1; - cp->PipeNativeSTDERR[0] = -1; - cp->PipeNativeSTDERR[1] = -1; - - /* Set initial status. */ - cp->State = kwsysProcess_State_Starting; - - return cp; -} - -void kwsysProcess_Delete(kwsysProcess* cp) -{ - /* Make sure we have an instance. */ - if (!cp) { - return; - } - - /* If the process is executing, wait for it to finish. */ - if (cp->State == kwsysProcess_State_Executing) { - if (cp->Detached) { - kwsysProcess_Disown(cp); - } else { - kwsysProcess_WaitForExit(cp, 0); - } - } - - /* Free memory. */ - kwsysProcess_SetCommand(cp, 0); - kwsysProcess_SetWorkingDirectory(cp, 0); - kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0); - kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0); - kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0); - free(cp->CommandExitCodes); - free(cp->ProcessResults); - free(cp); -} - -int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command) -{ - int i; - if (!cp) { - return 0; - } - for (i = 0; i < cp->NumberOfCommands; ++i) { - char** c = cp->Commands[i]; - while (*c) { - free(*c++); - } - free(cp->Commands[i]); - } - cp->NumberOfCommands = 0; - if (cp->Commands) { - free(cp->Commands); - cp->Commands = 0; - } - if (command) { - return kwsysProcess_AddCommand(cp, command); - } - return 1; -} - -int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) -{ - int newNumberOfCommands; - char*** newCommands; - - /* Make sure we have a command to add. */ - if (!cp || !command || !*command) { - return 0; - } - - /* Allocate a new array for command pointers. */ - newNumberOfCommands = cp->NumberOfCommands + 1; - if (!(newCommands = - (char***)malloc(sizeof(char**) * (size_t)(newNumberOfCommands)))) { - /* Out of memory. */ - return 0; - } - - /* Copy any existing commands into the new array. */ - { - int i; - for (i = 0; i < cp->NumberOfCommands; ++i) { - newCommands[i] = cp->Commands[i]; - } - } - - /* Add the new command. */ - if (cp->Verbatim) { - /* In order to run the given command line verbatim we need to - parse it. */ - newCommands[cp->NumberOfCommands] = - kwsysSystem_Parse_CommandForUnix(*command, 0); - if (!newCommands[cp->NumberOfCommands] || - !newCommands[cp->NumberOfCommands][0]) { - /* Out of memory or no command parsed. */ - free(newCommands); - return 0; - } - } else { - /* Copy each argument string individually. */ - char const* const* c = command; - kwsysProcess_ptrdiff_t n = 0; - kwsysProcess_ptrdiff_t i = 0; - while (*c++) - ; - n = c - command - 1; - newCommands[cp->NumberOfCommands] = - (char**)malloc((size_t)(n + 1) * sizeof(char*)); - if (!newCommands[cp->NumberOfCommands]) { - /* Out of memory. */ - free(newCommands); - return 0; - } - for (i = 0; i < n; ++i) { - assert(command[i]); /* Quiet Clang scan-build. */ - newCommands[cp->NumberOfCommands][i] = strdup(command[i]); - if (!newCommands[cp->NumberOfCommands][i]) { - break; - } - } - if (i < n) { - /* Out of memory. */ - for (; i > 0; --i) { - free(newCommands[cp->NumberOfCommands][i - 1]); - } - free(newCommands); - return 0; - } - newCommands[cp->NumberOfCommands][n] = 0; - } - - /* Successfully allocated new command array. Free the old array. */ - free(cp->Commands); - cp->Commands = newCommands; - cp->NumberOfCommands = newNumberOfCommands; - - return 1; -} - -void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout) -{ - if (!cp) { - return; - } - cp->Timeout = timeout; - if (cp->Timeout < 0) { - cp->Timeout = 0; - } - // Force recomputation of TimeoutTime. - cp->TimeoutTime.tv_sec = -1; -} - -int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir) -{ - if (!cp) { - return 0; - } - if (cp->WorkingDirectory == dir) { - return 1; - } - if (cp->WorkingDirectory && dir && strcmp(cp->WorkingDirectory, dir) == 0) { - return 1; - } - if (cp->WorkingDirectory) { - free(cp->WorkingDirectory); - cp->WorkingDirectory = 0; - } - if (dir) { - cp->WorkingDirectory = strdup(dir); - if (!cp->WorkingDirectory) { - return 0; - } - } - return 1; -} - -int kwsysProcess_SetPipeFile(kwsysProcess* cp, int prPipe, const char* file) -{ - char** pfile; - if (!cp) { - return 0; - } - switch (prPipe) { - case kwsysProcess_Pipe_STDIN: - pfile = &cp->PipeFileSTDIN; - break; - case kwsysProcess_Pipe_STDOUT: - pfile = &cp->PipeFileSTDOUT; - break; - case kwsysProcess_Pipe_STDERR: - pfile = &cp->PipeFileSTDERR; - break; - default: - return 0; - } - if (*pfile) { - free(*pfile); - *pfile = 0; - } - if (file) { - *pfile = strdup(file); - if (!*pfile) { - return 0; - } - } - - /* If we are redirecting the pipe, do not share it or use a native - pipe. */ - if (*pfile) { - kwsysProcess_SetPipeNative(cp, prPipe, 0); - kwsysProcess_SetPipeShared(cp, prPipe, 0); - } - return 1; -} - -void kwsysProcess_SetPipeShared(kwsysProcess* cp, int prPipe, int shared) -{ - if (!cp) { - return; - } - - switch (prPipe) { - case kwsysProcess_Pipe_STDIN: - cp->PipeSharedSTDIN = shared ? 1 : 0; - break; - case kwsysProcess_Pipe_STDOUT: - cp->PipeSharedSTDOUT = shared ? 1 : 0; - break; - case kwsysProcess_Pipe_STDERR: - cp->PipeSharedSTDERR = shared ? 1 : 0; - break; - default: - return; - } - - /* If we are sharing the pipe, do not redirect it to a file or use a - native pipe. */ - if (shared) { - kwsysProcess_SetPipeFile(cp, prPipe, 0); - kwsysProcess_SetPipeNative(cp, prPipe, 0); - } -} - -void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, int p[2]) -{ - int* pPipeNative = 0; - - if (!cp) { - return; - } - - switch (prPipe) { - case kwsysProcess_Pipe_STDIN: - pPipeNative = cp->PipeNativeSTDIN; - break; - case kwsysProcess_Pipe_STDOUT: - pPipeNative = cp->PipeNativeSTDOUT; - break; - case kwsysProcess_Pipe_STDERR: - pPipeNative = cp->PipeNativeSTDERR; - break; - default: - return; - } - - /* Copy the native pipe descriptors provided. */ - if (p) { - pPipeNative[0] = p[0]; - pPipeNative[1] = p[1]; - } else { - pPipeNative[0] = -1; - pPipeNative[1] = -1; - } - - /* If we are using a native pipe, do not share it or redirect it to - a file. */ - if (p) { - kwsysProcess_SetPipeFile(cp, prPipe, 0); - kwsysProcess_SetPipeShared(cp, prPipe, 0); - } -} - -int kwsysProcess_GetOption(kwsysProcess* cp, int optionId) -{ - if (!cp) { - return 0; - } - - switch (optionId) { - case kwsysProcess_Option_Detach: - return cp->OptionDetach; - case kwsysProcess_Option_MergeOutput: - return cp->MergeOutput; - case kwsysProcess_Option_Verbatim: - return cp->Verbatim; - case kwsysProcess_Option_CreateProcessGroup: - return cp->CreateProcessGroup; - default: - return 0; - } -} - -void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value) -{ - if (!cp) { - return; - } - - switch (optionId) { - case kwsysProcess_Option_Detach: - cp->OptionDetach = value; - break; - case kwsysProcess_Option_MergeOutput: - cp->MergeOutput = value; - break; - case kwsysProcess_Option_Verbatim: - cp->Verbatim = value; - break; - case kwsysProcess_Option_CreateProcessGroup: - cp->CreateProcessGroup = value; - break; - default: - break; - } -} - -int kwsysProcess_GetState(kwsysProcess* cp) -{ - return cp ? cp->State : kwsysProcess_State_Error; -} - -int kwsysProcess_GetExitException(kwsysProcess* cp) -{ - return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) - ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitException - : kwsysProcess_Exception_Other; -} - -int kwsysProcess_GetExitCode(kwsysProcess* cp) -{ - return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) - ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitCode - : 0; -} - -int kwsysProcess_GetExitValue(kwsysProcess* cp) -{ - return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) - ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitValue - : -1; -} - -const char* kwsysProcess_GetErrorString(kwsysProcess* cp) -{ - if (!cp) { - return "Process management structure could not be allocated"; - } else if (cp->State == kwsysProcess_State_Error) { - return cp->ErrorMessage; - } - return "Success"; -} - -const char* kwsysProcess_GetExceptionString(kwsysProcess* cp) -{ - if (!(cp && cp->ProcessResults && (cp->NumberOfCommands > 0))) { - return "GetExceptionString called with NULL process management structure"; - } else if (cp->State == kwsysProcess_State_Exception) { - return cp->ProcessResults[cp->NumberOfCommands - 1].ExitExceptionString; - } - return "No exception"; -} - -/* the index should be in array bound. */ -#define KWSYSPE_IDX_CHK(RET) \ - if (!cp || idx >= cp->NumberOfCommands || idx < 0) { \ - return RET; \ - } - -int kwsysProcess_GetStateByIndex(kwsysProcess* cp, int idx) -{ - KWSYSPE_IDX_CHK(kwsysProcess_State_Error) - return cp->ProcessResults[idx].State; -} - -int kwsysProcess_GetExitExceptionByIndex(kwsysProcess* cp, int idx) -{ - KWSYSPE_IDX_CHK(kwsysProcess_Exception_Other) - return cp->ProcessResults[idx].ExitException; -} - -int kwsysProcess_GetExitValueByIndex(kwsysProcess* cp, int idx) -{ - KWSYSPE_IDX_CHK(-1) - return cp->ProcessResults[idx].ExitValue; -} - -int kwsysProcess_GetExitCodeByIndex(kwsysProcess* cp, int idx) -{ - KWSYSPE_IDX_CHK(-1) - return cp->CommandExitCodes[idx]; -} - -const char* kwsysProcess_GetExceptionStringByIndex(kwsysProcess* cp, int idx) -{ - KWSYSPE_IDX_CHK("GetExceptionString called with NULL process management " - "structure or index out of bound") - if (cp->ProcessResults[idx].State == kwsysProcess_StateByIndex_Exception) { - return cp->ProcessResults[idx].ExitExceptionString; - } - return "No exception"; -} - -#undef KWSYSPE_IDX_CHK - -void kwsysProcess_Execute(kwsysProcess* cp) -{ - int i; - - /* Do not execute a second copy simultaneously. */ - if (!cp || cp->State == kwsysProcess_State_Executing) { - return; - } - - /* Make sure we have something to run. */ - if (cp->NumberOfCommands < 1) { - strcpy(cp->ErrorMessage, "No command"); - cp->State = kwsysProcess_State_Error; - return; - } - - /* Initialize the control structure for a new process. */ - if (!kwsysProcessInitialize(cp)) { - strcpy(cp->ErrorMessage, "Out of memory"); - cp->State = kwsysProcess_State_Error; - return; - } - -#if defined(__VMS) - /* Make sure pipes behave like streams on VMS. */ - if (!kwsysProcessSetVMSFeature("DECC$STREAM_PIPE", 1)) { - kwsysProcessCleanup(cp, 1); - return; - } -#endif - - /* Save the real working directory of this process and change to - the working directory for the child processes. This is needed - to make pipe file paths evaluate correctly. */ - if (cp->WorkingDirectory) { - int r; - if (!getcwd(cp->RealWorkingDirectory, - (size_t)(cp->RealWorkingDirectoryLength))) { - kwsysProcessCleanup(cp, 1); - return; - } - - /* Some platforms specify that the chdir call may be - interrupted. Repeat the call until it finishes. */ - while (((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR)) - ; - if (r < 0) { - kwsysProcessCleanup(cp, 1); - return; - } - } - - /* If not running a detached child, add this object to the global - set of process objects that wish to be notified when a child - exits. */ - if (!cp->OptionDetach) { - if (!kwsysProcessesAdd(cp)) { - kwsysProcessCleanup(cp, 1); - return; - } - } - - /* Setup the stdin pipe for the first process. */ - if (cp->PipeFileSTDIN) { - /* Open a file for the child's stdin to read. */ - cp->PipeChildStd[0] = open(cp->PipeFileSTDIN, O_RDONLY); - if (cp->PipeChildStd[0] < 0) { - kwsysProcessCleanup(cp, 1); - return; - } - - /* Set close-on-exec flag on the pipe's end. */ - if (fcntl(cp->PipeChildStd[0], F_SETFD, FD_CLOEXEC) < 0) { - kwsysProcessCleanup(cp, 1); - return; - } - } else if (cp->PipeSharedSTDIN) { - cp->PipeChildStd[0] = 0; - } else if (cp->PipeNativeSTDIN[0] >= 0) { - cp->PipeChildStd[0] = cp->PipeNativeSTDIN[0]; - - /* Set close-on-exec flag on the pipe's ends. The read end will - be dup2-ed into the stdin descriptor after the fork but before - the exec. */ - if ((fcntl(cp->PipeNativeSTDIN[0], F_SETFD, FD_CLOEXEC) < 0) || - (fcntl(cp->PipeNativeSTDIN[1], F_SETFD, FD_CLOEXEC) < 0)) { - kwsysProcessCleanup(cp, 1); - return; - } - } else { - cp->PipeChildStd[0] = -1; - } - - /* Create the output pipe for the last process. - We always create this so the pipe can be passed to select even if - it will report closed immediately. */ - { - /* Create the pipe. */ - int p[2]; - if (pipe(p KWSYSPE_VMS_NONBLOCK) < 0) { - kwsysProcessCleanup(cp, 1); - return; - } - - /* Store the pipe. */ - cp->PipeReadEnds[KWSYSPE_PIPE_STDOUT] = p[0]; - cp->PipeChildStd[1] = p[1]; - - /* Set close-on-exec flag on the pipe's ends. */ - if ((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) || - (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0)) { - kwsysProcessCleanup(cp, 1); - return; - } - - /* Set to non-blocking in case select lies, or for the polling - implementation. */ - if (!kwsysProcessSetNonBlocking(p[0])) { - kwsysProcessCleanup(cp, 1); - return; - } - } - - if (cp->PipeFileSTDOUT) { - /* Use a file for stdout. */ - if (!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1], - cp->PipeFileSTDOUT)) { - kwsysProcessCleanup(cp, 1); - return; - } - } else if (cp->PipeSharedSTDOUT) { - /* Use the parent stdout. */ - kwsysProcessCleanupDescriptor(&cp->PipeChildStd[1]); - cp->PipeChildStd[1] = 1; - } else if (cp->PipeNativeSTDOUT[1] >= 0) { - /* Use the given descriptor for stdout. */ - if (!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[1], - cp->PipeNativeSTDOUT)) { - kwsysProcessCleanup(cp, 1); - return; - } - } - - /* Create stderr pipe to be shared by all processes in the pipeline. - We always create this so the pipe can be passed to select even if - it will report closed immediately. */ - { - /* Create the pipe. */ - int p[2]; - if (pipe(p KWSYSPE_VMS_NONBLOCK) < 0) { - kwsysProcessCleanup(cp, 1); - return; - } - - /* Store the pipe. */ - cp->PipeReadEnds[KWSYSPE_PIPE_STDERR] = p[0]; - cp->PipeChildStd[2] = p[1]; - - /* Set close-on-exec flag on the pipe's ends. */ - if ((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) || - (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0)) { - kwsysProcessCleanup(cp, 1); - return; - } - - /* Set to non-blocking in case select lies, or for the polling - implementation. */ - if (!kwsysProcessSetNonBlocking(p[0])) { - kwsysProcessCleanup(cp, 1); - return; - } - } - - if (cp->PipeFileSTDERR) { - /* Use a file for stderr. */ - if (!kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2], - cp->PipeFileSTDERR)) { - kwsysProcessCleanup(cp, 1); - return; - } - } else if (cp->PipeSharedSTDERR) { - /* Use the parent stderr. */ - kwsysProcessCleanupDescriptor(&cp->PipeChildStd[2]); - cp->PipeChildStd[2] = 2; - } else if (cp->PipeNativeSTDERR[1] >= 0) { - /* Use the given handle for stderr. */ - if (!kwsysProcessSetupOutputPipeNative(&cp->PipeChildStd[2], - cp->PipeNativeSTDERR)) { - kwsysProcessCleanup(cp, 1); - return; - } - } - - /* The timeout period starts now. */ - cp->StartTime = kwsysProcessTimeGetCurrent(); - cp->TimeoutTime.tv_sec = -1; - cp->TimeoutTime.tv_usec = -1; - - /* Create the pipeline of processes. */ - { - kwsysProcessCreateInformation si = { -1, -1, -1, { -1, -1 } }; - int nextStdIn = cp->PipeChildStd[0]; - for (i = 0; i < cp->NumberOfCommands; ++i) { - /* Setup the process's pipes. */ - si.StdIn = nextStdIn; - if (i == cp->NumberOfCommands - 1) { - nextStdIn = -1; - si.StdOut = cp->PipeChildStd[1]; - } else { - /* Create a pipe to sit between the children. */ - int p[2] = { -1, -1 }; - if (pipe(p KWSYSPE_VMS_NONBLOCK) < 0) { - if (nextStdIn != cp->PipeChildStd[0]) { - kwsysProcessCleanupDescriptor(&nextStdIn); - } - kwsysProcessCleanup(cp, 1); - return; - } - - /* Set close-on-exec flag on the pipe's ends. */ - if ((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) || - (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0)) { - close(p[0]); - close(p[1]); - if (nextStdIn != cp->PipeChildStd[0]) { - kwsysProcessCleanupDescriptor(&nextStdIn); - } - kwsysProcessCleanup(cp, 1); - return; - } - nextStdIn = p[0]; - si.StdOut = p[1]; - } - si.StdErr = cp->MergeOutput ? cp->PipeChildStd[1] : cp->PipeChildStd[2]; - - { - int res = kwsysProcessCreate(cp, i, &si); - - /* Close our copies of pipes used between children. */ - if (si.StdIn != cp->PipeChildStd[0]) { - kwsysProcessCleanupDescriptor(&si.StdIn); - } - if (si.StdOut != cp->PipeChildStd[1]) { - kwsysProcessCleanupDescriptor(&si.StdOut); - } - if (si.StdErr != cp->PipeChildStd[2] && !cp->MergeOutput) { - kwsysProcessCleanupDescriptor(&si.StdErr); - } - - if (!res) { - kwsysProcessCleanupDescriptor(&si.ErrorPipe[0]); - kwsysProcessCleanupDescriptor(&si.ErrorPipe[1]); - if (nextStdIn != cp->PipeChildStd[0]) { - kwsysProcessCleanupDescriptor(&nextStdIn); - } - kwsysProcessCleanup(cp, 1); - return; - } - } - } - } - - /* The parent process does not need the child's pipe ends. */ - for (i = 0; i < 3; ++i) { - kwsysProcessCleanupDescriptor(&cp->PipeChildStd[i]); - } - - /* Restore the working directory. */ - if (cp->RealWorkingDirectory) { - /* Some platforms specify that the chdir call may be - interrupted. Repeat the call until it finishes. */ - while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR)) - ; - free(cp->RealWorkingDirectory); - cp->RealWorkingDirectory = 0; - } - - /* All the pipes are now open. */ - cp->PipesLeft = KWSYSPE_PIPE_COUNT; - - /* The process has now started. */ - cp->State = kwsysProcess_State_Executing; - cp->Detached = cp->OptionDetach; -} - -kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp) -{ - /* Make sure a detached child process is running. */ - if (!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing || - cp->TimeoutExpired || cp->Killed) { - return; - } - - /* Close all the pipes safely. */ - kwsysProcessClosePipes(cp); - - /* We will not wait for exit, so cleanup now. */ - kwsysProcessCleanup(cp, 0); - - /* The process has been disowned. */ - cp->State = kwsysProcess_State_Disowned; -} - -typedef struct kwsysProcessWaitData_s -{ - int Expired; - int PipeId; - int User; - double* UserTimeout; - kwsysProcessTime TimeoutTime; -} kwsysProcessWaitData; -static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length, - kwsysProcessWaitData* wd); - -int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, - double* userTimeout) -{ - kwsysProcessTime userStartTime = { 0, 0 }; - kwsysProcessWaitData wd = { 0, kwsysProcess_Pipe_None, 0, 0, { 0, 0 } }; - wd.UserTimeout = userTimeout; - /* Make sure we are executing a process. */ - if (!cp || cp->State != kwsysProcess_State_Executing || cp->Killed || - cp->TimeoutExpired) { - return kwsysProcess_Pipe_None; - } - - /* Record the time at which user timeout period starts. */ - if (userTimeout) { - userStartTime = kwsysProcessTimeGetCurrent(); - } - - /* Calculate the time at which a timeout will expire, and whether it - is the user or process timeout. */ - wd.User = kwsysProcessGetTimeoutTime(cp, userTimeout, &wd.TimeoutTime); - - /* Data can only be available when pipes are open. If the process - is not running, cp->PipesLeft will be 0. */ - while (cp->PipesLeft > 0 && - !kwsysProcessWaitForPipe(cp, data, length, &wd)) { - } - - /* Update the user timeout. */ - if (userTimeout) { - kwsysProcessTime userEndTime = kwsysProcessTimeGetCurrent(); - kwsysProcessTime difference = - kwsysProcessTimeSubtract(userEndTime, userStartTime); - double d = kwsysProcessTimeToDouble(difference); - *userTimeout -= d; - if (*userTimeout < 0) { - *userTimeout = 0; - } - } - - /* Check what happened. */ - if (wd.PipeId) { - /* Data are ready on a pipe. */ - return wd.PipeId; - } else if (wd.Expired) { - /* A timeout has expired. */ - if (wd.User) { - /* The user timeout has expired. It has no time left. */ - return kwsysProcess_Pipe_Timeout; - } else { - /* The process timeout has expired. Kill the children now. */ - kwsysProcess_Kill(cp); - cp->Killed = 0; - cp->TimeoutExpired = 1; - return kwsysProcess_Pipe_None; - } - } else { - /* No pipes are left open. */ - return kwsysProcess_Pipe_None; - } -} - -static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length, - kwsysProcessWaitData* wd) -{ - int i; - kwsysProcessTimeNative timeoutLength; - -#if KWSYSPE_USE_SELECT - int numReady = 0; - int max = -1; - kwsysProcessTimeNative* timeout = 0; - - /* Check for any open pipes with data reported ready by the last - call to select. According to "man select_tut" we must deal - with all descriptors reported by a call to select before - passing them to another select call. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - if (cp->PipeReadEnds[i] >= 0 && - FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet)) { - kwsysProcess_ssize_t n; - - /* We are handling this pipe now. Remove it from the set. */ - FD_CLR(cp->PipeReadEnds[i], &cp->PipeSet); - - /* The pipe is ready to read without blocking. Keep trying to - read until the operation is not interrupted. */ - while (((n = read(cp->PipeReadEnds[i], cp->PipeBuffer, - KWSYSPE_PIPE_BUFFER_SIZE)) < 0) && - (errno == EINTR)) - ; - if (n > 0) { - /* We have data on this pipe. */ - if (i == KWSYSPE_PIPE_SIGNAL) { - /* A child process has terminated. */ - kwsysProcessDestroy(cp); - } else if (data && length) { - /* Report this data. */ - *data = cp->PipeBuffer; - *length = (int)(n); - switch (i) { - case KWSYSPE_PIPE_STDOUT: - wd->PipeId = kwsysProcess_Pipe_STDOUT; - break; - case KWSYSPE_PIPE_STDERR: - wd->PipeId = kwsysProcess_Pipe_STDERR; - break; - } - return 1; - } - } else if (n < 0 && errno == EAGAIN) { - /* No data are really ready. The select call lied. See the - "man select" page on Linux for cases when this occurs. */ - } else { - /* We are done reading from this pipe. */ - kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]); - --cp->PipesLeft; - } - } - } - - /* If we have data, break early. */ - if (wd->PipeId) { - return 1; - } - - /* Make sure the set is empty (it should always be empty here - anyway). */ - FD_ZERO(&cp->PipeSet); - - /* Setup a timeout if required. */ - if (wd->TimeoutTime.tv_sec < 0) { - timeout = 0; - } else { - timeout = &timeoutLength; - } - if (kwsysProcessGetTimeoutLeft( - &wd->TimeoutTime, wd->User ? wd->UserTimeout : 0, &timeoutLength, 0)) { - /* Timeout has already expired. */ - wd->Expired = 1; - return 1; - } - - /* Add the pipe reading ends that are still open. */ - max = -1; - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - if (cp->PipeReadEnds[i] >= 0) { - FD_SET(cp->PipeReadEnds[i], &cp->PipeSet); - if (cp->PipeReadEnds[i] > max) { - max = cp->PipeReadEnds[i]; - } - } - } - - /* Make sure we have a non-empty set. */ - if (max < 0) { - /* All pipes have closed. Child has terminated. */ - return 1; - } - - /* Run select to block until data are available. Repeat call - until it is not interrupted. */ - while (((numReady = select(max + 1, &cp->PipeSet, 0, 0, timeout)) < 0) && - (errno == EINTR)) - ; - - /* Check result of select. */ - if (numReady == 0) { - /* Select's timeout expired. */ - wd->Expired = 1; - return 1; - } else if (numReady < 0) { - /* Select returned an error. Leave the error description in the - pipe buffer. */ - strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE); - - /* Kill the children now. */ - kwsysProcess_Kill(cp); - cp->Killed = 0; - cp->SelectError = 1; - } - - return 0; -#else - /* Poll pipes for data since we do not have select. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - if (cp->PipeReadEnds[i] >= 0) { - const int fd = cp->PipeReadEnds[i]; - int n = read(fd, cp->PipeBuffer, KWSYSPE_PIPE_BUFFER_SIZE); - if (n > 0) { - /* We have data on this pipe. */ - if (i == KWSYSPE_PIPE_SIGNAL) { - /* A child process has terminated. */ - kwsysProcessDestroy(cp); - } else if (data && length) { - /* Report this data. */ - *data = cp->PipeBuffer; - *length = n; - switch (i) { - case KWSYSPE_PIPE_STDOUT: - wd->PipeId = kwsysProcess_Pipe_STDOUT; - break; - case KWSYSPE_PIPE_STDERR: - wd->PipeId = kwsysProcess_Pipe_STDERR; - break; - }; - } - return 1; - } else if (n == 0) /* EOF */ - { -/* We are done reading from this pipe. */ -# if defined(__VMS) - if (!cp->CommandsLeft) -# endif - { - kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]); - --cp->PipesLeft; - } - } else if (n < 0) /* error */ - { -# if defined(__VMS) - if (!cp->CommandsLeft) { - kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]); - --cp->PipesLeft; - } else -# endif - if ((errno != EINTR) && (errno != EAGAIN)) { - strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE); - /* Kill the children now. */ - kwsysProcess_Kill(cp); - cp->Killed = 0; - cp->SelectError = 1; - return 1; - } - } - } - } - - /* If we have data, break early. */ - if (wd->PipeId) { - return 1; - } - - if (kwsysProcessGetTimeoutLeft( - &wd->TimeoutTime, wd->User ? wd->UserTimeout : 0, &timeoutLength, 1)) { - /* Timeout has already expired. */ - wd->Expired = 1; - return 1; - } - - /* Sleep a little, try again. */ - { - unsigned int msec = - ((timeoutLength.tv_sec * 1000) + (timeoutLength.tv_usec / 1000)); - if (msec > 100000) { - msec = 100000; /* do not sleep more than 100 milliseconds at a time */ - } - kwsysProcess_usleep(msec); - } - return 0; -#endif -} - -int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout) -{ - int prPipe = 0; - - /* Make sure we are executing a process. */ - if (!cp || cp->State != kwsysProcess_State_Executing) { - return 1; - } - - /* Wait for all the pipes to close. Ignore all data. */ - while ((prPipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0) { - if (prPipe == kwsysProcess_Pipe_Timeout) { - return 0; - } - } - - /* Check if there was an error in one of the waitpid calls. */ - if (cp->State == kwsysProcess_State_Error) { - /* The error message is already in its buffer. Tell - kwsysProcessCleanup to not create it. */ - kwsysProcessCleanup(cp, 0); - return 1; - } - - /* Check whether the child reported an error invoking the process. */ - if (cp->SelectError) { - /* The error message is already in its buffer. Tell - kwsysProcessCleanup to not create it. */ - kwsysProcessCleanup(cp, 0); - cp->State = kwsysProcess_State_Error; - return 1; - } - /* Determine the outcome. */ - if (cp->Killed) { - /* We killed the child. */ - cp->State = kwsysProcess_State_Killed; - } else if (cp->TimeoutExpired) { - /* The timeout expired. */ - cp->State = kwsysProcess_State_Expired; - } else { - /* The children exited. Report the outcome of the child processes. */ - for (prPipe = 0; prPipe < cp->NumberOfCommands; ++prPipe) { - cp->ProcessResults[prPipe].ExitCode = cp->CommandExitCodes[prPipe]; - if (WIFEXITED(cp->ProcessResults[prPipe].ExitCode)) { - /* The child exited normally. */ - cp->ProcessResults[prPipe].State = kwsysProcess_StateByIndex_Exited; - cp->ProcessResults[prPipe].ExitException = kwsysProcess_Exception_None; - cp->ProcessResults[prPipe].ExitValue = - (int)WEXITSTATUS(cp->ProcessResults[prPipe].ExitCode); - } else if (WIFSIGNALED(cp->ProcessResults[prPipe].ExitCode)) { - /* The child received an unhandled signal. */ - cp->ProcessResults[prPipe].State = kwsysProcess_State_Exception; - kwsysProcessSetExitExceptionByIndex( - cp, (int)WTERMSIG(cp->ProcessResults[prPipe].ExitCode), prPipe); - } else { - /* Error getting the child return code. */ - strcpy(cp->ProcessResults[prPipe].ExitExceptionString, - "Error getting child return code."); - cp->ProcessResults[prPipe].State = kwsysProcess_StateByIndex_Error; - } - } - /* support legacy state status value */ - cp->State = cp->ProcessResults[cp->NumberOfCommands - 1].State; - } - /* Normal cleanup. */ - kwsysProcessCleanup(cp, 0); - return 1; -} - -void kwsysProcess_Interrupt(kwsysProcess* cp) -{ - int i; - /* Make sure we are executing a process. */ - if (!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired || - cp->Killed) { - return; - } - - /* Interrupt the children. */ - if (cp->CreateProcessGroup) { - if (cp->ForkPIDs) { - for (i = 0; i < cp->NumberOfCommands; ++i) { - /* Make sure the PID is still valid. */ - if (cp->ForkPIDs[i]) { - /* The user created a process group for this process. The group ID - is the process ID for the original process in the group. */ - kill(-cp->ForkPIDs[i], SIGINT); - } - } - } - } else { - /* No process group was created. Kill our own process group. - NOTE: While one could argue that we could call kill(cp->ForkPIDs[i], - SIGINT) as a way to still interrupt the process even though it's not in - a special group, this is not an option on Windows. Therefore, we kill - the current process group for consistency with Windows. */ - kill(0, SIGINT); - } -} - -void kwsysProcess_Kill(kwsysProcess* cp) -{ - int i; - - /* Make sure we are executing a process. */ - if (!cp || cp->State != kwsysProcess_State_Executing) { - return; - } - - /* First close the child exit report pipe write end to avoid causing a - SIGPIPE when the child terminates and our signal handler tries to - report it after we have already closed the read end. */ - kwsysProcessCleanupDescriptor(&cp->SignalPipe); - -#if !defined(__APPLE__) - /* Close all the pipe read ends. Do this before killing the - children because Cygwin has problems killing processes that are - blocking to wait for writing to their output pipes. */ - kwsysProcessClosePipes(cp); -#endif - - /* Kill the children. */ - cp->Killed = 1; - for (i = 0; i < cp->NumberOfCommands; ++i) { - int status; - if (cp->ForkPIDs[i]) { - /* Kill the child. */ - kwsysProcessKill(cp->ForkPIDs[i]); - - /* Reap the child. Keep trying until the call is not - interrupted. */ - while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR)) - ; - } - } - -#if defined(__APPLE__) - /* Close all the pipe read ends. Do this after killing the - children because OS X has problems closing pipe read ends whose - pipes are full and still have an open write end. */ - kwsysProcessClosePipes(cp); -#endif - - cp->CommandsLeft = 0; -} - -/* Call the free() function with a pointer to volatile without causing - compiler warnings. */ -static void kwsysProcessVolatileFree(volatile void* p) -{ -/* clang has made it impossible to free memory that points to volatile - without first using special pragmas to disable a warning... */ -#if defined(__clang__) && !defined(__INTEL_COMPILER) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wcast-qual" -#endif - free((void*)p); /* The cast will silence most compilers, but not clang. */ -#if defined(__clang__) && !defined(__INTEL_COMPILER) -# pragma clang diagnostic pop -#endif -} - -/* Initialize a process control structure for kwsysProcess_Execute. */ -static int kwsysProcessInitialize(kwsysProcess* cp) -{ - int i; - volatile pid_t* oldForkPIDs; - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - cp->PipeReadEnds[i] = -1; - } - for (i = 0; i < 3; ++i) { - cp->PipeChildStd[i] = -1; - } - cp->SignalPipe = -1; - cp->SelectError = 0; - cp->StartTime.tv_sec = -1; - cp->StartTime.tv_usec = -1; - cp->TimeoutTime.tv_sec = -1; - cp->TimeoutTime.tv_usec = -1; - cp->TimeoutExpired = 0; - cp->PipesLeft = 0; - cp->CommandsLeft = 0; -#if KWSYSPE_USE_SELECT - FD_ZERO(&cp->PipeSet); -#endif - cp->State = kwsysProcess_State_Starting; - cp->Killed = 0; - cp->ErrorMessage[0] = 0; - - oldForkPIDs = cp->ForkPIDs; - cp->ForkPIDs = (volatile pid_t*)malloc(sizeof(volatile pid_t) * - (size_t)(cp->NumberOfCommands)); - kwsysProcessVolatileFree(oldForkPIDs); - if (!cp->ForkPIDs) { - return 0; - } - for (i = 0; i < cp->NumberOfCommands; ++i) { - cp->ForkPIDs[i] = 0; /* can't use memset due to volatile */ - } - - free(cp->CommandExitCodes); - cp->CommandExitCodes = - (int*)malloc(sizeof(int) * (size_t)(cp->NumberOfCommands)); - if (!cp->CommandExitCodes) { - return 0; - } - memset(cp->CommandExitCodes, 0, - sizeof(int) * (size_t)(cp->NumberOfCommands)); - - /* Allocate process result information for each process. */ - free(cp->ProcessResults); - cp->ProcessResults = (kwsysProcessResults*)malloc( - sizeof(kwsysProcessResults) * (size_t)(cp->NumberOfCommands)); - if (!cp->ProcessResults) { - return 0; - } - memset(cp->ProcessResults, 0, - sizeof(kwsysProcessResults) * (size_t)(cp->NumberOfCommands)); - for (i = 0; i < cp->NumberOfCommands; i++) { - cp->ProcessResults[i].ExitException = kwsysProcess_Exception_None; - cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Starting; - cp->ProcessResults[i].ExitCode = 1; - cp->ProcessResults[i].ExitValue = 1; - strcpy(cp->ProcessResults[i].ExitExceptionString, "No exception"); - } - - /* Allocate memory to save the real working directory. */ - if (cp->WorkingDirectory) { -#if defined(MAXPATHLEN) - cp->RealWorkingDirectoryLength = MAXPATHLEN; -#elif defined(PATH_MAX) - cp->RealWorkingDirectoryLength = PATH_MAX; -#else - cp->RealWorkingDirectoryLength = 4096; -#endif - cp->RealWorkingDirectory = - (char*)malloc((size_t)(cp->RealWorkingDirectoryLength)); - if (!cp->RealWorkingDirectory) { - return 0; - } - } - - return 1; -} - -/* Free all resources used by the given kwsysProcess instance that were - allocated by kwsysProcess_Execute. */ -static void kwsysProcessCleanup(kwsysProcess* cp, int error) -{ - int i; - - if (error) { - /* We are cleaning up due to an error. Report the error message - if one has not been provided already. */ - if (cp->ErrorMessage[0] == 0) { - strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE); - } - - /* Set the error state. */ - cp->State = kwsysProcess_State_Error; - - /* Kill any children already started. */ - if (cp->ForkPIDs) { - int status; - for (i = 0; i < cp->NumberOfCommands; ++i) { - if (cp->ForkPIDs[i]) { - /* Kill the child. */ - kwsysProcessKill(cp->ForkPIDs[i]); - - /* Reap the child. Keep trying until the call is not - interrupted. */ - while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && - (errno == EINTR)) - ; - } - } - } - - /* Restore the working directory. */ - if (cp->RealWorkingDirectory) { - while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR)) - ; - } - } - - /* If not creating a detached child, remove this object from the - global set of process objects that wish to be notified when a - child exits. */ - if (!cp->OptionDetach) { - kwsysProcessesRemove(cp); - } - - /* Free memory. */ - if (cp->ForkPIDs) { - kwsysProcessVolatileFree(cp->ForkPIDs); - cp->ForkPIDs = 0; - } - if (cp->RealWorkingDirectory) { - free(cp->RealWorkingDirectory); - cp->RealWorkingDirectory = 0; - } - - /* Close pipe handles. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]); - } - for (i = 0; i < 3; ++i) { - kwsysProcessCleanupDescriptor(&cp->PipeChildStd[i]); - } -} - -/* Close the given file descriptor if it is open. Reset its value to -1. */ -static void kwsysProcessCleanupDescriptor(int* pfd) -{ - if (pfd && *pfd > 2) { - /* Keep trying to close until it is not interrupted by a - * signal. */ - while ((close(*pfd) < 0) && (errno == EINTR)) - ; - *pfd = -1; - } -} - -static void kwsysProcessClosePipes(kwsysProcess* cp) -{ - int i; - - /* Close any pipes that are still open. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - if (cp->PipeReadEnds[i] >= 0) { -#if KWSYSPE_USE_SELECT - /* If the pipe was reported by the last call to select, we must - read from it. This is needed to satisfy the suggestions from - "man select_tut" and is not needed for the polling - implementation. Ignore the data. */ - if (FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet)) { - /* We are handling this pipe now. Remove it from the set. */ - FD_CLR(cp->PipeReadEnds[i], &cp->PipeSet); - - /* The pipe is ready to read without blocking. Keep trying to - read until the operation is not interrupted. */ - while ((read(cp->PipeReadEnds[i], cp->PipeBuffer, - KWSYSPE_PIPE_BUFFER_SIZE) < 0) && - (errno == EINTR)) - ; - } -#endif - - /* We are done reading from this pipe. */ - kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]); - --cp->PipesLeft; - } - } -} - -static int kwsysProcessSetNonBlocking(int fd) -{ - int flags = fcntl(fd, F_GETFL); - if (flags >= 0) { - flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK); - } - return flags >= 0; -} - -#if defined(__VMS) -int decc$set_child_standard_streams(int fd1, int fd2, int fd3); -#endif - -static int kwsysProcessCreate(kwsysProcess* cp, int prIndex, - kwsysProcessCreateInformation* si) -{ - sigset_t mask, old_mask; - int pgidPipe[2]; - char tmp; - ssize_t readRes; - - /* Create the error reporting pipe. */ - if (pipe(si->ErrorPipe) < 0) { - return 0; - } - - /* Create a pipe for detecting that the child process has created a process - group and session. */ - if (pipe(pgidPipe) < 0) { - kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]); - kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]); - return 0; - } - - /* Set close-on-exec flag on the pipe's write end. */ - if (fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0 || - fcntl(pgidPipe[1], F_SETFD, FD_CLOEXEC) < 0) { - kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]); - kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]); - kwsysProcessCleanupDescriptor(&pgidPipe[0]); - kwsysProcessCleanupDescriptor(&pgidPipe[1]); - return 0; - } - - /* Block SIGINT / SIGTERM while we start. The purpose is so that our signal - handler doesn't get called from the child process after the fork and - before the exec, and subsequently start kill()'ing PIDs from ForkPIDs. */ - sigemptyset(&mask); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGTERM); - if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0) { - kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]); - kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]); - kwsysProcessCleanupDescriptor(&pgidPipe[0]); - kwsysProcessCleanupDescriptor(&pgidPipe[1]); - return 0; - } - -/* Fork off a child process. */ -#if defined(__VMS) - /* VMS needs vfork and execvp to be in the same function because - they use setjmp/longjmp to run the child startup code in the - parent! TODO: OptionDetach. Also - TODO: CreateProcessGroup. */ - cp->ForkPIDs[prIndex] = vfork(); -#else - cp->ForkPIDs[prIndex] = kwsysProcessFork(cp, si); -#endif - if (cp->ForkPIDs[prIndex] < 0) { - sigprocmask(SIG_SETMASK, &old_mask, 0); - kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]); - kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]); - kwsysProcessCleanupDescriptor(&pgidPipe[0]); - kwsysProcessCleanupDescriptor(&pgidPipe[1]); - return 0; - } - - if (cp->ForkPIDs[prIndex] == 0) { -#if defined(__VMS) - /* Specify standard pipes for child process. */ - decc$set_child_standard_streams(si->StdIn, si->StdOut, si->StdErr); -#else - /* Close the read end of the error reporting / process group - setup pipe. */ - close(si->ErrorPipe[0]); - close(pgidPipe[0]); - - /* Setup the stdin, stdout, and stderr pipes. */ - if (si->StdIn > 0) { - dup2(si->StdIn, 0); - } else if (si->StdIn < 0) { - close(0); - } - if (si->StdOut != 1) { - dup2(si->StdOut, 1); - } - if (si->StdErr != 2) { - dup2(si->StdErr, 2); - } - - /* Clear the close-on-exec flag for stdin, stdout, and stderr. - All other pipe handles will be closed when exec succeeds. */ - fcntl(0, F_SETFD, 0); - fcntl(1, F_SETFD, 0); - fcntl(2, F_SETFD, 0); - - /* Restore all default signal handlers. */ - kwsysProcessRestoreDefaultSignalHandlers(); - - /* Now that we have restored default signal handling and created the - process group, restore mask. */ - sigprocmask(SIG_SETMASK, &old_mask, 0); - - /* Create new process group. We use setsid instead of setpgid to avoid - the child getting hung up on signals like SIGTTOU. (In the real world, - this has been observed where "git svn" ends up calling the "resize" - program which opens /dev/tty. */ - if (cp->CreateProcessGroup && setsid() < 0) { - kwsysProcessChildErrorExit(si->ErrorPipe[1]); - } -#endif - - /* Execute the real process. If successful, this does not return. */ - execvp(cp->Commands[prIndex][0], cp->Commands[prIndex]); - /* TODO: What does VMS do if the child fails to start? */ - /* TODO: On VMS, how do we put the process in a new group? */ - - /* Failure. Report error to parent and terminate. */ - kwsysProcessChildErrorExit(si->ErrorPipe[1]); - } - -#if defined(__VMS) - /* Restore the standard pipes of this process. */ - decc$set_child_standard_streams(0, 1, 2); -#endif - - /* We are done with the error reporting pipe and process group setup pipe - write end. */ - kwsysProcessCleanupDescriptor(&si->ErrorPipe[1]); - kwsysProcessCleanupDescriptor(&pgidPipe[1]); - - /* Make sure the child is in the process group before we proceed. This - avoids race conditions with calls to the kill function that we make for - signalling process groups. */ - while ((readRes = read(pgidPipe[0], &tmp, 1)) > 0) - ; - if (readRes < 0) { - sigprocmask(SIG_SETMASK, &old_mask, 0); - kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]); - kwsysProcessCleanupDescriptor(&pgidPipe[0]); - return 0; - } - kwsysProcessCleanupDescriptor(&pgidPipe[0]); - - /* Unmask signals. */ - if (sigprocmask(SIG_SETMASK, &old_mask, 0) < 0) { - kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]); - return 0; - } - - /* A child has been created. */ - ++cp->CommandsLeft; - - /* Block until the child's exec call succeeds and closes the error - pipe or writes data to the pipe to report an error. */ - { - kwsysProcess_ssize_t total = 0; - kwsysProcess_ssize_t n = 1; - /* Read the entire error message up to the length of our buffer. */ - while (total < KWSYSPE_PIPE_BUFFER_SIZE && n > 0) { - /* Keep trying to read until the operation is not interrupted. */ - while (((n = read(si->ErrorPipe[0], cp->ErrorMessage + total, - (size_t)(KWSYSPE_PIPE_BUFFER_SIZE - total))) < 0) && - (errno == EINTR)) - ; - if (n > 0) { - total += n; - } - } - - /* We are done with the error reporting pipe read end. */ - kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]); - - if (total > 0) { - /* The child failed to execute the process. */ - return 0; - } - } - - return 1; -} - -static void kwsysProcessDestroy(kwsysProcess* cp) -{ - /* A child process has terminated. Reap it if it is one handled by - this object. */ - int i; - /* Temporarily disable signals that access ForkPIDs. We don't want them to - read a reaped PID, and writes to ForkPIDs are not atomic. */ - sigset_t mask, old_mask; - sigemptyset(&mask); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGTERM); - if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0) { - return; - } - - for (i = 0; i < cp->NumberOfCommands; ++i) { - if (cp->ForkPIDs[i]) { - int result; - while (((result = waitpid(cp->ForkPIDs[i], &cp->CommandExitCodes[i], - WNOHANG)) < 0) && - (errno == EINTR)) - ; - if (result > 0) { - /* This child has terminated. */ - cp->ForkPIDs[i] = 0; - if (--cp->CommandsLeft == 0) { - /* All children have terminated. Close the signal pipe - write end so that no more notifications are sent to this - object. */ - kwsysProcessCleanupDescriptor(&cp->SignalPipe); - - /* TODO: Once the children have terminated, switch - WaitForData to use a non-blocking read to get the - rest of the data from the pipe. This is needed when - grandchildren keep the output pipes open. */ - } - } else if (result < 0 && cp->State != kwsysProcess_State_Error) { - /* Unexpected error. Report the first time this happens. */ - strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE); - cp->State = kwsysProcess_State_Error; - } - } - } - - /* Re-enable signals. */ - sigprocmask(SIG_SETMASK, &old_mask, 0); -} - -static int kwsysProcessSetupOutputPipeFile(int* p, const char* name) -{ - int fout; - if (!name) { - return 1; - } - - /* Close the existing descriptor. */ - kwsysProcessCleanupDescriptor(p); - - /* Open a file for the pipe to write. */ - if ((fout = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { - return 0; - } - - /* Set close-on-exec flag on the pipe's end. */ - if (fcntl(fout, F_SETFD, FD_CLOEXEC) < 0) { - close(fout); - return 0; - } - - /* Assign the replacement descriptor. */ - *p = fout; - return 1; -} - -static int kwsysProcessSetupOutputPipeNative(int* p, int des[2]) -{ - /* Close the existing descriptor. */ - kwsysProcessCleanupDescriptor(p); - - /* Set close-on-exec flag on the pipe's ends. The proper end will - be dup2-ed into the standard descriptor number after fork but - before exec. */ - if ((fcntl(des[0], F_SETFD, FD_CLOEXEC) < 0) || - (fcntl(des[1], F_SETFD, FD_CLOEXEC) < 0)) { - return 0; - } - - /* Assign the replacement descriptor. */ - *p = des[1]; - return 1; -} - -/* Get the time at which either the process or user timeout will - expire. Returns 1 if the user timeout is first, and 0 otherwise. */ -static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, - kwsysProcessTime* timeoutTime) -{ - /* The first time this is called, we need to calculate the time at - which the child will timeout. */ - if (cp->Timeout > 0 && cp->TimeoutTime.tv_sec < 0) { - kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout); - cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length); - } - - /* Start with process timeout. */ - *timeoutTime = cp->TimeoutTime; - - /* Check if the user timeout is earlier. */ - if (userTimeout) { - kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent(); - kwsysProcessTime userTimeoutLength = - kwsysProcessTimeFromDouble(*userTimeout); - kwsysProcessTime userTimeoutTime = - kwsysProcessTimeAdd(currentTime, userTimeoutLength); - if (timeoutTime->tv_sec < 0 || - kwsysProcessTimeLess(userTimeoutTime, *timeoutTime)) { - *timeoutTime = userTimeoutTime; - return 1; - } - } - return 0; -} - -/* Get the length of time before the given timeout time arrives. - Returns 1 if the time has already arrived, and 0 otherwise. */ -static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime, - double* userTimeout, - kwsysProcessTimeNative* timeoutLength, - int zeroIsExpired) -{ - if (timeoutTime->tv_sec < 0) { - /* No timeout time has been requested. */ - return 0; - } else { - /* Calculate the remaining time. */ - kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent(); - kwsysProcessTime timeLeft = - kwsysProcessTimeSubtract(*timeoutTime, currentTime); - if (timeLeft.tv_sec < 0 && userTimeout && *userTimeout <= 0) { - /* Caller has explicitly requested a zero timeout. */ - timeLeft.tv_sec = 0; - timeLeft.tv_usec = 0; - } - - if (timeLeft.tv_sec < 0 || - (timeLeft.tv_sec == 0 && timeLeft.tv_usec == 0 && zeroIsExpired)) { - /* Timeout has already expired. */ - return 1; - } else { - /* There is some time left. */ - timeoutLength->tv_sec = timeLeft.tv_sec; - timeoutLength->tv_usec = timeLeft.tv_usec; - return 0; - } - } -} - -static kwsysProcessTime kwsysProcessTimeGetCurrent(void) -{ - kwsysProcessTime current; - kwsysProcessTimeNative current_native; -#if KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC - struct timespec current_timespec; - clock_gettime(CLOCK_MONOTONIC, ¤t_timespec); - - current_native.tv_sec = current_timespec.tv_sec; - current_native.tv_usec = current_timespec.tv_nsec / 1000; -#else - gettimeofday(¤t_native, 0); -#endif - current.tv_sec = (long)current_native.tv_sec; - current.tv_usec = (long)current_native.tv_usec; - return current; -} - -static double kwsysProcessTimeToDouble(kwsysProcessTime t) -{ - return (double)t.tv_sec + (double)(t.tv_usec) * 0.000001; -} - -static kwsysProcessTime kwsysProcessTimeFromDouble(double d) -{ - kwsysProcessTime t; - t.tv_sec = (long)d; - t.tv_usec = (long)((d - (double)(t.tv_sec)) * 1000000); - return t; -} - -static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2) -{ - return ((in1.tv_sec < in2.tv_sec) || - ((in1.tv_sec == in2.tv_sec) && (in1.tv_usec < in2.tv_usec))); -} - -static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, - kwsysProcessTime in2) -{ - kwsysProcessTime out; - out.tv_sec = in1.tv_sec + in2.tv_sec; - out.tv_usec = in1.tv_usec + in2.tv_usec; - if (out.tv_usec >= 1000000) { - out.tv_usec -= 1000000; - out.tv_sec += 1; - } - return out; -} - -static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, - kwsysProcessTime in2) -{ - kwsysProcessTime out; - out.tv_sec = in1.tv_sec - in2.tv_sec; - out.tv_usec = in1.tv_usec - in2.tv_usec; - if (out.tv_usec < 0) { - out.tv_usec += 1000000; - out.tv_sec -= 1; - } - return out; -} - -#define KWSYSPE_CASE(type, str) \ - cp->ProcessResults[idx].ExitException = kwsysProcess_Exception_##type; \ - strcpy(cp->ProcessResults[idx].ExitExceptionString, str) -static void kwsysProcessSetExitExceptionByIndex(kwsysProcess* cp, int sig, - int idx) -{ - switch (sig) { -#ifdef SIGSEGV - case SIGSEGV: - KWSYSPE_CASE(Fault, "Segmentation fault"); - break; -#endif -#ifdef SIGBUS -# if !defined(SIGSEGV) || SIGBUS != SIGSEGV - case SIGBUS: - KWSYSPE_CASE(Fault, "Bus error"); - break; -# endif -#endif -#ifdef SIGFPE - case SIGFPE: - KWSYSPE_CASE(Numerical, "Floating-point exception"); - break; -#endif -#ifdef SIGILL - case SIGILL: - KWSYSPE_CASE(Illegal, "Illegal instruction"); - break; -#endif -#ifdef SIGINT - case SIGINT: - KWSYSPE_CASE(Interrupt, "User interrupt"); - break; -#endif -#ifdef SIGABRT - case SIGABRT: - KWSYSPE_CASE(Other, "Child aborted"); - break; -#endif -#ifdef SIGKILL - case SIGKILL: - KWSYSPE_CASE(Other, "Child killed"); - break; -#endif -#ifdef SIGTERM - case SIGTERM: - KWSYSPE_CASE(Other, "Child terminated"); - break; -#endif -#ifdef SIGHUP - case SIGHUP: - KWSYSPE_CASE(Other, "SIGHUP"); - break; -#endif -#ifdef SIGQUIT - case SIGQUIT: - KWSYSPE_CASE(Other, "SIGQUIT"); - break; -#endif -#ifdef SIGTRAP - case SIGTRAP: - KWSYSPE_CASE(Other, "SIGTRAP"); - break; -#endif -#ifdef SIGIOT -# if !defined(SIGABRT) || SIGIOT != SIGABRT - case SIGIOT: - KWSYSPE_CASE(Other, "SIGIOT"); - break; -# endif -#endif -#ifdef SIGUSR1 - case SIGUSR1: - KWSYSPE_CASE(Other, "SIGUSR1"); - break; -#endif -#ifdef SIGUSR2 - case SIGUSR2: - KWSYSPE_CASE(Other, "SIGUSR2"); - break; -#endif -#ifdef SIGPIPE - case SIGPIPE: - KWSYSPE_CASE(Other, "SIGPIPE"); - break; -#endif -#ifdef SIGALRM - case SIGALRM: - KWSYSPE_CASE(Other, "SIGALRM"); - break; -#endif -#ifdef SIGSTKFLT - case SIGSTKFLT: - KWSYSPE_CASE(Other, "SIGSTKFLT"); - break; -#endif -#ifdef SIGCHLD - case SIGCHLD: - KWSYSPE_CASE(Other, "SIGCHLD"); - break; -#elif defined(SIGCLD) - case SIGCLD: - KWSYSPE_CASE(Other, "SIGCLD"); - break; -#endif -#ifdef SIGCONT - case SIGCONT: - KWSYSPE_CASE(Other, "SIGCONT"); - break; -#endif -#ifdef SIGSTOP - case SIGSTOP: - KWSYSPE_CASE(Other, "SIGSTOP"); - break; -#endif -#ifdef SIGTSTP - case SIGTSTP: - KWSYSPE_CASE(Other, "SIGTSTP"); - break; -#endif -#ifdef SIGTTIN - case SIGTTIN: - KWSYSPE_CASE(Other, "SIGTTIN"); - break; -#endif -#ifdef SIGTTOU - case SIGTTOU: - KWSYSPE_CASE(Other, "SIGTTOU"); - break; -#endif -#ifdef SIGURG - case SIGURG: - KWSYSPE_CASE(Other, "SIGURG"); - break; -#endif -#ifdef SIGXCPU - case SIGXCPU: - KWSYSPE_CASE(Other, "SIGXCPU"); - break; -#endif -#ifdef SIGXFSZ - case SIGXFSZ: - KWSYSPE_CASE(Other, "SIGXFSZ"); - break; -#endif -#ifdef SIGVTALRM - case SIGVTALRM: - KWSYSPE_CASE(Other, "SIGVTALRM"); - break; -#endif -#ifdef SIGPROF - case SIGPROF: - KWSYSPE_CASE(Other, "SIGPROF"); - break; -#endif -#ifdef SIGWINCH - case SIGWINCH: - KWSYSPE_CASE(Other, "SIGWINCH"); - break; -#endif -#ifdef SIGPOLL - case SIGPOLL: - KWSYSPE_CASE(Other, "SIGPOLL"); - break; -#endif -#ifdef SIGIO -# if !defined(SIGPOLL) || SIGIO != SIGPOLL - case SIGIO: - KWSYSPE_CASE(Other, "SIGIO"); - break; -# endif -#endif -#ifdef SIGPWR - case SIGPWR: - KWSYSPE_CASE(Other, "SIGPWR"); - break; -#endif -#ifdef SIGSYS - case SIGSYS: - KWSYSPE_CASE(Other, "SIGSYS"); - break; -#endif -#ifdef SIGUNUSED -# if !defined(SIGSYS) || SIGUNUSED != SIGSYS - case SIGUNUSED: - KWSYSPE_CASE(Other, "SIGUNUSED"); - break; -# endif -#endif - default: - cp->ProcessResults[idx].ExitException = kwsysProcess_Exception_Other; - sprintf(cp->ProcessResults[idx].ExitExceptionString, "Signal %d", sig); - break; - } -} -#undef KWSYSPE_CASE - -/* When the child process encounters an error before its program is - invoked, this is called to report the error to the parent and - exit. */ -static void kwsysProcessChildErrorExit(int errorPipe) -{ - /* Construct the error message. */ - char buffer[KWSYSPE_PIPE_BUFFER_SIZE]; - kwsysProcess_ssize_t result; - strncpy(buffer, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE); - buffer[KWSYSPE_PIPE_BUFFER_SIZE - 1] = '\0'; - - /* Report the error to the parent through the special pipe. */ - result = write(errorPipe, buffer, strlen(buffer)); - (void)result; - - /* Terminate without cleanup. */ - _exit(1); -} - -/* Restores all signal handlers to their default values. */ -static void kwsysProcessRestoreDefaultSignalHandlers(void) -{ - struct sigaction act; - memset(&act, 0, sizeof(struct sigaction)); - act.sa_handler = SIG_DFL; -#ifdef SIGHUP - sigaction(SIGHUP, &act, 0); -#endif -#ifdef SIGINT - sigaction(SIGINT, &act, 0); -#endif -#ifdef SIGQUIT - sigaction(SIGQUIT, &act, 0); -#endif -#ifdef SIGILL - sigaction(SIGILL, &act, 0); -#endif -#ifdef SIGTRAP - sigaction(SIGTRAP, &act, 0); -#endif -#ifdef SIGABRT - sigaction(SIGABRT, &act, 0); -#endif -#ifdef SIGIOT - sigaction(SIGIOT, &act, 0); -#endif -#ifdef SIGBUS - sigaction(SIGBUS, &act, 0); -#endif -#ifdef SIGFPE - sigaction(SIGFPE, &act, 0); -#endif -#ifdef SIGUSR1 - sigaction(SIGUSR1, &act, 0); -#endif -#ifdef SIGSEGV - sigaction(SIGSEGV, &act, 0); -#endif -#ifdef SIGUSR2 - sigaction(SIGUSR2, &act, 0); -#endif -#ifdef SIGPIPE - sigaction(SIGPIPE, &act, 0); -#endif -#ifdef SIGALRM - sigaction(SIGALRM, &act, 0); -#endif -#ifdef SIGTERM - sigaction(SIGTERM, &act, 0); -#endif -#ifdef SIGSTKFLT - sigaction(SIGSTKFLT, &act, 0); -#endif -#ifdef SIGCLD - sigaction(SIGCLD, &act, 0); -#endif -#ifdef SIGCHLD - sigaction(SIGCHLD, &act, 0); -#endif -#ifdef SIGCONT - sigaction(SIGCONT, &act, 0); -#endif -#ifdef SIGTSTP - sigaction(SIGTSTP, &act, 0); -#endif -#ifdef SIGTTIN - sigaction(SIGTTIN, &act, 0); -#endif -#ifdef SIGTTOU - sigaction(SIGTTOU, &act, 0); -#endif -#ifdef SIGURG - sigaction(SIGURG, &act, 0); -#endif -#ifdef SIGXCPU - sigaction(SIGXCPU, &act, 0); -#endif -#ifdef SIGXFSZ - sigaction(SIGXFSZ, &act, 0); -#endif -#ifdef SIGVTALRM - sigaction(SIGVTALRM, &act, 0); -#endif -#ifdef SIGPROF - sigaction(SIGPROF, &act, 0); -#endif -#ifdef SIGWINCH - sigaction(SIGWINCH, &act, 0); -#endif -#ifdef SIGPOLL - sigaction(SIGPOLL, &act, 0); -#endif -#ifdef SIGIO - sigaction(SIGIO, &act, 0); -#endif -#ifdef SIGPWR - sigaction(SIGPWR, &act, 0); -#endif -#ifdef SIGSYS - sigaction(SIGSYS, &act, 0); -#endif -#ifdef SIGUNUSED - sigaction(SIGUNUSED, &act, 0); -#endif -} - -static void kwsysProcessExit(void) -{ - _exit(0); -} - -#if !defined(__VMS) -static pid_t kwsysProcessFork(kwsysProcess* cp, - kwsysProcessCreateInformation* si) -{ - /* Create a detached process if requested. */ - if (cp->OptionDetach) { - /* Create an intermediate process. */ - pid_t middle_pid = fork(); - if (middle_pid < 0) { - /* Fork failed. Return as if we were not detaching. */ - return middle_pid; - } else if (middle_pid == 0) { - /* This is the intermediate process. Create the real child. */ - pid_t child_pid = fork(); - if (child_pid == 0) { - /* This is the real child process. There is nothing to do here. */ - return 0; - } else { - /* Use the error pipe to report the pid to the real parent. */ - while ((write(si->ErrorPipe[1], &child_pid, sizeof(child_pid)) < 0) && - (errno == EINTR)) - ; - - /* Exit without cleanup. The parent holds all resources. */ - kwsysProcessExit(); - return 0; /* Never reached, but avoids SunCC warning. */ - } - } else { - /* This is the original parent process. The intermediate - process will use the error pipe to report the pid of the - detached child. */ - pid_t child_pid; - int status; - while ((read(si->ErrorPipe[0], &child_pid, sizeof(child_pid)) < 0) && - (errno == EINTR)) - ; - - /* Wait for the intermediate process to exit and clean it up. */ - while ((waitpid(middle_pid, &status, 0) < 0) && (errno == EINTR)) - ; - return child_pid; - } - } else { - /* Not creating a detached process. Use normal fork. */ - return fork(); - } -} -#endif - -/* We try to obtain process information by invoking the ps command. - Here we define the command to call on each platform and the - corresponding parsing format string. The parsing format should - have two integers to store: the pid and then the ppid. */ -#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ - defined(__OpenBSD__) || defined(__GLIBC__) || defined(__GNU__) -# define KWSYSPE_PS_COMMAND "ps axo pid,ppid" -# define KWSYSPE_PS_FORMAT "%d %d\n" -#elif defined(__sun) && (defined(__SVR4) || defined(__svr4__)) /* Solaris */ -# define KWSYSPE_PS_COMMAND "ps -e -o pid,ppid" -# define KWSYSPE_PS_FORMAT "%d %d\n" -#elif defined(__hpux) || defined(__sun__) || defined(__sgi) || \ - defined(_AIX) || defined(__sparc) -# define KWSYSPE_PS_COMMAND "ps -ef" -# define KWSYSPE_PS_FORMAT "%*s %d %d %*[^\n]\n" -#elif defined(__QNX__) -# define KWSYSPE_PS_COMMAND "ps -Af" -# define KWSYSPE_PS_FORMAT "%*d %d %d %*[^\n]\n" -#elif defined(__CYGWIN__) -# define KWSYSPE_PS_COMMAND "ps aux" -# define KWSYSPE_PS_FORMAT "%d %d %*[^\n]\n" -#endif - -void kwsysProcess_KillPID(unsigned long process_id) -{ - kwsysProcessKill((pid_t)process_id); -} - -static void kwsysProcessKill(pid_t process_id) -{ -#if defined(__linux__) || defined(__CYGWIN__) - DIR* procdir; -#endif - - /* Suspend the process to be sure it will not create more children. */ - kill(process_id, SIGSTOP); - -#if defined(__CYGWIN__) - /* Some Cygwin versions seem to need help here. Give up our time slice - so that the child can process SIGSTOP before we send SIGKILL. */ - usleep(1); -#endif - -/* Kill all children if we can find them. */ -#if defined(__linux__) || defined(__CYGWIN__) - /* First try using the /proc filesystem. */ - if ((procdir = opendir("/proc")) != NULL) { -# if defined(MAXPATHLEN) - char fname[MAXPATHLEN]; -# elif defined(PATH_MAX) - char fname[PATH_MAX]; -# else - char fname[4096]; -# endif - char buffer[KWSYSPE_PIPE_BUFFER_SIZE + 1]; - struct dirent* d; - - /* Each process has a directory in /proc whose name is the pid. - Within this directory is a file called stat that has the - following format: - - pid (command line) status ppid ... - - We want to get the ppid for all processes. Those that have - process_id as their parent should be recursively killed. */ - for (d = readdir(procdir); d; d = readdir(procdir)) { - int pid; - if (sscanf(d->d_name, "%d", &pid) == 1 && pid != 0) { - struct stat finfo; - sprintf(fname, "/proc/%d/stat", pid); - if (stat(fname, &finfo) == 0) { - FILE* f = fopen(fname, "r"); - if (f) { - size_t nread = fread(buffer, 1, KWSYSPE_PIPE_BUFFER_SIZE, f); - fclose(f); - buffer[nread] = '\0'; - if (nread > 0) { - const char* rparen = strrchr(buffer, ')'); - int ppid; - if (rparen && (sscanf(rparen + 1, "%*s %d", &ppid) == 1)) { - if (ppid == process_id) { - /* Recursively kill this child and its children. */ - kwsysProcessKill(pid); - } - } - } - } - } - } - } - closedir(procdir); - } else -#endif - { -#if defined(KWSYSPE_PS_COMMAND) - /* Try running "ps" to get the process information. */ - FILE* ps = popen(KWSYSPE_PS_COMMAND, "r"); - - /* Make sure the process started and provided a valid header. */ - if (ps && fscanf(ps, "%*[^\n]\n") != EOF) { - /* Look for processes whose parent is the process being killed. */ - int pid, ppid; - while (fscanf(ps, KWSYSPE_PS_FORMAT, &pid, &ppid) == 2) { - if (ppid == process_id) { - /* Recursively kill this child and its children. */ - kwsysProcessKill(pid); - } - } - } - - /* We are done with the ps process. */ - if (ps) { - pclose(ps); - } -#endif - } - - /* Kill the process. */ - kill(process_id, SIGKILL); - -#if defined(__APPLE__) - /* On OS X 10.3 the above SIGSTOP occasionally prevents the SIGKILL - from working. Just in case, we resume the child and kill it - again. There is a small race condition in this obscure case. If - the child manages to fork again between these two signals, we - will not catch its children. */ - kill(process_id, SIGCONT); - kill(process_id, SIGKILL); -#endif -} - -#if defined(__VMS) -int decc$feature_get_index(const char* name); -int decc$feature_set_value(int index, int mode, int value); -static int kwsysProcessSetVMSFeature(const char* name, int value) -{ - int i; - errno = 0; - i = decc$feature_get_index(name); - return i >= 0 && (decc$feature_set_value(i, 1, value) >= 0 || errno == 0); -} -#endif - -/* Global set of executing processes for use by the signal handler. - This global instance will be zero-initialized by the compiler. */ -typedef struct kwsysProcessInstances_s -{ - int Count; - int Size; - kwsysProcess** Processes; -} kwsysProcessInstances; -static kwsysProcessInstances kwsysProcesses; - -/* The old SIGCHLD / SIGINT / SIGTERM handlers. */ -static struct sigaction kwsysProcessesOldSigChldAction; -static struct sigaction kwsysProcessesOldSigIntAction; -static struct sigaction kwsysProcessesOldSigTermAction; - -static void kwsysProcessesUpdate(kwsysProcessInstances* newProcesses) -{ - /* Block signals while we update the set of pipes to check. - TODO: sigprocmask is undefined for threaded apps. See - pthread_sigmask. */ - sigset_t newset; - sigset_t oldset; - sigemptyset(&newset); - sigaddset(&newset, SIGCHLD); - sigaddset(&newset, SIGINT); - sigaddset(&newset, SIGTERM); - sigprocmask(SIG_BLOCK, &newset, &oldset); - - /* Store the new set in that seen by the signal handler. */ - kwsysProcesses = *newProcesses; - - /* Restore the signal mask to the previous setting. */ - sigprocmask(SIG_SETMASK, &oldset, 0); -} - -static int kwsysProcessesAdd(kwsysProcess* cp) -{ - /* Create a pipe through which the signal handler can notify the - given process object that a child has exited. */ - { - /* Create the pipe. */ - int p[2]; - if (pipe(p KWSYSPE_VMS_NONBLOCK) < 0) { - return 0; - } - - /* Store the pipes now to be sure they are cleaned up later. */ - cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL] = p[0]; - cp->SignalPipe = p[1]; - - /* Switch the pipe to non-blocking mode so that reading a byte can - be an atomic test-and-set. */ - if (!kwsysProcessSetNonBlocking(p[0]) || - !kwsysProcessSetNonBlocking(p[1])) { - return 0; - } - - /* The children do not need this pipe. Set close-on-exec flag on - the pipe's ends. */ - if ((fcntl(p[0], F_SETFD, FD_CLOEXEC) < 0) || - (fcntl(p[1], F_SETFD, FD_CLOEXEC) < 0)) { - return 0; - } - } - - /* Attempt to add the given signal pipe to the signal handler set. */ - { - - /* Make sure there is enough space for the new signal pipe. */ - kwsysProcessInstances oldProcesses = kwsysProcesses; - kwsysProcessInstances newProcesses = oldProcesses; - if (oldProcesses.Count == oldProcesses.Size) { - /* Start with enough space for a small number of process instances - and double the size each time more is needed. */ - newProcesses.Size = oldProcesses.Size ? oldProcesses.Size * 2 : 4; - - /* Try allocating the new block of memory. */ - if ((newProcesses.Processes = ((kwsysProcess**)malloc( - (size_t)(newProcesses.Size) * sizeof(kwsysProcess*))))) { - /* Copy the old pipe set to the new memory. */ - if (oldProcesses.Count > 0) { - memcpy(newProcesses.Processes, oldProcesses.Processes, - ((size_t)(oldProcesses.Count) * sizeof(kwsysProcess*))); - } - } else { - /* Failed to allocate memory for the new signal pipe set. */ - return 0; - } - } - - /* Append the new signal pipe to the set. */ - newProcesses.Processes[newProcesses.Count++] = cp; - - /* Store the new set in that seen by the signal handler. */ - kwsysProcessesUpdate(&newProcesses); - - /* Free the original pipes if new ones were allocated. */ - if (newProcesses.Processes != oldProcesses.Processes) { - free(oldProcesses.Processes); - } - - /* If this is the first process, enable the signal handler. */ - if (newProcesses.Count == 1) { - /* Install our handler for SIGCHLD. Repeat call until it is not - interrupted. */ - struct sigaction newSigAction; - memset(&newSigAction, 0, sizeof(struct sigaction)); -#if KWSYSPE_USE_SIGINFO - newSigAction.sa_sigaction = kwsysProcessesSignalHandler; - newSigAction.sa_flags = SA_NOCLDSTOP | SA_SIGINFO; -# ifdef SA_RESTART - newSigAction.sa_flags |= SA_RESTART; -# endif -#else - newSigAction.sa_handler = kwsysProcessesSignalHandler; - newSigAction.sa_flags = SA_NOCLDSTOP; -#endif - sigemptyset(&newSigAction.sa_mask); - while ((sigaction(SIGCHLD, &newSigAction, - &kwsysProcessesOldSigChldAction) < 0) && - (errno == EINTR)) - ; - - /* Install our handler for SIGINT / SIGTERM. Repeat call until - it is not interrupted. */ - sigemptyset(&newSigAction.sa_mask); - sigaddset(&newSigAction.sa_mask, SIGTERM); - while ((sigaction(SIGINT, &newSigAction, - &kwsysProcessesOldSigIntAction) < 0) && - (errno == EINTR)) - ; - - sigemptyset(&newSigAction.sa_mask); - sigaddset(&newSigAction.sa_mask, SIGINT); - while ((sigaction(SIGTERM, &newSigAction, - &kwsysProcessesOldSigIntAction) < 0) && - (errno == EINTR)) - ; - } - } - - return 1; -} - -static void kwsysProcessesRemove(kwsysProcess* cp) -{ - /* Attempt to remove the given signal pipe from the signal handler set. */ - { - /* Find the given process in the set. */ - kwsysProcessInstances newProcesses = kwsysProcesses; - int i; - for (i = 0; i < newProcesses.Count; ++i) { - if (newProcesses.Processes[i] == cp) { - break; - } - } - if (i < newProcesses.Count) { - /* Remove the process from the set. */ - --newProcesses.Count; - for (; i < newProcesses.Count; ++i) { - newProcesses.Processes[i] = newProcesses.Processes[i + 1]; - } - - /* If this was the last process, disable the signal handler. */ - if (newProcesses.Count == 0) { - /* Restore the signal handlers. Repeat call until it is not - interrupted. */ - while ((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) && - (errno == EINTR)) - ; - while ((sigaction(SIGINT, &kwsysProcessesOldSigIntAction, 0) < 0) && - (errno == EINTR)) - ; - while ((sigaction(SIGTERM, &kwsysProcessesOldSigTermAction, 0) < 0) && - (errno == EINTR)) - ; - - /* Free the table of process pointers since it is now empty. - This is safe because the signal handler has been removed. */ - newProcesses.Size = 0; - free(newProcesses.Processes); - newProcesses.Processes = 0; - } - - /* Store the new set in that seen by the signal handler. */ - kwsysProcessesUpdate(&newProcesses); - } - } - - /* Close the pipe through which the signal handler may have notified - the given process object that a child has exited. */ - kwsysProcessCleanupDescriptor(&cp->SignalPipe); -} - -static void kwsysProcessesSignalHandler(int signum -#if KWSYSPE_USE_SIGINFO - , - siginfo_t* info, void* ucontext -#endif -) -{ - int i, j, procStatus, old_errno = errno; -#if KWSYSPE_USE_SIGINFO - (void)info; - (void)ucontext; -#endif - - /* Signal all process objects that a child has terminated. */ - switch (signum) { - case SIGCHLD: - for (i = 0; i < kwsysProcesses.Count; ++i) { - /* Set the pipe in a signalled state. */ - char buf = 1; - kwsysProcess* cp = kwsysProcesses.Processes[i]; - kwsysProcess_ssize_t pipeStatus = - read(cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL], &buf, 1); - (void)pipeStatus; - pipeStatus = write(cp->SignalPipe, &buf, 1); - (void)pipeStatus; - } - break; - case SIGINT: - case SIGTERM: - /* Signal child processes that are running in new process groups. */ - for (i = 0; i < kwsysProcesses.Count; ++i) { - kwsysProcess* cp = kwsysProcesses.Processes[i]; - /* Check Killed to avoid data race condition when killing. - Check State to avoid data race condition in kwsysProcessCleanup - when there is an error (it leaves a reaped PID). */ - if (cp->CreateProcessGroup && !cp->Killed && - cp->State != kwsysProcess_State_Error && cp->ForkPIDs) { - for (j = 0; j < cp->NumberOfCommands; ++j) { - /* Make sure the PID is still valid. */ - if (cp->ForkPIDs[j]) { - /* The user created a process group for this process. The group - ID - is the process ID for the original process in the group. */ - kill(-cp->ForkPIDs[j], SIGINT); - } - } - } - } - - /* Wait for all processes to terminate. */ - while (wait(&procStatus) >= 0 || errno != ECHILD) { - } - - /* Terminate the process, which is now in an inconsistent state - because we reaped all the PIDs that it may have been reaping - or may have reaped in the future. Reraise the signal so that - the proper exit code is returned. */ - { - /* Install default signal handler. */ - struct sigaction defSigAction; - sigset_t unblockSet; - memset(&defSigAction, 0, sizeof(defSigAction)); - defSigAction.sa_handler = SIG_DFL; - sigemptyset(&defSigAction.sa_mask); - while ((sigaction(signum, &defSigAction, 0) < 0) && (errno == EINTR)) - ; - /* Unmask the signal. */ - sigemptyset(&unblockSet); - sigaddset(&unblockSet, signum); - sigprocmask(SIG_UNBLOCK, &unblockSet, 0); - /* Raise the signal again. */ - raise(signum); - /* We shouldn't get here... but if we do... */ - _exit(1); - } - /* break omitted to silence unreachable code clang compiler warning. */ - } - -#if !KWSYSPE_USE_SIGINFO - /* Re-Install our handler. Repeat call until it is not interrupted. */ - { - struct sigaction newSigAction; - struct sigaction& oldSigAction; - memset(&newSigAction, 0, sizeof(struct sigaction)); - newSigChldAction.sa_handler = kwsysProcessesSignalHandler; - newSigChldAction.sa_flags = SA_NOCLDSTOP; - sigemptyset(&newSigAction.sa_mask); - switch (signum) { - case SIGCHLD: - oldSigAction = &kwsysProcessesOldSigChldAction; - break; - case SIGINT: - sigaddset(&newSigAction.sa_mask, SIGTERM); - oldSigAction = &kwsysProcessesOldSigIntAction; - break; - case SIGTERM: - sigaddset(&newSigAction.sa_mask, SIGINT); - oldSigAction = &kwsysProcessesOldSigTermAction; - break; - default: - return 0; - } - while ((sigaction(signum, &newSigAction, oldSigAction) < 0) && - (errno == EINTR)) - ; - } -#endif - - errno = old_errno; -} - -void kwsysProcess_ResetStartTime(kwsysProcess* cp) -{ - if (!cp) { - return; - } - /* Reset start time. */ - cp->StartTime = kwsysProcessTimeGetCurrent(); -} diff --git a/test/API/driver/kwsys/ProcessWin32.c b/test/API/driver/kwsys/ProcessWin32.c deleted file mode 100644 index a963862..0000000 --- a/test/API/driver/kwsys/ProcessWin32.c +++ /dev/null @@ -1,2786 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Process.h) -#include KWSYS_HEADER(Encoding.h) - -/* Work-around CMake dependency scanning limitation. This must - duplicate the above list of headers. */ -#if 0 -# include "Encoding.h.in" -# include "Process.h.in" -#endif - -/* - -Implementation for Windows - -On windows, a thread is created to wait for data on each pipe. The -threads are synchronized with the main thread to simulate the use of -a UNIX-style select system call. - -*/ - -#ifdef _MSC_VER -# pragma warning(push, 1) -#endif -#include <windows.h> /* Windows API */ -#if defined(_MSC_VER) && _MSC_VER >= 1800 -# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx -#endif -#include <io.h> /* _unlink */ -#include <stdio.h> /* sprintf */ -#include <string.h> /* strlen, strdup */ -#ifdef __WATCOMC__ -# define _unlink unlink -#endif - -#ifndef _MAX_FNAME -# define _MAX_FNAME 4096 -#endif -#ifndef _MAX_PATH -# define _MAX_PATH 4096 -#endif - -#ifdef _MSC_VER -# pragma warning(pop) -# pragma warning(disable : 4514) -# pragma warning(disable : 4706) -#endif - -#if defined(__BORLANDC__) -# pragma warn - 8004 /* assigned a value that is never used */ -# pragma warn - 8060 /* Assignment inside if() condition. */ -#endif - -/* There are pipes for the process pipeline's stdout and stderr. */ -#define KWSYSPE_PIPE_COUNT 2 -#define KWSYSPE_PIPE_STDOUT 0 -#define KWSYSPE_PIPE_STDERR 1 - -/* The maximum amount to read from a pipe at a time. */ -#define KWSYSPE_PIPE_BUFFER_SIZE 1024 - -/* Debug output macro. */ -#if 0 -# define KWSYSPE_DEBUG(x) \ - ((void*)cp == (void*)0x00226DE0 \ - ? (fprintf(stderr, "%d/%p/%d ", (int)GetCurrentProcessId(), cp, \ - __LINE__), \ - fprintf x, fflush(stderr), 1) \ - : (1)) -#else -# define KWSYSPE_DEBUG(x) (void)1 -#endif - -typedef LARGE_INTEGER kwsysProcessTime; - -typedef struct kwsysProcessCreateInformation_s -{ - /* Windows child startup control data. */ - STARTUPINFOW StartupInfo; - - /* Original handles before making inherited duplicates. */ - HANDLE hStdInput; - HANDLE hStdOutput; - HANDLE hStdError; -} kwsysProcessCreateInformation; - -typedef struct kwsysProcessPipeData_s kwsysProcessPipeData; -static DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd); -static void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, - kwsysProcessPipeData* td); -static DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd); -static void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp, - kwsysProcessPipeData* td); -static int kwsysProcessInitialize(kwsysProcess* cp); -static DWORD kwsysProcessCreate(kwsysProcess* cp, int index, - kwsysProcessCreateInformation* si); -static void kwsysProcessDestroy(kwsysProcess* cp, int event); -static DWORD kwsysProcessSetupOutputPipeFile(PHANDLE handle, const char* name); -static void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle); -static void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle); -static void kwsysProcessCleanupHandle(PHANDLE h); -static void kwsysProcessCleanup(kwsysProcess* cp, DWORD error); -static void kwsysProcessCleanErrorMessage(kwsysProcess* cp); -static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, - kwsysProcessTime* timeoutTime); -static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime, - double* userTimeout, - kwsysProcessTime* timeoutLength); -static kwsysProcessTime kwsysProcessTimeGetCurrent(void); -static DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t); -static double kwsysProcessTimeToDouble(kwsysProcessTime t); -static kwsysProcessTime kwsysProcessTimeFromDouble(double d); -static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2); -static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, - kwsysProcessTime in2); -static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, - kwsysProcessTime in2); -static void kwsysProcessSetExitExceptionByIndex(kwsysProcess* cp, int code, - int idx); -static void kwsysProcessKillTree(int pid); -static void kwsysProcessDisablePipeThreads(kwsysProcess* cp); -static int kwsysProcessesInitialize(void); -static int kwsysTryEnterCreateProcessSection(void); -static void kwsysLeaveCreateProcessSection(void); -static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessId, - int newProcessGroup); -static void kwsysProcessesRemove(HANDLE hProcess); -static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType); - -/* A structure containing synchronization data for each thread. */ -typedef struct kwsysProcessPipeSync_s kwsysProcessPipeSync; -struct kwsysProcessPipeSync_s -{ - /* Handle to the thread. */ - HANDLE Thread; - - /* Semaphore indicating to the thread that a process has started. */ - HANDLE Ready; - - /* Semaphore indicating to the thread that it should begin work. */ - HANDLE Go; - - /* Semaphore indicating thread has reset for another process. */ - HANDLE Reset; -}; - -/* A structure containing data for each pipe's threads. */ -struct kwsysProcessPipeData_s -{ - /* ------------- Data managed per instance of kwsysProcess ------------- */ - - /* Synchronization data for reading thread. */ - kwsysProcessPipeSync Reader; - - /* Synchronization data for waking thread. */ - kwsysProcessPipeSync Waker; - - /* Index of this pipe. */ - int Index; - - /* The kwsysProcess instance owning this pipe. */ - kwsysProcess* Process; - - /* ------------- Data managed per call to Execute ------------- */ - - /* Buffer for data read in this pipe's thread. */ - char DataBuffer[KWSYSPE_PIPE_BUFFER_SIZE]; - - /* The length of the data stored in the buffer. */ - DWORD DataLength; - - /* Whether the pipe has been closed. */ - int Closed; - - /* Handle for the read end of this pipe. */ - HANDLE Read; - - /* Handle for the write end of this pipe. */ - HANDLE Write; -}; - -/* A structure containing results data for each process. */ -typedef struct kwsysProcessResults_s kwsysProcessResults; -struct kwsysProcessResults_s -{ - /* The status of the process. */ - int State; - - /* The exceptional behavior that terminated the process, if any. */ - int ExitException; - - /* The process exit code. */ - DWORD ExitCode; - - /* The process return code, if any. */ - int ExitValue; - - /* Description for the ExitException. */ - char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE + 1]; -}; - -/* Structure containing data used to implement the child's execution. */ -struct kwsysProcess_s -{ - /* ------------- Data managed per instance of kwsysProcess ------------- */ - - /* The status of the process structure. */ - int State; - - /* The command lines to execute. */ - wchar_t** Commands; - int NumberOfCommands; - - /* The exit code of each command. */ - DWORD* CommandExitCodes; - - /* The working directory for the child process. */ - wchar_t* WorkingDirectory; - - /* Whether to create the child as a detached process. */ - int OptionDetach; - - /* Whether the child was created as a detached process. */ - int Detached; - - /* Whether to hide the child process's window. */ - int HideWindow; - - /* Whether to treat command lines as verbatim. */ - int Verbatim; - - /* Whether to merge stdout/stderr of the child. */ - int MergeOutput; - - /* Whether to create the process in a new process group. */ - int CreateProcessGroup; - - /* Mutex to protect the shared index used by threads to report data. */ - HANDLE SharedIndexMutex; - - /* Semaphore used by threads to signal data ready. */ - HANDLE Full; - - /* Whether we are currently deleting this kwsysProcess instance. */ - int Deleting; - - /* Data specific to each pipe and its thread. */ - kwsysProcessPipeData Pipe[KWSYSPE_PIPE_COUNT]; - - /* Name of files to which stdin and stdout pipes are attached. */ - char* PipeFileSTDIN; - char* PipeFileSTDOUT; - char* PipeFileSTDERR; - - /* Whether each pipe is shared with the parent process. */ - int PipeSharedSTDIN; - int PipeSharedSTDOUT; - int PipeSharedSTDERR; - - /* Native pipes provided by the user. */ - HANDLE PipeNativeSTDIN[2]; - HANDLE PipeNativeSTDOUT[2]; - HANDLE PipeNativeSTDERR[2]; - - /* ------------- Data managed per call to Execute ------------- */ - - /* Index of last pipe to report data, if any. */ - int CurrentIndex; - - /* Index shared by threads to report data. */ - int SharedIndex; - - /* The timeout length. */ - double Timeout; - - /* Time at which the child started. */ - kwsysProcessTime StartTime; - - /* Time at which the child will timeout. Negative for no timeout. */ - kwsysProcessTime TimeoutTime; - - /* Flag for whether the process was killed. */ - int Killed; - - /* Flag for whether the timeout expired. */ - int TimeoutExpired; - - /* Flag for whether the process has terminated. */ - int Terminated; - - /* The number of pipes still open during execution and while waiting - for pipes to close after process termination. */ - int PipesLeft; - - /* Buffer for error messages. */ - char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE + 1]; - - /* process results. */ - kwsysProcessResults* ProcessResults; - - /* Windows process information data. */ - PROCESS_INFORMATION* ProcessInformation; - - /* Data and process termination events for which to wait. */ - PHANDLE ProcessEvents; - int ProcessEventsLength; - - /* Real working directory of our own process. */ - DWORD RealWorkingDirectoryLength; - wchar_t* RealWorkingDirectory; - - /* Own handles for the child's ends of the pipes in the parent process. - Used temporarily during process creation. */ - HANDLE PipeChildStd[3]; -}; - -kwsysProcess* kwsysProcess_New(void) -{ - int i; - - /* Process control structure. */ - kwsysProcess* cp; - - /* Windows version number data. */ - OSVERSIONINFO osv; - - /* Initialize list of processes before we get any farther. It's especially - important that the console Ctrl handler be added BEFORE starting the - first process. This prevents the risk of an orphaned process being - started by the main thread while the default Ctrl handler is in - progress. */ - if (!kwsysProcessesInitialize()) { - return 0; - } - - /* Allocate a process control structure. */ - cp = (kwsysProcess*)malloc(sizeof(kwsysProcess)); - if (!cp) { - /* Could not allocate memory for the control structure. */ - return 0; - } - ZeroMemory(cp, sizeof(*cp)); - - /* Share stdin with the parent process by default. */ - cp->PipeSharedSTDIN = 1; - - /* Set initial status. */ - cp->State = kwsysProcess_State_Starting; - - /* Choose a method of running the child based on version of - windows. */ - ZeroMemory(&osv, sizeof(osv)); - osv.dwOSVersionInfoSize = sizeof(osv); -#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx -# pragma warning(push) -# ifdef __INTEL_COMPILER -# pragma warning(disable : 1478) -# elif defined __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" -# else -# pragma warning(disable : 4996) -# endif -#endif - GetVersionEx(&osv); -#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx -# ifdef __clang__ -# pragma clang diagnostic pop -# else -# pragma warning(pop) -# endif -#endif - if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { - /* Win9x no longer supported. */ - kwsysProcess_Delete(cp); - return 0; - } - - /* Initially no thread owns the mutex. Initialize semaphore to 1. */ - if (!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0))) { - kwsysProcess_Delete(cp); - return 0; - } - - /* Initially no data are available. Initialize semaphore to 0. */ - if (!(cp->Full = CreateSemaphore(0, 0, 1, 0))) { - kwsysProcess_Delete(cp); - return 0; - } - - /* Create the thread to read each pipe. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - DWORD dummy = 0; - - /* Assign the thread its index. */ - cp->Pipe[i].Index = i; - - /* Give the thread a pointer back to the kwsysProcess instance. */ - cp->Pipe[i].Process = cp; - - /* No process is yet running. Initialize semaphore to 0. */ - if (!(cp->Pipe[i].Reader.Ready = CreateSemaphore(0, 0, 1, 0))) { - kwsysProcess_Delete(cp); - return 0; - } - - /* The pipe is not yet reset. Initialize semaphore to 0. */ - if (!(cp->Pipe[i].Reader.Reset = CreateSemaphore(0, 0, 1, 0))) { - kwsysProcess_Delete(cp); - return 0; - } - - /* The thread's buffer is initially empty. Initialize semaphore to 1. */ - if (!(cp->Pipe[i].Reader.Go = CreateSemaphore(0, 1, 1, 0))) { - kwsysProcess_Delete(cp); - return 0; - } - - /* Create the reading thread. It will block immediately. The - thread will not make deeply nested calls, so we need only a - small stack. */ - if (!(cp->Pipe[i].Reader.Thread = CreateThread( - 0, 1024, kwsysProcessPipeThreadRead, &cp->Pipe[i], 0, &dummy))) { - kwsysProcess_Delete(cp); - return 0; - } - - /* No process is yet running. Initialize semaphore to 0. */ - if (!(cp->Pipe[i].Waker.Ready = CreateSemaphore(0, 0, 1, 0))) { - kwsysProcess_Delete(cp); - return 0; - } - - /* The pipe is not yet reset. Initialize semaphore to 0. */ - if (!(cp->Pipe[i].Waker.Reset = CreateSemaphore(0, 0, 1, 0))) { - kwsysProcess_Delete(cp); - return 0; - } - - /* The waker should not wake immediately. Initialize semaphore to 0. */ - if (!(cp->Pipe[i].Waker.Go = CreateSemaphore(0, 0, 1, 0))) { - kwsysProcess_Delete(cp); - return 0; - } - - /* Create the waking thread. It will block immediately. The - thread will not make deeply nested calls, so we need only a - small stack. */ - if (!(cp->Pipe[i].Waker.Thread = CreateThread( - 0, 1024, kwsysProcessPipeThreadWake, &cp->Pipe[i], 0, &dummy))) { - kwsysProcess_Delete(cp); - return 0; - } - } - for (i = 0; i < 3; ++i) { - cp->PipeChildStd[i] = INVALID_HANDLE_VALUE; - } - - return cp; -} - -void kwsysProcess_Delete(kwsysProcess* cp) -{ - int i; - - /* Make sure we have an instance. */ - if (!cp) { - return; - } - - /* If the process is executing, wait for it to finish. */ - if (cp->State == kwsysProcess_State_Executing) { - if (cp->Detached) { - kwsysProcess_Disown(cp); - } else { - kwsysProcess_WaitForExit(cp, 0); - } - } - - /* We are deleting the kwsysProcess instance. */ - cp->Deleting = 1; - - /* Terminate each of the threads. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - /* Terminate this reading thread. */ - if (cp->Pipe[i].Reader.Thread) { - /* Signal the thread we are ready for it. It will terminate - immediately since Deleting is set. */ - ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0); - - /* Wait for the thread to exit. */ - WaitForSingleObject(cp->Pipe[i].Reader.Thread, INFINITE); - - /* Close the handle to the thread. */ - kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Thread); - } - - /* Terminate this waking thread. */ - if (cp->Pipe[i].Waker.Thread) { - /* Signal the thread we are ready for it. It will terminate - immediately since Deleting is set. */ - ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0); - - /* Wait for the thread to exit. */ - WaitForSingleObject(cp->Pipe[i].Waker.Thread, INFINITE); - - /* Close the handle to the thread. */ - kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Thread); - } - - /* Cleanup the pipe's semaphores. */ - kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Ready); - kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Go); - kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Reset); - kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Ready); - kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Go); - kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Reset); - } - - /* Close the shared semaphores. */ - kwsysProcessCleanupHandle(&cp->SharedIndexMutex); - kwsysProcessCleanupHandle(&cp->Full); - - /* Free memory. */ - kwsysProcess_SetCommand(cp, 0); - kwsysProcess_SetWorkingDirectory(cp, 0); - kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0); - kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0); - kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0); - free(cp->CommandExitCodes); - free(cp->ProcessResults); - free(cp); -} - -int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command) -{ - int i; - if (!cp) { - return 0; - } - for (i = 0; i < cp->NumberOfCommands; ++i) { - free(cp->Commands[i]); - } - cp->NumberOfCommands = 0; - if (cp->Commands) { - free(cp->Commands); - cp->Commands = 0; - } - if (command) { - return kwsysProcess_AddCommand(cp, command); - } - return 1; -} - -int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command) -{ - int newNumberOfCommands; - wchar_t** newCommands; - - /* Make sure we have a command to add. */ - if (!cp || !command || !*command) { - return 0; - } - - /* Allocate a new array for command pointers. */ - newNumberOfCommands = cp->NumberOfCommands + 1; - if (!(newCommands = - (wchar_t**)malloc(sizeof(wchar_t*) * newNumberOfCommands))) { - /* Out of memory. */ - return 0; - } - - /* Copy any existing commands into the new array. */ - { - int i; - for (i = 0; i < cp->NumberOfCommands; ++i) { - newCommands[i] = cp->Commands[i]; - } - } - - if (cp->Verbatim) { - /* Copy the verbatim command line into the buffer. */ - newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(*command); - } else { - /* Encode the arguments so CommandLineToArgvW can decode - them from the command line string in the child. */ - char buffer[32768]; /* CreateProcess max command-line length. */ - char* end = buffer + sizeof(buffer); - char* out = buffer; - char const* const* a; - for (a = command; *a; ++a) { - int quote = !**a; /* Quote the empty string. */ - int slashes = 0; - char const* c; - if (a != command && out != end) { - *out++ = ' '; - } - for (c = *a; !quote && *c; ++c) { - quote = (*c == ' ' || *c == '\t'); - } - if (quote && out != end) { - *out++ = '"'; - } - for (c = *a; *c; ++c) { - if (*c == '\\') { - ++slashes; - } else { - if (*c == '"') { - // Add n+1 backslashes to total 2n+1 before internal '"'. - while (slashes-- >= 0 && out != end) { - *out++ = '\\'; - } - } - slashes = 0; - } - if (out != end) { - *out++ = *c; - } - } - if (quote) { - // Add n backslashes to total 2n before ending '"'. - while (slashes-- > 0 && out != end) { - *out++ = '\\'; - } - if (out != end) { - *out++ = '"'; - } - } - } - if (out != end) { - *out = '\0'; - newCommands[cp->NumberOfCommands] = kwsysEncoding_DupToWide(buffer); - } else { - newCommands[cp->NumberOfCommands] = 0; - } - } - if (!newCommands[cp->NumberOfCommands]) { - /* Out of memory or command line too long. */ - free(newCommands); - return 0; - } - - /* Save the new array of commands. */ - free(cp->Commands); - cp->Commands = newCommands; - cp->NumberOfCommands = newNumberOfCommands; - return 1; -} - -void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout) -{ - if (!cp) { - return; - } - cp->Timeout = timeout; - if (cp->Timeout < 0) { - cp->Timeout = 0; - } - // Force recomputation of TimeoutTime. - cp->TimeoutTime.QuadPart = -1; -} - -int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir) -{ - if (!cp) { - return 0; - } - if (cp->WorkingDirectory) { - free(cp->WorkingDirectory); - cp->WorkingDirectory = 0; - } - if (dir && dir[0]) { - wchar_t* wdir = kwsysEncoding_DupToWide(dir); - /* We must convert the working directory to a full path. */ - DWORD length = GetFullPathNameW(wdir, 0, 0, 0); - if (length > 0) { - wchar_t* work_dir = malloc(length * sizeof(wchar_t)); - if (!work_dir) { - free(wdir); - return 0; - } - if (!GetFullPathNameW(wdir, length, work_dir, 0)) { - free(work_dir); - free(wdir); - return 0; - } - cp->WorkingDirectory = work_dir; - } - free(wdir); - } - return 1; -} - -int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file) -{ - char** pfile; - if (!cp) { - return 0; - } - switch (pipe) { - case kwsysProcess_Pipe_STDIN: - pfile = &cp->PipeFileSTDIN; - break; - case kwsysProcess_Pipe_STDOUT: - pfile = &cp->PipeFileSTDOUT; - break; - case kwsysProcess_Pipe_STDERR: - pfile = &cp->PipeFileSTDERR; - break; - default: - return 0; - } - if (*pfile) { - free(*pfile); - *pfile = 0; - } - if (file) { - *pfile = strdup(file); - if (!*pfile) { - return 0; - } - } - - /* If we are redirecting the pipe, do not share it or use a native - pipe. */ - if (*pfile) { - kwsysProcess_SetPipeNative(cp, pipe, 0); - kwsysProcess_SetPipeShared(cp, pipe, 0); - } - - return 1; -} - -void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared) -{ - if (!cp) { - return; - } - - switch (pipe) { - case kwsysProcess_Pipe_STDIN: - cp->PipeSharedSTDIN = shared ? 1 : 0; - break; - case kwsysProcess_Pipe_STDOUT: - cp->PipeSharedSTDOUT = shared ? 1 : 0; - break; - case kwsysProcess_Pipe_STDERR: - cp->PipeSharedSTDERR = shared ? 1 : 0; - break; - default: - return; - } - - /* If we are sharing the pipe, do not redirect it to a file or use a - native pipe. */ - if (shared) { - kwsysProcess_SetPipeFile(cp, pipe, 0); - kwsysProcess_SetPipeNative(cp, pipe, 0); - } -} - -void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, HANDLE p[2]) -{ - HANDLE* pPipeNative = 0; - - if (!cp) { - return; - } - - switch (pipe) { - case kwsysProcess_Pipe_STDIN: - pPipeNative = cp->PipeNativeSTDIN; - break; - case kwsysProcess_Pipe_STDOUT: - pPipeNative = cp->PipeNativeSTDOUT; - break; - case kwsysProcess_Pipe_STDERR: - pPipeNative = cp->PipeNativeSTDERR; - break; - default: - return; - } - - /* Copy the native pipe handles provided. */ - if (p) { - pPipeNative[0] = p[0]; - pPipeNative[1] = p[1]; - } else { - pPipeNative[0] = 0; - pPipeNative[1] = 0; - } - - /* If we are using a native pipe, do not share it or redirect it to - a file. */ - if (p) { - kwsysProcess_SetPipeFile(cp, pipe, 0); - kwsysProcess_SetPipeShared(cp, pipe, 0); - } -} - -int kwsysProcess_GetOption(kwsysProcess* cp, int optionId) -{ - if (!cp) { - return 0; - } - - switch (optionId) { - case kwsysProcess_Option_Detach: - return cp->OptionDetach; - case kwsysProcess_Option_HideWindow: - return cp->HideWindow; - case kwsysProcess_Option_MergeOutput: - return cp->MergeOutput; - case kwsysProcess_Option_Verbatim: - return cp->Verbatim; - case kwsysProcess_Option_CreateProcessGroup: - return cp->CreateProcessGroup; - default: - return 0; - } -} - -void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value) -{ - if (!cp) { - return; - } - - switch (optionId) { - case kwsysProcess_Option_Detach: - cp->OptionDetach = value; - break; - case kwsysProcess_Option_HideWindow: - cp->HideWindow = value; - break; - case kwsysProcess_Option_MergeOutput: - cp->MergeOutput = value; - break; - case kwsysProcess_Option_Verbatim: - cp->Verbatim = value; - break; - case kwsysProcess_Option_CreateProcessGroup: - cp->CreateProcessGroup = value; - break; - default: - break; - } -} - -int kwsysProcess_GetState(kwsysProcess* cp) -{ - return cp ? cp->State : kwsysProcess_State_Error; -} - -int kwsysProcess_GetExitException(kwsysProcess* cp) -{ - return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) - ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitException - : kwsysProcess_Exception_Other; -} - -int kwsysProcess_GetExitValue(kwsysProcess* cp) -{ - return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) - ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitValue - : -1; -} - -int kwsysProcess_GetExitCode(kwsysProcess* cp) -{ - return (cp && cp->ProcessResults && (cp->NumberOfCommands > 0)) - ? cp->ProcessResults[cp->NumberOfCommands - 1].ExitCode - : 0; -} - -const char* kwsysProcess_GetErrorString(kwsysProcess* cp) -{ - if (!cp) { - return "Process management structure could not be allocated"; - } else if (cp->State == kwsysProcess_State_Error) { - return cp->ErrorMessage; - } - return "Success"; -} - -const char* kwsysProcess_GetExceptionString(kwsysProcess* cp) -{ - if (!(cp && cp->ProcessResults && (cp->NumberOfCommands > 0))) { - return "GetExceptionString called with NULL process management structure"; - } else if (cp->State == kwsysProcess_State_Exception) { - return cp->ProcessResults[cp->NumberOfCommands - 1].ExitExceptionString; - } - return "No exception"; -} - -/* the index should be in array bound. */ -#define KWSYSPE_IDX_CHK(RET) \ - if (!cp || idx >= cp->NumberOfCommands || idx < 0) { \ - KWSYSPE_DEBUG((stderr, "array index out of bound\n")); \ - return RET; \ - } - -int kwsysProcess_GetStateByIndex(kwsysProcess* cp, int idx) -{ - KWSYSPE_IDX_CHK(kwsysProcess_State_Error) - return cp->ProcessResults[idx].State; -} - -int kwsysProcess_GetExitExceptionByIndex(kwsysProcess* cp, int idx) -{ - KWSYSPE_IDX_CHK(kwsysProcess_Exception_Other) - return cp->ProcessResults[idx].ExitException; -} - -int kwsysProcess_GetExitValueByIndex(kwsysProcess* cp, int idx) -{ - KWSYSPE_IDX_CHK(-1) - return cp->ProcessResults[idx].ExitValue; -} - -int kwsysProcess_GetExitCodeByIndex(kwsysProcess* cp, int idx) -{ - KWSYSPE_IDX_CHK(-1) - return cp->CommandExitCodes[idx]; -} - -const char* kwsysProcess_GetExceptionStringByIndex(kwsysProcess* cp, int idx) -{ - KWSYSPE_IDX_CHK("GetExceptionString called with NULL process management " - "structure or index out of bound") - if (cp->ProcessResults[idx].State == kwsysProcess_StateByIndex_Exception) { - return cp->ProcessResults[idx].ExitExceptionString; - } - return "No exception"; -} - -#undef KWSYSPE_IDX_CHK - -void kwsysProcess_Execute(kwsysProcess* cp) -{ - int i; - - /* Do not execute a second time. */ - if (!cp || cp->State == kwsysProcess_State_Executing) { - return; - } - - /* Make sure we have something to run. */ - if (cp->NumberOfCommands < 1) { - strcpy(cp->ErrorMessage, "No command"); - cp->State = kwsysProcess_State_Error; - return; - } - - /* Initialize the control structure for a new process. */ - if (!kwsysProcessInitialize(cp)) { - strcpy(cp->ErrorMessage, "Out of memory"); - cp->State = kwsysProcess_State_Error; - return; - } - - /* Save the real working directory of this process and change to - the working directory for the child processes. This is needed - to make pipe file paths evaluate correctly. */ - if (cp->WorkingDirectory) { - if (!GetCurrentDirectoryW(cp->RealWorkingDirectoryLength, - cp->RealWorkingDirectory)) { - kwsysProcessCleanup(cp, GetLastError()); - return; - } - SetCurrentDirectoryW(cp->WorkingDirectory); - } - - /* Setup the stdin pipe for the first process. */ - if (cp->PipeFileSTDIN) { - /* Create a handle to read a file for stdin. */ - wchar_t* wstdin = kwsysEncoding_DupToWide(cp->PipeFileSTDIN); - DWORD error; - cp->PipeChildStd[0] = - CreateFileW(wstdin, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, - OPEN_EXISTING, 0, 0); - error = GetLastError(); /* Check now in case free changes this. */ - free(wstdin); - if (cp->PipeChildStd[0] == INVALID_HANDLE_VALUE) { - kwsysProcessCleanup(cp, error); - return; - } - } else if (cp->PipeSharedSTDIN) { - /* Share this process's stdin with the child. */ - kwsysProcessSetupSharedPipe(STD_INPUT_HANDLE, &cp->PipeChildStd[0]); - } else if (cp->PipeNativeSTDIN[0]) { - /* Use the provided native pipe. */ - kwsysProcessSetupPipeNative(cp->PipeNativeSTDIN[0], &cp->PipeChildStd[0]); - } else { - /* Explicitly give the child no stdin. */ - cp->PipeChildStd[0] = INVALID_HANDLE_VALUE; - } - - /* Create the output pipe for the last process. - We always create this so the pipe thread can run even if we - do not end up giving the write end to the child below. */ - if (!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDOUT].Read, - &cp->Pipe[KWSYSPE_PIPE_STDOUT].Write, 0, 0)) { - kwsysProcessCleanup(cp, GetLastError()); - return; - } - - if (cp->PipeFileSTDOUT) { - /* Use a file for stdout. */ - DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[1], - cp->PipeFileSTDOUT); - if (error) { - kwsysProcessCleanup(cp, error); - return; - } - } else if (cp->PipeSharedSTDOUT) { - /* Use the parent stdout. */ - kwsysProcessSetupSharedPipe(STD_OUTPUT_HANDLE, &cp->PipeChildStd[1]); - } else if (cp->PipeNativeSTDOUT[1]) { - /* Use the given handle for stdout. */ - kwsysProcessSetupPipeNative(cp->PipeNativeSTDOUT[1], &cp->PipeChildStd[1]); - } else { - /* Use our pipe for stdout. Duplicate the handle since our waker - thread will use the original. Do not make it inherited yet. */ - if (!DuplicateHandle(GetCurrentProcess(), - cp->Pipe[KWSYSPE_PIPE_STDOUT].Write, - GetCurrentProcess(), &cp->PipeChildStd[1], 0, FALSE, - DUPLICATE_SAME_ACCESS)) { - kwsysProcessCleanup(cp, GetLastError()); - return; - } - } - - /* Create stderr pipe to be shared by all processes in the pipeline. - We always create this so the pipe thread can run even if we do not - end up giving the write end to the child below. */ - if (!CreatePipe(&cp->Pipe[KWSYSPE_PIPE_STDERR].Read, - &cp->Pipe[KWSYSPE_PIPE_STDERR].Write, 0, 0)) { - kwsysProcessCleanup(cp, GetLastError()); - return; - } - - if (cp->PipeFileSTDERR) { - /* Use a file for stderr. */ - DWORD error = kwsysProcessSetupOutputPipeFile(&cp->PipeChildStd[2], - cp->PipeFileSTDERR); - if (error) { - kwsysProcessCleanup(cp, error); - return; - } - } else if (cp->PipeSharedSTDERR) { - /* Use the parent stderr. */ - kwsysProcessSetupSharedPipe(STD_ERROR_HANDLE, &cp->PipeChildStd[2]); - } else if (cp->PipeNativeSTDERR[1]) { - /* Use the given handle for stderr. */ - kwsysProcessSetupPipeNative(cp->PipeNativeSTDERR[1], &cp->PipeChildStd[2]); - } else { - /* Use our pipe for stderr. Duplicate the handle since our waker - thread will use the original. Do not make it inherited yet. */ - if (!DuplicateHandle(GetCurrentProcess(), - cp->Pipe[KWSYSPE_PIPE_STDERR].Write, - GetCurrentProcess(), &cp->PipeChildStd[2], 0, FALSE, - DUPLICATE_SAME_ACCESS)) { - kwsysProcessCleanup(cp, GetLastError()); - return; - } - } - - /* Create the pipeline of processes. */ - { - /* Child startup control data. */ - kwsysProcessCreateInformation si; - HANDLE nextStdInput = cp->PipeChildStd[0]; - - /* Initialize startup info data. */ - ZeroMemory(&si, sizeof(si)); - si.StartupInfo.cb = sizeof(si.StartupInfo); - - /* Decide whether a child window should be shown. */ - si.StartupInfo.dwFlags |= STARTF_USESHOWWINDOW; - si.StartupInfo.wShowWindow = - (unsigned short)(cp->HideWindow ? SW_HIDE : SW_SHOWDEFAULT); - - /* Connect the child's output pipes to the threads. */ - si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES; - - for (i = 0; i < cp->NumberOfCommands; ++i) { - /* Setup the process's pipes. */ - si.hStdInput = nextStdInput; - if (i == cp->NumberOfCommands - 1) { - /* The last child gets the overall stdout. */ - nextStdInput = INVALID_HANDLE_VALUE; - si.hStdOutput = cp->PipeChildStd[1]; - } else { - /* Create a pipe to sit between the children. */ - HANDLE p[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; - if (!CreatePipe(&p[0], &p[1], 0, 0)) { - DWORD error = GetLastError(); - if (nextStdInput != cp->PipeChildStd[0]) { - kwsysProcessCleanupHandle(&nextStdInput); - } - kwsysProcessCleanup(cp, error); - return; - } - nextStdInput = p[0]; - si.hStdOutput = p[1]; - } - si.hStdError = - cp->MergeOutput ? cp->PipeChildStd[1] : cp->PipeChildStd[2]; - - { - DWORD error = kwsysProcessCreate(cp, i, &si); - - /* Close our copies of pipes used between children. */ - if (si.hStdInput != cp->PipeChildStd[0]) { - kwsysProcessCleanupHandle(&si.hStdInput); - } - if (si.hStdOutput != cp->PipeChildStd[1]) { - kwsysProcessCleanupHandle(&si.hStdOutput); - } - if (si.hStdError != cp->PipeChildStd[2] && !cp->MergeOutput) { - kwsysProcessCleanupHandle(&si.hStdError); - } - if (!error) { - cp->ProcessEvents[i + 1] = cp->ProcessInformation[i].hProcess; - } else { - if (nextStdInput != cp->PipeChildStd[0]) { - kwsysProcessCleanupHandle(&nextStdInput); - } - kwsysProcessCleanup(cp, error); - return; - } - } - } - } - - /* The parent process does not need the child's pipe ends. */ - for (i = 0; i < 3; ++i) { - kwsysProcessCleanupHandle(&cp->PipeChildStd[i]); - } - - /* Restore the working directory. */ - if (cp->RealWorkingDirectory) { - SetCurrentDirectoryW(cp->RealWorkingDirectory); - free(cp->RealWorkingDirectory); - cp->RealWorkingDirectory = 0; - } - - /* The timeout period starts now. */ - cp->StartTime = kwsysProcessTimeGetCurrent(); - cp->TimeoutTime = kwsysProcessTimeFromDouble(-1); - - /* All processes in the pipeline have been started in suspended - mode. Resume them all now. */ - for (i = 0; i < cp->NumberOfCommands; ++i) { - ResumeThread(cp->ProcessInformation[i].hThread); - } - - /* ---- It is no longer safe to call kwsysProcessCleanup. ----- */ - /* Tell the pipe threads that a process has started. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0); - ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0); - } - - /* We don't care about the children's main threads. */ - for (i = 0; i < cp->NumberOfCommands; ++i) { - kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread); - } - - /* No pipe has reported data. */ - cp->CurrentIndex = KWSYSPE_PIPE_COUNT; - cp->PipesLeft = KWSYSPE_PIPE_COUNT; - - /* The process has now started. */ - cp->State = kwsysProcess_State_Executing; - cp->Detached = cp->OptionDetach; -} - -void kwsysProcess_Disown(kwsysProcess* cp) -{ - int i; - - /* Make sure we are executing a detached process. */ - if (!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing || - cp->TimeoutExpired || cp->Killed || cp->Terminated) { - return; - } - - /* Disable the reading threads. */ - kwsysProcessDisablePipeThreads(cp); - - /* Wait for all pipe threads to reset. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - WaitForSingleObject(cp->Pipe[i].Reader.Reset, INFINITE); - WaitForSingleObject(cp->Pipe[i].Waker.Reset, INFINITE); - } - - /* We will not wait for exit, so cleanup now. */ - kwsysProcessCleanup(cp, 0); - - /* The process has been disowned. */ - cp->State = kwsysProcess_State_Disowned; -} - -int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, - double* userTimeout) -{ - kwsysProcessTime userStartTime; - kwsysProcessTime timeoutLength; - kwsysProcessTime timeoutTime; - DWORD timeout; - int user; - int done = 0; - int expired = 0; - int pipeId = kwsysProcess_Pipe_None; - DWORD w; - - /* Make sure we are executing a process. */ - if (!cp || cp->State != kwsysProcess_State_Executing || cp->Killed || - cp->TimeoutExpired) { - return kwsysProcess_Pipe_None; - } - - /* Record the time at which user timeout period starts. */ - userStartTime = kwsysProcessTimeGetCurrent(); - - /* Calculate the time at which a timeout will expire, and whether it - is the user or process timeout. */ - user = kwsysProcessGetTimeoutTime(cp, userTimeout, &timeoutTime); - - /* Loop until we have a reason to return. */ - while (!done && cp->PipesLeft > 0) { - /* If we previously got data from a thread, let it know we are - done with the data. */ - if (cp->CurrentIndex < KWSYSPE_PIPE_COUNT) { - KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex)); - ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0); - cp->CurrentIndex = KWSYSPE_PIPE_COUNT; - } - - /* Setup a timeout if required. */ - if (kwsysProcessGetTimeoutLeft(&timeoutTime, user ? userTimeout : 0, - &timeoutLength)) { - /* Timeout has already expired. */ - expired = 1; - break; - } - if (timeoutTime.QuadPart < 0) { - timeout = INFINITE; - } else { - timeout = kwsysProcessTimeToDWORD(timeoutLength); - } - - /* Wait for a pipe's thread to signal or a process to terminate. */ - w = WaitForMultipleObjects(cp->ProcessEventsLength, cp->ProcessEvents, 0, - timeout); - if (w == WAIT_TIMEOUT) { - /* Timeout has expired. */ - expired = 1; - done = 1; - } else if (w == WAIT_OBJECT_0) { - /* Save the index of the reporting thread and release the mutex. - The thread will block until we signal its Empty mutex. */ - cp->CurrentIndex = cp->SharedIndex; - ReleaseSemaphore(cp->SharedIndexMutex, 1, 0); - - /* Data are available or a pipe closed. */ - if (cp->Pipe[cp->CurrentIndex].Closed) { - /* The pipe closed at the write end. Close the read end and - inform the wakeup thread it is done with this process. */ - kwsysProcessCleanupHandle(&cp->Pipe[cp->CurrentIndex].Read); - ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Waker.Go, 1, 0); - KWSYSPE_DEBUG((stderr, "wakeup %d\n", cp->CurrentIndex)); - --cp->PipesLeft; - } else if (data && length) { - /* Report this data. */ - *data = cp->Pipe[cp->CurrentIndex].DataBuffer; - *length = cp->Pipe[cp->CurrentIndex].DataLength; - switch (cp->CurrentIndex) { - case KWSYSPE_PIPE_STDOUT: - pipeId = kwsysProcess_Pipe_STDOUT; - break; - case KWSYSPE_PIPE_STDERR: - pipeId = kwsysProcess_Pipe_STDERR; - break; - } - done = 1; - } - } else { - /* A process has terminated. */ - kwsysProcessDestroy(cp, w - WAIT_OBJECT_0); - } - } - - /* Update the user timeout. */ - if (userTimeout) { - kwsysProcessTime userEndTime = kwsysProcessTimeGetCurrent(); - kwsysProcessTime difference = - kwsysProcessTimeSubtract(userEndTime, userStartTime); - double d = kwsysProcessTimeToDouble(difference); - *userTimeout -= d; - if (*userTimeout < 0) { - *userTimeout = 0; - } - } - - /* Check what happened. */ - if (pipeId) { - /* Data are ready on a pipe. */ - return pipeId; - } else if (expired) { - /* A timeout has expired. */ - if (user) { - /* The user timeout has expired. It has no time left. */ - return kwsysProcess_Pipe_Timeout; - } else { - /* The process timeout has expired. Kill the child now. */ - KWSYSPE_DEBUG((stderr, "killing child because timeout expired\n")); - kwsysProcess_Kill(cp); - cp->TimeoutExpired = 1; - cp->Killed = 0; - return kwsysProcess_Pipe_None; - } - } else { - /* The children have terminated and no more data are available. */ - return kwsysProcess_Pipe_None; - } -} - -int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout) -{ - int i; - int pipe; - - /* Make sure we are executing a process. */ - if (!cp || cp->State != kwsysProcess_State_Executing) { - return 1; - } - - /* Wait for the process to terminate. Ignore all data. */ - while ((pipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0) { - if (pipe == kwsysProcess_Pipe_Timeout) { - /* The user timeout has expired. */ - return 0; - } - } - - KWSYSPE_DEBUG((stderr, "no more data\n")); - - /* When the last pipe closes in WaitForData, the loop terminates - without releasing the pipe's thread. Release it now. */ - if (cp->CurrentIndex < KWSYSPE_PIPE_COUNT) { - KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex)); - ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0); - cp->CurrentIndex = KWSYSPE_PIPE_COUNT; - } - - /* Wait for all pipe threads to reset. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - KWSYSPE_DEBUG((stderr, "waiting reader reset %d\n", i)); - WaitForSingleObject(cp->Pipe[i].Reader.Reset, INFINITE); - KWSYSPE_DEBUG((stderr, "waiting waker reset %d\n", i)); - WaitForSingleObject(cp->Pipe[i].Waker.Reset, INFINITE); - } - - /* ---- It is now safe again to call kwsysProcessCleanup. ----- */ - /* Close all the pipes. */ - kwsysProcessCleanup(cp, 0); - - /* Determine the outcome. */ - if (cp->Killed) { - /* We killed the child. */ - cp->State = kwsysProcess_State_Killed; - } else if (cp->TimeoutExpired) { - /* The timeout expired. */ - cp->State = kwsysProcess_State_Expired; - } else { - /* The children exited. Report the outcome of the child processes. */ - for (i = 0; i < cp->NumberOfCommands; ++i) { - cp->ProcessResults[i].ExitCode = cp->CommandExitCodes[i]; - if ((cp->ProcessResults[i].ExitCode & 0xF0000000) == 0xC0000000) { - /* Child terminated due to exceptional behavior. */ - cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Exception; - cp->ProcessResults[i].ExitValue = 1; - kwsysProcessSetExitExceptionByIndex(cp, cp->ProcessResults[i].ExitCode, - i); - } else { - /* Child exited without exception. */ - cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Exited; - cp->ProcessResults[i].ExitException = kwsysProcess_Exception_None; - cp->ProcessResults[i].ExitValue = cp->ProcessResults[i].ExitCode; - } - } - /* support legacy state status value */ - cp->State = cp->ProcessResults[cp->NumberOfCommands - 1].State; - } - - return 1; -} - -void kwsysProcess_Interrupt(kwsysProcess* cp) -{ - int i; - /* Make sure we are executing a process. */ - if (!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired || - cp->Killed) { - KWSYSPE_DEBUG((stderr, "interrupt: child not executing\n")); - return; - } - - /* Skip actually interrupting the child if it has already terminated. */ - if (cp->Terminated) { - KWSYSPE_DEBUG((stderr, "interrupt: child already terminated\n")); - return; - } - - /* Interrupt the children. */ - if (cp->CreateProcessGroup) { - if (cp->ProcessInformation) { - for (i = 0; i < cp->NumberOfCommands; ++i) { - /* Make sure the process handle isn't closed (e.g. from disowning). */ - if (cp->ProcessInformation[i].hProcess) { - /* The user created a process group for this process. The group ID - is the process ID for the original process in the group. Note - that we have to use Ctrl+Break: Ctrl+C is not allowed for process - groups. */ - GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, - cp->ProcessInformation[i].dwProcessId); - } - } - } - } else { - /* No process group was created. Kill our own process group... */ - GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0); - } -} - -void kwsysProcess_Kill(kwsysProcess* cp) -{ - int i; - /* Make sure we are executing a process. */ - if (!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired || - cp->Killed) { - KWSYSPE_DEBUG((stderr, "kill: child not executing\n")); - return; - } - - /* Disable the reading threads. */ - KWSYSPE_DEBUG((stderr, "kill: disabling pipe threads\n")); - kwsysProcessDisablePipeThreads(cp); - - /* Skip actually killing the child if it has already terminated. */ - if (cp->Terminated) { - KWSYSPE_DEBUG((stderr, "kill: child already terminated\n")); - return; - } - - /* Kill the children. */ - cp->Killed = 1; - for (i = 0; i < cp->NumberOfCommands; ++i) { - kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId); - /* Remove from global list of processes and close handles. */ - kwsysProcessesRemove(cp->ProcessInformation[i].hProcess); - kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread); - kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess); - } - - /* We are killing the children and ignoring all data. Do not wait - for them to exit. */ -} - -void kwsysProcess_KillPID(unsigned long process_id) -{ - kwsysProcessKillTree((DWORD)process_id); -} - -/* - Function executed for each pipe's thread. Argument is a pointer to - the kwsysProcessPipeData instance for this thread. -*/ -DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd) -{ - kwsysProcessPipeData* td = (kwsysProcessPipeData*)ptd; - kwsysProcess* cp = td->Process; - - /* Wait for a process to be ready. */ - while ((WaitForSingleObject(td->Reader.Ready, INFINITE), !cp->Deleting)) { - /* Read output from the process for this thread's pipe. */ - kwsysProcessPipeThreadReadPipe(cp, td); - - /* Signal the main thread we have reset for a new process. */ - ReleaseSemaphore(td->Reader.Reset, 1, 0); - } - return 0; -} - -/* - Function called in each pipe's thread to handle data for one - execution of a subprocess. -*/ -void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td) -{ - /* Wait for space in the thread's buffer. */ - while ((KWSYSPE_DEBUG((stderr, "wait for read %d\n", td->Index)), - WaitForSingleObject(td->Reader.Go, INFINITE), !td->Closed)) { - KWSYSPE_DEBUG((stderr, "reading %d\n", td->Index)); - - /* Read data from the pipe. This may block until data are available. */ - if (!ReadFile(td->Read, td->DataBuffer, KWSYSPE_PIPE_BUFFER_SIZE, - &td->DataLength, 0)) { - if (GetLastError() != ERROR_BROKEN_PIPE) { - /* UNEXPECTED failure to read the pipe. */ - } - - /* The pipe closed. There are no more data to read. */ - td->Closed = 1; - KWSYSPE_DEBUG((stderr, "read closed %d\n", td->Index)); - } - - KWSYSPE_DEBUG((stderr, "read %d\n", td->Index)); - - /* Wait for our turn to be handled by the main thread. */ - WaitForSingleObject(cp->SharedIndexMutex, INFINITE); - - KWSYSPE_DEBUG((stderr, "reporting read %d\n", td->Index)); - - /* Tell the main thread we have something to report. */ - cp->SharedIndex = td->Index; - ReleaseSemaphore(cp->Full, 1, 0); - } - - /* We were signalled to exit with our buffer empty. Reset the - mutex for a new process. */ - KWSYSPE_DEBUG((stderr, "self releasing reader %d\n", td->Index)); - ReleaseSemaphore(td->Reader.Go, 1, 0); -} - -/* - Function executed for each pipe's thread. Argument is a pointer to - the kwsysProcessPipeData instance for this thread. -*/ -DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd) -{ - kwsysProcessPipeData* td = (kwsysProcessPipeData*)ptd; - kwsysProcess* cp = td->Process; - - /* Wait for a process to be ready. */ - while ((WaitForSingleObject(td->Waker.Ready, INFINITE), !cp->Deleting)) { - /* Wait for a possible wakeup. */ - kwsysProcessPipeThreadWakePipe(cp, td); - - /* Signal the main thread we have reset for a new process. */ - ReleaseSemaphore(td->Waker.Reset, 1, 0); - } - return 0; -} - -/* - Function called in each pipe's thread to handle reading thread - wakeup for one execution of a subprocess. -*/ -void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp, kwsysProcessPipeData* td) -{ - (void)cp; - - /* Wait for a possible wake command. */ - KWSYSPE_DEBUG((stderr, "wait for wake %d\n", td->Index)); - WaitForSingleObject(td->Waker.Go, INFINITE); - KWSYSPE_DEBUG((stderr, "waking %d\n", td->Index)); - - /* If the pipe is not closed, we need to wake up the reading thread. */ - if (!td->Closed) { - DWORD dummy; - KWSYSPE_DEBUG((stderr, "waker %d writing byte\n", td->Index)); - WriteFile(td->Write, "", 1, &dummy, 0); - KWSYSPE_DEBUG((stderr, "waker %d wrote byte\n", td->Index)); - } -} - -/* Initialize a process control structure for kwsysProcess_Execute. */ -int kwsysProcessInitialize(kwsysProcess* cp) -{ - int i; - /* Reset internal status flags. */ - cp->TimeoutExpired = 0; - cp->Terminated = 0; - cp->Killed = 0; - - free(cp->ProcessResults); - /* Allocate process result information for each process. */ - cp->ProcessResults = (kwsysProcessResults*)malloc( - sizeof(kwsysProcessResults) * (cp->NumberOfCommands)); - if (!cp->ProcessResults) { - return 0; - } - ZeroMemory(cp->ProcessResults, - sizeof(kwsysProcessResults) * cp->NumberOfCommands); - for (i = 0; i < cp->NumberOfCommands; i++) { - cp->ProcessResults[i].ExitException = kwsysProcess_Exception_None; - cp->ProcessResults[i].State = kwsysProcess_StateByIndex_Starting; - cp->ProcessResults[i].ExitCode = 1; - cp->ProcessResults[i].ExitValue = 1; - strcpy(cp->ProcessResults[i].ExitExceptionString, "No exception"); - } - - /* Allocate process information for each process. */ - free(cp->ProcessInformation); - cp->ProcessInformation = (PROCESS_INFORMATION*)malloc( - sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands); - if (!cp->ProcessInformation) { - return 0; - } - ZeroMemory(cp->ProcessInformation, - sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands); - free(cp->CommandExitCodes); - cp->CommandExitCodes = (DWORD*)malloc(sizeof(DWORD) * cp->NumberOfCommands); - if (!cp->CommandExitCodes) { - return 0; - } - ZeroMemory(cp->CommandExitCodes, sizeof(DWORD) * cp->NumberOfCommands); - - /* Allocate event wait array. The first event is cp->Full, the rest - are the process termination events. */ - cp->ProcessEvents = - (PHANDLE)malloc(sizeof(HANDLE) * (cp->NumberOfCommands + 1)); - if (!cp->ProcessEvents) { - return 0; - } - ZeroMemory(cp->ProcessEvents, sizeof(HANDLE) * (cp->NumberOfCommands + 1)); - cp->ProcessEvents[0] = cp->Full; - cp->ProcessEventsLength = cp->NumberOfCommands + 1; - - /* Allocate space to save the real working directory of this process. */ - if (cp->WorkingDirectory) { - cp->RealWorkingDirectoryLength = GetCurrentDirectoryW(0, 0); - if (cp->RealWorkingDirectoryLength > 0) { - cp->RealWorkingDirectory = - malloc(cp->RealWorkingDirectoryLength * sizeof(wchar_t)); - if (!cp->RealWorkingDirectory) { - return 0; - } - } - } - { - for (i = 0; i < 3; ++i) { - cp->PipeChildStd[i] = INVALID_HANDLE_VALUE; - } - } - - return 1; -} - -static DWORD kwsysProcessCreateChildHandle(PHANDLE out, HANDLE in, int isStdIn) -{ - DWORD flags; - - /* Check whether the handle is valid for this process. */ - if (in != INVALID_HANDLE_VALUE && GetHandleInformation(in, &flags)) { - /* Use the handle as-is if it is already inherited. */ - if (flags & HANDLE_FLAG_INHERIT) { - *out = in; - return ERROR_SUCCESS; - } - - /* Create an inherited copy of this handle. */ - if (DuplicateHandle(GetCurrentProcess(), in, GetCurrentProcess(), out, 0, - TRUE, DUPLICATE_SAME_ACCESS)) { - return ERROR_SUCCESS; - } else { - return GetLastError(); - } - } else { - /* The given handle is not valid for this process. Some child - processes may break if they do not have a valid standard handle, - so open NUL to give to the child. */ - SECURITY_ATTRIBUTES sa; - ZeroMemory(&sa, sizeof(sa)); - sa.nLength = (DWORD)sizeof(sa); - sa.bInheritHandle = 1; - *out = CreateFileW( - L"NUL", - (isStdIn ? GENERIC_READ : (GENERIC_WRITE | FILE_READ_ATTRIBUTES)), - FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, 0); - return (*out != INVALID_HANDLE_VALUE) ? ERROR_SUCCESS : GetLastError(); - } -} - -DWORD kwsysProcessCreate(kwsysProcess* cp, int index, - kwsysProcessCreateInformation* si) -{ - DWORD creationFlags; - DWORD error = ERROR_SUCCESS; - - /* Check if we are currently exiting. */ - if (!kwsysTryEnterCreateProcessSection()) { - /* The Ctrl handler is currently working on exiting our process. Rather - than return an error code, which could cause incorrect conclusions to be - reached by the caller, we simply hang. (For example, a CMake try_run - configure step might cause the project to configure wrong.) */ - Sleep(INFINITE); - } - - /* Create the child in a suspended state so we can wait until all - children have been created before running any one. */ - creationFlags = CREATE_SUSPENDED; - if (cp->CreateProcessGroup) { - creationFlags |= CREATE_NEW_PROCESS_GROUP; - } - - /* Create inherited copies of the handles. */ - (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdInput, - si->hStdInput, 1)) || - (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdOutput, - si->hStdOutput, 0)) || - (error = kwsysProcessCreateChildHandle(&si->StartupInfo.hStdError, - si->hStdError, 0)) || - /* Create the process. */ - (!CreateProcessW(0, cp->Commands[index], 0, 0, TRUE, creationFlags, 0, 0, - &si->StartupInfo, &cp->ProcessInformation[index]) && - (error = GetLastError())); - - /* Close the inherited copies of the handles. */ - if (si->StartupInfo.hStdInput != si->hStdInput) { - kwsysProcessCleanupHandle(&si->StartupInfo.hStdInput); - } - if (si->StartupInfo.hStdOutput != si->hStdOutput) { - kwsysProcessCleanupHandle(&si->StartupInfo.hStdOutput); - } - if (si->StartupInfo.hStdError != si->hStdError) { - kwsysProcessCleanupHandle(&si->StartupInfo.hStdError); - } - - /* Add the process to the global list of processes. */ - if (!error && - !kwsysProcessesAdd(cp->ProcessInformation[index].hProcess, - cp->ProcessInformation[index].dwProcessId, - cp->CreateProcessGroup)) { - /* This failed for some reason. Kill the suspended process. */ - TerminateProcess(cp->ProcessInformation[index].hProcess, 1); - /* And clean up... */ - kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess); - kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread); - strcpy(cp->ErrorMessage, "kwsysProcessesAdd function failed"); - error = ERROR_NOT_ENOUGH_MEMORY; /* Most likely reason. */ - } - - /* If the console Ctrl handler is waiting for us, this will release it... */ - kwsysLeaveCreateProcessSection(); - return error; -} - -void kwsysProcessDestroy(kwsysProcess* cp, int event) -{ - int i; - int index; - - /* Find the process index for the termination event. */ - for (index = 0; index < cp->NumberOfCommands; ++index) { - if (cp->ProcessInformation[index].hProcess == cp->ProcessEvents[event]) { - break; - } - } - - /* Check the exit code of the process. */ - GetExitCodeProcess(cp->ProcessInformation[index].hProcess, - &cp->CommandExitCodes[index]); - - /* Remove from global list of processes. */ - kwsysProcessesRemove(cp->ProcessInformation[index].hProcess); - - /* Close the process handle for the terminated process. */ - kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess); - - /* Remove the process from the available events. */ - cp->ProcessEventsLength -= 1; - for (i = event; i < cp->ProcessEventsLength; ++i) { - cp->ProcessEvents[i] = cp->ProcessEvents[i + 1]; - } - - /* Check if all processes have terminated. */ - if (cp->ProcessEventsLength == 1) { - cp->Terminated = 1; - - /* Close our copies of the pipe write handles so the pipe threads - can detect end-of-data. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - /* TODO: If the child created its own child (our grandchild) - which inherited a copy of the pipe write-end then the pipe - may not close and we will still need the waker write pipe. - However we still want to be able to detect end-of-data in the - normal case. The reader thread will have to switch to using - PeekNamedPipe to read the last bit of data from the pipe - without blocking. This is equivalent to using a non-blocking - read on posix. */ - KWSYSPE_DEBUG((stderr, "closing wakeup write %d\n", i)); - kwsysProcessCleanupHandle(&cp->Pipe[i].Write); - } - } -} - -DWORD kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name) -{ - HANDLE fout; - wchar_t* wname; - DWORD error; - if (!name) { - return ERROR_INVALID_PARAMETER; - } - - /* Close the existing handle. */ - kwsysProcessCleanupHandle(phandle); - - /* Create a handle to write a file for the pipe. */ - wname = kwsysEncoding_DupToWide(name); - fout = - CreateFileW(wname, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0); - error = GetLastError(); - free(wname); - if (fout == INVALID_HANDLE_VALUE) { - return error; - } - - /* Assign the replacement handle. */ - *phandle = fout; - return ERROR_SUCCESS; -} - -void kwsysProcessSetupSharedPipe(DWORD nStdHandle, PHANDLE handle) -{ - /* Close the existing handle. */ - kwsysProcessCleanupHandle(handle); - /* Store the new standard handle. */ - *handle = GetStdHandle(nStdHandle); -} - -void kwsysProcessSetupPipeNative(HANDLE native, PHANDLE handle) -{ - /* Close the existing handle. */ - kwsysProcessCleanupHandle(handle); - /* Store the new given handle. */ - *handle = native; -} - -/* Close the given handle if it is open. Reset its value to 0. */ -void kwsysProcessCleanupHandle(PHANDLE h) -{ - if (h && *h && *h != INVALID_HANDLE_VALUE && - *h != GetStdHandle(STD_INPUT_HANDLE) && - *h != GetStdHandle(STD_OUTPUT_HANDLE) && - *h != GetStdHandle(STD_ERROR_HANDLE)) { - CloseHandle(*h); - *h = INVALID_HANDLE_VALUE; - } -} - -/* Close all handles created by kwsysProcess_Execute. */ -void kwsysProcessCleanup(kwsysProcess* cp, DWORD error) -{ - int i; - /* If this is an error case, report the error. */ - if (error) { - /* Construct an error message if one has not been provided already. */ - if (cp->ErrorMessage[0] == 0) { - /* Format the error message. */ - wchar_t err_msg[KWSYSPE_PIPE_BUFFER_SIZE]; - DWORD length = FormatMessageW( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_msg, - KWSYSPE_PIPE_BUFFER_SIZE, 0); - if (length < 1) { - /* FormatMessage failed. Use a default message. */ - _snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE, - "Process execution failed with error 0x%X. " - "FormatMessage failed with error 0x%X", - error, GetLastError()); - } - if (!WideCharToMultiByte(CP_UTF8, 0, err_msg, -1, cp->ErrorMessage, - KWSYSPE_PIPE_BUFFER_SIZE, NULL, NULL)) { - /* WideCharToMultiByte failed. Use a default message. */ - _snprintf(cp->ErrorMessage, KWSYSPE_PIPE_BUFFER_SIZE, - "Process execution failed with error 0x%X. " - "WideCharToMultiByte failed with error 0x%X", - error, GetLastError()); - } - } - - /* Remove trailing period and newline, if any. */ - kwsysProcessCleanErrorMessage(cp); - - /* Set the error state. */ - cp->State = kwsysProcess_State_Error; - - /* Cleanup any processes already started in a suspended state. */ - if (cp->ProcessInformation) { - for (i = 0; i < cp->NumberOfCommands; ++i) { - if (cp->ProcessInformation[i].hProcess) { - TerminateProcess(cp->ProcessInformation[i].hProcess, 255); - WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE); - } - } - for (i = 0; i < cp->NumberOfCommands; ++i) { - /* Remove from global list of processes and close handles. */ - kwsysProcessesRemove(cp->ProcessInformation[i].hProcess); - kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread); - kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess); - } - } - - /* Restore the working directory. */ - if (cp->RealWorkingDirectory) { - SetCurrentDirectoryW(cp->RealWorkingDirectory); - } - } - - /* Free memory. */ - if (cp->ProcessInformation) { - free(cp->ProcessInformation); - cp->ProcessInformation = 0; - } - if (cp->ProcessEvents) { - free(cp->ProcessEvents); - cp->ProcessEvents = 0; - } - if (cp->RealWorkingDirectory) { - free(cp->RealWorkingDirectory); - cp->RealWorkingDirectory = 0; - } - - /* Close each pipe. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - kwsysProcessCleanupHandle(&cp->Pipe[i].Write); - kwsysProcessCleanupHandle(&cp->Pipe[i].Read); - cp->Pipe[i].Closed = 0; - } - for (i = 0; i < 3; ++i) { - kwsysProcessCleanupHandle(&cp->PipeChildStd[i]); - } -} - -void kwsysProcessCleanErrorMessage(kwsysProcess* cp) -{ - /* Remove trailing period and newline, if any. */ - size_t length = strlen(cp->ErrorMessage); - if (cp->ErrorMessage[length - 1] == '\n') { - cp->ErrorMessage[length - 1] = 0; - --length; - if (length > 0 && cp->ErrorMessage[length - 1] == '\r') { - cp->ErrorMessage[length - 1] = 0; - --length; - } - } - if (length > 0 && cp->ErrorMessage[length - 1] == '.') { - cp->ErrorMessage[length - 1] = 0; - } -} - -/* Get the time at which either the process or user timeout will - expire. Returns 1 if the user timeout is first, and 0 otherwise. */ -int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout, - kwsysProcessTime* timeoutTime) -{ - /* The first time this is called, we need to calculate the time at - which the child will timeout. */ - if (cp->Timeout && cp->TimeoutTime.QuadPart < 0) { - kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout); - cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length); - } - - /* Start with process timeout. */ - *timeoutTime = cp->TimeoutTime; - - /* Check if the user timeout is earlier. */ - if (userTimeout) { - kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent(); - kwsysProcessTime userTimeoutLength = - kwsysProcessTimeFromDouble(*userTimeout); - kwsysProcessTime userTimeoutTime = - kwsysProcessTimeAdd(currentTime, userTimeoutLength); - if (timeoutTime->QuadPart < 0 || - kwsysProcessTimeLess(userTimeoutTime, *timeoutTime)) { - *timeoutTime = userTimeoutTime; - return 1; - } - } - return 0; -} - -/* Get the length of time before the given timeout time arrives. - Returns 1 if the time has already arrived, and 0 otherwise. */ -int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime, - double* userTimeout, - kwsysProcessTime* timeoutLength) -{ - if (timeoutTime->QuadPart < 0) { - /* No timeout time has been requested. */ - return 0; - } else { - /* Calculate the remaining time. */ - kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent(); - *timeoutLength = kwsysProcessTimeSubtract(*timeoutTime, currentTime); - - if (timeoutLength->QuadPart < 0 && userTimeout && *userTimeout <= 0) { - /* Caller has explicitly requested a zero timeout. */ - timeoutLength->QuadPart = 0; - } - - if (timeoutLength->QuadPart < 0) { - /* Timeout has already expired. */ - return 1; - } else { - /* There is some time left. */ - return 0; - } - } -} - -kwsysProcessTime kwsysProcessTimeGetCurrent() -{ - kwsysProcessTime current; - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - current.LowPart = ft.dwLowDateTime; - current.HighPart = ft.dwHighDateTime; - return current; -} - -DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t) -{ - return (DWORD)(t.QuadPart * 0.0001); -} - -double kwsysProcessTimeToDouble(kwsysProcessTime t) -{ - return t.QuadPart * 0.0000001; -} - -kwsysProcessTime kwsysProcessTimeFromDouble(double d) -{ - kwsysProcessTime t; - t.QuadPart = (LONGLONG)(d * 10000000); - return t; -} - -int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2) -{ - return in1.QuadPart < in2.QuadPart; -} - -kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, - kwsysProcessTime in2) -{ - kwsysProcessTime out; - out.QuadPart = in1.QuadPart + in2.QuadPart; - return out; -} - -kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, - kwsysProcessTime in2) -{ - kwsysProcessTime out; - out.QuadPart = in1.QuadPart - in2.QuadPart; - return out; -} - -#define KWSYSPE_CASE(type, str) \ - cp->ProcessResults[idx].ExitException = kwsysProcess_Exception_##type; \ - strcpy(cp->ProcessResults[idx].ExitExceptionString, str) -static void kwsysProcessSetExitExceptionByIndex(kwsysProcess* cp, int code, - int idx) -{ - switch (code) { - case STATUS_CONTROL_C_EXIT: - KWSYSPE_CASE(Interrupt, "User interrupt"); - break; - - case STATUS_FLOAT_DENORMAL_OPERAND: - KWSYSPE_CASE(Numerical, "Floating-point exception (denormal operand)"); - break; - case STATUS_FLOAT_DIVIDE_BY_ZERO: - KWSYSPE_CASE(Numerical, "Divide-by-zero"); - break; - case STATUS_FLOAT_INEXACT_RESULT: - KWSYSPE_CASE(Numerical, "Floating-point exception (inexact result)"); - break; - case STATUS_FLOAT_INVALID_OPERATION: - KWSYSPE_CASE(Numerical, "Invalid floating-point operation"); - break; - case STATUS_FLOAT_OVERFLOW: - KWSYSPE_CASE(Numerical, "Floating-point overflow"); - break; - case STATUS_FLOAT_STACK_CHECK: - KWSYSPE_CASE(Numerical, "Floating-point stack check failed"); - break; - case STATUS_FLOAT_UNDERFLOW: - KWSYSPE_CASE(Numerical, "Floating-point underflow"); - break; -#ifdef STATUS_FLOAT_MULTIPLE_FAULTS - case STATUS_FLOAT_MULTIPLE_FAULTS: - KWSYSPE_CASE(Numerical, "Floating-point exception (multiple faults)"); - break; -#endif -#ifdef STATUS_FLOAT_MULTIPLE_TRAPS - case STATUS_FLOAT_MULTIPLE_TRAPS: - KWSYSPE_CASE(Numerical, "Floating-point exception (multiple traps)"); - break; -#endif - case STATUS_INTEGER_DIVIDE_BY_ZERO: - KWSYSPE_CASE(Numerical, "Integer divide-by-zero"); - break; - case STATUS_INTEGER_OVERFLOW: - KWSYSPE_CASE(Numerical, "Integer overflow"); - break; - - case STATUS_DATATYPE_MISALIGNMENT: - KWSYSPE_CASE(Fault, "Datatype misalignment"); - break; - case STATUS_ACCESS_VIOLATION: - KWSYSPE_CASE(Fault, "Access violation"); - break; - case STATUS_IN_PAGE_ERROR: - KWSYSPE_CASE(Fault, "In-page error"); - break; - case STATUS_INVALID_HANDLE: - KWSYSPE_CASE(Fault, "Invalid hanlde"); - break; - case STATUS_NONCONTINUABLE_EXCEPTION: - KWSYSPE_CASE(Fault, "Noncontinuable exception"); - break; - case STATUS_INVALID_DISPOSITION: - KWSYSPE_CASE(Fault, "Invalid disposition"); - break; - case STATUS_ARRAY_BOUNDS_EXCEEDED: - KWSYSPE_CASE(Fault, "Array bounds exceeded"); - break; - case STATUS_STACK_OVERFLOW: - KWSYSPE_CASE(Fault, "Stack overflow"); - break; - - case STATUS_ILLEGAL_INSTRUCTION: - KWSYSPE_CASE(Illegal, "Illegal instruction"); - break; - case STATUS_PRIVILEGED_INSTRUCTION: - KWSYSPE_CASE(Illegal, "Privileged instruction"); - break; - - case STATUS_NO_MEMORY: - default: - cp->ProcessResults[idx].ExitException = kwsysProcess_Exception_Other; - _snprintf(cp->ProcessResults[idx].ExitExceptionString, - KWSYSPE_PIPE_BUFFER_SIZE, "Exit code 0x%x\n", code); - break; - } -} -#undef KWSYSPE_CASE - -typedef struct kwsysProcess_List_s kwsysProcess_List; -static kwsysProcess_List* kwsysProcess_List_New(void); -static void kwsysProcess_List_Delete(kwsysProcess_List* self); -static int kwsysProcess_List_Update(kwsysProcess_List* self); -static int kwsysProcess_List_NextProcess(kwsysProcess_List* self); -static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self); -static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self); - -/* Windows NT 4 API definitions. */ -#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) -typedef LONG NTSTATUS; -typedef LONG KPRIORITY; -typedef struct _UNICODE_STRING UNICODE_STRING; -struct _UNICODE_STRING -{ - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -}; - -/* The process information structure. Declare only enough to get - process identifiers. The rest may be ignored because we use the - NextEntryDelta to move through an array of instances. */ -typedef struct _SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION; -typedef SYSTEM_PROCESS_INFORMATION* PSYSTEM_PROCESS_INFORMATION; -struct _SYSTEM_PROCESS_INFORMATION -{ - ULONG NextEntryDelta; - ULONG ThreadCount; - ULONG Reserved1[6]; - LARGE_INTEGER CreateTime; - LARGE_INTEGER UserTime; - LARGE_INTEGER KernelTime; - UNICODE_STRING ProcessName; - KPRIORITY BasePriority; - ULONG ProcessId; - ULONG InheritedFromProcessId; -}; - -/* Toolhelp32 API definitions. */ -#define TH32CS_SNAPPROCESS 0x00000002 -#if defined(_WIN64) -typedef unsigned __int64 ProcessULONG_PTR; -#else -typedef unsigned long ProcessULONG_PTR; -#endif -typedef struct tagPROCESSENTRY32 PROCESSENTRY32; -typedef PROCESSENTRY32* LPPROCESSENTRY32; -struct tagPROCESSENTRY32 -{ - DWORD dwSize; - DWORD cntUsage; - DWORD th32ProcessID; - ProcessULONG_PTR th32DefaultHeapID; - DWORD th32ModuleID; - DWORD cntThreads; - DWORD th32ParentProcessID; - LONG pcPriClassBase; - DWORD dwFlags; - char szExeFile[MAX_PATH]; -}; - -/* Windows API function types. */ -typedef HANDLE(WINAPI* CreateToolhelp32SnapshotType)(DWORD, DWORD); -typedef BOOL(WINAPI* Process32FirstType)(HANDLE, LPPROCESSENTRY32); -typedef BOOL(WINAPI* Process32NextType)(HANDLE, LPPROCESSENTRY32); -typedef NTSTATUS(WINAPI* ZwQuerySystemInformationType)(ULONG, PVOID, ULONG, - PULONG); - -static int kwsysProcess_List__New_NT4(kwsysProcess_List* self); -static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self); -static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self); -static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self); -static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self); -static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self); -static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self); -static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self); -static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self); -static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self); -static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self); -static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self); - -struct kwsysProcess_List_s -{ - /* Implementation switches at runtime based on version of Windows. */ - int NT4; - - /* Implementation functions and data for NT 4. */ - ZwQuerySystemInformationType P_ZwQuerySystemInformation; - char* Buffer; - int BufferSize; - PSYSTEM_PROCESS_INFORMATION CurrentInfo; - - /* Implementation functions and data for other Windows versions. */ - CreateToolhelp32SnapshotType P_CreateToolhelp32Snapshot; - Process32FirstType P_Process32First; - Process32NextType P_Process32Next; - HANDLE Snapshot; - PROCESSENTRY32 CurrentEntry; -}; - -static kwsysProcess_List* kwsysProcess_List_New(void) -{ - OSVERSIONINFO osv; - kwsysProcess_List* self; - - /* Allocate and initialize the list object. */ - if (!(self = (kwsysProcess_List*)malloc(sizeof(kwsysProcess_List)))) { - return 0; - } - memset(self, 0, sizeof(*self)); - - /* Select an implementation. */ - ZeroMemory(&osv, sizeof(osv)); - osv.dwOSVersionInfoSize = sizeof(osv); -#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx -# pragma warning(push) -# ifdef __INTEL_COMPILER -# pragma warning(disable : 1478) -# elif defined __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" -# else -# pragma warning(disable : 4996) -# endif -#endif - GetVersionEx(&osv); -#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx -# ifdef __clang__ -# pragma clang diagnostic pop -# else -# pragma warning(pop) -# endif -#endif - self->NT4 = - (osv.dwPlatformId == VER_PLATFORM_WIN32_NT && osv.dwMajorVersion < 5) ? 1 - : 0; - - /* Initialize the selected implementation. */ - if (!(self->NT4 ? kwsysProcess_List__New_NT4(self) - : kwsysProcess_List__New_Snapshot(self))) { - kwsysProcess_List_Delete(self); - return 0; - } - - /* Update to the current set of processes. */ - if (!kwsysProcess_List_Update(self)) { - kwsysProcess_List_Delete(self); - return 0; - } - return self; -} - -static void kwsysProcess_List_Delete(kwsysProcess_List* self) -{ - if (self) { - if (self->NT4) { - kwsysProcess_List__Delete_NT4(self); - } else { - kwsysProcess_List__Delete_Snapshot(self); - } - free(self); - } -} - -static int kwsysProcess_List_Update(kwsysProcess_List* self) -{ - return self ? (self->NT4 ? kwsysProcess_List__Update_NT4(self) - : kwsysProcess_List__Update_Snapshot(self)) - : 0; -} - -static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self) -{ - return self ? (self->NT4 ? kwsysProcess_List__GetProcessId_NT4(self) - : kwsysProcess_List__GetProcessId_Snapshot(self)) - : -1; -} - -static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self) -{ - return self ? (self->NT4 ? kwsysProcess_List__GetParentId_NT4(self) - : kwsysProcess_List__GetParentId_Snapshot(self)) - : -1; -} - -static int kwsysProcess_List_NextProcess(kwsysProcess_List* self) -{ - return (self ? (self->NT4 ? kwsysProcess_List__Next_NT4(self) - : kwsysProcess_List__Next_Snapshot(self)) - : 0); -} - -static int kwsysProcess_List__New_NT4(kwsysProcess_List* self) -{ - /* Get a handle to the NT runtime module that should already be - loaded in this program. This does not actually increment the - reference count to the module so we do not need to close the - handle. */ - HMODULE hNT = GetModuleHandleW(L"ntdll.dll"); - if (hNT) { - /* Get pointers to the needed API functions. */ - self->P_ZwQuerySystemInformation = - ((ZwQuerySystemInformationType)GetProcAddress( - hNT, "ZwQuerySystemInformation")); - } - if (!self->P_ZwQuerySystemInformation) { - return 0; - } - - /* Allocate an initial process information buffer. */ - self->BufferSize = 32768; - self->Buffer = (char*)malloc(self->BufferSize); - return self->Buffer ? 1 : 0; -} - -static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self) -{ - /* Free the process information buffer. */ - free(self->Buffer); -} - -static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self) -{ - self->CurrentInfo = 0; - for (;;) { - /* Query number 5 is for system process list. */ - NTSTATUS status = - self->P_ZwQuerySystemInformation(5, self->Buffer, self->BufferSize, 0); - if (status == STATUS_INFO_LENGTH_MISMATCH) { - /* The query requires a bigger buffer. */ - int newBufferSize = self->BufferSize * 2; - char* newBuffer = (char*)malloc(newBufferSize); - if (newBuffer) { - free(self->Buffer); - self->Buffer = newBuffer; - self->BufferSize = newBufferSize; - } else { - return 0; - } - } else if (status >= 0) { - /* The query succeeded. Initialize traversal of the process list. */ - self->CurrentInfo = (PSYSTEM_PROCESS_INFORMATION)self->Buffer; - return 1; - } else { - /* The query failed. */ - return 0; - } - } -} - -static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self) -{ - if (self->CurrentInfo) { - if (self->CurrentInfo->NextEntryDelta > 0) { - self->CurrentInfo = - ((PSYSTEM_PROCESS_INFORMATION)((char*)self->CurrentInfo + - self->CurrentInfo->NextEntryDelta)); - return 1; - } - self->CurrentInfo = 0; - } - return 0; -} - -static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self) -{ - return self->CurrentInfo ? self->CurrentInfo->ProcessId : -1; -} - -static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self) -{ - return self->CurrentInfo ? self->CurrentInfo->InheritedFromProcessId : -1; -} - -static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self) -{ - /* Get a handle to the Windows runtime module that should already be - loaded in this program. This does not actually increment the - reference count to the module so we do not need to close the - handle. */ - HMODULE hKernel = GetModuleHandleW(L"kernel32.dll"); - if (hKernel) { - self->P_CreateToolhelp32Snapshot = - ((CreateToolhelp32SnapshotType)GetProcAddress( - hKernel, "CreateToolhelp32Snapshot")); - self->P_Process32First = - ((Process32FirstType)GetProcAddress(hKernel, "Process32First")); - self->P_Process32Next = - ((Process32NextType)GetProcAddress(hKernel, "Process32Next")); - } - return (self->P_CreateToolhelp32Snapshot && self->P_Process32First && - self->P_Process32Next) - ? 1 - : 0; -} - -static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self) -{ - if (self->Snapshot) { - CloseHandle(self->Snapshot); - } -} - -static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self) -{ - if (self->Snapshot) { - CloseHandle(self->Snapshot); - } - if (!(self->Snapshot = - self->P_CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0))) { - return 0; - } - ZeroMemory(&self->CurrentEntry, sizeof(self->CurrentEntry)); - self->CurrentEntry.dwSize = sizeof(self->CurrentEntry); - if (!self->P_Process32First(self->Snapshot, &self->CurrentEntry)) { - CloseHandle(self->Snapshot); - self->Snapshot = 0; - return 0; - } - return 1; -} - -static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self) -{ - if (self->Snapshot) { - if (self->P_Process32Next(self->Snapshot, &self->CurrentEntry)) { - return 1; - } - CloseHandle(self->Snapshot); - self->Snapshot = 0; - } - return 0; -} - -static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self) -{ - return self->Snapshot ? self->CurrentEntry.th32ProcessID : -1; -} - -static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self) -{ - return self->Snapshot ? self->CurrentEntry.th32ParentProcessID : -1; -} - -static void kwsysProcessKill(DWORD pid) -{ - HANDLE h = OpenProcess(PROCESS_TERMINATE, 0, pid); - if (h) { - TerminateProcess(h, 255); - WaitForSingleObject(h, INFINITE); - CloseHandle(h); - } -} - -static void kwsysProcessKillTree(int pid) -{ - kwsysProcess_List* plist = kwsysProcess_List_New(); - kwsysProcessKill(pid); - if (plist) { - do { - if (kwsysProcess_List_GetCurrentParentId(plist) == pid) { - int ppid = kwsysProcess_List_GetCurrentProcessId(plist); - kwsysProcessKillTree(ppid); - } - } while (kwsysProcess_List_NextProcess(plist)); - kwsysProcess_List_Delete(plist); - } -} - -static void kwsysProcessDisablePipeThreads(kwsysProcess* cp) -{ - int i; - - /* If data were just reported data, release the pipe's thread. */ - if (cp->CurrentIndex < KWSYSPE_PIPE_COUNT) { - KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex)); - ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0); - cp->CurrentIndex = KWSYSPE_PIPE_COUNT; - } - - /* Wakeup all reading threads that are not on closed pipes. */ - for (i = 0; i < KWSYSPE_PIPE_COUNT; ++i) { - /* The wakeup threads will write one byte to the pipe write ends. - If there are no data in the pipe then this is enough to wakeup - the reading threads. If there are already data in the pipe - this may block. We cannot use PeekNamedPipe to check whether - there are data because an outside process might still be - writing data if we are disowning it. Also, PeekNamedPipe will - block if checking a pipe on which the reading thread is - currently calling ReadPipe. Therefore we need a separate - thread to call WriteFile. If it blocks, that is okay because - it will unblock when we close the read end and break the pipe - below. */ - if (cp->Pipe[i].Read) { - KWSYSPE_DEBUG((stderr, "releasing waker %d\n", i)); - ReleaseSemaphore(cp->Pipe[i].Waker.Go, 1, 0); - } - } - - /* Tell pipe threads to reset until we run another process. */ - while (cp->PipesLeft > 0) { - /* The waking threads will cause all reading threads to report. - Wait for the next one and save its index. */ - KWSYSPE_DEBUG((stderr, "waiting for reader\n")); - WaitForSingleObject(cp->Full, INFINITE); - cp->CurrentIndex = cp->SharedIndex; - ReleaseSemaphore(cp->SharedIndexMutex, 1, 0); - KWSYSPE_DEBUG((stderr, "got reader %d\n", cp->CurrentIndex)); - - /* We are done reading this pipe. Close its read handle. */ - cp->Pipe[cp->CurrentIndex].Closed = 1; - kwsysProcessCleanupHandle(&cp->Pipe[cp->CurrentIndex].Read); - --cp->PipesLeft; - - /* Tell the reading thread we are done with the data. It will - reset immediately because the pipe is closed. */ - ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0); - } -} - -/* Global set of executing processes for use by the Ctrl handler. - This global instance will be zero-initialized by the compiler. - - Note that the console Ctrl handler runs on a background thread and so - everything it does must be thread safe. Here, we track the hProcess - HANDLEs directly instead of kwsysProcess instances, so that we don't have - to make kwsysProcess thread safe. */ -typedef struct kwsysProcessInstance_s -{ - HANDLE hProcess; - DWORD dwProcessId; - int NewProcessGroup; /* Whether the process was created in a new group. */ -} kwsysProcessInstance; - -typedef struct kwsysProcessInstances_s -{ - /* Whether we have initialized key fields below, like critical sections. */ - int Initialized; - - /* Ctrl handler runs on a different thread, so we must sync access. */ - CRITICAL_SECTION Lock; - - int Exiting; - size_t Count; - size_t Size; - kwsysProcessInstance* Processes; -} kwsysProcessInstances; -static kwsysProcessInstances kwsysProcesses; - -/* Initialize critial section and set up console Ctrl handler. You MUST call - this before using any other kwsysProcesses* functions below. */ -static int kwsysProcessesInitialize(void) -{ - /* Initialize everything if not done already. */ - if (!kwsysProcesses.Initialized) { - InitializeCriticalSection(&kwsysProcesses.Lock); - - /* Set up console ctrl handler. */ - if (!SetConsoleCtrlHandler(kwsysCtrlHandler, TRUE)) { - return 0; - } - - kwsysProcesses.Initialized = 1; - } - return 1; -} - -/* The Ctrl handler waits on the global list of processes. To prevent an - orphaned process, do not create a new process if the Ctrl handler is - already running. Do so by using this function to check if it is ok to - create a process. */ -static int kwsysTryEnterCreateProcessSection(void) -{ - /* Enter main critical section; this means creating a process and the Ctrl - handler are mutually exclusive. */ - EnterCriticalSection(&kwsysProcesses.Lock); - /* Indicate to the caller if they can create a process. */ - if (kwsysProcesses.Exiting) { - LeaveCriticalSection(&kwsysProcesses.Lock); - return 0; - } else { - return 1; - } -} - -/* Matching function on successful kwsysTryEnterCreateProcessSection return. - Make sure you called kwsysProcessesAdd if applicable before calling this.*/ -static void kwsysLeaveCreateProcessSection(void) -{ - LeaveCriticalSection(&kwsysProcesses.Lock); -} - -/* Add new process to global process list. The Ctrl handler will wait for - the process to exit before it returns. Do not close the process handle - until after calling kwsysProcessesRemove. The newProcessGroup parameter - must be set if the process was created with CREATE_NEW_PROCESS_GROUP. */ -static int kwsysProcessesAdd(HANDLE hProcess, DWORD dwProcessid, - int newProcessGroup) -{ - if (!kwsysProcessesInitialize() || !hProcess || - hProcess == INVALID_HANDLE_VALUE) { - return 0; - } - - /* Enter the critical section. */ - EnterCriticalSection(&kwsysProcesses.Lock); - - /* Make sure there is enough space for the new process handle. */ - if (kwsysProcesses.Count == kwsysProcesses.Size) { - size_t newSize; - kwsysProcessInstance* newArray; - /* Start with enough space for a small number of process handles - and double the size each time more is needed. */ - newSize = kwsysProcesses.Size ? kwsysProcesses.Size * 2 : 4; - - /* Try allocating the new block of memory. */ - if ((newArray = (kwsysProcessInstance*)malloc( - newSize * sizeof(kwsysProcessInstance)))) { - /* Copy the old process handles to the new memory. */ - if (kwsysProcesses.Count > 0) { - memcpy(newArray, kwsysProcesses.Processes, - kwsysProcesses.Count * sizeof(kwsysProcessInstance)); - } - } else { - /* Failed to allocate memory for the new process handle set. */ - LeaveCriticalSection(&kwsysProcesses.Lock); - return 0; - } - - /* Free original array. */ - free(kwsysProcesses.Processes); - - /* Update original structure with new allocation. */ - kwsysProcesses.Size = newSize; - kwsysProcesses.Processes = newArray; - } - - /* Append the new process information to the set. */ - kwsysProcesses.Processes[kwsysProcesses.Count].hProcess = hProcess; - kwsysProcesses.Processes[kwsysProcesses.Count].dwProcessId = dwProcessid; - kwsysProcesses.Processes[kwsysProcesses.Count++].NewProcessGroup = - newProcessGroup; - - /* Leave critical section and return success. */ - LeaveCriticalSection(&kwsysProcesses.Lock); - - return 1; -} - -/* Removes process to global process list. */ -static void kwsysProcessesRemove(HANDLE hProcess) -{ - size_t i; - - if (!hProcess || hProcess == INVALID_HANDLE_VALUE) { - return; - } - - EnterCriticalSection(&kwsysProcesses.Lock); - - /* Find the given process in the set. */ - for (i = 0; i < kwsysProcesses.Count; ++i) { - if (kwsysProcesses.Processes[i].hProcess == hProcess) { - break; - } - } - if (i < kwsysProcesses.Count) { - /* Found it! Remove the process from the set. */ - --kwsysProcesses.Count; - for (; i < kwsysProcesses.Count; ++i) { - kwsysProcesses.Processes[i] = kwsysProcesses.Processes[i + 1]; - } - - /* If this was the last process, free the array. */ - if (kwsysProcesses.Count == 0) { - kwsysProcesses.Size = 0; - free(kwsysProcesses.Processes); - kwsysProcesses.Processes = 0; - } - } - - LeaveCriticalSection(&kwsysProcesses.Lock); -} - -static BOOL WINAPI kwsysCtrlHandler(DWORD dwCtrlType) -{ - size_t i; - (void)dwCtrlType; - /* Enter critical section. */ - EnterCriticalSection(&kwsysProcesses.Lock); - - /* Set flag indicating that we are exiting. */ - kwsysProcesses.Exiting = 1; - - /* If some of our processes were created in a new process group, we must - manually interrupt them. They won't otherwise receive a Ctrl+C/Break. */ - for (i = 0; i < kwsysProcesses.Count; ++i) { - if (kwsysProcesses.Processes[i].NewProcessGroup) { - DWORD groupId = kwsysProcesses.Processes[i].dwProcessId; - if (groupId) { - GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, groupId); - } - } - } - - /* Wait for each child process to exit. This is the key step that prevents - us from leaving several orphaned children processes running in the - background when the user presses Ctrl+C. */ - for (i = 0; i < kwsysProcesses.Count; ++i) { - WaitForSingleObject(kwsysProcesses.Processes[i].hProcess, INFINITE); - } - - /* Leave critical section. */ - LeaveCriticalSection(&kwsysProcesses.Lock); - - /* Continue on to default Ctrl handler (which calls ExitProcess). */ - return FALSE; -} - -void kwsysProcess_ResetStartTime(kwsysProcess* cp) -{ - if (!cp) { - return; - } - /* Reset start time. */ - cp->StartTime = kwsysProcessTimeGetCurrent(); -} diff --git a/test/API/driver/kwsys/README.rst b/test/API/driver/kwsys/README.rst deleted file mode 100644 index fc6b590..0000000 --- a/test/API/driver/kwsys/README.rst +++ /dev/null @@ -1,37 +0,0 @@ -KWSys -***** - -Introduction -============ - -KWSys is the Kitware System Library. It provides platform-independent -APIs to many common system features that are implemented differently on -every platform. This library is intended to be shared among many -projects at the source level, so it has a configurable namespace. -Each project should configure KWSys to use a namespace unique to itself. -See comments in `CMakeLists.txt`_ for details. - -.. _`CMakeLists.txt`: CMakeLists.txt - -License -======= - -KWSys is distributed under the OSI-approved BSD 3-clause License. -See `Copyright.txt`_ for details. - -.. _`Copyright.txt`: Copyright.txt - -Reporting Bugs -============== - -KWSys has no independent issue tracker. After encountering an issue -(bug) please submit a patch using the instructions for `Contributing`_. -Otherwise please report the issue to the tracker for the project that -hosts the copy of KWSys in which the problem was found. - -Contributing -============ - -See `CONTRIBUTING.rst`_ for instructions to contribute. - -.. _`CONTRIBUTING.rst`: CONTRIBUTING.rst diff --git a/test/API/driver/kwsys/RegularExpression.cxx b/test/API/driver/kwsys/RegularExpression.cxx deleted file mode 100644 index 5e6f8da..0000000 --- a/test/API/driver/kwsys/RegularExpression.cxx +++ /dev/null @@ -1,1218 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -// -// Copyright (C) 1991 Texas Instruments Incorporated. -// -// Permission is granted to any individual or institution to use, copy, modify -// and distribute this software, provided that this complete copyright and -// permission notice is maintained, intact, in all copies and supporting -// documentation. -// -// Texas Instruments Incorporated provides this software "as is" without -// express or implied warranty. -// -// -// Created: MNF 06/13/89 Initial Design and Implementation -// Updated: LGO 08/09/89 Inherit from Generic -// Updated: MBN 09/07/89 Added conditional exception handling -// Updated: MBN 12/15/89 Sprinkled "const" qualifiers all over the place! -// Updated: DLS 03/22/91 New lite version -// - -#include "kwsysPrivate.h" -#include KWSYS_HEADER(RegularExpression.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "RegularExpression.hxx.in" -#endif - -#include <stdio.h> -#include <string.h> - -namespace KWSYS_NAMESPACE { - -// RegularExpression -- Copies the given regular expression. -RegularExpression::RegularExpression(const RegularExpression& rxp) -{ - if (!rxp.program) { - this->program = nullptr; - return; - } - int ind; - this->progsize = rxp.progsize; // Copy regular expression size - this->program = new char[this->progsize]; // Allocate storage - for (ind = this->progsize; ind-- != 0;) // Copy regular expression - this->program[ind] = rxp.program[ind]; - // Copy pointers into last successful "find" operation - this->regmatch = rxp.regmatch; - this->regmust = rxp.regmust; // Copy field - if (rxp.regmust != nullptr) { - char* dum = rxp.program; - ind = 0; - while (dum != rxp.regmust) { - ++dum; - ++ind; - } - this->regmust = this->program + ind; - } - this->regstart = rxp.regstart; // Copy starting index - this->reganch = rxp.reganch; // Copy remaining private data - this->regmlen = rxp.regmlen; // Copy remaining private data -} - -// operator= -- Copies the given regular expression. -RegularExpression& RegularExpression::operator=(const RegularExpression& rxp) -{ - if (this == &rxp) { - return *this; - } - if (!rxp.program) { - this->program = nullptr; - return *this; - } - int ind; - this->progsize = rxp.progsize; // Copy regular expression size - delete[] this->program; - this->program = new char[this->progsize]; // Allocate storage - for (ind = this->progsize; ind-- != 0;) // Copy regular expression - this->program[ind] = rxp.program[ind]; - // Copy pointers into last successful "find" operation - this->regmatch = rxp.regmatch; - this->regmust = rxp.regmust; // Copy field - if (rxp.regmust != nullptr) { - char* dum = rxp.program; - ind = 0; - while (dum != rxp.regmust) { - ++dum; - ++ind; - } - this->regmust = this->program + ind; - } - this->regstart = rxp.regstart; // Copy starting index - this->reganch = rxp.reganch; // Copy remaining private data - this->regmlen = rxp.regmlen; // Copy remaining private data - - return *this; -} - -// operator== -- Returns true if two regular expressions have the same -// compiled program for pattern matching. -bool RegularExpression::operator==(const RegularExpression& rxp) const -{ - if (this != &rxp) { // Same address? - int ind = this->progsize; // Get regular expression size - if (ind != rxp.progsize) // If different size regexp - return false; // Return failure - while (ind-- != 0) // Else while still characters - if (this->program[ind] != rxp.program[ind]) // If regexp are different - return false; // Return failure - } - return true; // Else same, return success -} - -// deep_equal -- Returns true if have the same compiled regular expressions -// and the same start and end pointers. - -bool RegularExpression::deep_equal(const RegularExpression& rxp) const -{ - int ind = this->progsize; // Get regular expression size - if (ind != rxp.progsize) // If different size regexp - return false; // Return failure - while (ind-- != 0) // Else while still characters - if (this->program[ind] != rxp.program[ind]) // If regexp are different - return false; // Return failure - // Else if same start/end ptrs, return true - return (this->regmatch.start() == rxp.regmatch.start() && - this->regmatch.end() == rxp.regmatch.end()); -} - -// The remaining code in this file is derived from the regular expression code -// whose copyright statement appears below. It has been changed to work -// with the class concepts of C++ and COOL. - -/* - * compile and find - * - * Copyright (c) 1986 by University of Toronto. - * Written by Henry Spencer. Not derived from licensed software. - * - * Permission is granted to anyone to use this software for any - * purpose on any computer system, and to redistribute it freely, - * subject to the following restrictions: - * - * 1. The author is not responsible for the consequences of use of - * this software, no matter how awful, even if they arise - * from defects in it. - * - * 2. The origin of this software must not be misrepresented, either - * by explicit claim or by omission. - * - * 3. Altered versions must be plainly marked as such, and must not - * be misrepresented as being the original software. - * - * Beware that some of this code is subtly aware of the way operator - * precedence is structured in regular expressions. Serious changes in - * regular-expression syntax might require a total rethink. - */ - -/* - * The "internal use only" fields in regexp.h are present to pass info from - * compile to execute that permits the execute phase to run lots faster on - * simple cases. They are: - * - * regstart char that must begin a match; '\0' if none obvious - * reganch is the match anchored (at beginning-of-line only)? - * regmust string (pointer into program) that match must include, or - * nullptr regmlen length of regmust string - * - * Regstart and reganch permit very fast decisions on suitable starting points - * for a match, cutting down the work a lot. Regmust permits fast rejection - * of lines that cannot possibly match. The regmust tests are costly enough - * that compile() supplies a regmust only if the r.e. contains something - * potentially expensive (at present, the only such thing detected is * or + - * at the start of the r.e., which can involve a lot of backup). Regmlen is - * supplied because the test in find() needs it and compile() is computing - * it anyway. - */ - -/* - * Structure for regexp "program". This is essentially a linear encoding - * of a nondeterministic finite-state machine (aka syntax charts or - * "railroad normal form" in parsing technology). Each node is an opcode - * plus a "next" pointer, possibly plus an operand. "Next" pointers of - * all nodes except BRANCH implement concatenation; a "next" pointer with - * a BRANCH on both ends of it is connecting two alternatives. (Here we - * have one of the subtle syntax dependencies: an individual BRANCH (as - * opposed to a collection of them) is never concatenated with anything - * because of operator precedence.) The operand of some types of node is - * a literal string; for others, it is a node leading into a sub-FSM. In - * particular, the operand of a BRANCH node is the first node of the branch. - * (NB this is *not* a tree structure: the tail of the branch connects - * to the thing following the set of BRANCHes.) The opcodes are: - */ - -// definition number opnd? meaning -#define END 0 // no End of program. -#define BOL 1 // no Match "" at beginning of line. -#define EOL 2 // no Match "" at end of line. -#define ANY 3 // no Match any one character. -#define ANYOF 4 // str Match any character in this string. -#define ANYBUT \ - 5 // str Match any character not in this - // string. -#define BRANCH \ - 6 // node Match this alternative, or the - // next... -#define BACK 7 // no Match "", "next" ptr points backward. -#define EXACTLY 8 // str Match this string. -#define NOTHING 9 // no Match empty string. -#define STAR \ - 10 // node Match this (simple) thing 0 or more - // times. -#define PLUS \ - 11 // node Match this (simple) thing 1 or more - // times. -#define OPEN \ - 20 // no Mark this point in input as start of - // #n. -// OPEN+1 is number 1, etc. -#define CLOSE 30 // no Analogous to OPEN. - -/* - * Opcode notes: - * - * BRANCH The set of branches constituting a single choice are hooked - * together with their "next" pointers, since precedence prevents - * anything being concatenated to any individual branch. The - * "next" pointer of the last BRANCH in a choice points to the - * thing following the whole choice. This is also where the - * final "next" pointer of each individual branch points; each - * branch starts with the operand node of a BRANCH node. - * - * BACK Normal "next" pointers all implicitly point forward; BACK - * exists to make loop structures possible. - * - * STAR,PLUS '?', and complex '*' and '+', are implemented as circular - * BRANCH structures using BACK. Simple cases (one character - * per match) are implemented with STAR and PLUS for speed - * and to minimize recursive plunges. - * - * OPEN,CLOSE ...are numbered at compile time. - */ - -/* - * A node is one char of opcode followed by two chars of "next" pointer. - * "Next" pointers are stored as two 8-bit pieces, high order first. The - * value is a positive offset from the opcode of the node containing it. - * An operand, if any, simply follows the node. (Note that much of the - * code generation knows about this implicit relationship.) - * - * Using two bytes for the "next" pointer is vast overkill for most things, - * but allows patterns to get big without disasters. - */ - -#define OP(p) (*(p)) -#define NEXT(p) (((*((p) + 1) & 0377) << 8) + (*((p) + 2) & 0377)) -#define OPERAND(p) ((p) + 3) - -const unsigned char MAGIC = 0234; -/* - * Utility definitions. - */ - -#define UCHARAT(p) (reinterpret_cast<const unsigned char*>(p))[0] - -#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') -#define META "^$.[()|?+*\\" - -/* - * Flags to be passed up and down. - */ -#define HASWIDTH 01 // Known never to match null string. -#define SIMPLE 02 // Simple enough to be STAR/PLUS operand. -#define SPSTART 04 // Starts with * or +. -#define WORST 0 // Worst case. - -///////////////////////////////////////////////////////////////////////// -// -// COMPILE AND ASSOCIATED FUNCTIONS -// -///////////////////////////////////////////////////////////////////////// - -/* - * Read only utility variables. - */ -static char regdummy; -static char* const regdummyptr = ®dummy; - -/* - * Utility class for RegularExpression::compile(). - */ -class RegExpCompile -{ -public: - const char* regparse; // Input-scan pointer. - int regnpar; // () count. - char* regcode; // Code-emit pointer; regdummyptr = don't. - long regsize; // Code size. - - char* reg(int, int*); - char* regbranch(int*); - char* regpiece(int*); - char* regatom(int*); - char* regnode(char); - void regc(char); - void reginsert(char, char*); - static void regtail(char*, const char*); - static void regoptail(char*, const char*); -}; - -static const char* regnext(const char*); -static char* regnext(char*); - -#ifdef STRCSPN -static int strcspn(); -#endif - -/* - * We can't allocate space until we know how big the compiled form will be, - * but we can't compile it (and thus know how big it is) until we've got a - * place to put the code. So we cheat: we compile it twice, once with code - * generation turned off and size counting turned on, and once "for real". - * This also means that we don't allocate space until we are sure that the - * thing really will compile successfully, and we never have to move the - * code and thus invalidate pointers into it. (Note that it has to be in - * one piece because free() must be able to free it all.) - * - * Beware that the optimization-preparation code in here knows about some - * of the structure of the compiled regexp. - */ - -// compile -- compile a regular expression into internal code -// for later pattern matching. - -bool RegularExpression::compile(const char* exp) -{ - const char* scan; - const char* longest; - int flags; - - if (exp == nullptr) { - // RAISE Error, SYM(RegularExpression), SYM(No_Expr), - printf("RegularExpression::compile(): No expression supplied.\n"); - return false; - } - - // First pass: determine size, legality. - RegExpCompile comp; - comp.regparse = exp; - comp.regnpar = 1; - comp.regsize = 0L; - comp.regcode = regdummyptr; - comp.regc(static_cast<char>(MAGIC)); - if (!comp.reg(0, &flags)) { - printf("RegularExpression::compile(): Error in compile.\n"); - return false; - } - this->regmatch.clear(); - - // Small enough for pointer-storage convention? - if (comp.regsize >= 32767L) { // Probably could be 65535L. - // RAISE Error, SYM(RegularExpression), SYM(Expr_Too_Big), - printf("RegularExpression::compile(): Expression too big.\n"); - return false; - } - - // Allocate space. - //#ifndef _WIN32 - if (this->program != nullptr) - delete[] this->program; - //#endif - this->program = new char[comp.regsize]; - this->progsize = static_cast<int>(comp.regsize); - - if (this->program == nullptr) { - // RAISE Error, SYM(RegularExpression), SYM(Out_Of_Memory), - printf("RegularExpression::compile(): Out of memory.\n"); - return false; - } - - // Second pass: emit code. - comp.regparse = exp; - comp.regnpar = 1; - comp.regcode = this->program; - comp.regc(static_cast<char>(MAGIC)); - comp.reg(0, &flags); - - // Dig out information for optimizations. - this->regstart = '\0'; // Worst-case defaults. - this->reganch = 0; - this->regmust = nullptr; - this->regmlen = 0; - scan = this->program + 1; // First BRANCH. - if (OP(regnext(scan)) == END) { // Only one top-level choice. - scan = OPERAND(scan); - - // Starting-point info. - if (OP(scan) == EXACTLY) - this->regstart = *OPERAND(scan); - else if (OP(scan) == BOL) - this->reganch++; - - // - // If there's something expensive in the r.e., find the longest - // literal string that must appear and make it the regmust. Resolve - // ties in favor of later strings, since the regstart check works - // with the beginning of the r.e. and avoiding duplication - // strengthens checking. Not a strong reason, but sufficient in the - // absence of others. - // - if (flags & SPSTART) { - longest = nullptr; - size_t len = 0; - for (; scan != nullptr; scan = regnext(scan)) - if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { - longest = OPERAND(scan); - len = strlen(OPERAND(scan)); - } - this->regmust = longest; - this->regmlen = len; - } - } - return true; -} - -/* - - reg - regular expression, i.e. main body or parenthesized thing - * - * Caller must absorb opening parenthesis. - * - * Combining parenthesis handling with the base level of regular expression - * is a trifle forced, but the need to tie the tails of the branches to what - * follows makes it hard to avoid. - */ -char* RegExpCompile::reg(int paren, int* flagp) -{ - char* ret; - char* br; - char* ender; - int parno = 0; - int flags; - - *flagp = HASWIDTH; // Tentatively. - - // Make an OPEN node, if parenthesized. - if (paren) { - if (regnpar >= RegularExpressionMatch::NSUBEXP) { - // RAISE Error, SYM(RegularExpression), SYM(Too_Many_Parens), - printf("RegularExpression::compile(): Too many parentheses.\n"); - return nullptr; - } - parno = regnpar; - regnpar++; - ret = regnode(static_cast<char>(OPEN + parno)); - } else - ret = nullptr; - - // Pick up the branches, linking them together. - br = regbranch(&flags); - if (br == nullptr) - return (nullptr); - if (ret != nullptr) - regtail(ret, br); // OPEN -> first. - else - ret = br; - if (!(flags & HASWIDTH)) - *flagp &= ~HASWIDTH; - *flagp |= flags & SPSTART; - while (*regparse == '|') { - regparse++; - br = regbranch(&flags); - if (br == nullptr) - return (nullptr); - regtail(ret, br); // BRANCH -> BRANCH. - if (!(flags & HASWIDTH)) - *flagp &= ~HASWIDTH; - *flagp |= flags & SPSTART; - } - - // Make a closing node, and hook it on the end. - ender = regnode(static_cast<char>((paren) ? CLOSE + parno : END)); - regtail(ret, ender); - - // Hook the tails of the branches to the closing node. - for (br = ret; br != nullptr; br = regnext(br)) - regoptail(br, ender); - - // Check for proper termination. - if (paren && *regparse++ != ')') { - // RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens), - printf("RegularExpression::compile(): Unmatched parentheses.\n"); - return nullptr; - } else if (!paren && *regparse != '\0') { - if (*regparse == ')') { - // RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens), - printf("RegularExpression::compile(): Unmatched parentheses.\n"); - return nullptr; - } else { - // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), - printf("RegularExpression::compile(): Internal error.\n"); - return nullptr; - } - // NOTREACHED - } - return (ret); -} - -/* - - regbranch - one alternative of an | operator - * - * Implements the concatenation operator. - */ -char* RegExpCompile::regbranch(int* flagp) -{ - char* ret; - char* chain; - char* latest; - int flags; - - *flagp = WORST; // Tentatively. - - ret = regnode(BRANCH); - chain = nullptr; - while (*regparse != '\0' && *regparse != '|' && *regparse != ')') { - latest = regpiece(&flags); - if (latest == nullptr) - return (nullptr); - *flagp |= flags & HASWIDTH; - if (chain == nullptr) // First piece. - *flagp |= flags & SPSTART; - else - regtail(chain, latest); - chain = latest; - } - if (chain == nullptr) // Loop ran zero times. - regnode(NOTHING); - - return (ret); -} - -/* - - regpiece - something followed by possible [*+?] - * - * Note that the branching code sequences used for ? and the general cases - * of * and + are somewhat optimized: they use the same NOTHING node as - * both the endmarker for their branch list and the body of the last branch. - * It might seem that this node could be dispensed with entirely, but the - * endmarker role is not redundant. - */ -char* RegExpCompile::regpiece(int* flagp) -{ - char* ret; - char op; - char* next; - int flags; - - ret = regatom(&flags); - if (ret == nullptr) - return (nullptr); - - op = *regparse; - if (!ISMULT(op)) { - *flagp = flags; - return (ret); - } - - if (!(flags & HASWIDTH) && op != '?') { - // RAISE Error, SYM(RegularExpression), SYM(Empty_Operand), - printf("RegularExpression::compile() : *+ operand could be empty.\n"); - return nullptr; - } - *flagp = (op != '+') ? (WORST | SPSTART) : (WORST | HASWIDTH); - - if (op == '*' && (flags & SIMPLE)) - reginsert(STAR, ret); - else if (op == '*') { - // Emit x* as (x&|), where & means "self". - reginsert(BRANCH, ret); // Either x - regoptail(ret, regnode(BACK)); // and loop - regoptail(ret, ret); // back - regtail(ret, regnode(BRANCH)); // or - regtail(ret, regnode(NOTHING)); // null. - } else if (op == '+' && (flags & SIMPLE)) - reginsert(PLUS, ret); - else if (op == '+') { - // Emit x+ as x(&|), where & means "self". - next = regnode(BRANCH); // Either - regtail(ret, next); - regtail(regnode(BACK), ret); // loop back - regtail(next, regnode(BRANCH)); // or - regtail(ret, regnode(NOTHING)); // null. - } else if (op == '?') { - // Emit x? as (x|) - reginsert(BRANCH, ret); // Either x - regtail(ret, regnode(BRANCH)); // or - next = regnode(NOTHING); // null. - regtail(ret, next); - regoptail(ret, next); - } - regparse++; - if (ISMULT(*regparse)) { - // RAISE Error, SYM(RegularExpression), SYM(Nested_Operand), - printf("RegularExpression::compile(): Nested *?+.\n"); - return nullptr; - } - return (ret); -} - -/* - - regatom - the lowest level - * - * Optimization: gobbles an entire sequence of ordinary characters so that - * it can turn them into a single node, which is smaller to store and - * faster to run. Backslashed characters are exceptions, each becoming a - * separate node; the code is simpler that way and it's not worth fixing. - */ -char* RegExpCompile::regatom(int* flagp) -{ - char* ret; - int flags; - - *flagp = WORST; // Tentatively. - - switch (*regparse++) { - case '^': - ret = regnode(BOL); - break; - case '$': - ret = regnode(EOL); - break; - case '.': - ret = regnode(ANY); - *flagp |= HASWIDTH | SIMPLE; - break; - case '[': { - int rxpclass; - int rxpclassend; - - if (*regparse == '^') { // Complement of range. - ret = regnode(ANYBUT); - regparse++; - } else - ret = regnode(ANYOF); - if (*regparse == ']' || *regparse == '-') - regc(*regparse++); - while (*regparse != '\0' && *regparse != ']') { - if (*regparse == '-') { - regparse++; - if (*regparse == ']' || *regparse == '\0') - regc('-'); - else { - rxpclass = UCHARAT(regparse - 2) + 1; - rxpclassend = UCHARAT(regparse); - if (rxpclass > rxpclassend + 1) { - // RAISE Error, SYM(RegularExpression), SYM(Invalid_Range), - printf("RegularExpression::compile(): Invalid range in [].\n"); - return nullptr; - } - for (; rxpclass <= rxpclassend; rxpclass++) - regc(static_cast<char>(rxpclass)); - regparse++; - } - } else - regc(*regparse++); - } - regc('\0'); - if (*regparse != ']') { - // RAISE Error, SYM(RegularExpression), SYM(Unmatched_Bracket), - printf("RegularExpression::compile(): Unmatched [].\n"); - return nullptr; - } - regparse++; - *flagp |= HASWIDTH | SIMPLE; - } break; - case '(': - ret = reg(1, &flags); - if (ret == nullptr) - return (nullptr); - *flagp |= flags & (HASWIDTH | SPSTART); - break; - case '\0': - case '|': - case ')': - // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), - printf("RegularExpression::compile(): Internal error.\n"); // Never here - return nullptr; - case '?': - case '+': - case '*': - // RAISE Error, SYM(RegularExpression), SYM(No_Operand), - printf("RegularExpression::compile(): ?+* follows nothing.\n"); - return nullptr; - case '\\': - if (*regparse == '\0') { - // RAISE Error, SYM(RegularExpression), SYM(Trailing_Backslash), - printf("RegularExpression::compile(): Trailing backslash.\n"); - return nullptr; - } - ret = regnode(EXACTLY); - regc(*regparse++); - regc('\0'); - *flagp |= HASWIDTH | SIMPLE; - break; - default: { - int len; - char ender; - - regparse--; - len = int(strcspn(regparse, META)); - if (len <= 0) { - // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), - printf("RegularExpression::compile(): Internal error.\n"); - return nullptr; - } - ender = *(regparse + len); - if (len > 1 && ISMULT(ender)) - len--; // Back off clear of ?+* operand. - *flagp |= HASWIDTH; - if (len == 1) - *flagp |= SIMPLE; - ret = regnode(EXACTLY); - while (len > 0) { - regc(*regparse++); - len--; - } - regc('\0'); - } break; - } - return (ret); -} - -/* - - regnode - emit a node - Location. - */ -char* RegExpCompile::regnode(char op) -{ - char* ret; - char* ptr; - - ret = regcode; - if (ret == regdummyptr) { - regsize += 3; - return (ret); - } - - ptr = ret; - *ptr++ = op; - *ptr++ = '\0'; // Null "next" pointer. - *ptr++ = '\0'; - regcode = ptr; - - return (ret); -} - -/* - - regc - emit (if appropriate) a byte of code - */ -void RegExpCompile::regc(char b) -{ - if (regcode != regdummyptr) - *regcode++ = b; - else - regsize++; -} - -/* - - reginsert - insert an operator in front of already-emitted operand - * - * Means relocating the operand. - */ -void RegExpCompile::reginsert(char op, char* opnd) -{ - char* src; - char* dst; - char* place; - - if (regcode == regdummyptr) { - regsize += 3; - return; - } - - src = regcode; - regcode += 3; - dst = regcode; - while (src > opnd) - *--dst = *--src; - - place = opnd; // Op node, where operand used to be. - *place++ = op; - *place++ = '\0'; - *place = '\0'; -} - -/* - - regtail - set the next-pointer at the end of a node chain - */ -void RegExpCompile::regtail(char* p, const char* val) -{ - char* scan; - char* temp; - int offset; - - if (p == regdummyptr) - return; - - // Find last node. - scan = p; - for (;;) { - temp = regnext(scan); - if (temp == nullptr) - break; - scan = temp; - } - - if (OP(scan) == BACK) - offset = int(scan - val); - else - offset = int(val - scan); - *(scan + 1) = static_cast<char>((offset >> 8) & 0377); - *(scan + 2) = static_cast<char>(offset & 0377); -} - -/* - - regoptail - regtail on operand of first argument; nop if operandless - */ -void RegExpCompile::regoptail(char* p, const char* val) -{ - // "Operandless" and "op != BRANCH" are synonymous in practice. - if (p == nullptr || p == regdummyptr || OP(p) != BRANCH) - return; - regtail(OPERAND(p), val); -} - -//////////////////////////////////////////////////////////////////////// -// -// find and friends -// -//////////////////////////////////////////////////////////////////////// - -/* - * Utility class for RegularExpression::find(). - */ -class RegExpFind -{ -public: - const char* reginput; // String-input pointer. - const char* regbol; // Beginning of input, for ^ check. - const char** regstartp; // Pointer to startp array. - const char** regendp; // Ditto for endp. - - int regtry(const char*, const char**, const char**, const char*); - int regmatch(const char*); - int regrepeat(const char*); -}; - -// find -- Matches the regular expression to the given string. -// Returns true if found, and sets start and end indexes accordingly. -bool RegularExpression::find(char const* string, - RegularExpressionMatch& rmatch) const -{ - const char* s; - - rmatch.clear(); - rmatch.searchstring = string; - - if (!this->program) { - return false; - } - - // Check validity of program. - if (UCHARAT(this->program) != MAGIC) { - // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), - printf( - "RegularExpression::find(): Compiled regular expression corrupted.\n"); - return false; - } - - // If there is a "must appear" string, look for it. - if (this->regmust != nullptr) { - s = string; - while ((s = strchr(s, this->regmust[0])) != nullptr) { - if (strncmp(s, this->regmust, this->regmlen) == 0) - break; // Found it. - s++; - } - if (s == nullptr) // Not present. - return false; - } - - RegExpFind regFind; - - // Mark beginning of line for ^ . - regFind.regbol = string; - - // Simplest case: anchored match need be tried only once. - if (this->reganch) - return ( - regFind.regtry(string, rmatch.startp, rmatch.endp, this->program) != 0); - - // Messy cases: unanchored match. - s = string; - if (this->regstart != '\0') - // We know what char it must start with. - while ((s = strchr(s, this->regstart)) != nullptr) { - if (regFind.regtry(s, rmatch.startp, rmatch.endp, this->program)) - return true; - s++; - } - else - // We don't -- general case. - do { - if (regFind.regtry(s, rmatch.startp, rmatch.endp, this->program)) - return true; - } while (*s++ != '\0'); - - // Failure. - return false; -} - -/* - - regtry - try match at specific point - 0 failure, 1 success - */ -int RegExpFind::regtry(const char* string, const char** start, - const char** end, const char* prog) -{ - int i; - const char** sp1; - const char** ep; - - reginput = string; - regstartp = start; - regendp = end; - - sp1 = start; - ep = end; - for (i = RegularExpressionMatch::NSUBEXP; i > 0; i--) { - *sp1++ = nullptr; - *ep++ = nullptr; - } - if (regmatch(prog + 1)) { - start[0] = string; - end[0] = reginput; - return (1); - } else - return (0); -} - -/* - - regmatch - main matching routine - * - * Conceptually the strategy is simple: check to see whether the current - * node matches, call self recursively to see whether the rest matches, - * and then act accordingly. In practice we make some effort to avoid - * recursion, in particular by going through "ordinary" nodes (that don't - * need to know whether the rest of the match failed) by a loop instead of - * by recursion. - * 0 failure, 1 success - */ -int RegExpFind::regmatch(const char* prog) -{ - const char* scan; // Current node. - const char* next; // Next node. - - scan = prog; - - while (scan != nullptr) { - - next = regnext(scan); - - switch (OP(scan)) { - case BOL: - if (reginput != regbol) - return (0); - break; - case EOL: - if (*reginput != '\0') - return (0); - break; - case ANY: - if (*reginput == '\0') - return (0); - reginput++; - break; - case EXACTLY: { - size_t len; - const char* opnd; - - opnd = OPERAND(scan); - // Inline the first character, for speed. - if (*opnd != *reginput) - return (0); - len = strlen(opnd); - if (len > 1 && strncmp(opnd, reginput, len) != 0) - return (0); - reginput += len; - } break; - case ANYOF: - if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == nullptr) - return (0); - reginput++; - break; - case ANYBUT: - if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != nullptr) - return (0); - reginput++; - break; - case NOTHING: - break; - case BACK: - break; - case OPEN + 1: - case OPEN + 2: - case OPEN + 3: - case OPEN + 4: - case OPEN + 5: - case OPEN + 6: - case OPEN + 7: - case OPEN + 8: - case OPEN + 9: { - int no; - const char* save; - - no = OP(scan) - OPEN; - save = reginput; - - if (regmatch(next)) { - - // - // Don't set startp if some later invocation of the - // same parentheses already has. - // - if (regstartp[no] == nullptr) - regstartp[no] = save; - return (1); - } else - return (0); - } - // break; - case CLOSE + 1: - case CLOSE + 2: - case CLOSE + 3: - case CLOSE + 4: - case CLOSE + 5: - case CLOSE + 6: - case CLOSE + 7: - case CLOSE + 8: - case CLOSE + 9: { - int no; - const char* save; - - no = OP(scan) - CLOSE; - save = reginput; - - if (regmatch(next)) { - - // - // Don't set endp if some later invocation of the - // same parentheses already has. - // - if (regendp[no] == nullptr) - regendp[no] = save; - return (1); - } else - return (0); - } - // break; - case BRANCH: { - - const char* save; - - if (OP(next) != BRANCH) // No choice. - next = OPERAND(scan); // Avoid recursion. - else { - do { - save = reginput; - if (regmatch(OPERAND(scan))) - return (1); - reginput = save; - scan = regnext(scan); - } while (scan != nullptr && OP(scan) == BRANCH); - return (0); - // NOTREACHED - } - } break; - case STAR: - case PLUS: { - char nextch; - int no; - const char* save; - int min_no; - - // - // Lookahead to avoid useless match attempts when we know - // what character comes next. - // - nextch = '\0'; - if (OP(next) == EXACTLY) - nextch = *OPERAND(next); - min_no = (OP(scan) == STAR) ? 0 : 1; - save = reginput; - no = regrepeat(OPERAND(scan)); - while (no >= min_no) { - // If it could work, try it. - if (nextch == '\0' || *reginput == nextch) - if (regmatch(next)) - return (1); - // Couldn't or didn't -- back up. - no--; - reginput = save + no; - } - return (0); - } - // break; - case END: - return (1); // Success! - - default: - // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), - printf( - "RegularExpression::find(): Internal error -- memory corrupted.\n"); - return 0; - } - scan = next; - } - - // - // We get here only if there's trouble -- normally "case END" is the - // terminating point. - // - // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), - printf("RegularExpression::find(): Internal error -- corrupted pointers.\n"); - return (0); -} - -/* - - regrepeat - repeatedly match something simple, report how many - */ -int RegExpFind::regrepeat(const char* p) -{ - int count = 0; - const char* scan; - const char* opnd; - - scan = reginput; - opnd = OPERAND(p); - switch (OP(p)) { - case ANY: - count = int(strlen(scan)); - scan += count; - break; - case EXACTLY: - while (*opnd == *scan) { - count++; - scan++; - } - break; - case ANYOF: - while (*scan != '\0' && strchr(opnd, *scan) != nullptr) { - count++; - scan++; - } - break; - case ANYBUT: - while (*scan != '\0' && strchr(opnd, *scan) == nullptr) { - count++; - scan++; - } - break; - default: // Oh dear. Called inappropriately. - // RAISE Error, SYM(RegularExpression), SYM(Internal_Error), - printf("cm RegularExpression::find(): Internal error.\n"); - return 0; - } - reginput = scan; - return (count); -} - -/* - - regnext - dig the "next" pointer out of a node - */ -static const char* regnext(const char* p) -{ - int offset; - - if (p == regdummyptr) - return (nullptr); - - offset = NEXT(p); - if (offset == 0) - return (nullptr); - - if (OP(p) == BACK) - return (p - offset); - else - return (p + offset); -} - -static char* regnext(char* p) -{ - int offset; - - if (p == regdummyptr) - return (nullptr); - - offset = NEXT(p); - if (offset == 0) - return (nullptr); - - if (OP(p) == BACK) - return (p - offset); - else - return (p + offset); -} - -} // namespace KWSYS_NAMESPACE diff --git a/test/API/driver/kwsys/RegularExpression.hxx.in b/test/API/driver/kwsys/RegularExpression.hxx.in deleted file mode 100644 index 0c2366b..0000000 --- a/test/API/driver/kwsys/RegularExpression.hxx.in +++ /dev/null @@ -1,562 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -// Original Copyright notice: -// Copyright (C) 1991 Texas Instruments Incorporated. -// -// Permission is granted to any individual or institution to use, copy, modify, -// and distribute this software, provided that this complete copyright and -// permission notice is maintained, intact, in all copies and supporting -// documentation. -// -// Texas Instruments Incorporated provides this software "as is" without -// express or implied warranty. -// -// Created: MNF 06/13/89 Initial Design and Implementation -// Updated: LGO 08/09/89 Inherit from Generic -// Updated: MBN 09/07/89 Added conditional exception handling -// Updated: MBN 12/15/89 Sprinkled "const" qualifiers all over the place! -// Updated: DLS 03/22/91 New lite version -// - -#ifndef @KWSYS_NAMESPACE@_RegularExpression_hxx -#define @KWSYS_NAMESPACE@_RegularExpression_hxx - -#include <@KWSYS_NAMESPACE@/Configure.h> -#include <@KWSYS_NAMESPACE@/Configure.hxx> - -#include <string> - -/* Disable useless Borland warnings. KWSys tries not to force things - on its includers, but there is no choice here. */ -#if defined(__BORLANDC__) -# pragma warn - 8027 /* function not inlined. */ -#endif - -namespace @KWSYS_NAMESPACE@ { - -// Forward declaration -class RegularExpression; - -/** \class RegularExpressionMatch - * \brief Stores the pattern matches of a RegularExpression - */ -class @KWSYS_NAMESPACE@_EXPORT RegularExpressionMatch -{ -public: - RegularExpressionMatch(); - - bool isValid() const; - void clear(); - - std::string::size_type start() const; - std::string::size_type end() const; - std::string::size_type start(int n) const; - std::string::size_type end(int n) const; - std::string match(int n) const; - - enum - { - NSUBEXP = 10 - }; - -private: - friend class RegularExpression; - const char* startp[NSUBEXP]; - const char* endp[NSUBEXP]; - const char* searchstring; -}; - -/** - * \brief Creates an invalid match object - */ -inline RegularExpressionMatch::RegularExpressionMatch() - : startp{} - , endp{} - , searchstring{} -{ -} - -/** - * \brief Returns true if the match pointers are valid - */ -inline bool RegularExpressionMatch::isValid() const -{ - return (this->startp[0] != nullptr); -} - -/** - * \brief Resets to the (invalid) construction state. - */ -inline void RegularExpressionMatch::clear() -{ - startp[0] = nullptr; - endp[0] = nullptr; - searchstring = nullptr; -} - -/** - * \brief Returns the start index of the full match. - */ -inline std::string::size_type RegularExpressionMatch::start() const -{ - return static_cast<std::string::size_type>(this->startp[0] - searchstring); -} - -/** - * \brief Returns the end index of the full match. - */ -inline std::string::size_type RegularExpressionMatch::end() const -{ - return static_cast<std::string::size_type>(this->endp[0] - searchstring); -} - -/** - * \brief Returns the start index of nth submatch. - * start(0) is the start of the full match. - */ -inline std::string::size_type RegularExpressionMatch::start(int n) const -{ - return static_cast<std::string::size_type>(this->startp[n] - - this->searchstring); -} - -/** - * \brief Returns the end index of nth submatch. - * end(0) is the end of the full match. - */ -inline std::string::size_type RegularExpressionMatch::end(int n) const -{ - return static_cast<std::string::size_type>(this->endp[n] - - this->searchstring); -} - -/** - * \brief Returns the nth submatch as a string. - */ -inline std::string RegularExpressionMatch::match(int n) const -{ - if (this->startp[n] == nullptr) { - return std::string(); - } else { - return std::string( - this->startp[n], - static_cast<std::string::size_type>(this->endp[n] - this->startp[n])); - } -} - -/** \class RegularExpression - * \brief Implements pattern matching with regular expressions. - * - * This is the header file for the regular expression class. An object of - * this class contains a regular expression, in a special "compiled" format. - * This compiled format consists of several slots all kept as the objects - * private data. The RegularExpression class provides a convenient way to - * represent regular expressions. It makes it easy to search for the same - * regular expression in many different strings without having to compile a - * string to regular expression format more than necessary. - * - * This class implements pattern matching via regular expressions. - * A regular expression allows a programmer to specify complex - * patterns that can be searched for and matched against the - * character string of a string object. In its simplest form, a - * regular expression is a sequence of characters used to - * search for exact character matches. However, many times the - * exact sequence to be found is not known, or only a match at - * the beginning or end of a string is desired. The RegularExpression regu- - * lar expression class implements regular expression pattern - * matching as is found and implemented in many UNIX commands - * and utilities. - * - * Example: The perl code - * - * $filename =~ m"([a-z]+)\.cc"; - * print $1; - * - * Is written as follows in C++ - * - * RegularExpression re("([a-z]+)\\.cc"); - * re.find(filename); - * cerr << re.match(1); - * - * - * The regular expression class provides a convenient mechanism - * for specifying and manipulating regular expressions. The - * regular expression object allows specification of such pat- - * terns by using the following regular expression metacharac- - * ters: - * - * ^ Matches at beginning of a line - * - * $ Matches at end of a line - * - * . Matches any single character - * - * [ ] Matches any character(s) inside the brackets - * - * [^ ] Matches any character(s) not inside the brackets - * - * - Matches any character in range on either side of a dash - * - * * Matches preceding pattern zero or more times - * - * + Matches preceding pattern one or more times - * - * ? Matches preceding pattern zero or once only - * - * () Saves a matched expression and uses it in a later match - * - * Note that more than one of these metacharacters can be used - * in a single regular expression in order to create complex - * search patterns. For example, the pattern [^ab1-9] says to - * match any character sequence that does not begin with the - * characters "ab" followed by numbers in the series one - * through nine. - * - * There are three constructors for RegularExpression. One just creates an - * empty RegularExpression object. Another creates a RegularExpression - * object and initializes it with a regular expression that is given in the - * form of a char*. The third takes a reference to a RegularExpression - * object as an argument and creates an object initialized with the - * information from the given RegularExpression object. - * - * The find member function finds the first occurrence of the regular - * expression of that object in the string given to find as an argument. Find - * returns a boolean, and if true, mutates the private data appropriately. - * Find sets pointers to the beginning and end of the thing last found, they - * are pointers into the actual string that was searched. The start and end - * member functions return indices into the searched string that correspond - * to the beginning and end pointers respectively. The compile member - * function takes a char* and puts the compiled version of the char* argument - * into the object's private data fields. The == and != operators only check - * the to see if the compiled regular expression is the same, and the - * deep_equal functions also checks to see if the start and end pointers are - * the same. The is_valid function returns false if program is set to - * nullptr, (i.e. there is no valid compiled expression). The set_invalid - * function sets the program to nullptr (Warning: this deletes the compiled - * expression). The following examples may help clarify regular expression - * usage: - * - * * The regular expression "^hello" matches a "hello" only at the - * beginning of a line. It would match "hello there" but not "hi, - * hello there". - * - * * The regular expression "long$" matches a "long" only at the end - * of a line. It would match "so long\0", but not "long ago". - * - * * The regular expression "t..t..g" will match anything that has a - * "t" then any two characters, another "t", any two characters and - * then a "g". It will match "testing", or "test again" but would - * not match "toasting" - * - * * The regular expression "[1-9ab]" matches any number one through - * nine, and the characters "a" and "b". It would match "hello 1" - * or "begin", but would not match "no-match". - * - * * The regular expression "[^1-9ab]" matches any character that is - * not a number one through nine, or an "a" or "b". It would NOT - * match "hello 1" or "begin", but would match "no-match". - * - * * The regular expression "br* " matches something that begins with - * a "b", is followed by zero or more "r"s, and ends in a space. It - * would match "brrrrr ", and "b ", but would not match "brrh ". - * - * * The regular expression "br+ " matches something that begins with - * a "b", is followed by one or more "r"s, and ends in a space. It - * would match "brrrrr ", and "br ", but would not match "b " or - * "brrh ". - * - * * The regular expression "br? " matches something that begins with - * a "b", is followed by zero or one "r"s, and ends in a space. It - * would match "br ", and "b ", but would not match "brrrr " or - * "brrh ". - * - * * The regular expression "(..p)b" matches something ending with pb - * and beginning with whatever the two characters before the first p - * encountered in the line were. It would find "repb" in "rep drepa - * qrepb". The regular expression "(..p)a" would find "repa qrepb" - * in "rep drepa qrepb" - * - * * The regular expression "d(..p)" matches something ending with p, - * beginning with d, and having two characters in between that are - * the same as the two characters before the first p encountered in - * the line. It would match "drepa qrepb" in "rep drepa qrepb". - * - * All methods of RegularExpression can be called simultaneously from - * different threads but only if each invocation uses an own instance of - * RegularExpression. - */ -class @KWSYS_NAMESPACE@_EXPORT RegularExpression -{ -public: - /** - * Instantiate RegularExpression with program=nullptr. - */ - inline RegularExpression(); - - /** - * Instantiate RegularExpression with compiled char*. - */ - inline RegularExpression(char const*); - - /** - * Instantiate RegularExpression as a copy of another regular expression. - */ - RegularExpression(RegularExpression const&); - - /** - * Instantiate RegularExpression with compiled string. - */ - inline RegularExpression(std::string const&); - - /** - * Destructor. - */ - inline ~RegularExpression(); - - /** - * Compile a regular expression into internal code - * for later pattern matching. - */ - bool compile(char const*); - - /** - * Compile a regular expression into internal code - * for later pattern matching. - */ - inline bool compile(std::string const&); - - /** - * Matches the regular expression to the given string. - * Returns true if found, and sets start and end indexes - * in the RegularExpressionMatch instance accordingly. - * - * This method is thread safe when called with different - * RegularExpressionMatch instances. - */ - bool find(char const*, RegularExpressionMatch&) const; - - /** - * Matches the regular expression to the given string. - * Returns true if found, and sets start and end indexes accordingly. - */ - inline bool find(char const*); - - /** - * Matches the regular expression to the given std string. - * Returns true if found, and sets start and end indexes accordingly. - */ - inline bool find(std::string const&); - - /** - * Match indices - */ - inline RegularExpressionMatch const& regMatch() const; - inline std::string::size_type start() const; - inline std::string::size_type end() const; - inline std::string::size_type start(int n) const; - inline std::string::size_type end(int n) const; - - /** - * Match strings - */ - inline std::string match(int n) const; - - /** - * Copy the given regular expression. - */ - RegularExpression& operator=(const RegularExpression& rxp); - - /** - * Returns true if two regular expressions have the same - * compiled program for pattern matching. - */ - bool operator==(RegularExpression const&) const; - - /** - * Returns true if two regular expressions have different - * compiled program for pattern matching. - */ - inline bool operator!=(RegularExpression const&) const; - - /** - * Returns true if have the same compiled regular expressions - * and the same start and end pointers. - */ - bool deep_equal(RegularExpression const&) const; - - /** - * True if the compiled regexp is valid. - */ - inline bool is_valid() const; - - /** - * Marks the regular expression as invalid. - */ - inline void set_invalid(); - -private: - RegularExpressionMatch regmatch; - char regstart; // Internal use only - char reganch; // Internal use only - const char* regmust; // Internal use only - std::string::size_type regmlen; // Internal use only - char* program; - int progsize; -}; - -/** - * Create an empty regular expression. - */ -inline RegularExpression::RegularExpression() - : regstart{} - , reganch{} - , regmust{} - , program{ nullptr } - , progsize{} -{ -} - -/** - * Creates a regular expression from string s, and - * compiles s. - */ -inline RegularExpression::RegularExpression(const char* s) - : regstart{} - , reganch{} - , regmust{} - , program{ nullptr } - , progsize{} -{ - if (s) { - this->compile(s); - } -} - -/** - * Creates a regular expression from string s, and - * compiles s. - */ -inline RegularExpression::RegularExpression(const std::string& s) - : regstart{} - , reganch{} - , regmust{} - , program{ nullptr } - , progsize{} -{ - this->compile(s); -} - -/** - * Destroys and frees space allocated for the regular expression. - */ -inline RegularExpression::~RegularExpression() -{ - //#ifndef _WIN32 - delete[] this->program; - //#endif -} - -/** - * Compile a regular expression into internal code - * for later pattern matching. - */ -inline bool RegularExpression::compile(std::string const& s) -{ - return this->compile(s.c_str()); -} - -/** - * Matches the regular expression to the given std string. - * Returns true if found, and sets start and end indexes accordingly. - */ -inline bool RegularExpression::find(const char* s) -{ - return this->find(s, this->regmatch); -} - -/** - * Matches the regular expression to the given std string. - * Returns true if found, and sets start and end indexes accordingly. - */ -inline bool RegularExpression::find(std::string const& s) -{ - return this->find(s.c_str()); -} - -/** - * Returns the internal match object - */ -inline RegularExpressionMatch const& RegularExpression::regMatch() const -{ - return this->regmatch; -} - -/** - * Returns the start index of the full match. - */ -inline std::string::size_type RegularExpression::start() const -{ - return regmatch.start(); -} - -/** - * Returns the end index of the full match. - */ -inline std::string::size_type RegularExpression::end() const -{ - return regmatch.end(); -} - -/** - * Return start index of nth submatch. start(0) is the start of the full match. - */ -inline std::string::size_type RegularExpression::start(int n) const -{ - return regmatch.start(n); -} - -/** - * Return end index of nth submatch. end(0) is the end of the full match. - */ -inline std::string::size_type RegularExpression::end(int n) const -{ - return regmatch.end(n); -} - -/** - * Return nth submatch as a string. - */ -inline std::string RegularExpression::match(int n) const -{ - return regmatch.match(n); -} - -/** - * Returns true if two regular expressions have different - * compiled program for pattern matching. - */ -inline bool RegularExpression::operator!=(const RegularExpression& r) const -{ - return (!(*this == r)); -} - -/** - * Returns true if a valid regular expression is compiled - * and ready for pattern matching. - */ -inline bool RegularExpression::is_valid() const -{ - return (this->program != nullptr); -} - -inline void RegularExpression::set_invalid() -{ - //#ifndef _WIN32 - delete[] this->program; - //#endif - this->program = nullptr; -} - -} // namespace @KWSYS_NAMESPACE@ - -#endif diff --git a/test/API/driver/kwsys/SetupForDevelopment.sh b/test/API/driver/kwsys/SetupForDevelopment.sh deleted file mode 100644 index c3a2b16..0000000 --- a/test/API/driver/kwsys/SetupForDevelopment.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -cd "${BASH_SOURCE%/*}" && -GitSetup/setup-user && echo && -GitSetup/setup-hooks && echo && -GitSetup/setup-aliases && echo && -GitSetup/setup-upstream && echo && -GitSetup/tips - -# Rebase master by default -git config rebase.stat true -git config branch.master.rebase true - -# Disable Gerrit hook explicitly so the commit-msg hook will -# not complain even if some gerrit remotes are still configured. -git config hooks.GerritId false - -# Record the version of this setup so Scripts/pre-commit can check it. -SetupForDevelopment_VERSION=2 -git config hooks.SetupForDevelopment ${SetupForDevelopment_VERSION} diff --git a/test/API/driver/kwsys/SharedForward.h.in b/test/API/driver/kwsys/SharedForward.h.in deleted file mode 100644 index 5716cd4..0000000 --- a/test/API/driver/kwsys/SharedForward.h.in +++ /dev/null @@ -1,879 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_SharedForward_h -# define @KWSYS_NAMESPACE@_SharedForward_h - -/* - This header is used to create a forwarding executable sets up the - shared library search path and replaces itself with a real - executable. This is useful when creating installations on UNIX with - shared libraries that will run from any install directory. Typical - usage: - - #if defined(CMAKE_INTDIR) - # define CONFIG_DIR_PRE CMAKE_INTDIR "/" - # define CONFIG_DIR_POST "/" CMAKE_INTDIR - #else - # define CONFIG_DIR_PRE "" - # define CONFIG_DIR_POST "" - #endif - #define @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD "/path/to/foo-build/bin" - #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD "." CONFIG_DIR_POST - #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL "../lib/foo-1.2" - #define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD CONFIG_DIR_PRE "foo-real" - #define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL - "../lib/foo-1.2/foo-real" - #define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND "--command" - #define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT "--print" - #define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD "--ldd" - #if defined(CMAKE_INTDIR) - # define @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME CMAKE_INTDIR - #endif - #include <@KWSYS_NAMESPACE@/SharedForward.h> - int main(int argc, char** argv) - { - return @KWSYS_NAMESPACE@_shared_forward_to_real(argc, argv); - } - - Specify search and executable paths relative to the forwarding - executable location or as full paths. Include no trailing slash. - In the case of a multi-configuration build, when CMAKE_INTDIR is - defined, the DIR_BUILD setting should point at the directory above - the executable (the one containing the per-configuration - subdirectory specified by CMAKE_INTDIR). Then PATH_BUILD entries - and EXE_BUILD should be specified relative to this location and use - CMAKE_INTDIR as necessary. In the above example imagine appending - the PATH_BUILD or EXE_BUILD setting to the DIR_BUILD setting. The - result should form a valid path with per-configuration subdirectory. - - Additional paths may be specified in the PATH_BUILD and PATH_INSTALL - variables by using comma-separated strings. For example: - - #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD \ - "." CONFIG_DIR_POST, "/path/to/bar-build" CONFIG_DIR_POST - #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL \ - "../lib/foo-1.2", "../lib/bar-4.5" - - See the comments below for specific explanations of each macro. -*/ - -/* Disable -Wcast-qual warnings since they are too hard to fix in a - cross-platform way. */ -# if defined(__clang__) && defined(__has_warning) -# if __has_warning("-Wcast-qual") -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wcast-qual" -# endif -# endif - -# if defined(__BORLANDC__) && !defined(__cplusplus) -/* Code has no effect; raised by winnt.h in C (not C++) when ignoring an - unused parameter using "(param)" syntax (i.e. no cast to void). */ -# pragma warn - 8019 -# endif - -/* Full path to the directory in which this executable is built. Do - not include a trailing slash. */ -# if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD) -# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD" -# endif -# if !defined(KWSYS_SHARED_FORWARD_DIR_BUILD) -# define KWSYS_SHARED_FORWARD_DIR_BUILD \ - @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD -# endif - -/* Library search path for build tree. */ -# if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD) -# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD" -# endif -# if !defined(KWSYS_SHARED_FORWARD_PATH_BUILD) -# define KWSYS_SHARED_FORWARD_PATH_BUILD \ - @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD -# endif - -/* Library search path for install tree. */ -# if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL) -# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL" -# endif -# if !defined(KWSYS_SHARED_FORWARD_PATH_INSTALL) -# define KWSYS_SHARED_FORWARD_PATH_INSTALL \ - @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL -# endif - -/* The real executable to which to forward in the build tree. */ -# if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD) -# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD" -# endif -# if !defined(KWSYS_SHARED_FORWARD_EXE_BUILD) -# define KWSYS_SHARED_FORWARD_EXE_BUILD \ - @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD -# endif - -/* The real executable to which to forward in the install tree. */ -# if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL) -# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL" -# endif -# if !defined(KWSYS_SHARED_FORWARD_EXE_INSTALL) -# define KWSYS_SHARED_FORWARD_EXE_INSTALL \ - @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL -# endif - -/* The configuration name with which this executable was built (Debug/Release). - */ -# if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME) -# define KWSYS_SHARED_FORWARD_CONFIG_NAME \ - @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME -# else -# undef KWSYS_SHARED_FORWARD_CONFIG_NAME -# endif - -/* Create command line option to replace executable. */ -# if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND) -# if !defined(KWSYS_SHARED_FORWARD_OPTION_COMMAND) -# define KWSYS_SHARED_FORWARD_OPTION_COMMAND \ - @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND -# endif -# else -# undef KWSYS_SHARED_FORWARD_OPTION_COMMAND -# endif - -/* Create command line option to print environment setting and exit. */ -# if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT) -# if !defined(KWSYS_SHARED_FORWARD_OPTION_PRINT) -# define KWSYS_SHARED_FORWARD_OPTION_PRINT \ - @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT -# endif -# else -# undef KWSYS_SHARED_FORWARD_OPTION_PRINT -# endif - -/* Create command line option to run ldd or equivalent. */ -# if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD) -# if !defined(KWSYS_SHARED_FORWARD_OPTION_LDD) -# define KWSYS_SHARED_FORWARD_OPTION_LDD \ - @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD -# endif -# else -# undef KWSYS_SHARED_FORWARD_OPTION_LDD -# endif - -/* Include needed system headers. */ - -# include <errno.h> -# include <limits.h> -# include <stddef.h> /* size_t */ -# include <stdio.h> -# include <stdlib.h> -# include <string.h> - -# if defined(_WIN32) && !defined(__CYGWIN__) -# include <windows.h> - -# include <io.h> -# include <process.h> -# define KWSYS_SHARED_FORWARD_ESCAPE_ARGV /* re-escape argv for execvp */ -# else -# include <sys/stat.h> -# include <unistd.h> -# endif - -/* Configuration for this platform. */ - -/* The path separator for this platform. */ -# if defined(_WIN32) && !defined(__CYGWIN__) -# define KWSYS_SHARED_FORWARD_PATH_SEP ';' -# define KWSYS_SHARED_FORWARD_PATH_SLASH '\\' -# else -# define KWSYS_SHARED_FORWARD_PATH_SEP ':' -# define KWSYS_SHARED_FORWARD_PATH_SLASH '/' -# endif -static const char kwsys_shared_forward_path_sep[2] = { - KWSYS_SHARED_FORWARD_PATH_SEP, 0 -}; -static const char kwsys_shared_forward_path_slash[2] = { - KWSYS_SHARED_FORWARD_PATH_SLASH, 0 -}; - -/* The maximum length of a file name. */ -# if defined(PATH_MAX) -# define KWSYS_SHARED_FORWARD_MAXPATH PATH_MAX -# elif defined(MAXPATHLEN) -# define KWSYS_SHARED_FORWARD_MAXPATH MAXPATHLEN -# else -# define KWSYS_SHARED_FORWARD_MAXPATH 16384 -# endif - -/* Select the environment variable holding the shared library runtime - search path for this platform and build configuration. Also select - ldd command equivalent. */ - -/* Linux */ -# if defined(__linux) -# define KWSYS_SHARED_FORWARD_LDD "ldd" -# define KWSYS_SHARED_FORWARD_LDD_N 1 -# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH" - -/* FreeBSD */ -# elif defined(__FreeBSD__) -# define KWSYS_SHARED_FORWARD_LDD "ldd" -# define KWSYS_SHARED_FORWARD_LDD_N 1 -# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH" - -/* OpenBSD */ -# elif defined(__OpenBSD__) -# define KWSYS_SHARED_FORWARD_LDD "ldd" -# define KWSYS_SHARED_FORWARD_LDD_N 1 -# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH" - -/* OS X */ -# elif defined(__APPLE__) -# define KWSYS_SHARED_FORWARD_LDD "otool", "-L" -# define KWSYS_SHARED_FORWARD_LDD_N 2 -# define KWSYS_SHARED_FORWARD_LDPATH "DYLD_LIBRARY_PATH" - -/* AIX */ -# elif defined(_AIX) -# define KWSYS_SHARED_FORWARD_LDD "dump", "-H" -# define KWSYS_SHARED_FORWARD_LDD_N 2 -# define KWSYS_SHARED_FORWARD_LDPATH "LIBPATH" - -/* SUN */ -# elif defined(__sun) -# define KWSYS_SHARED_FORWARD_LDD "ldd" -# define KWSYS_SHARED_FORWARD_LDD_N 1 -# include <sys/isa_defs.h> -# if defined(_ILP32) -# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH" -# elif defined(_LP64) -# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH_64" -# endif - -/* HP-UX */ -# elif defined(__hpux) -# define KWSYS_SHARED_FORWARD_LDD "chatr" -# define KWSYS_SHARED_FORWARD_LDD_N 1 -# if defined(__LP64__) -# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH" -# else -# define KWSYS_SHARED_FORWARD_LDPATH "SHLIB_PATH" -# endif - -/* SGI MIPS */ -# elif defined(__sgi) && defined(_MIPS_SIM) -# define KWSYS_SHARED_FORWARD_LDD "ldd" -# define KWSYS_SHARED_FORWARD_LDD_N 1 -# if _MIPS_SIM == _ABIO32 -# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH" -# elif _MIPS_SIM == _ABIN32 -# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARYN32_PATH" -# elif _MIPS_SIM == _ABI64 -# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY64_PATH" -# endif - -/* Cygwin */ -# elif defined(__CYGWIN__) -# define KWSYS_SHARED_FORWARD_LDD \ - "cygcheck" /* TODO: cygwin 1.7 has ldd \ - */ -# define KWSYS_SHARED_FORWARD_LDD_N 1 -# define KWSYS_SHARED_FORWARD_LDPATH "PATH" - -/* Windows */ -# elif defined(_WIN32) -# define KWSYS_SHARED_FORWARD_LDPATH "PATH" - -/* Guess on this unknown system. */ -# else -# define KWSYS_SHARED_FORWARD_LDD "ldd" -# define KWSYS_SHARED_FORWARD_LDD_N 1 -# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH" -# endif - -# ifdef KWSYS_SHARED_FORWARD_ESCAPE_ARGV -typedef struct kwsys_sf_arg_info_s -{ - const char* arg; - int size; - int quote; -} kwsys_sf_arg_info; - -static kwsys_sf_arg_info kwsys_sf_get_arg_info(const char* in) -{ - /* Initialize information. */ - kwsys_sf_arg_info info; - - /* String iterator. */ - const char* c; - - /* Keep track of how many backslashes have been encountered in a row. */ - int windows_backslashes = 0; - - /* Start with the length of the original argument, plus one for - either a terminating null or a separating space. */ - info.arg = in; - info.size = (int)strlen(in) + 1; - info.quote = 0; - - /* Scan the string for characters that require escaping or quoting. */ - for (c = in; *c; ++c) { - /* Check whether this character needs quotes. */ - if (strchr(" \t?'#&<>|^", *c)) { - info.quote = 1; - } - - /* On Windows only backslashes and double-quotes need escaping. */ - if (*c == '\\') { - /* Found a backslash. It may need to be escaped later. */ - ++windows_backslashes; - } else if (*c == '"') { - /* Found a double-quote. We need to escape it and all - immediately preceding backslashes. */ - info.size += windows_backslashes + 1; - windows_backslashes = 0; - } else { - /* Found another character. This eliminates the possibility - that any immediately preceding backslashes will be - escaped. */ - windows_backslashes = 0; - } - } - - /* Check whether the argument needs surrounding quotes. */ - if (info.quote) { - /* Surrounding quotes are needed. Allocate space for them. */ - info.size += 2; - - /* We must escape all ending backslashes when quoting on windows. */ - info.size += windows_backslashes; - } - - return info; -} - -static char* kwsys_sf_get_arg(kwsys_sf_arg_info info, char* out) -{ - /* String iterator. */ - const char* c; - - /* Keep track of how many backslashes have been encountered in a row. */ - int windows_backslashes = 0; - - /* Whether the argument must be quoted. */ - if (info.quote) { - /* Add the opening quote for this argument. */ - *out++ = '"'; - } - - /* Scan the string for characters that require escaping or quoting. */ - for (c = info.arg; *c; ++c) { - /* On Windows only backslashes and double-quotes need escaping. */ - if (*c == '\\') { - /* Found a backslash. It may need to be escaped later. */ - ++windows_backslashes; - } else if (*c == '"') { - /* Found a double-quote. Escape all immediately preceding - backslashes. */ - while (windows_backslashes > 0) { - --windows_backslashes; - *out++ = '\\'; - } - - /* Add the backslash to escape the double-quote. */ - *out++ = '\\'; - } else { - /* We encountered a normal character. This eliminates any - escaping needed for preceding backslashes. */ - windows_backslashes = 0; - } - - /* Store this character. */ - *out++ = *c; - } - - if (info.quote) { - /* Add enough backslashes to escape any trailing ones. */ - while (windows_backslashes > 0) { - --windows_backslashes; - *out++ = '\\'; - } - - /* Add the closing quote for this argument. */ - *out++ = '"'; - } - - /* Store a terminating null without incrementing. */ - *out = 0; - - return out; -} -# endif - -/* Function to convert a logical or relative path to a physical full path. */ -static int kwsys_shared_forward_realpath(const char* in_path, char* out_path) -{ -# if defined(_WIN32) && !defined(__CYGWIN__) - /* Implementation for Windows. */ - DWORD n = - GetFullPathNameA(in_path, KWSYS_SHARED_FORWARD_MAXPATH, out_path, 0); - return n > 0 && n <= KWSYS_SHARED_FORWARD_MAXPATH; -# else - /* Implementation for UNIX. */ - return realpath(in_path, out_path) != 0; -# endif -} - -static int kwsys_shared_forward_samepath(const char* file1, const char* file2) -{ -# if defined(_WIN32) - int result = 0; - HANDLE h1 = CreateFileA(file1, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - HANDLE h2 = CreateFileA(file2, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (h1 != INVALID_HANDLE_VALUE && h2 != INVALID_HANDLE_VALUE) { - BY_HANDLE_FILE_INFORMATION fi1; - BY_HANDLE_FILE_INFORMATION fi2; - GetFileInformationByHandle(h1, &fi1); - GetFileInformationByHandle(h2, &fi2); - result = (fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber && - fi1.nFileIndexHigh == fi2.nFileIndexHigh && - fi1.nFileIndexLow == fi2.nFileIndexLow); - } - CloseHandle(h1); - CloseHandle(h2); - return result; -# else - struct stat fs1, fs2; - return (stat(file1, &fs1) == 0 && stat(file2, &fs2) == 0 && - memcmp(&fs2.st_dev, &fs1.st_dev, sizeof(fs1.st_dev)) == 0 && - memcmp(&fs2.st_ino, &fs1.st_ino, sizeof(fs1.st_ino)) == 0 && - fs2.st_size == fs1.st_size); -# endif -} - -/* Function to report a system error message. */ -static void kwsys_shared_forward_strerror(char* message) -{ -# if defined(_WIN32) && !defined(__CYGWIN__) - /* Implementation for Windows. */ - DWORD original = GetLastError(); - DWORD length = - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - 0, original, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - message, KWSYS_SHARED_FORWARD_MAXPATH, 0); - if (length < 1 || length > KWSYS_SHARED_FORWARD_MAXPATH) { - /* FormatMessage failed. Use a default message. */ - _snprintf(message, KWSYS_SHARED_FORWARD_MAXPATH, - "Error 0x%X (FormatMessage failed with error 0x%X)", original, - GetLastError()); - } -# else - /* Implementation for UNIX. */ - strcpy(message, strerror(errno)); -# endif -} - -/* Functions to execute a child process. */ -static void kwsys_shared_forward_execvp(const char* cmd, - char const* const* argv) -{ -# ifdef KWSYS_SHARED_FORWARD_ESCAPE_ARGV - /* Count the number of arguments. */ - int argc = 0; - { - char const* const* argvc; - for (argvc = argv; *argvc; ++argvc, ++argc) { - } - } - - /* Create the escaped arguments. */ - { - char** nargv = (char**)malloc((argc + 1) * sizeof(char*)); - int i; - for (i = 0; i < argc; ++i) { - kwsys_sf_arg_info info = kwsys_sf_get_arg_info(argv[i]); - nargv[i] = (char*)malloc(info.size); - kwsys_sf_get_arg(info, nargv[i]); - } - nargv[argc] = 0; - - /* Replace the command line to be used. */ - argv = (char const* const*)nargv; - } -# endif - -/* Invoke the child process. */ -# if defined(_MSC_VER) - _execvp(cmd, argv); -# elif defined(__MINGW32__) && !defined(__MINGW64__) - execvp(cmd, argv); -# else - execvp(cmd, (char* const*)argv); -# endif -} - -/* Function to get the directory containing the given file or directory. */ -static void kwsys_shared_forward_dirname(const char* begin, char* result) -{ - /* Find the location of the last slash. */ - int last_slash_index = -1; - const char* end = begin + strlen(begin); - for (; begin <= end && last_slash_index < 0; --end) { - if (*end == '/' || *end == '\\') { - last_slash_index = (int)(end - begin); - } - } - - /* Handle each case of the index of the last slash. */ - if (last_slash_index < 0) { - /* No slashes. */ - strcpy(result, "."); - } else if (last_slash_index == 0) { - /* Only one leading slash. */ - strcpy(result, kwsys_shared_forward_path_slash); - } -# if defined(_WIN32) - else if (last_slash_index == 2 && begin[1] == ':') { - /* Only one leading drive letter and slash. */ - strncpy(result, begin, (size_t)last_slash_index); - result[last_slash_index] = KWSYS_SHARED_FORWARD_PATH_SLASH; - result[last_slash_index + 1] = 0; - } -# endif - else { - /* A non-leading slash. */ - strncpy(result, begin, (size_t)last_slash_index); - result[last_slash_index] = 0; - } -} - -/* Function to check if a file exists and is executable. */ -static int kwsys_shared_forward_is_executable(const char* f) -{ -# if defined(_MSC_VER) -# define KWSYS_SHARED_FORWARD_ACCESS _access -# else -# define KWSYS_SHARED_FORWARD_ACCESS access -# endif -# if defined(X_OK) -# define KWSYS_SHARED_FORWARD_ACCESS_OK X_OK -# else -# define KWSYS_SHARED_FORWARD_ACCESS_OK 04 -# endif - if (KWSYS_SHARED_FORWARD_ACCESS(f, KWSYS_SHARED_FORWARD_ACCESS_OK) == 0) { - return 1; - } else { - return 0; - } -} - -/* Function to locate the executable currently running. */ -static int kwsys_shared_forward_self_path(const char* argv0, char* result) -{ - /* Check whether argv0 has a slash. */ - int has_slash = 0; - const char* p = argv0; - for (; *p && !has_slash; ++p) { - if (*p == '/' || *p == '\\') { - has_slash = 1; - } - } - - if (has_slash) { - /* There is a slash. Use the dirname of the given location. */ - kwsys_shared_forward_dirname(argv0, result); - return 1; - } else { - /* There is no slash. Search the PATH for the executable. */ - const char* path = getenv("PATH"); - const char* begin = path; - const char* end = begin + (begin ? strlen(begin) : 0); - const char* first = begin; - while (first != end) { - /* Store the end of this path entry. */ - const char* last; - - /* Skip all path separators. */ - for (; *first && *first == KWSYS_SHARED_FORWARD_PATH_SEP; ++first) - ; - - /* Find the next separator. */ - for (last = first; *last && *last != KWSYS_SHARED_FORWARD_PATH_SEP; - ++last) - ; - - /* If we got a non-empty directory, look for the executable there. */ - if (first < last) { - /* Determine the length without trailing slash. */ - size_t length = (size_t)(last - first); - if (*(last - 1) == '/' || *(last - 1) == '\\') { - --length; - } - - /* Construct the name of the executable in this location. */ - strncpy(result, first, length); - result[length] = KWSYS_SHARED_FORWARD_PATH_SLASH; - strcpy(result + (length) + 1, argv0); - - /* Check if it exists and is executable. */ - if (kwsys_shared_forward_is_executable(result)) { - /* Found it. */ - result[length] = 0; - return 1; - } - } - - /* Move to the next directory in the path. */ - first = last; - } - } - - /* We could not find the executable. */ - return 0; -} - -/* Function to convert a specified path to a full path. If it is not - already full, it is taken relative to the self path. */ -static int kwsys_shared_forward_fullpath(const char* self_path, - const char* in_path, char* result, - const char* desc) -{ - /* Check the specified path type. */ - if (in_path[0] == '/') { - /* Already a full path. */ - strcpy(result, in_path); - } -# if defined(_WIN32) - else if (in_path[0] && in_path[1] == ':') { - /* Already a full path. */ - strcpy(result, in_path); - } -# endif - else { - /* Relative to self path. */ - char temp_path[KWSYS_SHARED_FORWARD_MAXPATH]; - strcpy(temp_path, self_path); - strcat(temp_path, kwsys_shared_forward_path_slash); - strcat(temp_path, in_path); - if (!kwsys_shared_forward_realpath(temp_path, result)) { - if (desc) { - char msgbuf[KWSYS_SHARED_FORWARD_MAXPATH]; - kwsys_shared_forward_strerror(msgbuf); - fprintf(stderr, "Error converting %s \"%s\" to real path: %s\n", desc, - temp_path, msgbuf); - } - return 0; - } - } - return 1; -} - -/* Function to compute the library search path and executable name - based on the self path. */ -static int kwsys_shared_forward_get_settings(const char* self_path, - char* ldpath, char* exe) -{ - /* Possible search paths. */ - static const char* search_path_build[] = { KWSYS_SHARED_FORWARD_PATH_BUILD, - 0 }; - static const char* search_path_install[] = { - KWSYS_SHARED_FORWARD_PATH_INSTALL, 0 - }; - - /* Chosen paths. */ - const char** search_path; - const char* exe_path; - -/* Get the real name of the build and self paths. */ -# if defined(KWSYS_SHARED_FORWARD_CONFIG_NAME) - char build_path[] = - KWSYS_SHARED_FORWARD_DIR_BUILD "/" KWSYS_SHARED_FORWARD_CONFIG_NAME; - char self_path_logical[KWSYS_SHARED_FORWARD_MAXPATH]; -# else - char build_path[] = KWSYS_SHARED_FORWARD_DIR_BUILD; - const char* self_path_logical = self_path; -# endif - char build_path_real[KWSYS_SHARED_FORWARD_MAXPATH]; - char self_path_real[KWSYS_SHARED_FORWARD_MAXPATH]; - if (!kwsys_shared_forward_realpath(self_path, self_path_real)) { - char msgbuf[KWSYS_SHARED_FORWARD_MAXPATH]; - kwsys_shared_forward_strerror(msgbuf); - fprintf(stderr, "Error converting self path \"%s\" to real path: %s\n", - self_path, msgbuf); - return 0; - } - - /* Check whether we are running in the build tree or an install tree. */ - if (kwsys_shared_forward_realpath(build_path, build_path_real) && - kwsys_shared_forward_samepath(self_path_real, build_path_real)) { - /* Running in build tree. Use the build path and exe. */ - search_path = search_path_build; -# if defined(_WIN32) - exe_path = KWSYS_SHARED_FORWARD_EXE_BUILD ".exe"; -# else - exe_path = KWSYS_SHARED_FORWARD_EXE_BUILD; -# endif - -# if defined(KWSYS_SHARED_FORWARD_CONFIG_NAME) - /* Remove the configuration directory from self_path. */ - kwsys_shared_forward_dirname(self_path, self_path_logical); -# endif - } else { - /* Running in install tree. Use the install path and exe. */ - search_path = search_path_install; -# if defined(_WIN32) - exe_path = KWSYS_SHARED_FORWARD_EXE_INSTALL ".exe"; -# else - exe_path = KWSYS_SHARED_FORWARD_EXE_INSTALL; -# endif - -# if defined(KWSYS_SHARED_FORWARD_CONFIG_NAME) - /* Use the original self path directory. */ - strcpy(self_path_logical, self_path); -# endif - } - - /* Construct the runtime search path. */ - { - const char** dir; - for (dir = search_path; *dir; ++dir) { - /* Add separator between path components. */ - if (dir != search_path) { - strcat(ldpath, kwsys_shared_forward_path_sep); - } - - /* Add this path component. */ - if (!kwsys_shared_forward_fullpath(self_path_logical, *dir, - ldpath + strlen(ldpath), - "runtime path entry")) { - return 0; - } - } - } - - /* Construct the executable location. */ - if (!kwsys_shared_forward_fullpath(self_path_logical, exe_path, exe, - "executable file")) { - return 0; - } - return 1; -} - -/* Function to print why execution of a command line failed. */ -static void kwsys_shared_forward_print_failure(char const* const* argv) -{ - char msg[KWSYS_SHARED_FORWARD_MAXPATH]; - char const* const* arg = argv; - kwsys_shared_forward_strerror(msg); - fprintf(stderr, "Error running"); - for (; *arg; ++arg) { - fprintf(stderr, " \"%s\"", *arg); - } - fprintf(stderr, ": %s\n", msg); -} - -/* Static storage space to store the updated environment variable. */ -static char kwsys_shared_forward_ldpath[65535] = - KWSYS_SHARED_FORWARD_LDPATH "="; - -/* Main driver function to be called from main. */ -static int @KWSYS_NAMESPACE@_shared_forward_to_real(int argc, char** argv_in) -{ - char const** argv = (char const**)argv_in; - /* Get the directory containing this executable. */ - char self_path[KWSYS_SHARED_FORWARD_MAXPATH]; - if (kwsys_shared_forward_self_path(argv[0], self_path)) { - /* Found this executable. Use it to get the library directory. */ - char exe[KWSYS_SHARED_FORWARD_MAXPATH]; - if (kwsys_shared_forward_get_settings(self_path, - kwsys_shared_forward_ldpath, exe)) { - /* Append the old runtime search path. */ - const char* old_ldpath = getenv(KWSYS_SHARED_FORWARD_LDPATH); - if (old_ldpath) { - strcat(kwsys_shared_forward_ldpath, kwsys_shared_forward_path_sep); - strcat(kwsys_shared_forward_ldpath, old_ldpath); - } - - /* Store the environment variable. */ - putenv(kwsys_shared_forward_ldpath); - -# if defined(KWSYS_SHARED_FORWARD_OPTION_COMMAND) - /* Look for the command line replacement option. */ - if (argc > 1 && - strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_COMMAND) == 0) { - if (argc > 2) { - /* Use the command line given. */ - strcpy(exe, argv[2]); - argv += 2; - argc -= 2; - } else { - /* The option was not given an executable. */ - fprintf(stderr, - "Option " KWSYS_SHARED_FORWARD_OPTION_COMMAND - " must be followed by a command line.\n"); - return 1; - } - } -# endif - -# if defined(KWSYS_SHARED_FORWARD_OPTION_PRINT) - /* Look for the print command line option. */ - if (argc > 1 && - strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_PRINT) == 0) { - fprintf(stdout, "%s\n", kwsys_shared_forward_ldpath); - fprintf(stdout, "%s\n", exe); - return 0; - } -# endif - -# if defined(KWSYS_SHARED_FORWARD_OPTION_LDD) - /* Look for the ldd command line option. */ - if (argc > 1 && strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_LDD) == 0) { -# if defined(KWSYS_SHARED_FORWARD_LDD) - /* Use the named ldd-like executable and arguments. */ - char const* ldd_argv[] = { KWSYS_SHARED_FORWARD_LDD, 0, 0 }; - ldd_argv[KWSYS_SHARED_FORWARD_LDD_N] = exe; - kwsys_shared_forward_execvp(ldd_argv[0], ldd_argv); - - /* Report why execution failed. */ - kwsys_shared_forward_print_failure(ldd_argv); - return 1; -# else - /* We have no ldd-like executable available on this platform. */ - fprintf(stderr, "No ldd-like tool is known to this executable.\n"); - return 1; -# endif - } -# endif - - /* Replace this process with the real executable. */ - argv[0] = exe; - kwsys_shared_forward_execvp(argv[0], argv); - - /* Report why execution failed. */ - kwsys_shared_forward_print_failure(argv); - } else { - /* Could not convert self path to the library directory. */ - } - } else { - /* Could not find this executable. */ - fprintf(stderr, "Error locating executable \"%s\".\n", argv[0]); - } - - /* Avoid unused argument warning. */ - (void)argc; - - /* Exit with failure. */ - return 1; -} - -/* Restore warning stack. */ -# if defined(__clang__) && defined(__has_warning) -# if __has_warning("-Wcast-qual") -# pragma clang diagnostic pop -# endif -# endif - -#else -# error "@KWSYS_NAMESPACE@/SharedForward.h should be included only once." -#endif diff --git a/test/API/driver/kwsys/String.c b/test/API/driver/kwsys/String.c deleted file mode 100644 index daf7ad1..0000000 --- a/test/API/driver/kwsys/String.c +++ /dev/null @@ -1,100 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifdef KWSYS_STRING_C -/* -All code in this source file is conditionally compiled to work-around -template definition auto-search on VMS. Other source files in this -directory that use the stl string cause the compiler to load this -source to try to get the definition of the string template. This -condition blocks the compiler from seeing the symbols defined here. -*/ -# include "kwsysPrivate.h" -# include KWSYS_HEADER(String.h) - -/* Work-around CMake dependency scanning limitation. This must - duplicate the above list of headers. */ -# if 0 -# include "String.h.in" -# endif - -/* Select an implementation for strcasecmp. */ -# if defined(_MSC_VER) -# define KWSYS_STRING_USE_STRICMP -# include <string.h> -# elif defined(__GNUC__) -# define KWSYS_STRING_USE_STRCASECMP -# include <strings.h> -# else -/* Table to convert upper case letters to lower case and leave all - other characters alone. */ -static char kwsysString_strcasecmp_tolower[] = { - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', '\010', - '\011', '\012', '\013', '\014', '\015', '\016', '\017', '\020', '\021', - '\022', '\023', '\024', '\025', '\026', '\027', '\030', '\031', '\032', - '\033', '\034', '\035', '\036', '\037', '\040', '\041', '\042', '\043', - '\044', '\045', '\046', '\047', '\050', '\051', '\052', '\053', '\054', - '\055', '\056', '\057', '\060', '\061', '\062', '\063', '\064', '\065', - '\066', '\067', '\070', '\071', '\072', '\073', '\074', '\075', '\076', - '\077', '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', '\160', - '\161', '\162', '\163', '\164', '\165', '\166', '\167', '\170', '\171', - '\172', '\133', '\134', '\135', '\136', '\137', '\140', '\141', '\142', - '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\152', '\153', - '\154', '\155', '\156', '\157', '\160', '\161', '\162', '\163', '\164', - '\165', '\166', '\167', '\170', '\171', '\172', '\173', '\174', '\175', - '\176', '\177', '\200', '\201', '\202', '\203', '\204', '\205', '\206', - '\207', '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', - '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', '\230', - '\231', '\232', '\233', '\234', '\235', '\236', '\237', '\240', '\241', - '\242', '\243', '\244', '\245', '\246', '\247', '\250', '\251', '\252', - '\253', '\254', '\255', '\256', '\257', '\260', '\261', '\262', '\263', - '\264', '\265', '\266', '\267', '\270', '\271', '\272', '\273', '\274', - '\275', '\276', '\277', '\300', '\301', '\302', '\303', '\304', '\305', - '\306', '\307', '\310', '\311', '\312', '\313', '\314', '\315', '\316', - '\317', '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', - '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', '\340', - '\341', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351', - '\352', '\353', '\354', '\355', '\356', '\357', '\360', '\361', '\362', - '\363', '\364', '\365', '\366', '\367', '\370', '\371', '\372', '\373', - '\374', '\375', '\376', '\377' -}; -# endif - -/*--------------------------------------------------------------------------*/ -int kwsysString_strcasecmp(const char* lhs, const char* rhs) -{ -# if defined(KWSYS_STRING_USE_STRICMP) - return _stricmp(lhs, rhs); -# elif defined(KWSYS_STRING_USE_STRCASECMP) - return strcasecmp(lhs, rhs); -# else - const char* const lower = kwsysString_strcasecmp_tolower; - unsigned char const* us1 = (unsigned char const*)lhs; - unsigned char const* us2 = (unsigned char const*)rhs; - int result; - while ((result = lower[*us1] - lower[*us2++], result == 0) && *us1++) { - } - return result; -# endif -} - -/*--------------------------------------------------------------------------*/ -int kwsysString_strncasecmp(const char* lhs, const char* rhs, size_t n) -{ -# if defined(KWSYS_STRING_USE_STRICMP) - return _strnicmp(lhs, rhs, n); -# elif defined(KWSYS_STRING_USE_STRCASECMP) - return strncasecmp(lhs, rhs, n); -# else - const char* const lower = kwsysString_strcasecmp_tolower; - unsigned char const* us1 = (unsigned char const*)lhs; - unsigned char const* us2 = (unsigned char const*)rhs; - int result = 0; - while (n && (result = lower[*us1] - lower[*us2++], result == 0) && *us1++) { - --n; - } - return result; -# endif -} - -#endif /* KWSYS_STRING_C */ diff --git a/test/API/driver/kwsys/String.h.in b/test/API/driver/kwsys/String.h.in deleted file mode 100644 index 7c9348a..0000000 --- a/test/API/driver/kwsys/String.h.in +++ /dev/null @@ -1,57 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_String_h -#define @KWSYS_NAMESPACE@_String_h - -#include <@KWSYS_NAMESPACE@/Configure.h> - -#include <stddef.h> /* size_t */ - -/* Redefine all public interface symbol names to be in the proper - namespace. These macros are used internally to kwsys only, and are - not visible to user code. Use kwsysHeaderDump.pl to reproduce - these macros after making changes to the interface. */ -#if !defined(KWSYS_NAMESPACE) -# define kwsys_ns(x) @KWSYS_NAMESPACE@##x -# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT -#endif -#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# define kwsysString_strcasecmp kwsys_ns(String_strcasecmp) -# define kwsysString_strncasecmp kwsys_ns(String_strncasecmp) -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -/** - * Compare two strings ignoring the case of the characters. The - * integer returned is negative, zero, or positive if the first string - * is found to be less than, equal to, or greater than the second - * string, respectively. - */ -kwsysEXPORT int kwsysString_strcasecmp(const char* lhs, const char* rhs); - -/** - * Identical to String_strcasecmp except that only the first n - * characters are considered. - */ -kwsysEXPORT int kwsysString_strncasecmp(const char* lhs, const char* rhs, - size_t n); - -#if defined(__cplusplus) -} /* extern "C" */ -#endif - -/* If we are building a kwsys .c or .cxx file, let it use these macros. - Otherwise, undefine them to keep the namespace clean. */ -#if !defined(KWSYS_NAMESPACE) -# undef kwsys_ns -# undef kwsysEXPORT -# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# undef kwsysString_strcasecmp -# undef kwsysString_strncasecmp -# endif -#endif - -#endif diff --git a/test/API/driver/kwsys/String.hxx.in b/test/API/driver/kwsys/String.hxx.in deleted file mode 100644 index db1cf22..0000000 --- a/test/API/driver/kwsys/String.hxx.in +++ /dev/null @@ -1,65 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_String_hxx -#define @KWSYS_NAMESPACE@_String_hxx - -#include <string> - -namespace @KWSYS_NAMESPACE@ { - -/** \class String - * \brief Short-name version of the STL basic_string class template. - * - * The standard library "string" type is actually a typedef for - * "basic_string<..long argument list..>". This string class is - * simply a subclass of this type with the same interface so that the - * name is shorter in debugging symbols and error messages. - */ -class String : public std::string -{ - /** The original string type. */ - typedef std::string stl_string; - -public: - /** String member types. */ - typedef stl_string::value_type value_type; - typedef stl_string::pointer pointer; - typedef stl_string::reference reference; - typedef stl_string::const_reference const_reference; - typedef stl_string::size_type size_type; - typedef stl_string::difference_type difference_type; - typedef stl_string::iterator iterator; - typedef stl_string::const_iterator const_iterator; - typedef stl_string::reverse_iterator reverse_iterator; - typedef stl_string::const_reverse_iterator const_reverse_iterator; - - /** String constructors. */ - String() - : stl_string() - { - } - String(const value_type* s) - : stl_string(s) - { - } - String(const value_type* s, size_type n) - : stl_string(s, n) - { - } - String(const stl_string& s, size_type pos = 0, size_type n = npos) - : stl_string(s, pos, n) - { - } -}; // End Class: String - -#if defined(__WATCOMC__) -inline bool operator<(String const& l, String const& r) -{ - return (static_cast<std::string const&>(l) < - static_cast<std::string const&>(r)); -} -#endif - -} // namespace @KWSYS_NAMESPACE@ - -#endif diff --git a/test/API/driver/kwsys/System.c b/test/API/driver/kwsys/System.c deleted file mode 100644 index d43cc6f..0000000 --- a/test/API/driver/kwsys/System.c +++ /dev/null @@ -1,236 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(System.h) - -/* Work-around CMake dependency scanning limitation. This must - duplicate the above list of headers. */ -#if 0 -# include "System.h.in" -#endif - -#include <ctype.h> /* isspace */ -#include <stddef.h> /* ptrdiff_t */ -#include <stdlib.h> /* malloc, free */ -#include <string.h> /* memcpy */ - -#include <stdio.h> - -#if defined(KWSYS_C_HAS_PTRDIFF_T) && KWSYS_C_HAS_PTRDIFF_T -typedef ptrdiff_t kwsysSystem_ptrdiff_t; -#else -typedef int kwsysSystem_ptrdiff_t; -#endif - -static int kwsysSystem__AppendByte(char* local, char** begin, char** end, - int* size, char c) -{ - /* Allocate space for the character. */ - if ((*end - *begin) >= *size) { - kwsysSystem_ptrdiff_t length = *end - *begin; - char* newBuffer = (char*)malloc((size_t)(*size * 2)); - if (!newBuffer) { - return 0; - } - memcpy(newBuffer, *begin, (size_t)(length) * sizeof(char)); - if (*begin != local) { - free(*begin); - } - *begin = newBuffer; - *end = *begin + length; - *size *= 2; - } - - /* Store the character. */ - *(*end)++ = c; - return 1; -} - -static int kwsysSystem__AppendArgument(char** local, char*** begin, - char*** end, int* size, char* arg_local, - char** arg_begin, char** arg_end, - int* arg_size) -{ - /* Append a null-terminator to the argument string. */ - if (!kwsysSystem__AppendByte(arg_local, arg_begin, arg_end, arg_size, - '\0')) { - return 0; - } - - /* Allocate space for the argument pointer. */ - if ((*end - *begin) >= *size) { - kwsysSystem_ptrdiff_t length = *end - *begin; - char** newPointers = (char**)malloc((size_t)(*size) * 2 * sizeof(char*)); - if (!newPointers) { - return 0; - } - memcpy(newPointers, *begin, (size_t)(length) * sizeof(char*)); - if (*begin != local) { - free(*begin); - } - *begin = newPointers; - *end = *begin + length; - *size *= 2; - } - - /* Allocate space for the argument string. */ - **end = (char*)malloc((size_t)(*arg_end - *arg_begin)); - if (!**end) { - return 0; - } - - /* Store the argument in the command array. */ - memcpy(**end, *arg_begin, (size_t)(*arg_end - *arg_begin)); - ++(*end); - - /* Reset the argument to be empty. */ - *arg_end = *arg_begin; - - return 1; -} - -#define KWSYSPE_LOCAL_BYTE_COUNT 1024 -#define KWSYSPE_LOCAL_ARGS_COUNT 32 -static char** kwsysSystem__ParseUnixCommand(const char* command, int flags) -{ - /* Create a buffer for argument pointers during parsing. */ - char* local_pointers[KWSYSPE_LOCAL_ARGS_COUNT]; - int pointers_size = KWSYSPE_LOCAL_ARGS_COUNT; - char** pointer_begin = local_pointers; - char** pointer_end = pointer_begin; - - /* Create a buffer for argument strings during parsing. */ - char local_buffer[KWSYSPE_LOCAL_BYTE_COUNT]; - int buffer_size = KWSYSPE_LOCAL_BYTE_COUNT; - char* buffer_begin = local_buffer; - char* buffer_end = buffer_begin; - - /* Parse the command string. Try to behave like a UNIX shell. */ - char** newCommand = 0; - const char* c = command; - int in_argument = 0; - int in_escape = 0; - int in_single = 0; - int in_double = 0; - int failed = 0; - for (; *c; ++c) { - if (in_escape) { - /* This character is escaped so do no special handling. */ - if (!in_argument) { - in_argument = 1; - } - if (!kwsysSystem__AppendByte(local_buffer, &buffer_begin, &buffer_end, - &buffer_size, *c)) { - failed = 1; - break; - } - in_escape = 0; - } else if (*c == '\\') { - /* The next character should be escaped. */ - in_escape = 1; - } else if (*c == '\'' && !in_double) { - /* Enter or exit single-quote state. */ - if (in_single) { - in_single = 0; - } else { - in_single = 1; - if (!in_argument) { - in_argument = 1; - } - } - } else if (*c == '"' && !in_single) { - /* Enter or exit double-quote state. */ - if (in_double) { - in_double = 0; - } else { - in_double = 1; - if (!in_argument) { - in_argument = 1; - } - } - } else if (isspace((unsigned char)*c)) { - if (in_argument) { - if (in_single || in_double) { - /* This space belongs to a quoted argument. */ - if (!kwsysSystem__AppendByte(local_buffer, &buffer_begin, - &buffer_end, &buffer_size, *c)) { - failed = 1; - break; - } - } else { - /* This argument has been terminated by whitespace. */ - if (!kwsysSystem__AppendArgument( - local_pointers, &pointer_begin, &pointer_end, &pointers_size, - local_buffer, &buffer_begin, &buffer_end, &buffer_size)) { - failed = 1; - break; - } - in_argument = 0; - } - } - } else { - /* This character belong to an argument. */ - if (!in_argument) { - in_argument = 1; - } - if (!kwsysSystem__AppendByte(local_buffer, &buffer_begin, &buffer_end, - &buffer_size, *c)) { - failed = 1; - break; - } - } - } - - /* Finish the last argument. */ - if (in_argument) { - if (!kwsysSystem__AppendArgument( - local_pointers, &pointer_begin, &pointer_end, &pointers_size, - local_buffer, &buffer_begin, &buffer_end, &buffer_size)) { - failed = 1; - } - } - - /* If we still have memory allocate space for the new command - buffer. */ - if (!failed) { - kwsysSystem_ptrdiff_t n = pointer_end - pointer_begin; - newCommand = (char**)malloc((size_t)(n + 1) * sizeof(char*)); - } - - if (newCommand) { - /* Copy the arguments into the new command buffer. */ - kwsysSystem_ptrdiff_t n = pointer_end - pointer_begin; - memcpy(newCommand, pointer_begin, sizeof(char*) * (size_t)(n)); - newCommand[n] = 0; - } else { - /* Free arguments already allocated. */ - while (pointer_end != pointer_begin) { - free(*(--pointer_end)); - } - } - - /* Free temporary buffers. */ - if (pointer_begin != local_pointers) { - free(pointer_begin); - } - if (buffer_begin != local_buffer) { - free(buffer_begin); - } - - /* The flags argument is currently unused. */ - (void)flags; - - /* Return the final command buffer. */ - return newCommand; -} - -char** kwsysSystem_Parse_CommandForUnix(const char* command, int flags) -{ - /* Validate the flags. */ - if (flags != 0) { - return 0; - } - - /* Forward to our internal implementation. */ - return kwsysSystem__ParseUnixCommand(command, flags); -} diff --git a/test/API/driver/kwsys/System.h.in b/test/API/driver/kwsys/System.h.in deleted file mode 100644 index a9d4f5e..0000000 --- a/test/API/driver/kwsys/System.h.in +++ /dev/null @@ -1,60 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_System_h -#define @KWSYS_NAMESPACE@_System_h - -#include <@KWSYS_NAMESPACE@/Configure.h> - -/* Redefine all public interface symbol names to be in the proper - namespace. These macros are used internally to kwsys only, and are - not visible to user code. Use kwsysHeaderDump.pl to reproduce - these macros after making changes to the interface. */ -#if !defined(KWSYS_NAMESPACE) -# define kwsys_ns(x) @KWSYS_NAMESPACE@##x -# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT -#endif -#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# define kwsysSystem_Parse_CommandForUnix \ - kwsys_ns(System_Parse_CommandForUnix) -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -/** - * Parse a unix-style command line string into separate arguments. - * - * On success, returns a pointer to an array of pointers to individual - * argument strings. Each string is null-terminated and the last - * entry in the array is a NULL pointer (just like argv). It is the - * caller's responsibility to free() the strings and the array of - * pointers to them. - * - * On failure, returns NULL. Failure occurs only on invalid flags or - * when memory cannot be allocated; never due to content of the input - * string. Missing close-quotes are treated as if the necessary - * closing quote appears. - * - * By default single- and double-quoted arguments are supported, and - * any character may be escaped by a backslash. The flags argument is - * reserved for future use, and must be zero (or the call will fail). - */ -kwsysEXPORT char** kwsysSystem_Parse_CommandForUnix(const char* command, - int flags); - -#if defined(__cplusplus) -} /* extern "C" */ -#endif - -/* If we are building a kwsys .c or .cxx file, let it use these macros. - Otherwise, undefine them to keep the namespace clean. */ -#if !defined(KWSYS_NAMESPACE) -# undef kwsys_ns -# undef kwsysEXPORT -# if !defined(KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# undef kwsysSystem_Parse_CommandForUnix -# endif -#endif - -#endif diff --git a/test/API/driver/kwsys/SystemInformation.cxx b/test/API/driver/kwsys/SystemInformation.cxx deleted file mode 100644 index 6ec6e48..0000000 --- a/test/API/driver/kwsys/SystemInformation.cxx +++ /dev/null @@ -1,5466 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#if defined(_WIN32) -# define NOMINMAX // use our min,max -# if !defined(_WIN32_WINNT) && defined(_MSC_VER) && _MSC_VER >= 1800 -# define _WIN32_WINNT 0x0600 // vista -# endif -# if !defined(_WIN32_WINNT) && !(defined(_MSC_VER) && _MSC_VER < 1300) -# define _WIN32_WINNT 0x0501 -# endif -# include <winsock.h> // WSADATA, include before sys/types.h -#endif - -#if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE) -# define _GNU_SOURCE -#endif - -// TODO: -// We need an alternative implementation for many functions in this file -// when USE_ASM_INSTRUCTIONS gets defined as 0. -// -// Consider using these on Win32/Win64 for some of them: -// -// IsProcessorFeaturePresent -// http://msdn.microsoft.com/en-us/library/ms724482(VS.85).aspx -// -// GetProcessMemoryInfo -// http://msdn.microsoft.com/en-us/library/ms683219(VS.85).aspx - -#include "kwsysPrivate.h" -#include KWSYS_HEADER(SystemInformation.hxx) -#include KWSYS_HEADER(Process.h) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Process.h.in" -# include "SystemInformation.hxx.in" -#endif - -#include <algorithm> -#include <bitset> -#include <cassert> -#include <fstream> -#include <iostream> -#include <limits> -#include <set> -#include <sstream> -#include <string> -#include <vector> - -#if defined(_WIN32) -# include <windows.h> -# if defined(_MSC_VER) && _MSC_VER >= 1800 -# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx -# endif -# include <errno.h> -# if defined(KWSYS_SYS_HAS_PSAPI) -# include <psapi.h> -# endif -# if !defined(siginfo_t) -typedef int siginfo_t; -# endif -#else -# include <sys/types.h> - -# include <errno.h> // extern int errno; -# include <fcntl.h> -# include <signal.h> -# include <sys/resource.h> // getrlimit -# include <sys/time.h> -# include <sys/utsname.h> // int uname(struct utsname *buf); -# include <unistd.h> -#endif - -#if defined(__CYGWIN__) && !defined(_WIN32) -# include <windows.h> -# undef _WIN32 -#endif - -#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ - defined(__DragonFly__) -# include <netdb.h> -# include <netinet/in.h> -# include <sys/param.h> -# include <sys/socket.h> -# include <sys/sysctl.h> -# if defined(KWSYS_SYS_HAS_IFADDRS_H) -# include <ifaddrs.h> -# include <net/if.h> -# define KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN -# endif -#endif - -#if defined(KWSYS_SYS_HAS_MACHINE_CPU_H) -# include <machine/cpu.h> -#endif - -#ifdef __APPLE__ -# include <mach/host_info.h> -# include <mach/mach.h> -# include <mach/mach_types.h> -# include <mach/vm_statistics.h> -# include <netdb.h> -# include <netinet/in.h> -# include <sys/socket.h> -# include <sys/sysctl.h> -# if defined(KWSYS_SYS_HAS_IFADDRS_H) -# include <ifaddrs.h> -# include <net/if.h> -# define KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN -# endif -# if !(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ - 0 >= 1050) -# undef KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE -# endif -#endif - -#if defined(__linux) || defined(__sun) || defined(_SCO_DS) || \ - defined(__GLIBC__) || defined(__GNU__) -# include <netdb.h> -# include <netinet/in.h> -# include <sys/socket.h> -# if defined(KWSYS_SYS_HAS_IFADDRS_H) -# include <ifaddrs.h> -# include <net/if.h> -# if defined(__LSB_VERSION__) -/* LSB has no getifaddrs */ -# elif defined(__ANDROID_API__) && __ANDROID_API__ < 24 -/* Android has no getifaddrs prior to API 24. */ -# else -# define KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN -# endif -# endif -# if defined(KWSYS_CXX_HAS_RLIMIT64) -typedef struct rlimit64 ResourceLimitType; -# define GetResourceLimit getrlimit64 -# else -typedef struct rlimit ResourceLimitType; -# define GetResourceLimit getrlimit -# endif -#elif defined(__hpux) -# include <sys/param.h> -# include <sys/pstat.h> -# if defined(KWSYS_SYS_HAS_MPCTL_H) -# include <sys/mpctl.h> -# endif -#endif - -#ifdef __HAIKU__ -# include <OS.h> -#endif - -#if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE) -# include <execinfo.h> -# if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE) -# include <cxxabi.h> -# endif -# if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP) -# include <dlfcn.h> -# endif -#else -# undef KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE -# undef KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP -#endif - -#include <ctype.h> // int isdigit(int c); -#include <memory.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if defined(KWSYS_USE_LONG_LONG) -# if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG) -# define iostreamLongLong(x) (x) -# else -# define iostreamLongLong(x) ((long)(x)) -# endif -#elif defined(KWSYS_USE___INT64) -# if defined(KWSYS_IOS_HAS_OSTREAM___INT64) -# define iostreamLongLong(x) (x) -# else -# define iostreamLongLong(x) ((long)(x)) -# endif -#else -# error "No Long Long" -#endif - -#if defined(KWSYS_CXX_HAS_ATOLL) -# define atoLongLong atoll -#else -# if defined(KWSYS_CXX_HAS__ATOI64) -# define atoLongLong _atoi64 -# elif defined(KWSYS_CXX_HAS_ATOL) -# define atoLongLong atol -# else -# define atoLongLong atoi -# endif -#endif - -#if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(_WIN64) && \ - !defined(__clang__) -# define USE_ASM_INSTRUCTIONS 1 -#else -# define USE_ASM_INSTRUCTIONS 0 -#endif - -#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__clang__) -# include <intrin.h> -# define USE_CPUID_INTRINSICS 1 -#else -# define USE_CPUID_INTRINSICS 0 -#endif - -#if USE_ASM_INSTRUCTIONS || USE_CPUID_INTRINSICS || \ - defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID) -# define USE_CPUID 1 -#else -# define USE_CPUID 0 -#endif - -#if USE_CPUID - -# define CPUID_AWARE_COMPILER - -/** - * call CPUID instruction - * - * Will return false if the instruction failed. - */ -static bool call_cpuid(int select, int result[4]) -{ -# if USE_CPUID_INTRINSICS - __cpuid(result, select); - return true; -# else - int tmp[4]; -# if defined(_MSC_VER) - // Use SEH to determine CPUID presence - __try { - _asm { -# ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <<CPUID>> writes to, as the - ; optimiser does not know about <<CPUID>>, and so does not expect - ; these registers to change. - push eax - push ebx - push ecx - push edx -# endif - ; <<CPUID>> - mov eax, select -# ifdef CPUID_AWARE_COMPILER - cpuid -# else - _asm _emit 0x0f - _asm _emit 0xa2 -# endif - mov tmp[0 * TYPE int], eax - mov tmp[1 * TYPE int], ebx - mov tmp[2 * TYPE int], ecx - mov tmp[3 * TYPE int], edx - -# ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -# endif - } - } __except (1) { - return false; - } - - memcpy(result, tmp, sizeof(tmp)); -# elif defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID) - unsigned int a, b, c, d; - __asm { - mov EAX, select; - cpuid - mov a, EAX; - mov b, EBX; - mov c, ECX; - mov d, EDX; - } - - result[0] = a; - result[1] = b; - result[2] = c; - result[3] = d; -# endif - - // The cpuid instruction succeeded. - return true; -# endif -} -#endif - -namespace KWSYS_NAMESPACE { -template <typename T> -T min(T a, T b) -{ - return a < b ? a : b; -} - -extern "C" { -typedef void (*SigAction)(int, siginfo_t*, void*); -} - -// Define SystemInformationImplementation class -typedef void (*DELAY_FUNC)(unsigned int uiMS); - -class SystemInformationImplementation -{ -public: - typedef SystemInformation::LongLong LongLong; - SystemInformationImplementation(); - ~SystemInformationImplementation(); - - const char* GetVendorString(); - const char* GetVendorID(); - std::string GetTypeID(); - std::string GetFamilyID(); - std::string GetModelID(); - std::string GetModelName(); - std::string GetSteppingCode(); - const char* GetExtendedProcessorName(); - const char* GetProcessorSerialNumber(); - int GetProcessorCacheSize(); - unsigned int GetLogicalProcessorsPerPhysical(); - float GetProcessorClockFrequency(); - int GetProcessorAPICID(); - int GetProcessorCacheXSize(long int); - bool DoesCPUSupportFeature(long int); - - const char* GetOSName(); - const char* GetHostname(); - int GetFullyQualifiedDomainName(std::string& fqdn); - const char* GetOSRelease(); - const char* GetOSVersion(); - const char* GetOSPlatform(); - - bool Is64Bits(); - - unsigned int GetNumberOfLogicalCPU(); // per physical cpu - unsigned int GetNumberOfPhysicalCPU(); - - bool DoesCPUSupportCPUID(); - - // Retrieve memory information in MiB. - size_t GetTotalVirtualMemory(); - size_t GetAvailableVirtualMemory(); - size_t GetTotalPhysicalMemory(); - size_t GetAvailablePhysicalMemory(); - - LongLong GetProcessId(); - - // Retrieve memory information in KiB. - LongLong GetHostMemoryTotal(); - LongLong GetHostMemoryAvailable(const char* envVarName); - LongLong GetHostMemoryUsed(); - - LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName, - const char* procLimitEnvVarName); - LongLong GetProcMemoryUsed(); - - double GetLoadAverage(); - - // enable/disable stack trace signal handler. - static void SetStackTraceOnError(int enable); - - // get current stack - static std::string GetProgramStack(int firstFrame, int wholePath); - - /** Run the different checks */ - void RunCPUCheck(); - void RunOSCheck(); - void RunMemoryCheck(); - -public: - typedef struct tagID - { - int Type; - int Family; - int Model; - int Revision; - int ExtendedFamily; - int ExtendedModel; - std::string ProcessorName; - std::string Vendor; - std::string SerialNumber; - std::string ModelName; - } ID; - - typedef struct tagCPUPowerManagement - { - bool HasVoltageID; - bool HasFrequencyID; - bool HasTempSenseDiode; - } CPUPowerManagement; - - typedef struct tagCPUExtendedFeatures - { - bool Has3DNow; - bool Has3DNowPlus; - bool SupportsMP; - bool HasMMXPlus; - bool HasSSEMMX; - unsigned int LogicalProcessorsPerPhysical; - int APIC_ID; - CPUPowerManagement PowerManagement; - } CPUExtendedFeatures; - - typedef struct CPUtagFeatures - { - bool HasFPU; - bool HasTSC; - bool HasMMX; - bool HasSSE; - bool HasSSEFP; - bool HasSSE2; - bool HasIA64; - bool HasAPIC; - bool HasCMOV; - bool HasMTRR; - bool HasACPI; - bool HasSerial; - bool HasThermal; - int CPUSpeed; - int L1CacheSize; - int L2CacheSize; - int L3CacheSize; - CPUExtendedFeatures ExtendedFeatures; - } CPUFeatures; - - enum Manufacturer - { - AMD, - Intel, - NSC, - UMC, - Cyrix, - NexGen, - IDT, - Rise, - Transmeta, - Sun, - IBM, - Motorola, - HP, - Hygon, - UnknownManufacturer - }; - -protected: - // For windows - bool RetrieveCPUFeatures(); - bool RetrieveCPUIdentity(); - bool RetrieveCPUCacheDetails(); - bool RetrieveClassicalCPUCacheDetails(); - bool RetrieveCPUClockSpeed(); - bool RetrieveClassicalCPUClockSpeed(); - bool RetrieveCPUExtendedLevelSupport(int); - bool RetrieveExtendedCPUFeatures(); - bool RetrieveProcessorSerialNumber(); - bool RetrieveCPUPowerManagement(); - bool RetrieveClassicalCPUIdentity(); - bool RetrieveExtendedCPUIdentity(); - - // Processor information - Manufacturer ChipManufacturer; - CPUFeatures Features; - ID ChipID; - float CPUSpeedInMHz; - unsigned int NumberOfLogicalCPU; - unsigned int NumberOfPhysicalCPU; - - void CPUCountWindows(); // For windows - unsigned char GetAPICId(); // For windows - bool IsSMTSupported(); - static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int); // For windows - - // For Linux and Cygwin, /proc/cpuinfo formats are slightly different - bool RetreiveInformationFromCpuInfoFile(); - std::string ExtractValueFromCpuInfoFile(std::string buffer, const char* word, - size_t init = 0); - - bool QueryLinuxMemory(); - bool QueryCygwinMemory(); - - static void Delay(unsigned int); - static void DelayOverhead(unsigned int); - - void FindManufacturer(const std::string& family = ""); - - // For Mac - bool ParseSysCtl(); - int CallSwVers(const char* arg, std::string& ver); - void TrimNewline(std::string&); - std::string ExtractValueFromSysCtl(const char* word); - std::string SysCtlBuffer; - - // For Solaris - bool QuerySolarisMemory(); - bool QuerySolarisProcessor(); - std::string ParseValueFromKStat(const char* arguments); - std::string RunProcess(std::vector<const char*> args); - - // For Haiku OS - bool QueryHaikuInfo(); - - // For QNX - bool QueryQNXMemory(); - bool QueryQNXProcessor(); - - // For OpenBSD, FreeBSD, NetBSD, DragonFly - bool QueryBSDMemory(); - bool QueryBSDProcessor(); - - // For HP-UX - bool QueryHPUXMemory(); - bool QueryHPUXProcessor(); - - // For Microsoft Windows - bool QueryWindowsMemory(); - - // For AIX - bool QueryAIXMemory(); - - bool QueryProcessorBySysconf(); - bool QueryProcessor(); - - // Evaluate the memory information. - bool QueryMemoryBySysconf(); - bool QueryMemory(); - size_t TotalVirtualMemory; - size_t AvailableVirtualMemory; - size_t TotalPhysicalMemory; - size_t AvailablePhysicalMemory; - - size_t CurrentPositionInFile; - - // Operating System information - bool QueryOSInformation(); - std::string OSName; - std::string Hostname; - std::string OSRelease; - std::string OSVersion; - std::string OSPlatform; - bool OSIs64Bit; -}; - -SystemInformation::SystemInformation() -{ - this->Implementation = new SystemInformationImplementation; -} - -SystemInformation::~SystemInformation() -{ - delete this->Implementation; -} - -const char* SystemInformation::GetVendorString() -{ - return this->Implementation->GetVendorString(); -} - -const char* SystemInformation::GetVendorID() -{ - return this->Implementation->GetVendorID(); -} - -std::string SystemInformation::GetTypeID() -{ - return this->Implementation->GetTypeID(); -} - -std::string SystemInformation::GetFamilyID() -{ - return this->Implementation->GetFamilyID(); -} - -std::string SystemInformation::GetModelID() -{ - return this->Implementation->GetModelID(); -} - -std::string SystemInformation::GetModelName() -{ - return this->Implementation->GetModelName(); -} - -std::string SystemInformation::GetSteppingCode() -{ - return this->Implementation->GetSteppingCode(); -} - -const char* SystemInformation::GetExtendedProcessorName() -{ - return this->Implementation->GetExtendedProcessorName(); -} - -const char* SystemInformation::GetProcessorSerialNumber() -{ - return this->Implementation->GetProcessorSerialNumber(); -} - -int SystemInformation::GetProcessorCacheSize() -{ - return this->Implementation->GetProcessorCacheSize(); -} - -unsigned int SystemInformation::GetLogicalProcessorsPerPhysical() -{ - return this->Implementation->GetLogicalProcessorsPerPhysical(); -} - -float SystemInformation::GetProcessorClockFrequency() -{ - return this->Implementation->GetProcessorClockFrequency(); -} - -int SystemInformation::GetProcessorAPICID() -{ - return this->Implementation->GetProcessorAPICID(); -} - -int SystemInformation::GetProcessorCacheXSize(long int l) -{ - return this->Implementation->GetProcessorCacheXSize(l); -} - -bool SystemInformation::DoesCPUSupportFeature(long int i) -{ - return this->Implementation->DoesCPUSupportFeature(i); -} - -std::string SystemInformation::GetCPUDescription() -{ - std::ostringstream oss; - oss << this->GetNumberOfPhysicalCPU() << " core "; - if (this->GetModelName().empty()) { - oss << this->GetProcessorClockFrequency() << " MHz " - << this->GetVendorString() << " " << this->GetExtendedProcessorName(); - } else { - oss << this->GetModelName(); - } - - // remove extra spaces - std::string tmp = oss.str(); - size_t pos; - while ((pos = tmp.find(" ")) != std::string::npos) { - tmp.replace(pos, 2, " "); - } - - return tmp; -} - -const char* SystemInformation::GetOSName() -{ - return this->Implementation->GetOSName(); -} - -const char* SystemInformation::GetHostname() -{ - return this->Implementation->GetHostname(); -} - -std::string SystemInformation::GetFullyQualifiedDomainName() -{ - std::string fqdn; - this->Implementation->GetFullyQualifiedDomainName(fqdn); - return fqdn; -} - -const char* SystemInformation::GetOSRelease() -{ - return this->Implementation->GetOSRelease(); -} - -const char* SystemInformation::GetOSVersion() -{ - return this->Implementation->GetOSVersion(); -} - -const char* SystemInformation::GetOSPlatform() -{ - return this->Implementation->GetOSPlatform(); -} - -int SystemInformation::GetOSIsWindows() -{ -#if defined(_WIN32) - return 1; -#else - return 0; -#endif -} - -int SystemInformation::GetOSIsLinux() -{ -#if defined(__linux) - return 1; -#else - return 0; -#endif -} - -int SystemInformation::GetOSIsApple() -{ -#if defined(__APPLE__) - return 1; -#else - return 0; -#endif -} - -std::string SystemInformation::GetOSDescription() -{ - std::ostringstream oss; - oss << this->GetOSName() << " " << this->GetOSRelease() << " " - << this->GetOSVersion(); - - return oss.str(); -} - -bool SystemInformation::Is64Bits() -{ - return this->Implementation->Is64Bits(); -} - -unsigned int SystemInformation::GetNumberOfLogicalCPU() // per physical cpu -{ - return this->Implementation->GetNumberOfLogicalCPU(); -} - -unsigned int SystemInformation::GetNumberOfPhysicalCPU() -{ - return this->Implementation->GetNumberOfPhysicalCPU(); -} - -bool SystemInformation::DoesCPUSupportCPUID() -{ - return this->Implementation->DoesCPUSupportCPUID(); -} - -// Retrieve memory information in MiB. -size_t SystemInformation::GetTotalVirtualMemory() -{ - return this->Implementation->GetTotalVirtualMemory(); -} - -size_t SystemInformation::GetAvailableVirtualMemory() -{ - return this->Implementation->GetAvailableVirtualMemory(); -} - -size_t SystemInformation::GetTotalPhysicalMemory() -{ - return this->Implementation->GetTotalPhysicalMemory(); -} - -size_t SystemInformation::GetAvailablePhysicalMemory() -{ - return this->Implementation->GetAvailablePhysicalMemory(); -} - -std::string SystemInformation::GetMemoryDescription( - const char* hostLimitEnvVarName, const char* procLimitEnvVarName) -{ - std::ostringstream oss; - oss << "Host Total: " << iostreamLongLong(this->GetHostMemoryTotal()) - << " KiB, Host Available: " - << iostreamLongLong(this->GetHostMemoryAvailable(hostLimitEnvVarName)) - << " KiB, Process Available: " - << iostreamLongLong(this->GetProcMemoryAvailable(hostLimitEnvVarName, - procLimitEnvVarName)) - << " KiB"; - return oss.str(); -} - -// host memory info in units of KiB. -SystemInformation::LongLong SystemInformation::GetHostMemoryTotal() -{ - return this->Implementation->GetHostMemoryTotal(); -} - -SystemInformation::LongLong SystemInformation::GetHostMemoryAvailable( - const char* hostLimitEnvVarName) -{ - return this->Implementation->GetHostMemoryAvailable(hostLimitEnvVarName); -} - -SystemInformation::LongLong SystemInformation::GetHostMemoryUsed() -{ - return this->Implementation->GetHostMemoryUsed(); -} - -// process memory info in units of KiB. -SystemInformation::LongLong SystemInformation::GetProcMemoryAvailable( - const char* hostLimitEnvVarName, const char* procLimitEnvVarName) -{ - return this->Implementation->GetProcMemoryAvailable(hostLimitEnvVarName, - procLimitEnvVarName); -} - -SystemInformation::LongLong SystemInformation::GetProcMemoryUsed() -{ - return this->Implementation->GetProcMemoryUsed(); -} - -double SystemInformation::GetLoadAverage() -{ - return this->Implementation->GetLoadAverage(); -} - -SystemInformation::LongLong SystemInformation::GetProcessId() -{ - return this->Implementation->GetProcessId(); -} - -void SystemInformation::SetStackTraceOnError(int enable) -{ - SystemInformationImplementation::SetStackTraceOnError(enable); -} - -std::string SystemInformation::GetProgramStack(int firstFrame, int wholePath) -{ - return SystemInformationImplementation::GetProgramStack(firstFrame, - wholePath); -} - -/** Run the different checks */ -void SystemInformation::RunCPUCheck() -{ - this->Implementation->RunCPUCheck(); -} - -void SystemInformation::RunOSCheck() -{ - this->Implementation->RunOSCheck(); -} - -void SystemInformation::RunMemoryCheck() -{ - this->Implementation->RunMemoryCheck(); -} - -// SystemInformationImplementation starts here - -#if USE_CPUID -# define STORE_TLBCACHE_INFO(x, y) x = (x < (y)) ? (y) : x -# define TLBCACHE_INFO_UNITS (15) -#endif - -#if USE_ASM_INSTRUCTIONS -# define CLASSICAL_CPU_FREQ_LOOP 10000000 -# define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31 -#endif - -#define INITIAL_APIC_ID_BITS 0xFF000000 -// initial APIC ID for the processor this code is running on. -// Default value = 0xff if HT is not supported - -// Hide implementation details in an anonymous namespace. -namespace { -// ***************************************************************************** -#if defined(__linux) || defined(__APPLE__) -int LoadLines(FILE* file, std::vector<std::string>& lines) -{ - // Load each line in the given file into a the vector. - int nRead = 0; - const int bufSize = 1024; - char buf[bufSize] = { '\0' }; - while (!feof(file) && !ferror(file)) { - errno = 0; - if (fgets(buf, bufSize, file) == nullptr) { - if (ferror(file) && (errno == EINTR)) { - clearerr(file); - } - continue; - } - char* pBuf = buf; - while (*pBuf) { - if (*pBuf == '\n') - *pBuf = '\0'; - pBuf += 1; - } - lines.push_back(buf); - ++nRead; - } - if (ferror(file)) { - return 0; - } - return nRead; -} - -# if defined(__linux) -// ***************************************************************************** -int LoadLines(const char* fileName, std::vector<std::string>& lines) -{ - FILE* file = fopen(fileName, "r"); - if (file == 0) { - return 0; - } - int nRead = LoadLines(file, lines); - fclose(file); - return nRead; -} -# endif - -// **************************************************************************** -template <typename T> -int NameValue(std::vector<std::string> const& lines, std::string const& name, - T& value) -{ - size_t nLines = lines.size(); - for (size_t i = 0; i < nLines; ++i) { - size_t at = lines[i].find(name); - if (at == std::string::npos) { - continue; - } - std::istringstream is(lines[i].substr(at + name.size())); - is >> value; - return 0; - } - return -1; -} -#endif - -#if defined(__linux) -// **************************************************************************** -template <typename T> -int GetFieldsFromFile(const char* fileName, const char** fieldNames, T* values) -{ - std::vector<std::string> fields; - if (!LoadLines(fileName, fields)) { - return -1; - } - int i = 0; - while (fieldNames[i] != nullptr) { - int ierr = NameValue(fields, fieldNames[i], values[i]); - if (ierr) { - return -(i + 2); - } - i += 1; - } - return 0; -} - -// **************************************************************************** -template <typename T> -int GetFieldFromFile(const char* fileName, const char* fieldName, T& value) -{ - const char* fieldNames[2] = { fieldName, nullptr }; - T values[1] = { T(0) }; - int ierr = GetFieldsFromFile(fileName, fieldNames, values); - if (ierr) { - return ierr; - } - value = values[0]; - return 0; -} -#endif - -// **************************************************************************** -#if defined(__APPLE__) -template <typename T> -int GetFieldsFromCommand(const char* command, const char** fieldNames, - T* values) -{ - FILE* file = popen(command, "r"); - if (file == nullptr) { - return -1; - } - std::vector<std::string> fields; - int nl = LoadLines(file, fields); - pclose(file); - if (nl == 0) { - return -1; - } - int i = 0; - while (fieldNames[i] != nullptr) { - int ierr = NameValue(fields, fieldNames[i], values[i]); - if (ierr) { - return -(i + 2); - } - i += 1; - } - return 0; -} -#endif - -// **************************************************************************** -#if !defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) -void StacktraceSignalHandler(int sigNo, siginfo_t* sigInfo, - void* /*sigContext*/) -{ -# if defined(__linux) || defined(__APPLE__) - std::ostringstream oss; - oss << std::endl - << "=========================================================" - << std::endl - << "Process id " << getpid() << " "; - switch (sigNo) { - case SIGINT: - oss << "Caught SIGINT"; - break; - - case SIGTERM: - oss << "Caught SIGTERM"; - break; - - case SIGABRT: - oss << "Caught SIGABRT"; - break; - - case SIGFPE: - oss << "Caught SIGFPE at " << (sigInfo->si_addr == nullptr ? "0x" : "") - << sigInfo->si_addr << " "; - switch (sigInfo->si_code) { -# if defined(FPE_INTDIV) - case FPE_INTDIV: - oss << "integer division by zero"; - break; -# endif - -# if defined(FPE_INTOVF) - case FPE_INTOVF: - oss << "integer overflow"; - break; -# endif - - case FPE_FLTDIV: - oss << "floating point divide by zero"; - break; - - case FPE_FLTOVF: - oss << "floating point overflow"; - break; - - case FPE_FLTUND: - oss << "floating point underflow"; - break; - - case FPE_FLTRES: - oss << "floating point inexact result"; - break; - - case FPE_FLTINV: - oss << "floating point invalid operation"; - break; - -# if defined(FPE_FLTSUB) - case FPE_FLTSUB: - oss << "floating point subscript out of range"; - break; -# endif - - default: - oss << "code " << sigInfo->si_code; - break; - } - break; - - case SIGSEGV: - oss << "Caught SIGSEGV at " << (sigInfo->si_addr == nullptr ? "0x" : "") - << sigInfo->si_addr << " "; - switch (sigInfo->si_code) { - case SEGV_MAPERR: - oss << "address not mapped to object"; - break; - - case SEGV_ACCERR: - oss << "invalid permission for mapped object"; - break; - - default: - oss << "code " << sigInfo->si_code; - break; - } - break; - - case SIGBUS: - oss << "Caught SIGBUS at " << (sigInfo->si_addr == nullptr ? "0x" : "") - << sigInfo->si_addr << " "; - switch (sigInfo->si_code) { - case BUS_ADRALN: - oss << "invalid address alignment"; - break; - -# if defined(BUS_ADRERR) - case BUS_ADRERR: - oss << "nonexistent physical address"; - break; -# endif - -# if defined(BUS_OBJERR) - case BUS_OBJERR: - oss << "object-specific hardware error"; - break; -# endif - -# if defined(BUS_MCEERR_AR) - case BUS_MCEERR_AR: - oss << "Hardware memory error consumed on a machine check; action " - "required."; - break; -# endif - -# if defined(BUS_MCEERR_AO) - case BUS_MCEERR_AO: - oss << "Hardware memory error detected in process but not consumed; " - "action optional."; - break; -# endif - - default: - oss << "code " << sigInfo->si_code; - break; - } - break; - - case SIGILL: - oss << "Caught SIGILL at " << (sigInfo->si_addr == nullptr ? "0x" : "") - << sigInfo->si_addr << " "; - switch (sigInfo->si_code) { - case ILL_ILLOPC: - oss << "illegal opcode"; - break; - -# if defined(ILL_ILLOPN) - case ILL_ILLOPN: - oss << "illegal operand"; - break; -# endif - -# if defined(ILL_ILLADR) - case ILL_ILLADR: - oss << "illegal addressing mode."; - break; -# endif - - case ILL_ILLTRP: - oss << "illegal trap"; - break; - - case ILL_PRVOPC: - oss << "privileged opcode"; - break; - -# if defined(ILL_PRVREG) - case ILL_PRVREG: - oss << "privileged register"; - break; -# endif - -# if defined(ILL_COPROC) - case ILL_COPROC: - oss << "co-processor error"; - break; -# endif - -# if defined(ILL_BADSTK) - case ILL_BADSTK: - oss << "internal stack error"; - break; -# endif - - default: - oss << "code " << sigInfo->si_code; - break; - } - break; - - default: - oss << "Caught " << sigNo << " code " << sigInfo->si_code; - break; - } - oss << std::endl - << "Program Stack:" << std::endl - << SystemInformationImplementation::GetProgramStack(2, 0) - << "=========================================================" - << std::endl; - std::cerr << oss.str() << std::endl; - - // restore the previously registered handlers - // and abort - SystemInformationImplementation::SetStackTraceOnError(0); - abort(); -# else - // avoid warning C4100 - (void)sigNo; - (void)sigInfo; -# endif -} -#endif - -#if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE) -# define safes(_arg) ((_arg) ? (_arg) : "???") - -// Description: -// A container for symbol properties. Each instance -// must be Initialized. -class SymbolProperties -{ -public: - SymbolProperties(); - - // Description: - // The SymbolProperties instance must be initialized by - // passing a stack address. - void Initialize(void* address); - - // Description: - // Get the symbol's stack address. - void* GetAddress() const { return this->Address; } - - // Description: - // If not set paths will be removed. eg, from a binary - // or source file. - void SetReportPath(int rp) { this->ReportPath = rp; } - - // Description: - // Set/Get the name of the binary file that the symbol - // is found in. - void SetBinary(const char* binary) { this->Binary = safes(binary); } - - std::string GetBinary() const; - - // Description: - // Set the name of the function that the symbol is found in. - // If c++ demangling is supported it will be demangled. - void SetFunction(const char* function) - { - this->Function = this->Demangle(function); - } - - std::string GetFunction() const { return this->Function; } - - // Description: - // Set/Get the name of the source file where the symbol - // is defined. - void SetSourceFile(const char* sourcefile) - { - this->SourceFile = safes(sourcefile); - } - - std::string GetSourceFile() const - { - return this->GetFileName(this->SourceFile); - } - - // Description: - // Set/Get the line number where the symbol is defined - void SetLineNumber(long linenumber) { this->LineNumber = linenumber; } - long GetLineNumber() const { return this->LineNumber; } - - // Description: - // Set the address where the binary image is mapped - // into memory. - void SetBinaryBaseAddress(void* address) - { - this->BinaryBaseAddress = address; - } - -private: - void* GetRealAddress() const - { - return (void*)((char*)this->Address - (char*)this->BinaryBaseAddress); - } - - std::string GetFileName(const std::string& path) const; - std::string Demangle(const char* symbol) const; - -private: - std::string Binary; - void* BinaryBaseAddress; - void* Address; - std::string SourceFile; - std::string Function; - long LineNumber; - int ReportPath; -}; - -std::ostream& operator<<(std::ostream& os, const SymbolProperties& sp) -{ -# if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP) - os << std::hex << sp.GetAddress() << " : " << sp.GetFunction() << " [(" - << sp.GetBinary() << ") " << sp.GetSourceFile() << ":" << std::dec - << sp.GetLineNumber() << "]"; -# elif defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE) - void* addr = sp.GetAddress(); - char** syminfo = backtrace_symbols(&addr, 1); - os << safes(syminfo[0]); - free(syminfo); -# else - (void)os; - (void)sp; -# endif - return os; -} - -SymbolProperties::SymbolProperties() -{ - // not using an initializer list - // to avoid some PGI compiler warnings - this->SetBinary("???"); - this->SetBinaryBaseAddress(nullptr); - this->Address = nullptr; - this->SetSourceFile("???"); - this->SetFunction("???"); - this->SetLineNumber(-1); - this->SetReportPath(0); - // avoid PGI compiler warnings - this->GetRealAddress(); - this->GetFunction(); - this->GetSourceFile(); - this->GetLineNumber(); -} - -std::string SymbolProperties::GetFileName(const std::string& path) const -{ - std::string file(path); - if (!this->ReportPath) { - size_t at = file.rfind("/"); - if (at != std::string::npos) { - file = file.substr(at + 1); - } - } - return file; -} - -std::string SymbolProperties::GetBinary() const -{ -// only linux has proc fs -# if defined(__linux__) - if (this->Binary == "/proc/self/exe") { - std::string binary; - char buf[1024] = { '\0' }; - ssize_t ll = 0; - if ((ll = readlink("/proc/self/exe", buf, 1024)) > 0 && ll < 1024) { - buf[ll] = '\0'; - binary = buf; - } else { - binary = "/proc/self/exe"; - } - return this->GetFileName(binary); - } -# endif - return this->GetFileName(this->Binary); -} - -std::string SymbolProperties::Demangle(const char* symbol) const -{ - std::string result = safes(symbol); -# if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE) - int status = 0; - size_t bufferLen = 1024; - char* buffer = (char*)malloc(1024); - char* demangledSymbol = - abi::__cxa_demangle(symbol, buffer, &bufferLen, &status); - if (!status) { - result = demangledSymbol; - } - free(buffer); -# else - (void)symbol; -# endif - return result; -} - -void SymbolProperties::Initialize(void* address) -{ - this->Address = address; -# if defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP) - // first fallback option can demangle c++ functions - Dl_info info; - int ierr = dladdr(this->Address, &info); - if (ierr && info.dli_sname && info.dli_saddr) { - this->SetBinary(info.dli_fname); - this->SetFunction(info.dli_sname); - } -# else -// second fallback use builtin backtrace_symbols -// to decode the bactrace. -# endif -} -#endif // don't define this class if we're not using it - -#if defined(_WIN32) || defined(__CYGWIN__) -# define KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes -#endif -#if defined(_MSC_VER) && _MSC_VER < 1310 -# undef KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes -#endif -#if defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes) -double calculateCPULoad(unsigned __int64 idleTicks, - unsigned __int64 totalTicks) -{ - static double previousLoad = -0.0; - static unsigned __int64 previousIdleTicks = 0; - static unsigned __int64 previousTotalTicks = 0; - - unsigned __int64 const idleTicksSinceLastTime = - idleTicks - previousIdleTicks; - unsigned __int64 const totalTicksSinceLastTime = - totalTicks - previousTotalTicks; - - double load; - if (previousTotalTicks == 0 || totalTicksSinceLastTime == 0) { - // No new information. Use previous result. - load = previousLoad; - } else { - // Calculate load since last time. - load = 1.0 - double(idleTicksSinceLastTime) / totalTicksSinceLastTime; - - // Smooth if possible. - if (previousLoad > 0) { - load = 0.25 * load + 0.75 * previousLoad; - } - } - - previousLoad = load; - previousIdleTicks = idleTicks; - previousTotalTicks = totalTicks; - - return load; -} - -unsigned __int64 fileTimeToUInt64(FILETIME const& ft) -{ - LARGE_INTEGER out; - out.HighPart = ft.dwHighDateTime; - out.LowPart = ft.dwLowDateTime; - return out.QuadPart; -} -#endif - -} // anonymous namespace - -SystemInformationImplementation::SystemInformationImplementation() -{ - this->TotalVirtualMemory = 0; - this->AvailableVirtualMemory = 0; - this->TotalPhysicalMemory = 0; - this->AvailablePhysicalMemory = 0; - this->CurrentPositionInFile = 0; - this->ChipManufacturer = UnknownManufacturer; - memset(&this->Features, 0, sizeof(CPUFeatures)); - this->ChipID.Type = 0; - this->ChipID.Family = 0; - this->ChipID.Model = 0; - this->ChipID.Revision = 0; - this->ChipID.ExtendedFamily = 0; - this->ChipID.ExtendedModel = 0; - this->CPUSpeedInMHz = 0; - this->NumberOfLogicalCPU = 0; - this->NumberOfPhysicalCPU = 0; - this->OSName = ""; - this->Hostname = ""; - this->OSRelease = ""; - this->OSVersion = ""; - this->OSPlatform = ""; - this->OSIs64Bit = (sizeof(void*) == 8); -} - -SystemInformationImplementation::~SystemInformationImplementation() -{ -} - -void SystemInformationImplementation::RunCPUCheck() -{ -#ifdef _WIN32 - // Check to see if this processor supports CPUID. - bool supportsCPUID = DoesCPUSupportCPUID(); - - if (supportsCPUID) { - // Retrieve the CPU details. - RetrieveCPUIdentity(); - this->FindManufacturer(); - RetrieveCPUFeatures(); - } - - // These two may be called without support for the CPUID instruction. - // (But if the instruction is there, they should be called *after* - // the above call to RetrieveCPUIdentity... that's why the two if - // blocks exist with the same "if (supportsCPUID)" logic... - // - if (!RetrieveCPUClockSpeed()) { - RetrieveClassicalCPUClockSpeed(); - } - - if (supportsCPUID) { - // Retrieve cache information. - if (!RetrieveCPUCacheDetails()) { - RetrieveClassicalCPUCacheDetails(); - } - - // Retrieve the extended CPU details. - if (!RetrieveExtendedCPUIdentity()) { - RetrieveClassicalCPUIdentity(); - } - - RetrieveExtendedCPUFeatures(); - RetrieveCPUPowerManagement(); - - // Now attempt to retrieve the serial number (if possible). - RetrieveProcessorSerialNumber(); - } - - this->CPUCountWindows(); - -#elif defined(__APPLE__) - this->ParseSysCtl(); -#elif defined(__SVR4) && defined(__sun) - this->QuerySolarisProcessor(); -#elif defined(__HAIKU__) - this->QueryHaikuInfo(); -#elif defined(__QNX__) - this->QueryQNXProcessor(); -#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ - defined(__DragonFly__) - this->QueryBSDProcessor(); -#elif defined(__hpux) - this->QueryHPUXProcessor(); -#elif defined(__linux) || defined(__CYGWIN__) - this->RetreiveInformationFromCpuInfoFile(); -#else - this->QueryProcessor(); -#endif -} - -void SystemInformationImplementation::RunOSCheck() -{ - this->QueryOSInformation(); -} - -void SystemInformationImplementation::RunMemoryCheck() -{ -#if defined(__APPLE__) - this->ParseSysCtl(); -#elif defined(__SVR4) && defined(__sun) - this->QuerySolarisMemory(); -#elif defined(__HAIKU__) - this->QueryHaikuInfo(); -#elif defined(__QNX__) - this->QueryQNXMemory(); -#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ - defined(__DragonFly__) - this->QueryBSDMemory(); -#elif defined(__CYGWIN__) - this->QueryCygwinMemory(); -#elif defined(_WIN32) - this->QueryWindowsMemory(); -#elif defined(__hpux) - this->QueryHPUXMemory(); -#elif defined(__linux) - this->QueryLinuxMemory(); -#elif defined(_AIX) - this->QueryAIXMemory(); -#else - this->QueryMemory(); -#endif -} - -/** Get the vendor string */ -const char* SystemInformationImplementation::GetVendorString() -{ - return this->ChipID.Vendor.c_str(); -} - -/** Get the OS Name */ -const char* SystemInformationImplementation::GetOSName() -{ - return this->OSName.c_str(); -} - -/** Get the hostname */ -const char* SystemInformationImplementation::GetHostname() -{ - if (this->Hostname.empty()) { - this->Hostname = "localhost"; -#if defined(_WIN32) - WORD wVersionRequested; - WSADATA wsaData; - char name[255]; - wVersionRequested = MAKEWORD(2, 0); - if (WSAStartup(wVersionRequested, &wsaData) == 0) { - gethostname(name, sizeof(name)); - WSACleanup(); - } - this->Hostname = name; -#else - struct utsname unameInfo; - int errorFlag = uname(&unameInfo); - if (errorFlag == 0) { - this->Hostname = unameInfo.nodename; - } -#endif - } - return this->Hostname.c_str(); -} - -/** Get the FQDN */ -int SystemInformationImplementation::GetFullyQualifiedDomainName( - std::string& fqdn) -{ - // in the event of absolute failure return localhost. - fqdn = "localhost"; - -#if defined(_WIN32) - int ierr; - // TODO - a more robust implementation for windows, see comments - // in unix implementation. - WSADATA wsaData; - WORD ver = MAKEWORD(2, 0); - ierr = WSAStartup(ver, &wsaData); - if (ierr) { - return -1; - } - - char base[256] = { '\0' }; - ierr = gethostname(base, 256); - if (ierr) { - WSACleanup(); - return -2; - } - fqdn = base; - - HOSTENT* hent = gethostbyname(base); - if (hent) { - fqdn = hent->h_name; - } - - WSACleanup(); - return 0; - -#elif defined(KWSYS_SYSTEMINFORMATION_IMPLEMENT_FQDN) - // gethostname typical returns an alias for loopback interface - // we want the fully qualified domain name. Because there are - // any number of interfaces on this system we look for the - // first of these that contains the name returned by gethostname - // and is longer. failing that we return gethostname and indicate - // with a failure code. Return of a failure code is not necessarily - // an indication of an error. for instance gethostname may return - // the fully qualified domain name, or there may not be one if the - // system lives on a private network such as in the case of a cluster - // node. - - int ierr = 0; - char base[NI_MAXHOST]; - ierr = gethostname(base, NI_MAXHOST); - if (ierr) { - return -1; - } - size_t baseSize = strlen(base); - fqdn = base; - - struct ifaddrs* ifas; - struct ifaddrs* ifa; - ierr = getifaddrs(&ifas); - if (ierr) { - return -2; - } - - for (ifa = ifas; ifa != nullptr; ifa = ifa->ifa_next) { - int fam = ifa->ifa_addr ? ifa->ifa_addr->sa_family : -1; - // Skip Loopback interfaces - if (((fam == AF_INET) || (fam == AF_INET6)) && - !(ifa->ifa_flags & IFF_LOOPBACK)) { - char host[NI_MAXHOST] = { '\0' }; - - const size_t addrlen = (fam == AF_INET ? sizeof(struct sockaddr_in) - : sizeof(struct sockaddr_in6)); - - ierr = getnameinfo(ifa->ifa_addr, static_cast<socklen_t>(addrlen), host, - NI_MAXHOST, nullptr, 0, NI_NAMEREQD); - if (ierr) { - // don't report the failure now since we may succeed on another - // interface. If all attempts fail then return the failure code. - ierr = -3; - continue; - } - - std::string candidate = host; - if ((candidate.find(base) != std::string::npos) && - baseSize < candidate.size()) { - // success, stop now. - ierr = 0; - fqdn = candidate; - break; - } - } - } - freeifaddrs(ifas); - - return ierr; -#else - /* TODO: Implement on more platforms. */ - fqdn = this->GetHostname(); - return -1; -#endif -} - -/** Get the OS release */ -const char* SystemInformationImplementation::GetOSRelease() -{ - return this->OSRelease.c_str(); -} - -/** Get the OS version */ -const char* SystemInformationImplementation::GetOSVersion() -{ - return this->OSVersion.c_str(); -} - -/** Get the OS platform */ -const char* SystemInformationImplementation::GetOSPlatform() -{ - return this->OSPlatform.c_str(); -} - -/** Get the vendor ID */ -const char* SystemInformationImplementation::GetVendorID() -{ - // Return the vendor ID. - switch (this->ChipManufacturer) { - case Intel: - return "Intel Corporation"; - case AMD: - return "Advanced Micro Devices"; - case NSC: - return "National Semiconductor"; - case Cyrix: - return "Cyrix Corp., VIA Inc."; - case NexGen: - return "NexGen Inc., Advanced Micro Devices"; - case IDT: - return "IDT\\Centaur, Via Inc."; - case UMC: - return "United Microelectronics Corp."; - case Rise: - return "Rise"; - case Transmeta: - return "Transmeta"; - case Sun: - return "Sun Microelectronics"; - case IBM: - return "IBM"; - case Motorola: - return "Motorola"; - case HP: - return "Hewlett-Packard"; - case Hygon: - return "Chengdu Haiguang IC Design Co., Ltd."; - case UnknownManufacturer: - default: - return "Unknown Manufacturer"; - } -} - -/** Return the type ID of the CPU */ -std::string SystemInformationImplementation::GetTypeID() -{ - std::ostringstream str; - str << this->ChipID.Type; - return str.str(); -} - -/** Return the family of the CPU present */ -std::string SystemInformationImplementation::GetFamilyID() -{ - std::ostringstream str; - str << this->ChipID.Family; - return str.str(); -} - -// Return the model of CPU present */ -std::string SystemInformationImplementation::GetModelID() -{ - std::ostringstream str; - str << this->ChipID.Model; - return str.str(); -} - -// Return the model name of CPU present */ -std::string SystemInformationImplementation::GetModelName() -{ - return this->ChipID.ModelName; -} - -/** Return the stepping code of the CPU present. */ -std::string SystemInformationImplementation::GetSteppingCode() -{ - std::ostringstream str; - str << this->ChipID.Revision; - return str.str(); -} - -/** Return the stepping code of the CPU present. */ -const char* SystemInformationImplementation::GetExtendedProcessorName() -{ - return this->ChipID.ProcessorName.c_str(); -} - -/** Return the serial number of the processor - * in hexadecimal: xxxx-xxxx-xxxx-xxxx-xxxx-xxxx. */ -const char* SystemInformationImplementation::GetProcessorSerialNumber() -{ - return this->ChipID.SerialNumber.c_str(); -} - -/** Return the logical processors per physical */ -unsigned int SystemInformationImplementation::GetLogicalProcessorsPerPhysical() -{ - return this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical; -} - -/** Return the processor clock frequency. */ -float SystemInformationImplementation::GetProcessorClockFrequency() -{ - return this->CPUSpeedInMHz; -} - -/** Return the APIC ID. */ -int SystemInformationImplementation::GetProcessorAPICID() -{ - return this->Features.ExtendedFeatures.APIC_ID; -} - -/** Return the L1 cache size. */ -int SystemInformationImplementation::GetProcessorCacheSize() -{ - return this->Features.L1CacheSize; -} - -/** Return the chosen cache size. */ -int SystemInformationImplementation::GetProcessorCacheXSize(long int dwCacheID) -{ - switch (dwCacheID) { - case SystemInformation::CPU_FEATURE_L1CACHE: - return this->Features.L1CacheSize; - case SystemInformation::CPU_FEATURE_L2CACHE: - return this->Features.L2CacheSize; - case SystemInformation::CPU_FEATURE_L3CACHE: - return this->Features.L3CacheSize; - } - return -1; -} - -bool SystemInformationImplementation::DoesCPUSupportFeature(long int dwFeature) -{ - bool bHasFeature = false; - - // Check for MMX instructions. - if (((dwFeature & SystemInformation::CPU_FEATURE_MMX) != 0) && - this->Features.HasMMX) - bHasFeature = true; - - // Check for MMX+ instructions. - if (((dwFeature & SystemInformation::CPU_FEATURE_MMX_PLUS) != 0) && - this->Features.ExtendedFeatures.HasMMXPlus) - bHasFeature = true; - - // Check for SSE FP instructions. - if (((dwFeature & SystemInformation::CPU_FEATURE_SSE) != 0) && - this->Features.HasSSE) - bHasFeature = true; - - // Check for SSE FP instructions. - if (((dwFeature & SystemInformation::CPU_FEATURE_SSE_FP) != 0) && - this->Features.HasSSEFP) - bHasFeature = true; - - // Check for SSE MMX instructions. - if (((dwFeature & SystemInformation::CPU_FEATURE_SSE_MMX) != 0) && - this->Features.ExtendedFeatures.HasSSEMMX) - bHasFeature = true; - - // Check for SSE2 instructions. - if (((dwFeature & SystemInformation::CPU_FEATURE_SSE2) != 0) && - this->Features.HasSSE2) - bHasFeature = true; - - // Check for 3DNow! instructions. - if (((dwFeature & SystemInformation::CPU_FEATURE_AMD_3DNOW) != 0) && - this->Features.ExtendedFeatures.Has3DNow) - bHasFeature = true; - - // Check for 3DNow+ instructions. - if (((dwFeature & SystemInformation::CPU_FEATURE_AMD_3DNOW_PLUS) != 0) && - this->Features.ExtendedFeatures.Has3DNowPlus) - bHasFeature = true; - - // Check for IA64 instructions. - if (((dwFeature & SystemInformation::CPU_FEATURE_IA64) != 0) && - this->Features.HasIA64) - bHasFeature = true; - - // Check for MP capable. - if (((dwFeature & SystemInformation::CPU_FEATURE_MP_CAPABLE) != 0) && - this->Features.ExtendedFeatures.SupportsMP) - bHasFeature = true; - - // Check for a serial number for the processor. - if (((dwFeature & SystemInformation::CPU_FEATURE_SERIALNUMBER) != 0) && - this->Features.HasSerial) - bHasFeature = true; - - // Check for a local APIC in the processor. - if (((dwFeature & SystemInformation::CPU_FEATURE_APIC) != 0) && - this->Features.HasAPIC) - bHasFeature = true; - - // Check for CMOV instructions. - if (((dwFeature & SystemInformation::CPU_FEATURE_CMOV) != 0) && - this->Features.HasCMOV) - bHasFeature = true; - - // Check for MTRR instructions. - if (((dwFeature & SystemInformation::CPU_FEATURE_MTRR) != 0) && - this->Features.HasMTRR) - bHasFeature = true; - - // Check for L1 cache size. - if (((dwFeature & SystemInformation::CPU_FEATURE_L1CACHE) != 0) && - (this->Features.L1CacheSize != -1)) - bHasFeature = true; - - // Check for L2 cache size. - if (((dwFeature & SystemInformation::CPU_FEATURE_L2CACHE) != 0) && - (this->Features.L2CacheSize != -1)) - bHasFeature = true; - - // Check for L3 cache size. - if (((dwFeature & SystemInformation::CPU_FEATURE_L3CACHE) != 0) && - (this->Features.L3CacheSize != -1)) - bHasFeature = true; - - // Check for ACPI capability. - if (((dwFeature & SystemInformation::CPU_FEATURE_ACPI) != 0) && - this->Features.HasACPI) - bHasFeature = true; - - // Check for thermal monitor support. - if (((dwFeature & SystemInformation::CPU_FEATURE_THERMALMONITOR) != 0) && - this->Features.HasThermal) - bHasFeature = true; - - // Check for temperature sensing diode support. - if (((dwFeature & SystemInformation::CPU_FEATURE_TEMPSENSEDIODE) != 0) && - this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode) - bHasFeature = true; - - // Check for frequency ID support. - if (((dwFeature & SystemInformation::CPU_FEATURE_FREQUENCYID) != 0) && - this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID) - bHasFeature = true; - - // Check for voltage ID support. - if (((dwFeature & SystemInformation::CPU_FEATURE_VOLTAGEID_FREQUENCY) != - 0) && - this->Features.ExtendedFeatures.PowerManagement.HasVoltageID) - bHasFeature = true; - - // Check for FPU support. - if (((dwFeature & SystemInformation::CPU_FEATURE_FPU) != 0) && - this->Features.HasFPU) - bHasFeature = true; - - return bHasFeature; -} - -void SystemInformationImplementation::Delay(unsigned int uiMS) -{ -#ifdef _WIN32 - LARGE_INTEGER Frequency, StartCounter, EndCounter; - __int64 x; - - // Get the frequency of the high performance counter. - if (!QueryPerformanceFrequency(&Frequency)) - return; - x = Frequency.QuadPart / 1000 * uiMS; - - // Get the starting position of the counter. - QueryPerformanceCounter(&StartCounter); - - do { - // Get the ending position of the counter. - QueryPerformanceCounter(&EndCounter); - } while (EndCounter.QuadPart - StartCounter.QuadPart < x); -#endif - (void)uiMS; -} - -bool SystemInformationImplementation::DoesCPUSupportCPUID() -{ -#if USE_CPUID - int dummy[4] = { 0, 0, 0, 0 }; - -# if USE_ASM_INSTRUCTIONS - return call_cpuid(0, dummy); -# else - call_cpuid(0, dummy); - return dummy[0] || dummy[1] || dummy[2] || dummy[3]; -# endif -#else - // Assume no cpuid instruction. - return false; -#endif -} - -bool SystemInformationImplementation::RetrieveCPUFeatures() -{ -#if USE_CPUID - int cpuinfo[4] = { 0, 0, 0, 0 }; - - if (!call_cpuid(1, cpuinfo)) { - return false; - } - - // Retrieve the features of CPU present. - this->Features.HasFPU = - ((cpuinfo[3] & 0x00000001) != 0); // FPU Present --> Bit 0 - this->Features.HasTSC = - ((cpuinfo[3] & 0x00000010) != 0); // TSC Present --> Bit 4 - this->Features.HasAPIC = - ((cpuinfo[3] & 0x00000200) != 0); // APIC Present --> Bit 9 - this->Features.HasMTRR = - ((cpuinfo[3] & 0x00001000) != 0); // MTRR Present --> Bit 12 - this->Features.HasCMOV = - ((cpuinfo[3] & 0x00008000) != 0); // CMOV Present --> Bit 15 - this->Features.HasSerial = - ((cpuinfo[3] & 0x00040000) != 0); // Serial Present --> Bit 18 - this->Features.HasACPI = - ((cpuinfo[3] & 0x00400000) != 0); // ACPI Capable --> Bit 22 - this->Features.HasMMX = - ((cpuinfo[3] & 0x00800000) != 0); // MMX Present --> Bit 23 - this->Features.HasSSE = - ((cpuinfo[3] & 0x02000000) != 0); // SSE Present --> Bit 25 - this->Features.HasSSE2 = - ((cpuinfo[3] & 0x04000000) != 0); // SSE2 Present --> Bit 26 - this->Features.HasThermal = - ((cpuinfo[3] & 0x20000000) != 0); // Thermal Monitor Present --> Bit 29 - this->Features.HasIA64 = - ((cpuinfo[3] & 0x40000000) != 0); // IA64 Present --> Bit 30 - -# if USE_ASM_INSTRUCTIONS - // Retrieve extended SSE capabilities if SSE is available. - if (this->Features.HasSSE) { - - // Attempt to __try some SSE FP instructions. - __try { - // Perform: orps xmm0, xmm0 - _asm - { - _emit 0x0f - _emit 0x56 - _emit 0xc0 - } - - // SSE FP capable processor. - this->Features.HasSSEFP = true; - } __except (1) { - // bad instruction - processor or OS cannot handle SSE FP. - this->Features.HasSSEFP = false; - } - } else { - // Set the advanced SSE capabilities to not available. - this->Features.HasSSEFP = false; - } -# else - this->Features.HasSSEFP = false; -# endif - - // Retrieve Intel specific extended features. - if (this->ChipManufacturer == Intel) { - bool SupportsSMT = - ((cpuinfo[3] & 0x10000000) != 0); // Intel specific: SMT --> Bit 28 - - if ((SupportsSMT) && (this->Features.HasAPIC)) { - // Retrieve APIC information if there is one present. - this->Features.ExtendedFeatures.APIC_ID = - ((cpuinfo[1] & 0xFF000000) >> 24); - } - } - - return true; - -#else - return false; -#endif -} - -/** Find the manufacturer given the vendor id */ -void SystemInformationImplementation::FindManufacturer( - const std::string& family) -{ - if (this->ChipID.Vendor == "GenuineIntel") - this->ChipManufacturer = Intel; // Intel Corp. - else if (this->ChipID.Vendor == "UMC UMC UMC ") - this->ChipManufacturer = UMC; // United Microelectronics Corp. - else if (this->ChipID.Vendor == "AuthenticAMD") - this->ChipManufacturer = AMD; // Advanced Micro Devices - else if (this->ChipID.Vendor == "AMD ISBETTER") - this->ChipManufacturer = AMD; // Advanced Micro Devices (1994) - else if (this->ChipID.Vendor == "HygonGenuine") - this->ChipManufacturer = Hygon; // Chengdu Haiguang IC Design Co., Ltd. - else if (this->ChipID.Vendor == "CyrixInstead") - this->ChipManufacturer = Cyrix; // Cyrix Corp., VIA Inc. - else if (this->ChipID.Vendor == "NexGenDriven") - this->ChipManufacturer = NexGen; // NexGen Inc. (now AMD) - else if (this->ChipID.Vendor == "CentaurHauls") - this->ChipManufacturer = IDT; // IDT/Centaur (now VIA) - else if (this->ChipID.Vendor == "RiseRiseRise") - this->ChipManufacturer = Rise; // Rise - else if (this->ChipID.Vendor == "GenuineTMx86") - this->ChipManufacturer = Transmeta; // Transmeta - else if (this->ChipID.Vendor == "TransmetaCPU") - this->ChipManufacturer = Transmeta; // Transmeta - else if (this->ChipID.Vendor == "Geode By NSC") - this->ChipManufacturer = NSC; // National Semiconductor - else if (this->ChipID.Vendor == "Sun") - this->ChipManufacturer = Sun; // Sun Microelectronics - else if (this->ChipID.Vendor == "IBM") - this->ChipManufacturer = IBM; // IBM Microelectronics - else if (this->ChipID.Vendor == "Hewlett-Packard") - this->ChipManufacturer = HP; // Hewlett-Packard - else if (this->ChipID.Vendor == "Motorola") - this->ChipManufacturer = Motorola; // Motorola Microelectronics - else if (family.substr(0, 7) == "PA-RISC") - this->ChipManufacturer = HP; // Hewlett-Packard - else - this->ChipManufacturer = UnknownManufacturer; // Unknown manufacturer -} - -/** */ -bool SystemInformationImplementation::RetrieveCPUIdentity() -{ -#if USE_CPUID - int localCPUVendor[4]; - int localCPUSignature[4]; - - if (!call_cpuid(0, localCPUVendor)) { - return false; - } - if (!call_cpuid(1, localCPUSignature)) { - return false; - } - - // Process the returned information. - // ; eax = 0 --> eax: maximum value of CPUID instruction. - // ; ebx: part 1 of 3; CPU signature. - // ; edx: part 2 of 3; CPU signature. - // ; ecx: part 3 of 3; CPU signature. - char vbuf[13]; - memcpy(&(vbuf[0]), &(localCPUVendor[1]), sizeof(int)); - memcpy(&(vbuf[4]), &(localCPUVendor[3]), sizeof(int)); - memcpy(&(vbuf[8]), &(localCPUVendor[2]), sizeof(int)); - vbuf[12] = '\0'; - this->ChipID.Vendor = vbuf; - - // Retrieve the family of CPU present. - // ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, - // bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision - // ; ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, - // 15..8 - CFLUSH chunk size , 7..0 - brand ID - // ; edx: CPU feature flags - this->ChipID.ExtendedFamily = - ((localCPUSignature[0] & 0x0FF00000) >> 20); // Bits 27..20 Used - this->ChipID.ExtendedModel = - ((localCPUSignature[0] & 0x000F0000) >> 16); // Bits 19..16 Used - this->ChipID.Type = - ((localCPUSignature[0] & 0x0000F000) >> 12); // Bits 15..12 Used - this->ChipID.Family = - ((localCPUSignature[0] & 0x00000F00) >> 8); // Bits 11..8 Used - this->ChipID.Model = - ((localCPUSignature[0] & 0x000000F0) >> 4); // Bits 7..4 Used - this->ChipID.Revision = - ((localCPUSignature[0] & 0x0000000F) >> 0); // Bits 3..0 Used - - return true; - -#else - return false; -#endif -} - -/** */ -bool SystemInformationImplementation::RetrieveCPUCacheDetails() -{ -#if USE_CPUID - int L1Cache[4] = { 0, 0, 0, 0 }; - int L2Cache[4] = { 0, 0, 0, 0 }; - - // Check to see if what we are about to do is supported... - if (RetrieveCPUExtendedLevelSupport(0x80000005)) { - if (!call_cpuid(0x80000005, L1Cache)) { - return false; - } - // Save the L1 data cache size (in KB) from ecx: bits 31..24 as well as - // data cache size from edx: bits 31..24. - this->Features.L1CacheSize = ((L1Cache[2] & 0xFF000000) >> 24); - this->Features.L1CacheSize += ((L1Cache[3] & 0xFF000000) >> 24); - } else { - // Store -1 to indicate the cache could not be queried. - this->Features.L1CacheSize = -1; - } - - // Check to see if what we are about to do is supported... - if (RetrieveCPUExtendedLevelSupport(0x80000006)) { - if (!call_cpuid(0x80000006, L2Cache)) { - return false; - } - // Save the L2 unified cache size (in KB) from ecx: bits 31..16. - this->Features.L2CacheSize = ((L2Cache[2] & 0xFFFF0000) >> 16); - } else { - // Store -1 to indicate the cache could not be queried. - this->Features.L2CacheSize = -1; - } - - // Define L3 as being not present as we cannot test for it. - this->Features.L3CacheSize = -1; - -#endif - - // Return failure if we cannot detect either cache with this method. - return ((this->Features.L1CacheSize == -1) && - (this->Features.L2CacheSize == -1)) - ? false - : true; -} - -/** */ -bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails() -{ -#if USE_CPUID - int TLBCode = -1, TLBData = -1, L1Code = -1, L1Data = -1, L1Trace = -1, - L2Unified = -1, L3Unified = -1; - int TLBCacheData[4] = { 0, 0, 0, 0 }; - int TLBPassCounter = 0; - int TLBCacheUnit = 0; - - do { - if (!call_cpuid(2, TLBCacheData)) { - return false; - } - - int bob = ((TLBCacheData[0] & 0x00FF0000) >> 16); - (void)bob; - // Process the returned TLB and cache information. - for (int nCounter = 0; nCounter < TLBCACHE_INFO_UNITS; nCounter++) { - // First of all - decide which unit we are dealing with. - switch (nCounter) { - // eax: bits 8..15 : bits 16..23 : bits 24..31 - case 0: - TLBCacheUnit = ((TLBCacheData[0] & 0x0000FF00) >> 8); - break; - case 1: - TLBCacheUnit = ((TLBCacheData[0] & 0x00FF0000) >> 16); - break; - case 2: - TLBCacheUnit = ((TLBCacheData[0] & 0xFF000000) >> 24); - break; - - // ebx: bits 0..7 : bits 8..15 : bits 16..23 : bits 24..31 - case 3: - TLBCacheUnit = ((TLBCacheData[1] & 0x000000FF) >> 0); - break; - case 4: - TLBCacheUnit = ((TLBCacheData[1] & 0x0000FF00) >> 8); - break; - case 5: - TLBCacheUnit = ((TLBCacheData[1] & 0x00FF0000) >> 16); - break; - case 6: - TLBCacheUnit = ((TLBCacheData[1] & 0xFF000000) >> 24); - break; - - // ecx: bits 0..7 : bits 8..15 : bits 16..23 : bits 24..31 - case 7: - TLBCacheUnit = ((TLBCacheData[2] & 0x000000FF) >> 0); - break; - case 8: - TLBCacheUnit = ((TLBCacheData[2] & 0x0000FF00) >> 8); - break; - case 9: - TLBCacheUnit = ((TLBCacheData[2] & 0x00FF0000) >> 16); - break; - case 10: - TLBCacheUnit = ((TLBCacheData[2] & 0xFF000000) >> 24); - break; - - // edx: bits 0..7 : bits 8..15 : bits 16..23 : bits 24..31 - case 11: - TLBCacheUnit = ((TLBCacheData[3] & 0x000000FF) >> 0); - break; - case 12: - TLBCacheUnit = ((TLBCacheData[3] & 0x0000FF00) >> 8); - break; - case 13: - TLBCacheUnit = ((TLBCacheData[3] & 0x00FF0000) >> 16); - break; - case 14: - TLBCacheUnit = ((TLBCacheData[3] & 0xFF000000) >> 24); - break; - - // Default case - an error has occurred. - default: - return false; - } - - // Now process the resulting unit to see what it means.... - switch (TLBCacheUnit) { - case 0x00: - break; - case 0x01: - STORE_TLBCACHE_INFO(TLBCode, 4); - break; - case 0x02: - STORE_TLBCACHE_INFO(TLBCode, 4096); - break; - case 0x03: - STORE_TLBCACHE_INFO(TLBData, 4); - break; - case 0x04: - STORE_TLBCACHE_INFO(TLBData, 4096); - break; - case 0x06: - STORE_TLBCACHE_INFO(L1Code, 8); - break; - case 0x08: - STORE_TLBCACHE_INFO(L1Code, 16); - break; - case 0x0a: - STORE_TLBCACHE_INFO(L1Data, 8); - break; - case 0x0c: - STORE_TLBCACHE_INFO(L1Data, 16); - break; - case 0x10: - STORE_TLBCACHE_INFO(L1Data, 16); - break; // <-- FIXME: IA-64 Only - case 0x15: - STORE_TLBCACHE_INFO(L1Code, 16); - break; // <-- FIXME: IA-64 Only - case 0x1a: - STORE_TLBCACHE_INFO(L2Unified, 96); - break; // <-- FIXME: IA-64 Only - case 0x22: - STORE_TLBCACHE_INFO(L3Unified, 512); - break; - case 0x23: - STORE_TLBCACHE_INFO(L3Unified, 1024); - break; - case 0x25: - STORE_TLBCACHE_INFO(L3Unified, 2048); - break; - case 0x29: - STORE_TLBCACHE_INFO(L3Unified, 4096); - break; - case 0x39: - STORE_TLBCACHE_INFO(L2Unified, 128); - break; - case 0x3c: - STORE_TLBCACHE_INFO(L2Unified, 256); - break; - case 0x40: - STORE_TLBCACHE_INFO(L2Unified, 0); - break; // <-- FIXME: No integrated L2 cache (P6 core) or L3 cache (P4 - // core). - case 0x41: - STORE_TLBCACHE_INFO(L2Unified, 128); - break; - case 0x42: - STORE_TLBCACHE_INFO(L2Unified, 256); - break; - case 0x43: - STORE_TLBCACHE_INFO(L2Unified, 512); - break; - case 0x44: - STORE_TLBCACHE_INFO(L2Unified, 1024); - break; - case 0x45: - STORE_TLBCACHE_INFO(L2Unified, 2048); - break; - case 0x50: - STORE_TLBCACHE_INFO(TLBCode, 4096); - break; - case 0x51: - STORE_TLBCACHE_INFO(TLBCode, 4096); - break; - case 0x52: - STORE_TLBCACHE_INFO(TLBCode, 4096); - break; - case 0x5b: - STORE_TLBCACHE_INFO(TLBData, 4096); - break; - case 0x5c: - STORE_TLBCACHE_INFO(TLBData, 4096); - break; - case 0x5d: - STORE_TLBCACHE_INFO(TLBData, 4096); - break; - case 0x66: - STORE_TLBCACHE_INFO(L1Data, 8); - break; - case 0x67: - STORE_TLBCACHE_INFO(L1Data, 16); - break; - case 0x68: - STORE_TLBCACHE_INFO(L1Data, 32); - break; - case 0x70: - STORE_TLBCACHE_INFO(L1Trace, 12); - break; - case 0x71: - STORE_TLBCACHE_INFO(L1Trace, 16); - break; - case 0x72: - STORE_TLBCACHE_INFO(L1Trace, 32); - break; - case 0x77: - STORE_TLBCACHE_INFO(L1Code, 16); - break; // <-- FIXME: IA-64 Only - case 0x79: - STORE_TLBCACHE_INFO(L2Unified, 128); - break; - case 0x7a: - STORE_TLBCACHE_INFO(L2Unified, 256); - break; - case 0x7b: - STORE_TLBCACHE_INFO(L2Unified, 512); - break; - case 0x7c: - STORE_TLBCACHE_INFO(L2Unified, 1024); - break; - case 0x7e: - STORE_TLBCACHE_INFO(L2Unified, 256); - break; - case 0x81: - STORE_TLBCACHE_INFO(L2Unified, 128); - break; - case 0x82: - STORE_TLBCACHE_INFO(L2Unified, 256); - break; - case 0x83: - STORE_TLBCACHE_INFO(L2Unified, 512); - break; - case 0x84: - STORE_TLBCACHE_INFO(L2Unified, 1024); - break; - case 0x85: - STORE_TLBCACHE_INFO(L2Unified, 2048); - break; - case 0x88: - STORE_TLBCACHE_INFO(L3Unified, 2048); - break; // <-- FIXME: IA-64 Only - case 0x89: - STORE_TLBCACHE_INFO(L3Unified, 4096); - break; // <-- FIXME: IA-64 Only - case 0x8a: - STORE_TLBCACHE_INFO(L3Unified, 8192); - break; // <-- FIXME: IA-64 Only - case 0x8d: - STORE_TLBCACHE_INFO(L3Unified, 3096); - break; // <-- FIXME: IA-64 Only - case 0x90: - STORE_TLBCACHE_INFO(TLBCode, 262144); - break; // <-- FIXME: IA-64 Only - case 0x96: - STORE_TLBCACHE_INFO(TLBCode, 262144); - break; // <-- FIXME: IA-64 Only - case 0x9b: - STORE_TLBCACHE_INFO(TLBCode, 262144); - break; // <-- FIXME: IA-64 Only - - // Default case - an error has occurred. - default: - return false; - } - } - - // Increment the TLB pass counter. - TLBPassCounter++; - } while ((TLBCacheData[0] & 0x000000FF) > TLBPassCounter); - - // Ok - we now have the maximum TLB, L1, L2, and L3 sizes... - if ((L1Code == -1) && (L1Data == -1) && (L1Trace == -1)) { - this->Features.L1CacheSize = -1; - } else if ((L1Code == -1) && (L1Data == -1) && (L1Trace != -1)) { - this->Features.L1CacheSize = L1Trace; - } else if ((L1Code != -1) && (L1Data == -1)) { - this->Features.L1CacheSize = L1Code; - } else if ((L1Code == -1) && (L1Data != -1)) { - this->Features.L1CacheSize = L1Data; - } else if ((L1Code != -1) && (L1Data != -1)) { - this->Features.L1CacheSize = L1Code + L1Data; - } else { - this->Features.L1CacheSize = -1; - } - - // Ok - we now have the maximum TLB, L1, L2, and L3 sizes... - if (L2Unified == -1) { - this->Features.L2CacheSize = -1; - } else { - this->Features.L2CacheSize = L2Unified; - } - - // Ok - we now have the maximum TLB, L1, L2, and L3 sizes... - if (L3Unified == -1) { - this->Features.L3CacheSize = -1; - } else { - this->Features.L3CacheSize = L3Unified; - } - - return true; - -#else - return false; -#endif -} - -/** */ -bool SystemInformationImplementation::RetrieveCPUClockSpeed() -{ - bool retrieved = false; - -#if defined(_WIN32) - unsigned int uiRepetitions = 1; - unsigned int uiMSecPerRepetition = 50; - __int64 i64Total = 0; - __int64 i64Overhead = 0; - - // Check if the TSC implementation works at all - if (this->Features.HasTSC && - GetCyclesDifference(SystemInformationImplementation::Delay, - uiMSecPerRepetition) > 0) { - for (unsigned int nCounter = 0; nCounter < uiRepetitions; nCounter++) { - i64Total += GetCyclesDifference(SystemInformationImplementation::Delay, - uiMSecPerRepetition); - i64Overhead += GetCyclesDifference( - SystemInformationImplementation::DelayOverhead, uiMSecPerRepetition); - } - - // Calculate the MHz speed. - i64Total -= i64Overhead; - i64Total /= uiRepetitions; - i64Total /= uiMSecPerRepetition; - i64Total /= 1000; - - // Save the CPU speed. - this->CPUSpeedInMHz = (float)i64Total; - - retrieved = true; - } - - // If RDTSC is not supported, we fallback to trying to read this value - // from the registry: - if (!retrieved) { - HKEY hKey = nullptr; - LONG err = - RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, - KEY_READ, &hKey); - - if (ERROR_SUCCESS == err) { - DWORD dwType = 0; - DWORD data = 0; - DWORD dwSize = sizeof(DWORD); - - err = - RegQueryValueExW(hKey, L"~MHz", 0, &dwType, (LPBYTE)&data, &dwSize); - - if (ERROR_SUCCESS == err) { - this->CPUSpeedInMHz = (float)data; - retrieved = true; - } - - RegCloseKey(hKey); - hKey = nullptr; - } - } -#endif - - return retrieved; -} - -/** */ -bool SystemInformationImplementation::RetrieveClassicalCPUClockSpeed() -{ -#if USE_ASM_INSTRUCTIONS - LARGE_INTEGER liStart, liEnd, liCountsPerSecond; - double dFrequency, dDifference; - - // Attempt to get a starting tick count. - QueryPerformanceCounter(&liStart); - - __try { - _asm { - mov eax, 0x80000000 - mov ebx, CLASSICAL_CPU_FREQ_LOOP - Timer_Loop: - bsf ecx,eax - dec ebx - jnz Timer_Loop - } - } __except (1) { - return false; - } - - // Attempt to get a starting tick count. - QueryPerformanceCounter(&liEnd); - - // Get the difference... NB: This is in seconds.... - QueryPerformanceFrequency(&liCountsPerSecond); - dDifference = (((double)liEnd.QuadPart - (double)liStart.QuadPart) / - (double)liCountsPerSecond.QuadPart); - - // Calculate the clock speed. - if (this->ChipID.Family == 3) { - // 80386 processors.... Loop time is 115 cycles! - dFrequency = (((CLASSICAL_CPU_FREQ_LOOP * 115) / dDifference) / 1000000); - } else if (this->ChipID.Family == 4) { - // 80486 processors.... Loop time is 47 cycles! - dFrequency = (((CLASSICAL_CPU_FREQ_LOOP * 47) / dDifference) / 1000000); - } else if (this->ChipID.Family == 5) { - // Pentium processors.... Loop time is 43 cycles! - dFrequency = (((CLASSICAL_CPU_FREQ_LOOP * 43) / dDifference) / 1000000); - } - - // Save the clock speed. - this->Features.CPUSpeed = (int)dFrequency; - - return true; - -#else - return false; -#endif -} - -/** */ -bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport( - int CPULevelToCheck) -{ - int cpuinfo[4] = { 0, 0, 0, 0 }; - - // The extended CPUID is supported by various vendors starting with the - // following CPU models: - // - // Manufacturer & Chip Name | Family Model Revision - // - // AMD K6, K6-2 | 5 6 x - // Cyrix GXm, Cyrix III "Joshua" | 5 4 x - // IDT C6-2 | 5 8 x - // VIA Cyrix III | 6 5 x - // Transmeta Crusoe | 5 x x - // Intel Pentium 4 | f x x - // - - // We check to see if a supported processor is present... - if (this->ChipManufacturer == AMD) { - if (this->ChipID.Family < 5) - return false; - if ((this->ChipID.Family == 5) && (this->ChipID.Model < 6)) - return false; - } else if (this->ChipManufacturer == Cyrix) { - if (this->ChipID.Family < 5) - return false; - if ((this->ChipID.Family == 5) && (this->ChipID.Model < 4)) - return false; - if ((this->ChipID.Family == 6) && (this->ChipID.Model < 5)) - return false; - } else if (this->ChipManufacturer == IDT) { - if (this->ChipID.Family < 5) - return false; - if ((this->ChipID.Family == 5) && (this->ChipID.Model < 8)) - return false; - } else if (this->ChipManufacturer == Transmeta) { - if (this->ChipID.Family < 5) - return false; - } else if (this->ChipManufacturer == Intel) { - if (this->ChipID.Family < 0xf) { - return false; - } - } - -#if USE_CPUID - if (!call_cpuid(0x80000000, cpuinfo)) { - return false; - } -#endif - - // Now we have to check the level wanted vs level returned... - int nLevelWanted = (CPULevelToCheck & 0x7FFFFFFF); - int nLevelReturn = (cpuinfo[0] & 0x7FFFFFFF); - - // Check to see if the level provided is supported... - if (nLevelWanted > nLevelReturn) { - return false; - } - - return true; -} - -/** */ -bool SystemInformationImplementation::RetrieveExtendedCPUFeatures() -{ - - // Check that we are not using an Intel processor as it does not support - // this. - if (this->ChipManufacturer == Intel) { - return false; - } - - // Check to see if what we are about to do is supported... - if (!RetrieveCPUExtendedLevelSupport(static_cast<int>(0x80000001))) { - return false; - } - -#if USE_CPUID - int localCPUExtendedFeatures[4] = { 0, 0, 0, 0 }; - - if (!call_cpuid(0x80000001, localCPUExtendedFeatures)) { - return false; - } - - // Retrieve the extended features of CPU present. - this->Features.ExtendedFeatures.Has3DNow = - ((localCPUExtendedFeatures[3] & 0x80000000) != - 0); // 3DNow Present --> Bit 31. - this->Features.ExtendedFeatures.Has3DNowPlus = - ((localCPUExtendedFeatures[3] & 0x40000000) != - 0); // 3DNow+ Present -- > Bit 30. - this->Features.ExtendedFeatures.HasSSEMMX = - ((localCPUExtendedFeatures[3] & 0x00400000) != - 0); // SSE MMX Present --> Bit 22. - this->Features.ExtendedFeatures.SupportsMP = - ((localCPUExtendedFeatures[3] & 0x00080000) != - 0); // MP Capable -- > Bit 19. - - // Retrieve AMD specific extended features. - if (this->ChipManufacturer == AMD || this->ChipManufacturer == Hygon) { - this->Features.ExtendedFeatures.HasMMXPlus = - ((localCPUExtendedFeatures[3] & 0x00400000) != - 0); // AMD specific: MMX-SSE --> Bit 22 - } - - // Retrieve Cyrix specific extended features. - if (this->ChipManufacturer == Cyrix) { - this->Features.ExtendedFeatures.HasMMXPlus = - ((localCPUExtendedFeatures[3] & 0x01000000) != - 0); // Cyrix specific: Extended MMX --> Bit 24 - } - - return true; - -#else - return false; -#endif -} - -/** */ -bool SystemInformationImplementation::RetrieveProcessorSerialNumber() -{ - // Check to see if the processor supports the processor serial number. - if (!this->Features.HasSerial) { - return false; - } - -#if USE_CPUID - int SerialNumber[4]; - - if (!call_cpuid(3, SerialNumber)) { - return false; - } - - // Process the returned information. - // ; eax = 3 --> ebx: top 32 bits are the processor signature bits --> NB: - // Transmeta only ?!? - // ; ecx: middle 32 bits are the processor signature bits - // ; edx: bottom 32 bits are the processor signature bits - char sn[128]; - sprintf(sn, "%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x", - ((SerialNumber[1] & 0xff000000) >> 24), - ((SerialNumber[1] & 0x00ff0000) >> 16), - ((SerialNumber[1] & 0x0000ff00) >> 8), - ((SerialNumber[1] & 0x000000ff) >> 0), - ((SerialNumber[2] & 0xff000000) >> 24), - ((SerialNumber[2] & 0x00ff0000) >> 16), - ((SerialNumber[2] & 0x0000ff00) >> 8), - ((SerialNumber[2] & 0x000000ff) >> 0), - ((SerialNumber[3] & 0xff000000) >> 24), - ((SerialNumber[3] & 0x00ff0000) >> 16), - ((SerialNumber[3] & 0x0000ff00) >> 8), - ((SerialNumber[3] & 0x000000ff) >> 0)); - this->ChipID.SerialNumber = sn; - return true; - -#else - return false; -#endif -} - -/** */ -bool SystemInformationImplementation::RetrieveCPUPowerManagement() -{ - // Check to see if what we are about to do is supported... - if (!RetrieveCPUExtendedLevelSupport(static_cast<int>(0x80000007))) { - this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID = false; - this->Features.ExtendedFeatures.PowerManagement.HasVoltageID = false; - this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode = false; - return false; - } - -#if USE_CPUID - int localCPUPowerManagement[4] = { 0, 0, 0, 0 }; - - if (!call_cpuid(0x80000007, localCPUPowerManagement)) { - return false; - } - - // Check for the power management capabilities of the CPU. - this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode = - ((localCPUPowerManagement[3] & 0x00000001) != 0); - this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID = - ((localCPUPowerManagement[3] & 0x00000002) != 0); - this->Features.ExtendedFeatures.PowerManagement.HasVoltageID = - ((localCPUPowerManagement[3] & 0x00000004) != 0); - - return true; - -#else - return false; -#endif -} - -#if USE_CPUID -// Used only in USE_CPUID implementation below. -static void SystemInformationStripLeadingSpace(std::string& str) -{ - // Because some manufacturers have leading white space - we have to - // post-process the name. - std::string::size_type pos = str.find_first_not_of(" "); - if (pos != std::string::npos) { - str = str.substr(pos); - } -} -#endif - -/** */ -bool SystemInformationImplementation::RetrieveExtendedCPUIdentity() -{ - // Check to see if what we are about to do is supported... - if (!RetrieveCPUExtendedLevelSupport(static_cast<int>(0x80000002))) - return false; - if (!RetrieveCPUExtendedLevelSupport(static_cast<int>(0x80000003))) - return false; - if (!RetrieveCPUExtendedLevelSupport(static_cast<int>(0x80000004))) - return false; - -#if USE_CPUID - int CPUExtendedIdentity[12]; - - if (!call_cpuid(0x80000002, CPUExtendedIdentity)) { - return false; - } - if (!call_cpuid(0x80000003, CPUExtendedIdentity + 4)) { - return false; - } - if (!call_cpuid(0x80000004, CPUExtendedIdentity + 8)) { - return false; - } - - // Process the returned information. - char nbuf[49]; - memcpy(&(nbuf[0]), &(CPUExtendedIdentity[0]), sizeof(int)); - memcpy(&(nbuf[4]), &(CPUExtendedIdentity[1]), sizeof(int)); - memcpy(&(nbuf[8]), &(CPUExtendedIdentity[2]), sizeof(int)); - memcpy(&(nbuf[12]), &(CPUExtendedIdentity[3]), sizeof(int)); - memcpy(&(nbuf[16]), &(CPUExtendedIdentity[4]), sizeof(int)); - memcpy(&(nbuf[20]), &(CPUExtendedIdentity[5]), sizeof(int)); - memcpy(&(nbuf[24]), &(CPUExtendedIdentity[6]), sizeof(int)); - memcpy(&(nbuf[28]), &(CPUExtendedIdentity[7]), sizeof(int)); - memcpy(&(nbuf[32]), &(CPUExtendedIdentity[8]), sizeof(int)); - memcpy(&(nbuf[36]), &(CPUExtendedIdentity[9]), sizeof(int)); - memcpy(&(nbuf[40]), &(CPUExtendedIdentity[10]), sizeof(int)); - memcpy(&(nbuf[44]), &(CPUExtendedIdentity[11]), sizeof(int)); - nbuf[48] = '\0'; - this->ChipID.ProcessorName = nbuf; - this->ChipID.ModelName = nbuf; - - // Because some manufacturers have leading white space - we have to - // post-process the name. - SystemInformationStripLeadingSpace(this->ChipID.ProcessorName); - return true; -#else - return false; -#endif -} - -/** */ -bool SystemInformationImplementation::RetrieveClassicalCPUIdentity() -{ - // Start by decided which manufacturer we are using.... - switch (this->ChipManufacturer) { - case Intel: - // Check the family / model / revision to determine the CPU ID. - switch (this->ChipID.Family) { - case 3: - this->ChipID.ProcessorName = "Newer i80386 family"; - break; - case 4: - switch (this->ChipID.Model) { - case 0: - this->ChipID.ProcessorName = "i80486DX-25/33"; - break; - case 1: - this->ChipID.ProcessorName = "i80486DX-50"; - break; - case 2: - this->ChipID.ProcessorName = "i80486SX"; - break; - case 3: - this->ChipID.ProcessorName = "i80486DX2"; - break; - case 4: - this->ChipID.ProcessorName = "i80486SL"; - break; - case 5: - this->ChipID.ProcessorName = "i80486SX2"; - break; - case 7: - this->ChipID.ProcessorName = "i80486DX2 WriteBack"; - break; - case 8: - this->ChipID.ProcessorName = "i80486DX4"; - break; - case 9: - this->ChipID.ProcessorName = "i80486DX4 WriteBack"; - break; - default: - this->ChipID.ProcessorName = "Unknown 80486 family"; - return false; - } - break; - case 5: - switch (this->ChipID.Model) { - case 0: - this->ChipID.ProcessorName = "P5 A-Step"; - break; - case 1: - this->ChipID.ProcessorName = "P5"; - break; - case 2: - this->ChipID.ProcessorName = "P54C"; - break; - case 3: - this->ChipID.ProcessorName = "P24T OverDrive"; - break; - case 4: - this->ChipID.ProcessorName = "P55C"; - break; - case 7: - this->ChipID.ProcessorName = "P54C"; - break; - case 8: - this->ChipID.ProcessorName = "P55C (0.25micron)"; - break; - default: - this->ChipID.ProcessorName = "Unknown Pentium family"; - return false; - } - break; - case 6: - switch (this->ChipID.Model) { - case 0: - this->ChipID.ProcessorName = "P6 A-Step"; - break; - case 1: - this->ChipID.ProcessorName = "P6"; - break; - case 3: - this->ChipID.ProcessorName = "Pentium II (0.28 micron)"; - break; - case 5: - this->ChipID.ProcessorName = "Pentium II (0.25 micron)"; - break; - case 6: - this->ChipID.ProcessorName = "Pentium II With On-Die L2 Cache"; - break; - case 7: - this->ChipID.ProcessorName = "Pentium III (0.25 micron)"; - break; - case 8: - this->ChipID.ProcessorName = - "Pentium III (0.18 micron) With 256 KB On-Die L2 Cache "; - break; - case 0xa: - this->ChipID.ProcessorName = - "Pentium III (0.18 micron) With 1 Or 2 MB On-Die L2 Cache "; - break; - case 0xb: - this->ChipID.ProcessorName = "Pentium III (0.13 micron) With " - "256 Or 512 KB On-Die L2 Cache "; - break; - case 23: - this->ChipID.ProcessorName = - "Intel(R) Core(TM)2 Duo CPU T9500 @ 2.60GHz"; - break; - default: - this->ChipID.ProcessorName = "Unknown P6 family"; - return false; - } - break; - case 7: - this->ChipID.ProcessorName = "Intel Merced (IA-64)"; - break; - case 0xf: - // Check the extended family bits... - switch (this->ChipID.ExtendedFamily) { - case 0: - switch (this->ChipID.Model) { - case 0: - this->ChipID.ProcessorName = "Pentium IV (0.18 micron)"; - break; - case 1: - this->ChipID.ProcessorName = "Pentium IV (0.18 micron)"; - break; - case 2: - this->ChipID.ProcessorName = "Pentium IV (0.13 micron)"; - break; - default: - this->ChipID.ProcessorName = "Unknown Pentium 4 family"; - return false; - } - break; - case 1: - this->ChipID.ProcessorName = "Intel McKinley (IA-64)"; - break; - default: - this->ChipID.ProcessorName = "Pentium"; - } - break; - default: - this->ChipID.ProcessorName = "Unknown Intel family"; - return false; - } - break; - - case AMD: - // Check the family / model / revision to determine the CPU ID. - switch (this->ChipID.Family) { - case 4: - switch (this->ChipID.Model) { - case 3: - this->ChipID.ProcessorName = "80486DX2"; - break; - case 7: - this->ChipID.ProcessorName = "80486DX2 WriteBack"; - break; - case 8: - this->ChipID.ProcessorName = "80486DX4"; - break; - case 9: - this->ChipID.ProcessorName = "80486DX4 WriteBack"; - break; - case 0xe: - this->ChipID.ProcessorName = "5x86"; - break; - case 0xf: - this->ChipID.ProcessorName = "5x86WB"; - break; - default: - this->ChipID.ProcessorName = "Unknown 80486 family"; - return false; - } - break; - case 5: - switch (this->ChipID.Model) { - case 0: - this->ChipID.ProcessorName = "SSA5 (PR75, PR90 = PR100)"; - break; - case 1: - this->ChipID.ProcessorName = "5k86 (PR120 = PR133)"; - break; - case 2: - this->ChipID.ProcessorName = "5k86 (PR166)"; - break; - case 3: - this->ChipID.ProcessorName = "5k86 (PR200)"; - break; - case 6: - this->ChipID.ProcessorName = "K6 (0.30 micron)"; - break; - case 7: - this->ChipID.ProcessorName = "K6 (0.25 micron)"; - break; - case 8: - this->ChipID.ProcessorName = "K6-2"; - break; - case 9: - this->ChipID.ProcessorName = "K6-III"; - break; - case 0xd: - this->ChipID.ProcessorName = "K6-2+ or K6-III+ (0.18 micron)"; - break; - default: - this->ChipID.ProcessorName = "Unknown 80586 family"; - return false; - } - break; - case 6: - switch (this->ChipID.Model) { - case 1: - this->ChipID.ProcessorName = "Athlon- (0.25 micron)"; - break; - case 2: - this->ChipID.ProcessorName = "Athlon- (0.18 micron)"; - break; - case 3: - this->ChipID.ProcessorName = "Duron- (SF core)"; - break; - case 4: - this->ChipID.ProcessorName = "Athlon- (Thunderbird core)"; - break; - case 6: - this->ChipID.ProcessorName = "Athlon- (Palomino core)"; - break; - case 7: - this->ChipID.ProcessorName = "Duron- (Morgan core)"; - break; - case 8: - if (this->Features.ExtendedFeatures.SupportsMP) - this->ChipID.ProcessorName = "Athlon - MP (Thoroughbred core)"; - else - this->ChipID.ProcessorName = "Athlon - XP (Thoroughbred core)"; - break; - default: - this->ChipID.ProcessorName = "Unknown K7 family"; - return false; - } - break; - default: - this->ChipID.ProcessorName = "Unknown AMD family"; - return false; - } - break; - - case Hygon: - this->ChipID.ProcessorName = "Unknown Hygon family"; - return false; - - case Transmeta: - switch (this->ChipID.Family) { - case 5: - switch (this->ChipID.Model) { - case 4: - this->ChipID.ProcessorName = "Crusoe TM3x00 and TM5x00"; - break; - default: - this->ChipID.ProcessorName = "Unknown Crusoe family"; - return false; - } - break; - default: - this->ChipID.ProcessorName = "Unknown Transmeta family"; - return false; - } - break; - - case Rise: - switch (this->ChipID.Family) { - case 5: - switch (this->ChipID.Model) { - case 0: - this->ChipID.ProcessorName = "mP6 (0.25 micron)"; - break; - case 2: - this->ChipID.ProcessorName = "mP6 (0.18 micron)"; - break; - default: - this->ChipID.ProcessorName = "Unknown Rise family"; - return false; - } - break; - default: - this->ChipID.ProcessorName = "Unknown Rise family"; - return false; - } - break; - - case UMC: - switch (this->ChipID.Family) { - case 4: - switch (this->ChipID.Model) { - case 1: - this->ChipID.ProcessorName = "U5D"; - break; - case 2: - this->ChipID.ProcessorName = "U5S"; - break; - default: - this->ChipID.ProcessorName = "Unknown UMC family"; - return false; - } - break; - default: - this->ChipID.ProcessorName = "Unknown UMC family"; - return false; - } - break; - - case IDT: - switch (this->ChipID.Family) { - case 5: - switch (this->ChipID.Model) { - case 4: - this->ChipID.ProcessorName = "C6"; - break; - case 8: - this->ChipID.ProcessorName = "C2"; - break; - case 9: - this->ChipID.ProcessorName = "C3"; - break; - default: - this->ChipID.ProcessorName = "Unknown IDT\\Centaur family"; - return false; - } - break; - case 6: - switch (this->ChipID.Model) { - case 6: - this->ChipID.ProcessorName = "VIA Cyrix III - Samuel"; - break; - default: - this->ChipID.ProcessorName = "Unknown IDT\\Centaur family"; - return false; - } - break; - default: - this->ChipID.ProcessorName = "Unknown IDT\\Centaur family"; - return false; - } - break; - - case Cyrix: - switch (this->ChipID.Family) { - case 4: - switch (this->ChipID.Model) { - case 4: - this->ChipID.ProcessorName = "MediaGX GX = GXm"; - break; - case 9: - this->ChipID.ProcessorName = "5x86"; - break; - default: - this->ChipID.ProcessorName = "Unknown Cx5x86 family"; - return false; - } - break; - case 5: - switch (this->ChipID.Model) { - case 2: - this->ChipID.ProcessorName = "Cx6x86"; - break; - case 4: - this->ChipID.ProcessorName = "MediaGX GXm"; - break; - default: - this->ChipID.ProcessorName = "Unknown Cx6x86 family"; - return false; - } - break; - case 6: - switch (this->ChipID.Model) { - case 0: - this->ChipID.ProcessorName = "6x86MX"; - break; - case 5: - this->ChipID.ProcessorName = "Cyrix M2 Core"; - break; - case 6: - this->ChipID.ProcessorName = "WinChip C5A Core"; - break; - case 7: - this->ChipID.ProcessorName = "WinChip C5B\\C5C Core"; - break; - case 8: - this->ChipID.ProcessorName = "WinChip C5C-T Core"; - break; - default: - this->ChipID.ProcessorName = "Unknown 6x86MX\\Cyrix III family"; - return false; - } - break; - default: - this->ChipID.ProcessorName = "Unknown Cyrix family"; - return false; - } - break; - - case NexGen: - switch (this->ChipID.Family) { - case 5: - switch (this->ChipID.Model) { - case 0: - this->ChipID.ProcessorName = "Nx586 or Nx586FPU"; - break; - default: - this->ChipID.ProcessorName = "Unknown NexGen family"; - return false; - } - break; - default: - this->ChipID.ProcessorName = "Unknown NexGen family"; - return false; - } - break; - - case NSC: - this->ChipID.ProcessorName = "Cx486SLC \\ DLC \\ Cx486S A-Step"; - break; - - case Sun: - case IBM: - case Motorola: - case HP: - case UnknownManufacturer: - default: - this->ChipID.ProcessorName = - "Unknown family"; // We cannot identify the processor. - return false; - } - - return true; -} - -/** Extract a value from the CPUInfo file */ -std::string SystemInformationImplementation::ExtractValueFromCpuInfoFile( - std::string buffer, const char* word, size_t init) -{ - size_t pos = buffer.find(word, init); - if (pos != std::string::npos) { - this->CurrentPositionInFile = pos; - pos = buffer.find(":", pos); - size_t pos2 = buffer.find("\n", pos); - if (pos != std::string::npos && pos2 != std::string::npos) { - // It may happen that the beginning matches, but this is still not the - // requested key. - // An example is looking for "cpu" when "cpu family" comes first. So we - // check that - // we have only spaces from here to pos, otherwise we search again. - for (size_t i = this->CurrentPositionInFile + strlen(word); i < pos; - ++i) { - if (buffer[i] != ' ' && buffer[i] != '\t') { - return this->ExtractValueFromCpuInfoFile(buffer, word, pos2); - } - } - return buffer.substr(pos + 2, pos2 - pos - 2); - } - } - this->CurrentPositionInFile = std::string::npos; - return ""; -} - -/** Query for the cpu status */ -bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile() -{ - this->NumberOfLogicalCPU = 0; - this->NumberOfPhysicalCPU = 0; - std::string buffer; - - FILE* fd = fopen("/proc/cpuinfo", "r"); - if (!fd) { - std::cout << "Problem opening /proc/cpuinfo" << std::endl; - return false; - } - - size_t fileSize = 0; - while (!feof(fd)) { - buffer += static_cast<char>(fgetc(fd)); - fileSize++; - } - fclose(fd); - buffer.resize(fileSize - 2); - // Number of logical CPUs (combination of multiple processors, multi-core - // and SMT) - size_t pos = buffer.find("processor\t"); - while (pos != std::string::npos) { - this->NumberOfLogicalCPU++; - pos = buffer.find("processor\t", pos + 1); - } - -#ifdef __linux - // Count sockets. - std::set<int> PhysicalIDs; - std::string idc = this->ExtractValueFromCpuInfoFile(buffer, "physical id"); - while (this->CurrentPositionInFile != std::string::npos) { - int id = atoi(idc.c_str()); - PhysicalIDs.insert(id); - idc = this->ExtractValueFromCpuInfoFile(buffer, "physical id", - this->CurrentPositionInFile + 1); - } - uint64_t NumberOfSockets = PhysicalIDs.size(); - NumberOfSockets = std::max(NumberOfSockets, (uint64_t)1); - // Physical ids returned by Linux don't distinguish cores. - // We want to record the total number of cores in this->NumberOfPhysicalCPU - // (checking only the first proc) - std::string Cores = this->ExtractValueFromCpuInfoFile(buffer, "cpu cores"); - unsigned int NumberOfCoresPerSocket = (unsigned int)atoi(Cores.c_str()); - NumberOfCoresPerSocket = std::max(NumberOfCoresPerSocket, 1u); - this->NumberOfPhysicalCPU = - NumberOfCoresPerSocket * (unsigned int)NumberOfSockets; - -#else // __CYGWIN__ - // does not have "physical id" entries, neither "cpu cores" - // this has to be fixed for hyper-threading. - std::string cpucount = - this->ExtractValueFromCpuInfoFile(buffer, "cpu count"); - this->NumberOfPhysicalCPU = this->NumberOfLogicalCPU = - atoi(cpucount.c_str()); -#endif - // gotta have one, and if this is 0 then we get a / by 0n - // better to have a bad answer than a crash - if (this->NumberOfPhysicalCPU <= 0) { - this->NumberOfPhysicalCPU = 1; - } - // LogicalProcessorsPerPhysical>1 => SMT. - this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = - this->NumberOfLogicalCPU / this->NumberOfPhysicalCPU; - - // CPU speed (checking only the first processor) - std::string CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer, "cpu MHz"); - if (!CPUSpeed.empty()) { - this->CPUSpeedInMHz = static_cast<float>(atof(CPUSpeed.c_str())); - } -#ifdef __linux - else { - // Linux Sparc: CPU speed is in Hz and encoded in hexadecimal - CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer, "Cpu0ClkTck"); - this->CPUSpeedInMHz = - static_cast<float>(strtoull(CPUSpeed.c_str(), 0, 16)) / 1000000.0f; - } -#endif - - // Chip family - std::string familyStr = - this->ExtractValueFromCpuInfoFile(buffer, "cpu family"); - if (familyStr.empty()) { - familyStr = this->ExtractValueFromCpuInfoFile(buffer, "CPU architecture"); - } - this->ChipID.Family = atoi(familyStr.c_str()); - - // Chip Vendor - this->ChipID.Vendor = this->ExtractValueFromCpuInfoFile(buffer, "vendor_id"); - this->FindManufacturer(familyStr); - - // second try for setting family - if (this->ChipID.Family == 0 && this->ChipManufacturer == HP) { - if (familyStr == "PA-RISC 1.1a") - this->ChipID.Family = 0x11a; - else if (familyStr == "PA-RISC 2.0") - this->ChipID.Family = 0x200; - // If you really get CMake to work on a machine not belonging to - // any of those families I owe you a dinner if you get it to - // contribute nightly builds regularly. - } - - // Chip Model - this->ChipID.Model = - atoi(this->ExtractValueFromCpuInfoFile(buffer, "model").c_str()); - if (!this->RetrieveClassicalCPUIdentity()) { - // Some platforms (e.g. PA-RISC) tell us their CPU name here. - // Note: x86 does not. - std::string cpuname = this->ExtractValueFromCpuInfoFile(buffer, "cpu"); - if (!cpuname.empty()) { - this->ChipID.ProcessorName = cpuname; - } - } - - // Chip revision - std::string cpurev = this->ExtractValueFromCpuInfoFile(buffer, "stepping"); - if (cpurev.empty()) { - cpurev = this->ExtractValueFromCpuInfoFile(buffer, "CPU revision"); - } - this->ChipID.Revision = atoi(cpurev.c_str()); - - // Chip Model Name - this->ChipID.ModelName = - this->ExtractValueFromCpuInfoFile(buffer, "model name"); - - // L1 Cache size - // Different architectures may show different names for the caches. - // Sum up everything we find. - std::vector<const char*> cachename; - cachename.clear(); - - cachename.push_back("cache size"); // e.g. x86 - cachename.push_back("I-cache"); // e.g. PA-RISC - cachename.push_back("D-cache"); // e.g. PA-RISC - - this->Features.L1CacheSize = 0; - for (size_t index = 0; index < cachename.size(); index++) { - std::string cacheSize = - this->ExtractValueFromCpuInfoFile(buffer, cachename[index]); - if (!cacheSize.empty()) { - pos = cacheSize.find(" KB"); - if (pos != std::string::npos) { - cacheSize = cacheSize.substr(0, pos); - } - this->Features.L1CacheSize += atoi(cacheSize.c_str()); - } - } - - // processor feature flags (probably x86 specific) - std::string cpuflags = this->ExtractValueFromCpuInfoFile(buffer, "flags"); - if (!cpurev.empty()) { - // now we can match every flags as space + flag + space - cpuflags = " " + cpuflags + " "; - if ((cpuflags.find(" fpu ") != std::string::npos)) { - this->Features.HasFPU = true; - } - if ((cpuflags.find(" tsc ") != std::string::npos)) { - this->Features.HasTSC = true; - } - if ((cpuflags.find(" mmx ") != std::string::npos)) { - this->Features.HasMMX = true; - } - if ((cpuflags.find(" sse ") != std::string::npos)) { - this->Features.HasSSE = true; - } - if ((cpuflags.find(" sse2 ") != std::string::npos)) { - this->Features.HasSSE2 = true; - } - if ((cpuflags.find(" apic ") != std::string::npos)) { - this->Features.HasAPIC = true; - } - if ((cpuflags.find(" cmov ") != std::string::npos)) { - this->Features.HasCMOV = true; - } - if ((cpuflags.find(" mtrr ") != std::string::npos)) { - this->Features.HasMTRR = true; - } - if ((cpuflags.find(" acpi ") != std::string::npos)) { - this->Features.HasACPI = true; - } - if ((cpuflags.find(" 3dnow ") != std::string::npos)) { - this->Features.ExtendedFeatures.Has3DNow = true; - } - } - - return true; -} - -bool SystemInformationImplementation::QueryProcessorBySysconf() -{ -#if defined(_SC_NPROC_ONLN) && !defined(_SC_NPROCESSORS_ONLN) -// IRIX names this slightly different -# define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN -#endif - -#ifdef _SC_NPROCESSORS_ONLN - long c = sysconf(_SC_NPROCESSORS_ONLN); - if (c <= 0) { - return false; - } - - this->NumberOfPhysicalCPU = static_cast<unsigned int>(c); - this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU; - - return true; -#else - return false; -#endif -} - -bool SystemInformationImplementation::QueryProcessor() -{ - return this->QueryProcessorBySysconf(); -} - -/** -Get total system RAM in units of KiB. -*/ -SystemInformation::LongLong -SystemInformationImplementation::GetHostMemoryTotal() -{ -#if defined(_WIN32) -# if defined(_MSC_VER) && _MSC_VER < 1300 - MEMORYSTATUS stat; - stat.dwLength = sizeof(stat); - GlobalMemoryStatus(&stat); - return stat.dwTotalPhys / 1024; -# else - MEMORYSTATUSEX statex; - statex.dwLength = sizeof(statex); - GlobalMemoryStatusEx(&statex); - return statex.ullTotalPhys / 1024; -# endif -#elif defined(__linux) - SystemInformation::LongLong memTotal = 0; - int ierr = GetFieldFromFile("/proc/meminfo", "MemTotal:", memTotal); - if (ierr) { - return -1; - } - return memTotal; -#elif defined(__APPLE__) - uint64_t mem; - size_t len = sizeof(mem); - int ierr = sysctlbyname("hw.memsize", &mem, &len, nullptr, 0); - if (ierr) { - return -1; - } - return mem / 1024; -#else - return 0; -#endif -} - -/** -Get total system RAM in units of KiB. This may differ from the -host total if a host-wide resource limit is applied. -*/ -SystemInformation::LongLong -SystemInformationImplementation::GetHostMemoryAvailable( - const char* hostLimitEnvVarName) -{ - SystemInformation::LongLong memTotal = this->GetHostMemoryTotal(); - - // the following mechanism is provided for systems that - // apply resource limits across groups of processes. - // this is of use on certain SMP systems (eg. SGI UV) - // where the host has a large amount of ram but a given user's - // access to it is severely restricted. The system will - // apply a limit across a set of processes. Units are in KiB. - if (hostLimitEnvVarName) { - const char* hostLimitEnvVarValue = getenv(hostLimitEnvVarName); - if (hostLimitEnvVarValue) { - SystemInformation::LongLong hostLimit = - atoLongLong(hostLimitEnvVarValue); - if (hostLimit > 0) { - memTotal = min(hostLimit, memTotal); - } - } - } - - return memTotal; -} - -/** -Get total system RAM in units of KiB. This may differ from the -host total if a per-process resource limit is applied. -*/ -SystemInformation::LongLong -SystemInformationImplementation::GetProcMemoryAvailable( - const char* hostLimitEnvVarName, const char* procLimitEnvVarName) -{ - SystemInformation::LongLong memAvail = - this->GetHostMemoryAvailable(hostLimitEnvVarName); - - // the following mechanism is provide for systems where rlimits - // are not employed. Units are in KiB. - if (procLimitEnvVarName) { - const char* procLimitEnvVarValue = getenv(procLimitEnvVarName); - if (procLimitEnvVarValue) { - SystemInformation::LongLong procLimit = - atoLongLong(procLimitEnvVarValue); - if (procLimit > 0) { - memAvail = min(procLimit, memAvail); - } - } - } - -#if defined(__linux) - int ierr; - ResourceLimitType rlim; - ierr = GetResourceLimit(RLIMIT_DATA, &rlim); - if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) { - memAvail = - min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail); - } - - ierr = GetResourceLimit(RLIMIT_AS, &rlim); - if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) { - memAvail = - min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail); - } -#elif defined(__APPLE__) - struct rlimit rlim; - int ierr; - ierr = getrlimit(RLIMIT_DATA, &rlim); - if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) { - memAvail = - min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail); - } - - ierr = getrlimit(RLIMIT_RSS, &rlim); - if ((ierr == 0) && (rlim.rlim_cur != RLIM_INFINITY)) { - memAvail = - min((SystemInformation::LongLong)rlim.rlim_cur / 1024, memAvail); - } -#endif - - return memAvail; -} - -/** -Get RAM used by all processes in the host, in units of KiB. -*/ -SystemInformation::LongLong -SystemInformationImplementation::GetHostMemoryUsed() -{ -#if defined(_WIN32) -# if defined(_MSC_VER) && _MSC_VER < 1300 - MEMORYSTATUS stat; - stat.dwLength = sizeof(stat); - GlobalMemoryStatus(&stat); - return (stat.dwTotalPhys - stat.dwAvailPhys) / 1024; -# else - MEMORYSTATUSEX statex; - statex.dwLength = sizeof(statex); - GlobalMemoryStatusEx(&statex); - return (statex.ullTotalPhys - statex.ullAvailPhys) / 1024; -# endif -#elif defined(__linux) - // First try to use MemAvailable, but it only works on newer kernels - const char* names2[3] = { "MemTotal:", "MemAvailable:", nullptr }; - SystemInformation::LongLong values2[2] = { SystemInformation::LongLong(0) }; - int ierr = GetFieldsFromFile("/proc/meminfo", names2, values2); - if (ierr) { - const char* names4[5] = { "MemTotal:", "MemFree:", "Buffers:", "Cached:", - nullptr }; - SystemInformation::LongLong values4[4] = { SystemInformation::LongLong( - 0) }; - ierr = GetFieldsFromFile("/proc/meminfo", names4, values4); - if (ierr) { - return ierr; - } - SystemInformation::LongLong& memTotal = values4[0]; - SystemInformation::LongLong& memFree = values4[1]; - SystemInformation::LongLong& memBuffers = values4[2]; - SystemInformation::LongLong& memCached = values4[3]; - return memTotal - memFree - memBuffers - memCached; - } - SystemInformation::LongLong& memTotal = values2[0]; - SystemInformation::LongLong& memAvail = values2[1]; - return memTotal - memAvail; -#elif defined(__APPLE__) - SystemInformation::LongLong psz = getpagesize(); - if (psz < 1) { - return -1; - } - const char* names[3] = { "Pages wired down:", "Pages active:", nullptr }; - SystemInformation::LongLong values[2] = { SystemInformation::LongLong(0) }; - int ierr = GetFieldsFromCommand("vm_stat", names, values); - if (ierr) { - return -1; - } - SystemInformation::LongLong& vmWired = values[0]; - SystemInformation::LongLong& vmActive = values[1]; - return ((vmActive + vmWired) * psz) / 1024; -#else - return 0; -#endif -} - -/** -Get system RAM used by the process associated with the given -process id in units of KiB. -*/ -SystemInformation::LongLong -SystemInformationImplementation::GetProcMemoryUsed() -{ -#if defined(_WIN32) && defined(KWSYS_SYS_HAS_PSAPI) - long pid = GetCurrentProcessId(); - HANDLE hProc; - hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid); - if (hProc == 0) { - return -1; - } - PROCESS_MEMORY_COUNTERS pmc; - int ok = GetProcessMemoryInfo(hProc, &pmc, sizeof(pmc)); - CloseHandle(hProc); - if (!ok) { - return -2; - } - return pmc.WorkingSetSize / 1024; -#elif defined(__linux) - SystemInformation::LongLong memUsed = 0; - int ierr = GetFieldFromFile("/proc/self/status", "VmRSS:", memUsed); - if (ierr) { - return -1; - } - return memUsed; -#elif defined(__APPLE__) - SystemInformation::LongLong memUsed = 0; - pid_t pid = getpid(); - std::ostringstream oss; - oss << "ps -o rss= -p " << pid; - FILE* file = popen(oss.str().c_str(), "r"); - if (file == nullptr) { - return -1; - } - oss.str(""); - while (!feof(file) && !ferror(file)) { - char buf[256] = { '\0' }; - errno = 0; - size_t nRead = fread(buf, 1, 256, file); - if (ferror(file) && (errno == EINTR)) { - clearerr(file); - } - if (nRead) - oss << buf; - } - int ierr = ferror(file); - pclose(file); - if (ierr) { - return -2; - } - std::istringstream iss(oss.str()); - iss >> memUsed; - return memUsed; -#else - return 0; -#endif -} - -double SystemInformationImplementation::GetLoadAverage() -{ -#if defined(KWSYS_CXX_HAS_GETLOADAVG) - double loadavg[3] = { 0.0, 0.0, 0.0 }; - if (getloadavg(loadavg, 3) > 0) { - return loadavg[0]; - } - return -0.0; -#elif defined(KWSYS_SYSTEMINFORMATION_USE_GetSystemTimes) - // Old windows.h headers do not provide GetSystemTimes. - typedef BOOL(WINAPI * GetSystemTimesType)(LPFILETIME, LPFILETIME, - LPFILETIME); - static GetSystemTimesType pGetSystemTimes = - (GetSystemTimesType)GetProcAddress(GetModuleHandleW(L"kernel32"), - "GetSystemTimes"); - FILETIME idleTime, kernelTime, userTime; - if (pGetSystemTimes && pGetSystemTimes(&idleTime, &kernelTime, &userTime)) { - unsigned __int64 const idleTicks = fileTimeToUInt64(idleTime); - unsigned __int64 const totalTicks = - fileTimeToUInt64(kernelTime) + fileTimeToUInt64(userTime); - return calculateCPULoad(idleTicks, totalTicks) * GetNumberOfPhysicalCPU(); - } - return -0.0; -#else - // Not implemented on this platform. - return -0.0; -#endif -} - -/** -Get the process id of the running process. -*/ -SystemInformation::LongLong SystemInformationImplementation::GetProcessId() -{ -#if defined(_WIN32) - return GetCurrentProcessId(); -#elif defined(__linux) || defined(__APPLE__) || defined(__OpenBSD__) || \ - defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) - return getpid(); -#else - return -1; -#endif -} - -/** - * Used in GetProgramStack(...) below - */ -#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 && defined(_MSC_VER) && \ - _MSC_VER >= 1800 -# define KWSYS_SYSTEMINFORMATION_HAS_DBGHELP -# define TRACE_MAX_STACK_FRAMES 1024 -# define TRACE_MAX_FUNCTION_NAME_LENGTH 1024 -# pragma warning(push) -# pragma warning(disable : 4091) /* 'typedef ': ignored on left of '' */ -# include "dbghelp.h" -# pragma warning(pop) -#endif - -/** -return current program stack in a string -demangle cxx symbols if possible. -*/ -std::string SystemInformationImplementation::GetProgramStack(int firstFrame, - int wholePath) -{ - std::ostringstream oss; - std::string programStack = ""; - -#ifdef KWSYS_SYSTEMINFORMATION_HAS_DBGHELP - (void)wholePath; - - void* stack[TRACE_MAX_STACK_FRAMES]; - HANDLE process = GetCurrentProcess(); - SymInitialize(process, nullptr, TRUE); - WORD numberOfFrames = - CaptureStackBackTrace(firstFrame, TRACE_MAX_STACK_FRAMES, stack, nullptr); - SYMBOL_INFO* symbol = static_cast<SYMBOL_INFO*>( - malloc(sizeof(SYMBOL_INFO) + - (TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR))); - symbol->MaxNameLen = TRACE_MAX_FUNCTION_NAME_LENGTH; - symbol->SizeOfStruct = sizeof(SYMBOL_INFO); - DWORD displacement; - IMAGEHLP_LINE64 line; - line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); - for (int i = 0; i < numberOfFrames; i++) { - DWORD64 address = reinterpret_cast<DWORD64>(stack[i]); - SymFromAddr(process, address, nullptr, symbol); - if (SymGetLineFromAddr64(process, address, &displacement, &line)) { - oss << " at " << symbol->Name << " in " << line.FileName << " line " - << line.LineNumber << std::endl; - } else { - oss << " at " << symbol->Name << std::endl; - } - } - free(symbol); - -#else - programStack += "" -# if !defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE) - "WARNING: The stack could not be examined " - "because backtrace is not supported.\n" -# elif !defined(KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD) - "WARNING: The stack trace will not use advanced " - "capabilities because this is a release build.\n" -# else -# if !defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP) - "WARNING: Function names will not be demangled " - "because dladdr is not available.\n" -# endif -# if !defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE) - "WARNING: Function names will not be demangled " - "because cxxabi is not available.\n" -# endif -# endif - ; - -# if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE) - void* stackSymbols[256]; - int nFrames = backtrace(stackSymbols, 256); - for (int i = firstFrame; i < nFrames; ++i) { - SymbolProperties symProps; - symProps.SetReportPath(wholePath); - symProps.Initialize(stackSymbols[i]); - oss << symProps << std::endl; - } -# else - (void)firstFrame; - (void)wholePath; -# endif -#endif - - programStack += oss.str(); - - return programStack; -} - -/** -when set print stack trace in response to common signals. -*/ -void SystemInformationImplementation::SetStackTraceOnError(int enable) -{ -#if !defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) - static int saOrigValid = 0; - static struct sigaction saABRTOrig; - static struct sigaction saSEGVOrig; - static struct sigaction saTERMOrig; - static struct sigaction saINTOrig; - static struct sigaction saILLOrig; - static struct sigaction saBUSOrig; - static struct sigaction saFPEOrig; - - if (enable && !saOrigValid) { - // save the current actions - sigaction(SIGABRT, nullptr, &saABRTOrig); - sigaction(SIGSEGV, nullptr, &saSEGVOrig); - sigaction(SIGTERM, nullptr, &saTERMOrig); - sigaction(SIGINT, nullptr, &saINTOrig); - sigaction(SIGILL, nullptr, &saILLOrig); - sigaction(SIGBUS, nullptr, &saBUSOrig); - sigaction(SIGFPE, nullptr, &saFPEOrig); - - // enable read, disable write - saOrigValid = 1; - - // install ours - struct sigaction sa; - sa.sa_sigaction = (SigAction)StacktraceSignalHandler; - sa.sa_flags = SA_SIGINFO | SA_RESETHAND; -# ifdef SA_RESTART - sa.sa_flags |= SA_RESTART; -# endif - sigemptyset(&sa.sa_mask); - - sigaction(SIGABRT, &sa, nullptr); - sigaction(SIGSEGV, &sa, nullptr); - sigaction(SIGTERM, &sa, nullptr); - sigaction(SIGINT, &sa, nullptr); - sigaction(SIGILL, &sa, nullptr); - sigaction(SIGBUS, &sa, nullptr); - sigaction(SIGFPE, &sa, nullptr); - } else if (!enable && saOrigValid) { - // restore previous actions - sigaction(SIGABRT, &saABRTOrig, nullptr); - sigaction(SIGSEGV, &saSEGVOrig, nullptr); - sigaction(SIGTERM, &saTERMOrig, nullptr); - sigaction(SIGINT, &saINTOrig, nullptr); - sigaction(SIGILL, &saILLOrig, nullptr); - sigaction(SIGBUS, &saBUSOrig, nullptr); - sigaction(SIGFPE, &saFPEOrig, nullptr); - - // enable write, disable read - saOrigValid = 0; - } -#else - // avoid warning C4100 - (void)enable; -#endif -} - -bool SystemInformationImplementation::QueryWindowsMemory() -{ -#if defined(_WIN32) -# if defined(_MSC_VER) && _MSC_VER < 1300 - MEMORYSTATUS ms; - unsigned long tv, tp, av, ap; - ms.dwLength = sizeof(ms); - GlobalMemoryStatus(&ms); -# define MEM_VAL(value) dw##value -# else - MEMORYSTATUSEX ms; - DWORDLONG tv, tp, av, ap; - ms.dwLength = sizeof(ms); - if (0 == GlobalMemoryStatusEx(&ms)) { - return 0; - } -# define MEM_VAL(value) ull##value -# endif - tv = ms.MEM_VAL(TotalPageFile); - tp = ms.MEM_VAL(TotalPhys); - av = ms.MEM_VAL(AvailPageFile); - ap = ms.MEM_VAL(AvailPhys); - this->TotalVirtualMemory = tv >> 10 >> 10; - this->TotalPhysicalMemory = tp >> 10 >> 10; - this->AvailableVirtualMemory = av >> 10 >> 10; - this->AvailablePhysicalMemory = ap >> 10 >> 10; - return true; -#else - return false; -#endif -} - -bool SystemInformationImplementation::QueryLinuxMemory() -{ -#if defined(__linux) - unsigned long tv = 0; - unsigned long tp = 0; - unsigned long av = 0; - unsigned long ap = 0; - - char buffer[1024]; // for reading lines - - int linuxMajor = 0; - int linuxMinor = 0; - - // Find the Linux kernel version first - struct utsname unameInfo; - int errorFlag = uname(&unameInfo); - if (errorFlag != 0) { - std::cout << "Problem calling uname(): " << strerror(errno) << std::endl; - return false; - } - - if (strlen(unameInfo.release) >= 3) { - // release looks like "2.6.3-15mdk-i686-up-4GB" - char majorChar = unameInfo.release[0]; - char minorChar = unameInfo.release[2]; - - if (isdigit(majorChar)) { - linuxMajor = majorChar - '0'; - } - - if (isdigit(minorChar)) { - linuxMinor = minorChar - '0'; - } - } - - FILE* fd = fopen("/proc/meminfo", "r"); - if (!fd) { - std::cout << "Problem opening /proc/meminfo" << std::endl; - return false; - } - - if (linuxMajor >= 3 || ((linuxMajor >= 2) && (linuxMinor >= 6))) { - // new /proc/meminfo format since kernel 2.6.x - // Rigorously, this test should check from the developing version 2.5.x - // that introduced the new format... - - enum - { - mMemTotal, - mMemFree, - mBuffers, - mCached, - mSwapTotal, - mSwapFree - }; - const char* format[6] = { "MemTotal:%lu kB", "MemFree:%lu kB", - "Buffers:%lu kB", "Cached:%lu kB", - "SwapTotal:%lu kB", "SwapFree:%lu kB" }; - bool have[6] = { false, false, false, false, false, false }; - unsigned long value[6]; - int count = 0; - while (fgets(buffer, static_cast<int>(sizeof(buffer)), fd)) { - for (int i = 0; i < 6; ++i) { - if (!have[i] && sscanf(buffer, format[i], &value[i]) == 1) { - have[i] = true; - ++count; - } - } - } - if (count == 6) { - this->TotalPhysicalMemory = value[mMemTotal] / 1024; - this->AvailablePhysicalMemory = - (value[mMemFree] + value[mBuffers] + value[mCached]) / 1024; - this->TotalVirtualMemory = value[mSwapTotal] / 1024; - this->AvailableVirtualMemory = value[mSwapFree] / 1024; - } else { - std::cout << "Problem parsing /proc/meminfo" << std::endl; - fclose(fd); - return false; - } - } else { - // /proc/meminfo format for kernel older than 2.6.x - - unsigned long temp; - unsigned long cachedMem; - unsigned long buffersMem; - // Skip "total: used:..." - char* r = fgets(buffer, static_cast<int>(sizeof(buffer)), fd); - int status = 0; - if (r == buffer) { - status += fscanf(fd, "Mem: %lu %lu %lu %lu %lu %lu\n", &tp, &temp, &ap, - &temp, &buffersMem, &cachedMem); - } - if (status == 6) { - status += fscanf(fd, "Swap: %lu %lu %lu\n", &tv, &temp, &av); - } - if (status == 9) { - this->TotalVirtualMemory = tv >> 10 >> 10; - this->TotalPhysicalMemory = tp >> 10 >> 10; - this->AvailableVirtualMemory = av >> 10 >> 10; - this->AvailablePhysicalMemory = - (ap + buffersMem + cachedMem) >> 10 >> 10; - } else { - std::cout << "Problem parsing /proc/meminfo" << std::endl; - fclose(fd); - return false; - } - } - fclose(fd); - - return true; -#else - return false; -#endif -} - -bool SystemInformationImplementation::QueryCygwinMemory() -{ -#ifdef __CYGWIN__ - // _SC_PAGE_SIZE does return the mmap() granularity on Cygwin, - // see http://cygwin.com/ml/cygwin/2006-06/msg00350.html - // Therefore just use 4096 as the page size of Windows. - long m = sysconf(_SC_PHYS_PAGES); - if (m < 0) { - return false; - } - this->TotalPhysicalMemory = m >> 8; - return true; -#else - return false; -#endif -} - -bool SystemInformationImplementation::QueryAIXMemory() -{ -#if defined(_AIX) && defined(_SC_AIX_REALMEM) - long c = sysconf(_SC_AIX_REALMEM); - if (c <= 0) { - return false; - } - - this->TotalPhysicalMemory = c / 1024; - - return true; -#else - return false; -#endif -} - -bool SystemInformationImplementation::QueryMemoryBySysconf() -{ -#if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) - // Assume the mmap() granularity as returned by _SC_PAGESIZE is also - // the system page size. The only known system where this isn't true - // is Cygwin. - long p = sysconf(_SC_PHYS_PAGES); - long m = sysconf(_SC_PAGESIZE); - - if (p < 0 || m < 0) { - return false; - } - - // assume pagesize is a power of 2 and smaller 1 MiB - size_t pagediv = (1024 * 1024 / m); - - this->TotalPhysicalMemory = p; - this->TotalPhysicalMemory /= pagediv; - -# if defined(_SC_AVPHYS_PAGES) - p = sysconf(_SC_AVPHYS_PAGES); - if (p < 0) { - return false; - } - - this->AvailablePhysicalMemory = p; - this->AvailablePhysicalMemory /= pagediv; -# endif - - return true; -#else - return false; -#endif -} - -/** Query for the memory status */ -bool SystemInformationImplementation::QueryMemory() -{ - return this->QueryMemoryBySysconf(); -} - -/** */ -size_t SystemInformationImplementation::GetTotalVirtualMemory() -{ - return this->TotalVirtualMemory; -} - -/** */ -size_t SystemInformationImplementation::GetAvailableVirtualMemory() -{ - return this->AvailableVirtualMemory; -} - -size_t SystemInformationImplementation::GetTotalPhysicalMemory() -{ - return this->TotalPhysicalMemory; -} - -/** */ -size_t SystemInformationImplementation::GetAvailablePhysicalMemory() -{ - return this->AvailablePhysicalMemory; -} - -/** Get Cycle differences */ -SystemInformation::LongLong -SystemInformationImplementation::GetCyclesDifference(DELAY_FUNC DelayFunction, - unsigned int uiParameter) -{ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - unsigned __int64 stamp1, stamp2; - - stamp1 = __rdtsc(); - DelayFunction(uiParameter); - stamp2 = __rdtsc(); - - return stamp2 - stamp1; -#elif USE_ASM_INSTRUCTIONS - - unsigned int edx1, eax1; - unsigned int edx2, eax2; - - // Calculate the frequency of the CPU instructions. - __try { - _asm { - push uiParameter ; push parameter param - mov ebx, DelayFunction ; store func in ebx - - RDTSC_INSTRUCTION - - mov esi, eax ; esi = eax - mov edi, edx ; edi = edx - - call ebx ; call the delay functions - - RDTSC_INSTRUCTION - - pop ebx - - mov edx2, edx ; edx2 = edx - mov eax2, eax ; eax2 = eax - - mov edx1, edi ; edx2 = edi - mov eax1, esi ; eax2 = esi - } - } __except (1) { - return -1; - } - - return ((((__int64)edx2 << 32) + eax2) - (((__int64)edx1 << 32) + eax1)); - -#else - (void)DelayFunction; - (void)uiParameter; - return -1; -#endif -} - -/** Compute the delay overhead */ -void SystemInformationImplementation::DelayOverhead(unsigned int uiMS) -{ -#if defined(_WIN32) - LARGE_INTEGER Frequency, StartCounter, EndCounter; - __int64 x; - - // Get the frequency of the high performance counter. - if (!QueryPerformanceFrequency(&Frequency)) { - return; - } - x = Frequency.QuadPart / 1000 * uiMS; - - // Get the starting position of the counter. - QueryPerformanceCounter(&StartCounter); - - do { - // Get the ending position of the counter. - QueryPerformanceCounter(&EndCounter); - } while (EndCounter.QuadPart - StartCounter.QuadPart == x); -#endif - (void)uiMS; -} - -/** Works only for windows */ -bool SystemInformationImplementation::IsSMTSupported() -{ - return this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical > 1; -} - -/** Return the APIC Id. Works only for windows. */ -unsigned char SystemInformationImplementation::GetAPICId() -{ - int Regs[4] = { 0, 0, 0, 0 }; - -#if USE_CPUID - if (!this->IsSMTSupported()) { - return static_cast<unsigned char>(-1); // HT not supported - } // Logical processor = 1 - call_cpuid(1, Regs); -#endif - - return static_cast<unsigned char>((Regs[1] & INITIAL_APIC_ID_BITS) >> 24); -} - -/** Count the number of CPUs. Works only on windows. */ -void SystemInformationImplementation::CPUCountWindows() -{ -#if defined(_WIN32) - this->NumberOfPhysicalCPU = 0; - this->NumberOfLogicalCPU = 0; - - typedef BOOL(WINAPI * GetLogicalProcessorInformationType)( - PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); - static GetLogicalProcessorInformationType pGetLogicalProcessorInformation = - (GetLogicalProcessorInformationType)GetProcAddress( - GetModuleHandleW(L"kernel32"), "GetLogicalProcessorInformation"); - - if (!pGetLogicalProcessorInformation) { - // Fallback to approximate implementation on ancient Windows versions. - SYSTEM_INFO info; - ZeroMemory(&info, sizeof(info)); - GetSystemInfo(&info); - this->NumberOfPhysicalCPU = - static_cast<unsigned int>(info.dwNumberOfProcessors); - this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU; - return; - } - - std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> ProcInfo; - { - DWORD Length = 0; - DWORD rc = pGetLogicalProcessorInformation(nullptr, &Length); - assert(FALSE == rc); - (void)rc; // Silence unused variable warning in Borland C++ 5.81 - assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER); - ProcInfo.resize(Length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); - rc = pGetLogicalProcessorInformation(&ProcInfo[0], &Length); - assert(rc != FALSE); - (void)rc; // Silence unused variable warning in Borland C++ 5.81 - } - - typedef std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION>::iterator - pinfoIt_t; - for (pinfoIt_t it = ProcInfo.begin(); it != ProcInfo.end(); ++it) { - SYSTEM_LOGICAL_PROCESSOR_INFORMATION PInfo = *it; - if (PInfo.Relationship != RelationProcessorCore) { - continue; - } - - std::bitset<std::numeric_limits<ULONG_PTR>::digits> ProcMask( - (unsigned long long)PInfo.ProcessorMask); - unsigned int count = (unsigned int)ProcMask.count(); - if (count == 0) { // I think this should never happen, but just to be safe. - continue; - } - this->NumberOfPhysicalCPU++; - this->NumberOfLogicalCPU += (unsigned int)count; - this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = count; - } - this->NumberOfPhysicalCPU = std::max(1u, this->NumberOfPhysicalCPU); - this->NumberOfLogicalCPU = std::max(1u, this->NumberOfLogicalCPU); -#else -#endif -} - -/** Return the number of logical CPUs on the system */ -unsigned int SystemInformationImplementation::GetNumberOfLogicalCPU() -{ - return this->NumberOfLogicalCPU; -} - -/** Return the number of physical CPUs on the system */ -unsigned int SystemInformationImplementation::GetNumberOfPhysicalCPU() -{ - return this->NumberOfPhysicalCPU; -} - -/** For Mac use sysctlbyname calls to find system info */ -bool SystemInformationImplementation::ParseSysCtl() -{ -#if defined(__APPLE__) - char retBuf[128]; - int err = 0; - uint64_t value = 0; - size_t len = sizeof(value); - sysctlbyname("hw.memsize", &value, &len, nullptr, 0); - this->TotalPhysicalMemory = static_cast<size_t>(value / 1048576); - - // Parse values for Mac - this->AvailablePhysicalMemory = 0; - vm_statistics_data_t vmstat; - mach_msg_type_number_t count = HOST_VM_INFO_COUNT; - if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, - &count) == KERN_SUCCESS) { - len = sizeof(value); - err = sysctlbyname("hw.pagesize", &value, &len, nullptr, 0); - int64_t available_memory = - (vmstat.free_count + vmstat.inactive_count) * value; - this->AvailablePhysicalMemory = - static_cast<size_t>(available_memory / 1048576); - } - -# ifdef VM_SWAPUSAGE - // Virtual memory. - int mib[2] = { CTL_VM, VM_SWAPUSAGE }; - unsigned int miblen = - static_cast<unsigned int>(sizeof(mib) / sizeof(mib[0])); - struct xsw_usage swap; - len = sizeof(swap); - err = sysctl(mib, miblen, &swap, &len, nullptr, 0); - if (err == 0) { - this->AvailableVirtualMemory = - static_cast<size_t>(swap.xsu_avail / 1048576); - this->TotalVirtualMemory = static_cast<size_t>(swap.xsu_total / 1048576); - } -# else - this->AvailableVirtualMemory = 0; - this->TotalVirtualMemory = 0; -# endif - - // CPU Info - len = sizeof(this->NumberOfPhysicalCPU); - sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, nullptr, 0); - len = sizeof(this->NumberOfLogicalCPU); - sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, nullptr, 0); - - int cores_per_package = 0; - len = sizeof(cores_per_package); - err = sysctlbyname("machdep.cpu.cores_per_package", &cores_per_package, &len, - nullptr, 0); - // That name was not found, default to 1 - this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = - err != 0 ? 1 : static_cast<unsigned char>(cores_per_package); - - len = sizeof(value); - sysctlbyname("hw.cpufrequency", &value, &len, nullptr, 0); - this->CPUSpeedInMHz = static_cast<float>(value) / 1000000; - - // Chip family - len = sizeof(this->ChipID.Family); - // Seems only the intel chips will have this name so if this fails it is - // probably a PPC machine - err = - sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, nullptr, 0); - if (err != 0) // Go back to names we know but are less descriptive - { - this->ChipID.Family = 0; - ::memset(retBuf, 0, 128); - len = 32; - err = sysctlbyname("hw.machine", &retBuf, &len, nullptr, 0); - std::string machineBuf(retBuf); - if (machineBuf.find_first_of("Power") != std::string::npos) { - this->ChipID.Vendor = "IBM"; - len = sizeof(this->ChipID.Family); - err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len, nullptr, 0); - len = sizeof(this->ChipID.Model); - err = - sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len, nullptr, 0); - this->FindManufacturer(); - } - } else // Should be an Intel Chip. - { - len = sizeof(this->ChipID.Family); - err = sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, - nullptr, 0); - - ::memset(retBuf, 0, 128); - len = 128; - err = sysctlbyname("machdep.cpu.vendor", retBuf, &len, nullptr, 0); - // Chip Vendor - this->ChipID.Vendor = retBuf; - this->FindManufacturer(); - - // Chip Model - len = sizeof(value); - err = sysctlbyname("machdep.cpu.model", &value, &len, nullptr, 0); - this->ChipID.Model = static_cast<int>(value); - - // Chip Stepping - len = sizeof(value); - value = 0; - err = sysctlbyname("machdep.cpu.stepping", &value, &len, nullptr, 0); - if (!err) { - this->ChipID.Revision = static_cast<int>(value); - } - - // feature string - char* buf = nullptr; - size_t allocSize = 128; - - err = 0; - len = 0; - - // sysctlbyname() will return with err==0 && len==0 if the buffer is too - // small - while (err == 0 && len == 0) { - delete[] buf; - allocSize *= 2; - buf = new char[allocSize]; - if (!buf) { - break; - } - buf[0] = ' '; - len = allocSize - 2; // keep space for leading and trailing space - err = sysctlbyname("machdep.cpu.features", buf + 1, &len, nullptr, 0); - } - if (!err && buf && len) { - // now we can match every flags as space + flag + space - buf[len + 1] = ' '; - std::string cpuflags(buf, len + 2); - - if ((cpuflags.find(" FPU ") != std::string::npos)) { - this->Features.HasFPU = true; - } - if ((cpuflags.find(" TSC ") != std::string::npos)) { - this->Features.HasTSC = true; - } - if ((cpuflags.find(" MMX ") != std::string::npos)) { - this->Features.HasMMX = true; - } - if ((cpuflags.find(" SSE ") != std::string::npos)) { - this->Features.HasSSE = true; - } - if ((cpuflags.find(" SSE2 ") != std::string::npos)) { - this->Features.HasSSE2 = true; - } - if ((cpuflags.find(" APIC ") != std::string::npos)) { - this->Features.HasAPIC = true; - } - if ((cpuflags.find(" CMOV ") != std::string::npos)) { - this->Features.HasCMOV = true; - } - if ((cpuflags.find(" MTRR ") != std::string::npos)) { - this->Features.HasMTRR = true; - } - if ((cpuflags.find(" ACPI ") != std::string::npos)) { - this->Features.HasACPI = true; - } - } - delete[] buf; - } - - // brand string - ::memset(retBuf, 0, sizeof(retBuf)); - len = sizeof(retBuf); - err = sysctlbyname("machdep.cpu.brand_string", retBuf, &len, nullptr, 0); - if (!err) { - this->ChipID.ProcessorName = retBuf; - this->ChipID.ModelName = retBuf; - } - - // Cache size - len = sizeof(value); - err = sysctlbyname("hw.l1icachesize", &value, &len, nullptr, 0); - this->Features.L1CacheSize = static_cast<int>(value); - len = sizeof(value); - err = sysctlbyname("hw.l2cachesize", &value, &len, nullptr, 0); - this->Features.L2CacheSize = static_cast<int>(value); - - return true; -#else - return false; -#endif -} - -/** Extract a value from sysctl command */ -std::string SystemInformationImplementation::ExtractValueFromSysCtl( - const char* word) -{ - size_t pos = this->SysCtlBuffer.find(word); - if (pos != std::string::npos) { - pos = this->SysCtlBuffer.find(": ", pos); - size_t pos2 = this->SysCtlBuffer.find("\n", pos); - if (pos != std::string::npos && pos2 != std::string::npos) { - return this->SysCtlBuffer.substr(pos + 2, pos2 - pos - 2); - } - } - return ""; -} - -/** Run a given process */ -std::string SystemInformationImplementation::RunProcess( - std::vector<const char*> args) -{ - std::string buffer; - - // Run the application - kwsysProcess* gp = kwsysProcess_New(); - kwsysProcess_SetCommand(gp, args.data()); - kwsysProcess_SetOption(gp, kwsysProcess_Option_HideWindow, 1); - - kwsysProcess_Execute(gp); - - char* data = nullptr; - int length; - double timeout = 255; - int pipe; // pipe id as returned by kwsysProcess_WaitForData() - - while ((static_cast<void>( - pipe = kwsysProcess_WaitForData(gp, &data, &length, &timeout)), - (pipe == kwsysProcess_Pipe_STDOUT || - pipe == kwsysProcess_Pipe_STDERR))) // wait for 1s - { - buffer.append(data, length); - } - kwsysProcess_WaitForExit(gp, nullptr); - - int result = 0; - switch (kwsysProcess_GetState(gp)) { - case kwsysProcess_State_Exited: { - result = kwsysProcess_GetExitValue(gp); - } break; - case kwsysProcess_State_Error: { - std::cerr << "Error: Could not run " << args[0] << ":\n"; - std::cerr << kwsysProcess_GetErrorString(gp) << "\n"; - } break; - case kwsysProcess_State_Exception: { - std::cerr << "Error: " << args[0] << " terminated with an exception: " - << kwsysProcess_GetExceptionString(gp) << "\n"; - } break; - case kwsysProcess_State_Starting: - case kwsysProcess_State_Executing: - case kwsysProcess_State_Expired: - case kwsysProcess_State_Killed: { - // Should not get here. - std::cerr << "Unexpected ending state after running " << args[0] - << std::endl; - } break; - } - kwsysProcess_Delete(gp); - if (result) { - std::cerr << "Error " << args[0] << " returned :" << result << "\n"; - } - return buffer; -} - -std::string SystemInformationImplementation::ParseValueFromKStat( - const char* arguments) -{ - std::vector<std::string> args_string; - std::string command = arguments; - size_t start = std::string::npos; - size_t pos = command.find(' ', 0); - while (pos != std::string::npos) { - bool inQuotes = false; - // Check if we are between quotes - size_t b0 = command.find('"', 0); - size_t b1 = command.find('"', b0 + 1); - while (b0 != std::string::npos && b1 != std::string::npos && b1 > b0) { - if (pos > b0 && pos < b1) { - inQuotes = true; - break; - } - b0 = command.find('"', b1 + 1); - b1 = command.find('"', b0 + 1); - } - - if (!inQuotes) { - args_string.push_back(command.substr(start + 1, pos - start - 1)); - std::string& arg = args_string.back(); - - // Remove the quotes if any - arg.erase(std::remove(arg.begin(), arg.end(), '"'), arg.end()); - start = pos; - } - pos = command.find(' ', pos + 1); - } - args_string.push_back(command.substr(start + 1, command.size() - start - 1)); - - std::vector<const char*> args; - args.reserve(3 + args_string.size()); - args.push_back("kstat"); - args.push_back("-p"); - for (size_t i = 0; i < args_string.size(); ++i) { - args.push_back(args_string[i].c_str()); - } - args.push_back(nullptr); - - std::string buffer = this->RunProcess(args); - - std::string value; - for (size_t i = buffer.size() - 1; i > 0; i--) { - if (buffer[i] == ' ' || buffer[i] == '\t') { - break; - } - if (buffer[i] != '\n' && buffer[i] != '\r') { - value.insert(0u, 1, buffer[i]); - } - } - return value; -} - -/** Querying for system information from Solaris */ -bool SystemInformationImplementation::QuerySolarisMemory() -{ -#if defined(__SVR4) && defined(__sun) -// Solaris allows querying this value by sysconf, but if this is -// a 32 bit process on a 64 bit host the returned memory will be -// limited to 4GiB. So if this is a 32 bit process or if the sysconf -// method fails use the kstat interface. -# if SIZEOF_VOID_P == 8 - if (this->QueryMemoryBySysconf()) { - return true; - } -# endif - - char* tail; - unsigned long totalMemory = - strtoul(this->ParseValueFromKStat("-s physmem").c_str(), &tail, 0); - this->TotalPhysicalMemory = totalMemory / 128; - - return true; -#else - return false; -#endif -} - -bool SystemInformationImplementation::QuerySolarisProcessor() -{ - if (!this->QueryProcessorBySysconf()) { - return false; - } - - // Parse values - this->CPUSpeedInMHz = static_cast<float>( - atoi(this->ParseValueFromKStat("-s clock_MHz").c_str())); - - // Chip family - this->ChipID.Family = 0; - - // Chip Model - this->ChipID.ProcessorName = this->ParseValueFromKStat("-s cpu_type"); - this->ChipID.Model = 0; - - // Chip Vendor - if (this->ChipID.ProcessorName != "i386") { - this->ChipID.Vendor = "Sun"; - this->FindManufacturer(); - } - - return true; -} - -/** Querying for system information from Haiku OS */ -bool SystemInformationImplementation::QueryHaikuInfo() -{ -#if defined(__HAIKU__) - - // CPU count - system_info info; - get_system_info(&info); - this->NumberOfPhysicalCPU = info.cpu_count; - - // CPU speed - uint32 topologyNodeCount = 0; - cpu_topology_node_info* topology = 0; - get_cpu_topology_info(0, &topologyNodeCount); - if (topologyNodeCount != 0) - topology = new cpu_topology_node_info[topologyNodeCount]; - get_cpu_topology_info(topology, &topologyNodeCount); - - for (uint32 i = 0; i < topologyNodeCount; i++) { - if (topology[i].type == B_TOPOLOGY_CORE) { - this->CPUSpeedInMHz = - topology[i].data.core.default_frequency / 1000000.0f; - break; - } - } - - delete[] topology; - - // Physical Memory - this->TotalPhysicalMemory = (info.max_pages * B_PAGE_SIZE) / (1024 * 1024); - this->AvailablePhysicalMemory = this->TotalPhysicalMemory - - ((info.used_pages * B_PAGE_SIZE) / (1024 * 1024)); - - // NOTE: get_system_info_etc is currently a private call so just set to 0 - // until it becomes public - this->TotalVirtualMemory = 0; - this->AvailableVirtualMemory = 0; - - // Retrieve cpuid_info union for cpu 0 - cpuid_info cpu_info; - get_cpuid(&cpu_info, 0, 0); - - // Chip Vendor - // Use a temporary buffer so that we can add NULL termination to the string - char vbuf[13]; - strncpy(vbuf, cpu_info.eax_0.vendor_id, 12); - vbuf[12] = '\0'; - this->ChipID.Vendor = vbuf; - - this->FindManufacturer(); - - // Retrieve cpuid_info union for cpu 0 this time using a register value of 1 - get_cpuid(&cpu_info, 1, 0); - - this->NumberOfLogicalCPU = cpu_info.eax_1.logical_cpus; - - // Chip type - this->ChipID.Type = cpu_info.eax_1.type; - - // Chip family - this->ChipID.Family = cpu_info.eax_1.family; - - // Chip Model - this->ChipID.Model = cpu_info.eax_1.model; - - // Chip Revision - this->ChipID.Revision = cpu_info.eax_1.stepping; - - // Chip Extended Family - this->ChipID.ExtendedFamily = cpu_info.eax_1.extended_family; - - // Chip Extended Model - this->ChipID.ExtendedModel = cpu_info.eax_1.extended_model; - - // Get ChipID.ProcessorName from other information already gathered - this->RetrieveClassicalCPUIdentity(); - - // Cache size - this->Features.L1CacheSize = 0; - this->Features.L2CacheSize = 0; - - return true; - -#else - return false; -#endif -} - -bool SystemInformationImplementation::QueryQNXMemory() -{ -#if defined(__QNX__) - std::string buffer; - std::vector<const char*> args; - args.clear(); - - args.push_back("showmem"); - args.push_back("-S"); - args.push_back(0); - buffer = this->RunProcess(args); - args.clear(); - - size_t pos = buffer.find("System RAM:"); - if (pos == std::string::npos) - return false; - pos = buffer.find(":", pos); - size_t pos2 = buffer.find("M (", pos); - if (pos2 == std::string::npos) - return false; - - pos++; - while (buffer[pos] == ' ') - pos++; - - this->TotalPhysicalMemory = atoi(buffer.substr(pos, pos2 - pos).c_str()); - return true; -#endif - return false; -} - -bool SystemInformationImplementation::QueryBSDMemory() -{ -#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ - defined(__DragonFly__) - int ctrl[2] = { CTL_HW, HW_PHYSMEM }; -# if defined(HW_PHYSMEM64) - int64_t k; - ctrl[1] = HW_PHYSMEM64; -# else - int k; -# endif - size_t sz = sizeof(k); - - if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { - return false; - } - - this->TotalPhysicalMemory = k >> 10 >> 10; - - return true; -#else - return false; -#endif -} - -bool SystemInformationImplementation::QueryQNXProcessor() -{ -#if defined(__QNX__) - // the output on my QNX 6.4.1 looks like this: - // Processor1: 686 Pentium II Stepping 3 2175MHz FPU - std::string buffer; - std::vector<const char*> args; - args.clear(); - - args.push_back("pidin"); - args.push_back("info"); - args.push_back(0); - buffer = this->RunProcess(args); - args.clear(); - - size_t pos = buffer.find("Processor1:"); - if (pos == std::string::npos) - return false; - - size_t pos2 = buffer.find("MHz", pos); - if (pos2 == std::string::npos) - return false; - - size_t pos3 = pos2; - while (buffer[pos3] != ' ') - --pos3; - - this->CPUSpeedInMHz = atoi(buffer.substr(pos3 + 1, pos2 - pos3 - 1).c_str()); - - pos2 = buffer.find(" Stepping", pos); - if (pos2 != std::string::npos) { - pos2 = buffer.find(" ", pos2 + 1); - if (pos2 != std::string::npos && pos2 < pos3) { - this->ChipID.Revision = - atoi(buffer.substr(pos2 + 1, pos3 - pos2).c_str()); - } - } - - this->NumberOfPhysicalCPU = 0; - do { - pos = buffer.find("\nProcessor", pos + 1); - ++this->NumberOfPhysicalCPU; - } while (pos != std::string::npos); - this->NumberOfLogicalCPU = 1; - - return true; -#else - return false; -#endif -} - -bool SystemInformationImplementation::QueryBSDProcessor() -{ -#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ - defined(__DragonFly__) - int k; - size_t sz = sizeof(k); - int ctrl[2] = { CTL_HW, HW_NCPU }; - - if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { - return false; - } - - this->NumberOfPhysicalCPU = k; - this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU; - -# if defined(HW_CPUSPEED) - ctrl[1] = HW_CPUSPEED; - - if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { - return false; - } - - this->CPUSpeedInMHz = (float)k; -# endif - -# if defined(CPU_SSE) - ctrl[0] = CTL_MACHDEP; - ctrl[1] = CPU_SSE; - - if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { - return false; - } - - this->Features.HasSSE = (k > 0); -# endif - -# if defined(CPU_SSE2) - ctrl[0] = CTL_MACHDEP; - ctrl[1] = CPU_SSE2; - - if (sysctl(ctrl, 2, &k, &sz, nullptr, 0) != 0) { - return false; - } - - this->Features.HasSSE2 = (k > 0); -# endif - -# if defined(CPU_CPUVENDOR) - ctrl[0] = CTL_MACHDEP; - ctrl[1] = CPU_CPUVENDOR; - char vbuf[25]; - ::memset(vbuf, 0, sizeof(vbuf)); - sz = sizeof(vbuf) - 1; - if (sysctl(ctrl, 2, vbuf, &sz, nullptr, 0) != 0) { - return false; - } - - this->ChipID.Vendor = vbuf; - this->FindManufacturer(); -# endif - - return true; -#else - return false; -#endif -} - -bool SystemInformationImplementation::QueryHPUXMemory() -{ -#if defined(__hpux) - unsigned long tv = 0; - unsigned long tp = 0; - unsigned long av = 0; - unsigned long ap = 0; - struct pst_static pst; - struct pst_dynamic pdy; - - unsigned long ps = 0; - if (pstat_getstatic(&pst, sizeof(pst), (size_t)1, 0) == -1) { - return false; - } - - ps = pst.page_size; - tp = pst.physical_memory * ps; - tv = (pst.physical_memory + pst.pst_maxmem) * ps; - if (pstat_getdynamic(&pdy, sizeof(pdy), (size_t)1, 0) == -1) { - return false; - } - - ap = tp - pdy.psd_rm * ps; - av = tv - pdy.psd_vm; - this->TotalVirtualMemory = tv >> 10 >> 10; - this->TotalPhysicalMemory = tp >> 10 >> 10; - this->AvailableVirtualMemory = av >> 10 >> 10; - this->AvailablePhysicalMemory = ap >> 10 >> 10; - return true; -#else - return false; -#endif -} - -bool SystemInformationImplementation::QueryHPUXProcessor() -{ -#if defined(__hpux) -# if defined(KWSYS_SYS_HAS_MPCTL_H) - int c = mpctl(MPC_GETNUMSPUS_SYS, 0, 0); - if (c <= 0) { - return false; - } - - this->NumberOfPhysicalCPU = c; - this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU; - - long t = sysconf(_SC_CPU_VERSION); - - if (t == -1) { - return false; - } - - switch (t) { - case CPU_PA_RISC1_0: - this->ChipID.Vendor = "Hewlett-Packard"; - this->ChipID.Family = 0x100; - break; - case CPU_PA_RISC1_1: - this->ChipID.Vendor = "Hewlett-Packard"; - this->ChipID.Family = 0x110; - break; - case CPU_PA_RISC2_0: - this->ChipID.Vendor = "Hewlett-Packard"; - this->ChipID.Family = 0x200; - break; -# if defined(CPU_HP_INTEL_EM_1_0) || defined(CPU_IA64_ARCHREV_0) -# ifdef CPU_HP_INTEL_EM_1_0 - case CPU_HP_INTEL_EM_1_0: -# endif -# ifdef CPU_IA64_ARCHREV_0 - case CPU_IA64_ARCHREV_0: -# endif - this->ChipID.Vendor = "GenuineIntel"; - this->Features.HasIA64 = true; - break; -# endif - default: - return false; - } - - this->FindManufacturer(); - - return true; -# else - return false; -# endif -#else - return false; -#endif -} - -/** Query the operating system information */ -bool SystemInformationImplementation::QueryOSInformation() -{ -#if defined(_WIN32) - - this->OSName = "Windows"; - - OSVERSIONINFOEXW osvi; - BOOL bIsWindows64Bit; - BOOL bOsVersionInfoEx; - char operatingSystem[256]; - - // Try calling GetVersionEx using the OSVERSIONINFOEX structure. - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXW)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); -# ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx -# pragma warning(push) -# ifdef __INTEL_COMPILER -# pragma warning(disable : 1478) -# elif defined __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" -# else -# pragma warning(disable : 4996) -# endif -# endif - bOsVersionInfoEx = GetVersionExW((OSVERSIONINFOW*)&osvi); - if (!bOsVersionInfoEx) { - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); - if (!GetVersionExW((OSVERSIONINFOW*)&osvi)) { - return false; - } - } -# ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx -# ifdef __clang__ -# pragma clang diagnostic pop -# else -# pragma warning(pop) -# endif -# endif - - switch (osvi.dwPlatformId) { - case VER_PLATFORM_WIN32_NT: - // Test for the product. - if (osvi.dwMajorVersion <= 4) { - this->OSRelease = "NT"; - } - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) { - this->OSRelease = "2000"; - } - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) { - this->OSRelease = "XP"; - } - // XP Professional x64 - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) { - this->OSRelease = "XP"; - } -# ifdef VER_NT_WORKSTATION - // Test for product type. - if (bOsVersionInfoEx) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) { - this->OSRelease = "Vista"; - } - if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1) { - this->OSRelease = "7"; - } -// VER_SUITE_PERSONAL may not be defined -# ifdef VER_SUITE_PERSONAL - else { - if (osvi.wSuiteMask & VER_SUITE_PERSONAL) { - this->OSRelease += " Personal"; - } else { - this->OSRelease += " Professional"; - } - } -# endif - } else if (osvi.wProductType == VER_NT_SERVER) { - // Check for .NET Server instead of Windows XP. - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) { - this->OSRelease = ".NET"; - } - - // Continue with the type detection. - if (osvi.wSuiteMask & VER_SUITE_DATACENTER) { - this->OSRelease += " DataCenter Server"; - } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) { - this->OSRelease += " Advanced Server"; - } else { - this->OSRelease += " Server"; - } - } - - sprintf(operatingSystem, "%ls (Build %ld)", osvi.szCSDVersion, - osvi.dwBuildNumber & 0xFFFF); - this->OSVersion = operatingSystem; - } else -# endif // VER_NT_WORKSTATION - { - HKEY hKey; - wchar_t szProductType[80]; - DWORD dwBufLen; - - // Query the registry to retrieve information. - RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, - KEY_QUERY_VALUE, &hKey); - RegQueryValueExW(hKey, L"ProductType", nullptr, nullptr, - (LPBYTE)szProductType, &dwBufLen); - RegCloseKey(hKey); - - if (lstrcmpiW(L"WINNT", szProductType) == 0) { - this->OSRelease += " Professional"; - } - if (lstrcmpiW(L"LANMANNT", szProductType) == 0) { - // Decide between Windows 2000 Advanced Server and Windows .NET - // Enterprise Server. - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) { - this->OSRelease += " Standard Server"; - } else { - this->OSRelease += " Server"; - } - } - if (lstrcmpiW(L"SERVERNT", szProductType) == 0) { - // Decide between Windows 2000 Advanced Server and Windows .NET - // Enterprise Server. - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) { - this->OSRelease += " Enterprise Server"; - } else { - this->OSRelease += " Advanced Server"; - } - } - } - - // Display version, service pack (if any), and build number. - if (osvi.dwMajorVersion <= 4) { - // NB: NT 4.0 and earlier. - sprintf(operatingSystem, "version %ld.%ld %ls (Build %ld)", - osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.szCSDVersion, - osvi.dwBuildNumber & 0xFFFF); - this->OSVersion = operatingSystem; - } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) { - // Windows XP and .NET server. - typedef BOOL(CALLBACK * LPFNPROC)(HANDLE, BOOL*); - HINSTANCE hKernelDLL; - LPFNPROC DLLProc; - - // Load the Kernel32 DLL. - hKernelDLL = LoadLibraryW(L"kernel32"); - if (hKernelDLL != nullptr) { - // Only XP and .NET Server support IsWOW64Process so... Load - // dynamically! - DLLProc = (LPFNPROC)GetProcAddress(hKernelDLL, "IsWow64Process"); - - // If the function address is valid, call the function. - if (DLLProc != nullptr) - (DLLProc)(GetCurrentProcess(), &bIsWindows64Bit); - else - bIsWindows64Bit = false; - - // Free the DLL module. - FreeLibrary(hKernelDLL); - } - } else { - // Windows 2000 and everything else. - sprintf(operatingSystem, "%ls (Build %ld)", osvi.szCSDVersion, - osvi.dwBuildNumber & 0xFFFF); - this->OSVersion = operatingSystem; - } - break; - - case VER_PLATFORM_WIN32_WINDOWS: - // Test for the product. - if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) { - this->OSRelease = "95"; - if (osvi.szCSDVersion[1] == 'C') { - this->OSRelease += "OSR 2.5"; - } else if (osvi.szCSDVersion[1] == 'B') { - this->OSRelease += "OSR 2"; - } - } - - if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) { - this->OSRelease = "98"; - if (osvi.szCSDVersion[1] == 'A') { - this->OSRelease += "SE"; - } - } - - if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) { - this->OSRelease = "Me"; - } - break; - - case VER_PLATFORM_WIN32s: - this->OSRelease = "Win32s"; - break; - - default: - this->OSRelease = "Unknown"; - break; - } - - // Get the hostname - WORD wVersionRequested; - WSADATA wsaData; - char name[255]; - wVersionRequested = MAKEWORD(2, 0); - - if (WSAStartup(wVersionRequested, &wsaData) == 0) { - gethostname(name, sizeof(name)); - WSACleanup(); - } - this->Hostname = name; - - const char* arch = getenv("PROCESSOR_ARCHITECTURE"); - const char* wow64 = getenv("PROCESSOR_ARCHITEW6432"); - if (arch) { - this->OSPlatform = arch; - } - - if (wow64) { - // the PROCESSOR_ARCHITEW6432 is only defined when running 32bit programs - // on 64bit OS - this->OSIs64Bit = true; - } else if (arch) { - // all values other than x86 map to 64bit architectures - this->OSIs64Bit = (strncmp(arch, "x86", 3) != 0); - } - -#else - - struct utsname unameInfo; - int errorFlag = uname(&unameInfo); - if (errorFlag == 0) { - this->OSName = unameInfo.sysname; - this->Hostname = unameInfo.nodename; - this->OSRelease = unameInfo.release; - this->OSVersion = unameInfo.version; - this->OSPlatform = unameInfo.machine; - - // This is still insufficient to capture 64bit architecture such - // powerpc and possible mips and sparc - if (this->OSPlatform.find_first_of("64") != std::string::npos) { - this->OSIs64Bit = true; - } - } - -# ifdef __APPLE__ - this->OSName = "Unknown Apple OS"; - this->OSRelease = "Unknown product version"; - this->OSVersion = "Unknown build version"; - - this->CallSwVers("-productName", this->OSName); - this->CallSwVers("-productVersion", this->OSRelease); - this->CallSwVers("-buildVersion", this->OSVersion); -# endif - -#endif - - return true; -} - -int SystemInformationImplementation::CallSwVers(const char* arg, - std::string& ver) -{ -#ifdef __APPLE__ - std::vector<const char*> args; - args.push_back("sw_vers"); - args.push_back(arg); - args.push_back(nullptr); - ver = this->RunProcess(args); - this->TrimNewline(ver); -#else - // avoid C4100 - (void)arg; - (void)ver; -#endif - return 0; -} - -void SystemInformationImplementation::TrimNewline(std::string& output) -{ - // remove \r - std::string::size_type pos = 0; - while ((pos = output.find("\r", pos)) != std::string::npos) { - output.erase(pos); - } - - // remove \n - pos = 0; - while ((pos = output.find("\n", pos)) != std::string::npos) { - output.erase(pos); - } -} - -/** Return true if the machine is 64 bits */ -bool SystemInformationImplementation::Is64Bits() -{ - return this->OSIs64Bit; -} -} diff --git a/test/API/driver/kwsys/SystemInformation.hxx.in b/test/API/driver/kwsys/SystemInformation.hxx.in deleted file mode 100644 index fc42e9d..0000000 --- a/test/API/driver/kwsys/SystemInformation.hxx.in +++ /dev/null @@ -1,170 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_SystemInformation_h -#define @KWSYS_NAMESPACE@_SystemInformation_h - -#include <@KWSYS_NAMESPACE@/Configure.hxx> - -#include <stddef.h> /* size_t */ -#include <string> - -namespace @KWSYS_NAMESPACE@ { - -// forward declare the implementation class -class SystemInformationImplementation; - -class @KWSYS_NAMESPACE@_EXPORT SystemInformation -{ -#if @KWSYS_USE_LONG_LONG@ - typedef long long LongLong; -#elif @KWSYS_USE___INT64@ - typedef __int64 LongLong; -#else -# error "No Long Long" -#endif - friend class SystemInformationImplementation; - SystemInformationImplementation* Implementation; - -public: - // possible parameter values for DoesCPUSupportFeature() - static const long int CPU_FEATURE_MMX = 1 << 0; - static const long int CPU_FEATURE_MMX_PLUS = 1 << 1; - static const long int CPU_FEATURE_SSE = 1 << 2; - static const long int CPU_FEATURE_SSE2 = 1 << 3; - static const long int CPU_FEATURE_AMD_3DNOW = 1 << 4; - static const long int CPU_FEATURE_AMD_3DNOW_PLUS = 1 << 5; - static const long int CPU_FEATURE_IA64 = 1 << 6; - static const long int CPU_FEATURE_MP_CAPABLE = 1 << 7; - static const long int CPU_FEATURE_HYPERTHREAD = 1 << 8; - static const long int CPU_FEATURE_SERIALNUMBER = 1 << 9; - static const long int CPU_FEATURE_APIC = 1 << 10; - static const long int CPU_FEATURE_SSE_FP = 1 << 11; - static const long int CPU_FEATURE_SSE_MMX = 1 << 12; - static const long int CPU_FEATURE_CMOV = 1 << 13; - static const long int CPU_FEATURE_MTRR = 1 << 14; - static const long int CPU_FEATURE_L1CACHE = 1 << 15; - static const long int CPU_FEATURE_L2CACHE = 1 << 16; - static const long int CPU_FEATURE_L3CACHE = 1 << 17; - static const long int CPU_FEATURE_ACPI = 1 << 18; - static const long int CPU_FEATURE_THERMALMONITOR = 1 << 19; - static const long int CPU_FEATURE_TEMPSENSEDIODE = 1 << 20; - static const long int CPU_FEATURE_FREQUENCYID = 1 << 21; - static const long int CPU_FEATURE_VOLTAGEID_FREQUENCY = 1 << 22; - static const long int CPU_FEATURE_FPU = 1 << 23; - -public: - SystemInformation(); - ~SystemInformation(); - - SystemInformation(const SystemInformation&) = delete; - SystemInformation& operator=(const SystemInformation&) = delete; - - const char* GetVendorString(); - const char* GetVendorID(); - std::string GetTypeID(); - std::string GetFamilyID(); - std::string GetModelID(); - std::string GetModelName(); - std::string GetSteppingCode(); - const char* GetExtendedProcessorName(); - const char* GetProcessorSerialNumber(); - int GetProcessorCacheSize(); - unsigned int GetLogicalProcessorsPerPhysical(); - float GetProcessorClockFrequency(); - int GetProcessorAPICID(); - int GetProcessorCacheXSize(long int); - bool DoesCPUSupportFeature(long int); - - // returns an informative general description of the cpu - // on this system. - std::string GetCPUDescription(); - - const char* GetHostname(); - std::string GetFullyQualifiedDomainName(); - - const char* GetOSName(); - const char* GetOSRelease(); - const char* GetOSVersion(); - const char* GetOSPlatform(); - - int GetOSIsWindows(); - int GetOSIsLinux(); - int GetOSIsApple(); - - // returns an informative general description of the os - // on this system. - std::string GetOSDescription(); - - // returns if the operating system is 64bit or not. - bool Is64Bits(); - - unsigned int GetNumberOfLogicalCPU(); - unsigned int GetNumberOfPhysicalCPU(); - - bool DoesCPUSupportCPUID(); - - // Retrieve id of the current running process - LongLong GetProcessId(); - - // Retrieve memory information in MiB. - size_t GetTotalVirtualMemory(); - size_t GetAvailableVirtualMemory(); - size_t GetTotalPhysicalMemory(); - size_t GetAvailablePhysicalMemory(); - - // returns an informative general description if the installed and - // available ram on this system. See the GetHostMemoryTotal, and - // Get{Host,Proc}MemoryAvailable methods for more information. - std::string GetMemoryDescription(const char* hostLimitEnvVarName = nullptr, - const char* procLimitEnvVarName = nullptr); - - // Retrieve amount of physical memory installed on the system in KiB - // units. - LongLong GetHostMemoryTotal(); - - // Get total system RAM in units of KiB available colectivley to all - // processes in a process group. An example of a process group - // are the processes comprising an mpi program which is running in - // parallel. The amount of memory reported may differ from the host - // total if a host wide resource limit is applied. Such reource limits - // are reported to us via an application specified environment variable. - LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName = nullptr); - - // Get total system RAM in units of KiB available to this process. - // This may differ from the host available if a per-process resource - // limit is applied. per-process memory limits are applied on unix - // system via rlimit API. Resource limits that are not imposed via - // rlimit API may be reported to us via an application specified - // environment variable. - LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName = nullptr, - const char* procLimitEnvVarName = nullptr); - - // Get the system RAM used by all processes on the host, in units of KiB. - LongLong GetHostMemoryUsed(); - - // Get system RAM used by this process id in units of KiB. - LongLong GetProcMemoryUsed(); - - // Return the load average of the machine or -0.0 if it cannot - // be determined. - double GetLoadAverage(); - - // enable/disable stack trace signal handler. In order to - // produce an informative stack trace the application should - // be dynamically linked and compiled with debug symbols. - static void SetStackTraceOnError(int enable); - - // format and return the current program stack in a string. In - // order to produce an informative stack trace the application - // should be dynamically linked and compiled with debug symbols. - static std::string GetProgramStack(int firstFrame, int wholePath); - - /** Run the different checks */ - void RunCPUCheck(); - void RunOSCheck(); - void RunMemoryCheck(); -}; - -} // namespace @KWSYS_NAMESPACE@ - -#endif diff --git a/test/API/driver/kwsys/SystemTools.cxx b/test/API/driver/kwsys/SystemTools.cxx deleted file mode 100644 index ce4d6ef..0000000 --- a/test/API/driver/kwsys/SystemTools.cxx +++ /dev/null @@ -1,4703 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifdef __osf__ -# define _OSF_SOURCE -# define _POSIX_C_SOURCE 199506L -# define _XOPEN_SOURCE_EXTENDED -#endif - -#if defined(_WIN32) && \ - (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || \ - defined(__MINGW32__)) -# define KWSYS_WINDOWS_DIRS -#else -# if defined(__SUNPRO_CC) -# include <fcntl.h> -# endif -#endif - -#include "kwsysPrivate.h" -#include KWSYS_HEADER(RegularExpression.hxx) -#include KWSYS_HEADER(SystemTools.hxx) -#include KWSYS_HEADER(Directory.hxx) -#include KWSYS_HEADER(FStream.hxx) -#include KWSYS_HEADER(Encoding.h) -#include KWSYS_HEADER(Encoding.hxx) - -#include <fstream> -#include <iostream> -#include <set> -#include <sstream> -#include <utility> -#include <vector> - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Directory.hxx.in" -# include "Encoding.hxx.in" -# include "FStream.hxx.in" -# include "RegularExpression.hxx.in" -# include "SystemTools.hxx.in" -#endif - -#ifdef _MSC_VER -# pragma warning(disable : 4786) -#endif - -#if defined(__sgi) && !defined(__GNUC__) -# pragma set woff 1375 /* base class destructor not virtual */ -#endif - -#include <ctype.h> -#include <errno.h> -#ifdef __QNX__ -# include <malloc.h> /* for malloc/free on QNX */ -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#if defined(_WIN32) && !defined(_MSC_VER) && defined(__GNUC__) -# include <strings.h> /* for strcasecmp */ -#endif - -#ifdef _MSC_VER -# define umask _umask // Note this is still umask on Borland -#endif - -// support for realpath call -#ifndef _WIN32 -# include <limits.h> -# include <pwd.h> -# include <sys/ioctl.h> -# include <sys/time.h> -# include <sys/wait.h> -# include <unistd.h> -# include <utime.h> -# ifndef __VMS -# include <sys/param.h> -# include <termios.h> -# endif -# include <signal.h> /* sigprocmask */ -#endif - -#ifdef __linux -# include <linux/fs.h> -#endif - -// Windows API. -#if defined(_WIN32) -# include <windows.h> -# include <winioctl.h> -# ifndef INVALID_FILE_ATTRIBUTES -# define INVALID_FILE_ATTRIBUTES ((DWORD)-1) -# endif -# if defined(_MSC_VER) && _MSC_VER >= 1800 -# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx -# endif -#elif defined(__CYGWIN__) -# include <windows.h> -# undef _WIN32 -#endif - -#if !KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H -extern char** environ; -#endif - -#ifdef __CYGWIN__ -# include <sys/cygwin.h> -#endif - -// getpwnam doesn't exist on Windows and Cray Xt3/Catamount -// same for TIOCGWINSZ -#if defined(_WIN32) || defined(__LIBCATAMOUNT__) || \ - (defined(HAVE_GETPWNAM) && HAVE_GETPWNAM == 0) -# undef HAVE_GETPWNAM -# undef HAVE_TTY_INFO -#else -# define HAVE_GETPWNAM 1 -# define HAVE_TTY_INFO 1 -#endif - -#define VTK_URL_PROTOCOL_REGEX "([a-zA-Z0-9]*)://(.*)" -#define VTK_URL_REGEX \ - "([a-zA-Z0-9]*)://(([A-Za-z0-9]+)(:([^:@]+))?@)?([^:@/]+)(:([0-9]+))?/" \ - "(.+)?" - -#ifdef _MSC_VER -# include <sys/utime.h> -#else -# include <utime.h> -#endif - -// This is a hack to prevent warnings about these functions being -// declared but not referenced. -#if defined(__sgi) && !defined(__GNUC__) -# include <sys/termios.h> -namespace KWSYS_NAMESPACE { -class SystemToolsHack -{ -public: - enum - { - Ref1 = sizeof(cfgetospeed(0)), - Ref2 = sizeof(cfgetispeed(0)), - Ref3 = sizeof(tcgetattr(0, 0)), - Ref4 = sizeof(tcsetattr(0, 0, 0)), - Ref5 = sizeof(cfsetospeed(0, 0)), - Ref6 = sizeof(cfsetispeed(0, 0)) - }; -}; -} -#endif - -#if defined(_WIN32) && \ - (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || \ - defined(__MINGW32__)) -# include <direct.h> -# include <io.h> -# define _unlink unlink -#endif - -/* The maximum length of a file name. */ -#if defined(PATH_MAX) -# define KWSYS_SYSTEMTOOLS_MAXPATH PATH_MAX -#elif defined(MAXPATHLEN) -# define KWSYS_SYSTEMTOOLS_MAXPATH MAXPATHLEN -#else -# define KWSYS_SYSTEMTOOLS_MAXPATH 16384 -#endif -#if defined(__WATCOMC__) -# include <direct.h> -# define _mkdir mkdir -# define _rmdir rmdir -# define _getcwd getcwd -# define _chdir chdir -#endif - -#if defined(__BEOS__) && !defined(__ZETA__) -# include <be/kernel/OS.h> -# include <be/storage/Path.h> - -// BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. -static inline void usleep(unsigned int msec) -{ - ::snooze(msec); -} - -// BeOS 5 also doesn't have realpath(), but its C++ API offers something close. -static inline char* realpath(const char* path, char* resolved_path) -{ - const size_t maxlen = KWSYS_SYSTEMTOOLS_MAXPATH; - snprintf(resolved_path, maxlen, "%s", path); - BPath normalized(resolved_path, nullptr, true); - const char* resolved = normalized.Path(); - if (resolved != nullptr) // nullptr == No such file. - { - if (snprintf(resolved_path, maxlen, "%s", resolved) < maxlen) { - return resolved_path; - } - } - return nullptr; // something went wrong. -} -#endif - -#ifdef _WIN32 -static time_t windows_filetime_to_posix_time(const FILETIME& ft) -{ - LARGE_INTEGER date; - date.HighPart = ft.dwHighDateTime; - date.LowPart = ft.dwLowDateTime; - - // removes the diff between 1970 and 1601 - date.QuadPart -= ((LONGLONG)(369 * 365 + 89) * 24 * 3600 * 10000000); - - // converts back from 100-nanoseconds to seconds - return date.QuadPart / 10000000; -} -#endif - -#ifdef KWSYS_WINDOWS_DIRS -# include <wctype.h> - -inline int Mkdir(const std::string& dir) -{ - return _wmkdir( - KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str()); -} -inline int Rmdir(const std::string& dir) -{ - return _wrmdir( - KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str()); -} -inline const char* Getcwd(char* buf, unsigned int len) -{ - std::vector<wchar_t> w_buf(len); - if (_wgetcwd(&w_buf[0], len)) { - size_t nlen = kwsysEncoding_wcstombs(buf, &w_buf[0], len); - if (nlen == static_cast<size_t>(-1)) { - return 0; - } - if (nlen < len) { - // make sure the drive letter is capital - if (nlen > 1 && buf[1] == ':') { - buf[0] = toupper(buf[0]); - } - return buf; - } - } - return 0; -} -inline int Chdir(const std::string& dir) -{ -# if defined(__BORLANDC__) - return chdir(dir.c_str()); -# else - return _wchdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str()); -# endif -} -inline void Realpath(const std::string& path, std::string& resolved_path, - std::string* errorMessage = 0) -{ - std::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path); - wchar_t* ptemp; - wchar_t fullpath[MAX_PATH]; - DWORD bufferLen = GetFullPathNameW( - tmp.c_str(), sizeof(fullpath) / sizeof(fullpath[0]), fullpath, &ptemp); - if (bufferLen < sizeof(fullpath) / sizeof(fullpath[0])) { - resolved_path = KWSYS_NAMESPACE::Encoding::ToNarrow(fullpath); - KWSYS_NAMESPACE::SystemTools::ConvertToUnixSlashes(resolved_path); - } else if (errorMessage) { - if (bufferLen) { - *errorMessage = "Destination path buffer size too small."; - } else if (unsigned int errorId = GetLastError()) { - LPSTR message = nullptr; - DWORD size = FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, errorId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&message, 0, nullptr); - *errorMessage = std::string(message, size); - LocalFree(message); - } else { - *errorMessage = "Unknown error."; - } - - resolved_path = ""; - } else { - resolved_path = path; - } -} -#else -# include <sys/types.h> - -# include <fcntl.h> -# include <unistd.h> -inline int Mkdir(const std::string& dir) -{ - return mkdir(dir.c_str(), 00777); -} -inline int Rmdir(const std::string& dir) -{ - return rmdir(dir.c_str()); -} -inline const char* Getcwd(char* buf, unsigned int len) -{ - return getcwd(buf, len); -} - -inline int Chdir(const std::string& dir) -{ - return chdir(dir.c_str()); -} -inline void Realpath(const std::string& path, std::string& resolved_path, - std::string* errorMessage = nullptr) -{ - char resolved_name[KWSYS_SYSTEMTOOLS_MAXPATH]; - - errno = 0; - char* ret = realpath(path.c_str(), resolved_name); - if (ret) { - resolved_path = ret; - } else if (errorMessage) { - if (errno) { - *errorMessage = strerror(errno); - } else { - *errorMessage = "Unknown error."; - } - - resolved_path = ""; - } else { - // if path resolution fails, return what was passed in - resolved_path = path; - } -} -#endif - -#if !defined(_WIN32) && defined(__COMO__) -// Hack for como strict mode to avoid defining _SVID_SOURCE or _BSD_SOURCE. -extern "C" { -extern FILE* popen(__const char* __command, __const char* __modes) __THROW; -extern int pclose(FILE* __stream) __THROW; -extern char* realpath(__const char* __restrict __name, - char* __restrict __resolved) __THROW; -extern char* strdup(__const char* __s) __THROW; -extern int putenv(char* __string) __THROW; -} -#endif - -namespace KWSYS_NAMESPACE { - -double SystemTools::GetTime(void) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - return (429.4967296 * ft.dwHighDateTime + 0.0000001 * ft.dwLowDateTime - - 11644473600.0); -#else - struct timeval t; - gettimeofday(&t, nullptr); - return 1.0 * double(t.tv_sec) + 0.000001 * double(t.tv_usec); -#endif -} - -/* Type of character storing the environment. */ -#if defined(_WIN32) -typedef wchar_t envchar; -#else -typedef char envchar; -#endif - -/* Order by environment key only (VAR from VAR=VALUE). */ -struct kwsysEnvCompare -{ - bool operator()(const envchar* l, const envchar* r) const - { -#if defined(_WIN32) - const wchar_t* leq = wcschr(l, L'='); - const wchar_t* req = wcschr(r, L'='); - size_t llen = leq ? (leq - l) : wcslen(l); - size_t rlen = req ? (req - r) : wcslen(r); - if (llen == rlen) { - return wcsncmp(l, r, llen) < 0; - } else { - return wcscmp(l, r) < 0; - } -#else - const char* leq = strchr(l, '='); - const char* req = strchr(r, '='); - size_t llen = leq ? static_cast<size_t>(leq - l) : strlen(l); - size_t rlen = req ? static_cast<size_t>(req - r) : strlen(r); - if (llen == rlen) { - return strncmp(l, r, llen) < 0; - } else { - return strcmp(l, r) < 0; - } -#endif - } -}; - -class kwsysEnvSet : public std::set<const envchar*, kwsysEnvCompare> -{ -public: - class Free - { - const envchar* Env; - - public: - Free(const envchar* env) - : Env(env) - { - } - ~Free() { free(const_cast<envchar*>(this->Env)); } - - Free(const Free&) = delete; - Free& operator=(const Free&) = delete; - }; - - const envchar* Release(const envchar* env) - { - const envchar* old = nullptr; - iterator i = this->find(env); - if (i != this->end()) { - old = *i; - this->erase(i); - } - return old; - } -}; - -#ifdef _WIN32 -struct SystemToolsPathCaseCmp -{ - bool operator()(std::string const& l, std::string const& r) const - { -# ifdef _MSC_VER - return _stricmp(l.c_str(), r.c_str()) < 0; -# elif defined(__GNUC__) - return strcasecmp(l.c_str(), r.c_str()) < 0; -# else - return SystemTools::Strucmp(l.c_str(), r.c_str()) < 0; -# endif - } -}; -#endif - -/** - * SystemTools static variables singleton class. - */ -class SystemToolsStatic -{ -public: - typedef std::map<std::string, std::string> StringMap; -#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP - /** - * Path translation table from dir to refdir - * Each time 'dir' will be found it will be replace by 'refdir' - */ - StringMap TranslationMap; -#endif -#ifdef _WIN32 - static std::string GetCasePathName(std::string const& pathIn); - static std::string GetActualCaseForPathCached(std::string const& path); - static const char* GetEnvBuffered(const char* key); - std::map<std::string, std::string, SystemToolsPathCaseCmp> PathCaseMap; - std::map<std::string, std::string> EnvMap; -#endif -#ifdef __CYGWIN__ - StringMap Cyg2Win32Map; -#endif - - /** - * Actual implementation of ReplaceString. - */ - static void ReplaceString(std::string& source, const char* replace, - size_t replaceSize, const std::string& with); - - /** - * Actual implementation of FileIsFullPath. - */ - static bool FileIsFullPath(const char*, size_t); - - /** - * Find a filename (file or directory) in the system PATH, with - * optional extra paths. - */ - static std::string FindName( - const std::string& name, - const std::vector<std::string>& path = std::vector<std::string>(), - bool no_system_path = false); -}; - -#ifdef _WIN32 -std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn) -{ - std::string casePath; - - // First check if the file is relative. We don't fix relative paths since the - // real case depends on the root directory and the given path fragment may - // have meaning elsewhere in the project. - if (!SystemTools::FileIsFullPath(pathIn)) { - // This looks unnecessary, but it allows for the return value optimization - // since all return paths return the same local variable. - casePath = pathIn; - return casePath; - } - - std::vector<std::string> path_components; - SystemTools::SplitPath(pathIn, path_components); - - // Start with root component. - std::vector<std::string>::size_type idx = 0; - casePath = path_components[idx++]; - // make sure drive letter is always upper case - if (casePath.size() > 1 && casePath[1] == ':') { - casePath[0] = toupper(casePath[0]); - } - const char* sep = ""; - - // If network path, fill casePath with server/share so FindFirstFile - // will work after that. Maybe someday call other APIs to get - // actual case of servers and shares. - if (path_components.size() > 2 && path_components[0] == "//") { - casePath += path_components[idx++]; - casePath += "/"; - casePath += path_components[idx++]; - sep = "/"; - } - - // Convert case of all components that exist. - bool converting = true; - for (; idx < path_components.size(); idx++) { - casePath += sep; - sep = "/"; - - if (converting) { - // 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 casePath; -} - -std::string SystemToolsStatic::GetActualCaseForPathCached(std::string const& p) -{ - // Check to see if actual case has already been called - // for this path, and the result is stored in the PathCaseMap - auto& pcm = SystemTools::Statics->PathCaseMap; - { - auto itr = pcm.find(p); - if (itr != pcm.end()) { - return itr->second; - } - } - std::string casePath = SystemToolsStatic::GetCasePathName(p); - if (casePath.size() <= MAX_PATH) { - pcm[p] = casePath; - } - return casePath; -} -#endif - -// adds the elements of the env variable path to the arg passed in -void SystemTools::GetPath(std::vector<std::string>& path, const char* env) -{ - size_t const old_size = path.size(); -#if defined(_WIN32) && !defined(__CYGWIN__) - const char pathSep = ';'; -#else - const char pathSep = ':'; -#endif - if (!env) { - env = "PATH"; - } - std::string pathEnv; - if (!SystemTools::GetEnv(env, pathEnv)) { - return; - } - - // A hack to make the below algorithm work. - if (!pathEnv.empty() && pathEnv.back() != pathSep) { - pathEnv += pathSep; - } - std::string::size_type start = 0; - bool done = false; - while (!done) { - std::string::size_type endpos = pathEnv.find(pathSep, start); - if (endpos != std::string::npos) { - path.push_back(pathEnv.substr(start, endpos - start)); - start = endpos + 1; - } else { - done = true; - } - } - for (std::vector<std::string>::iterator i = path.begin() + old_size; - i != path.end(); ++i) { - SystemTools::ConvertToUnixSlashes(*i); - } -} - -#if defined(_WIN32) -const char* SystemToolsStatic::GetEnvBuffered(const char* key) -{ - std::string env; - if (SystemTools::GetEnv(key, env)) { - std::string& menv = SystemTools::Statics->EnvMap[key]; - if (menv != env) { - menv = std::move(env); - } - return menv.c_str(); - } - return nullptr; -} -#endif - -const char* SystemTools::GetEnv(const char* key) -{ -#if defined(_WIN32) - return SystemToolsStatic::GetEnvBuffered(key); -#else - return getenv(key); -#endif -} - -const char* SystemTools::GetEnv(const std::string& key) -{ -#if defined(_WIN32) - return SystemToolsStatic::GetEnvBuffered(key.c_str()); -#else - return getenv(key.c_str()); -#endif -} - -bool SystemTools::GetEnv(const char* key, std::string& result) -{ -#if defined(_WIN32) - const std::wstring wkey = Encoding::ToWide(key); - const wchar_t* wv = _wgetenv(wkey.c_str()); - if (wv) { - result = Encoding::ToNarrow(wv); - return true; - } -#else - const char* v = getenv(key); - if (v) { - result = v; - return true; - } -#endif - return false; -} - -bool SystemTools::GetEnv(const std::string& key, std::string& result) -{ - return SystemTools::GetEnv(key.c_str(), result); -} - -bool SystemTools::HasEnv(const char* key) -{ -#if defined(_WIN32) - const std::wstring wkey = Encoding::ToWide(key); - const wchar_t* v = _wgetenv(wkey.c_str()); -#else - const char* v = getenv(key); -#endif - return v != nullptr; -} - -bool SystemTools::HasEnv(const std::string& key) -{ - return SystemTools::HasEnv(key.c_str()); -} - -#if KWSYS_CXX_HAS_UNSETENV -/* unsetenv("A") removes A from the environment. - On older platforms it returns void instead of int. */ -static int kwsysUnPutEnv(const std::string& env) -{ - size_t pos = env.find('='); - if (pos != std::string::npos) { - std::string name = env.substr(0, pos); - unsetenv(name.c_str()); - } else { - unsetenv(env.c_str()); - } - return 0; -} - -#elif defined(__CYGWIN__) || defined(__GLIBC__) -/* putenv("A") removes A from the environment. It must not put the - memory in the environment because it does not have any "=" syntax. */ -static int kwsysUnPutEnv(const std::string& env) -{ - int err = 0; - size_t pos = env.find('='); - size_t const len = pos == std::string::npos ? env.size() : pos; - size_t const sz = len + 1; - char local_buf[256]; - char* buf = sz > sizeof(local_buf) ? (char*)malloc(sz) : local_buf; - if (!buf) { - return -1; - } - strncpy(buf, env.c_str(), len); - buf[len] = 0; - if (putenv(buf) < 0 && errno != EINVAL) { - err = errno; - } - if (buf != local_buf) { - free(buf); - } - if (err) { - errno = err; - return -1; - } - return 0; -} - -#elif defined(_WIN32) -/* putenv("A=") places "A=" in the environment, which is as close to - removal as we can get with the putenv API. We have to leak the - most recent value placed in the environment for each variable name - on program exit in case exit routines access it. */ - -static kwsysEnvSet kwsysUnPutEnvSet; - -static int kwsysUnPutEnv(std::string const& env) -{ - std::wstring wEnv = Encoding::ToWide(env); - size_t const pos = wEnv.find('='); - size_t const len = pos == std::string::npos ? wEnv.size() : pos; - wEnv.resize(len + 1, L'='); - wchar_t* newEnv = _wcsdup(wEnv.c_str()); - if (!newEnv) { - return -1; - } - kwsysEnvSet::Free oldEnv(kwsysUnPutEnvSet.Release(newEnv)); - kwsysUnPutEnvSet.insert(newEnv); - return _wputenv(newEnv); -} - -#else -/* Manipulate the "environ" global directly. */ -static int kwsysUnPutEnv(const std::string& env) -{ - size_t pos = env.find('='); - size_t const len = pos == std::string::npos ? env.size() : pos; - int in = 0; - int out = 0; - while (environ[in]) { - if (strlen(environ[in]) > len && environ[in][len] == '=' && - strncmp(env.c_str(), environ[in], len) == 0) { - ++in; - } else { - environ[out++] = environ[in++]; - } - } - while (out < in) { - environ[out++] = 0; - } - return 0; -} -#endif - -#if KWSYS_CXX_HAS_SETENV - -/* setenv("A", "B", 1) will set A=B in the environment and makes its - own copies of the strings. */ -bool SystemTools::PutEnv(const std::string& env) -{ - size_t pos = env.find('='); - if (pos != std::string::npos) { - std::string name = env.substr(0, pos); - return setenv(name.c_str(), env.c_str() + pos + 1, 1) == 0; - } else { - return kwsysUnPutEnv(env) == 0; - } -} - -bool SystemTools::UnPutEnv(const std::string& env) -{ - return kwsysUnPutEnv(env) == 0; -} - -#else - -/* putenv("A=B") will set A=B in the environment. Most putenv implementations - put their argument directly in the environment. They never free the memory - on program exit. Keep an active set of pointers to memory we allocate and - pass to putenv, one per environment key. At program exit remove any - environment values that may still reference memory we allocated. Then free - the memory. This will not affect any environment values we never set. */ - -# ifdef __INTEL_COMPILER -# pragma warning disable 444 /* base has non-virtual destructor */ -# endif - -class kwsysEnv : public kwsysEnvSet -{ -public: - ~kwsysEnv() - { - for (iterator i = this->begin(); i != this->end(); ++i) { -# if defined(_WIN32) - const std::string s = Encoding::ToNarrow(*i); - kwsysUnPutEnv(s); -# else - kwsysUnPutEnv(*i); -# endif - free(const_cast<envchar*>(*i)); - } - } - bool Put(const char* env) - { -# if defined(_WIN32) - const std::wstring wEnv = Encoding::ToWide(env); - wchar_t* newEnv = _wcsdup(wEnv.c_str()); -# else - char* newEnv = strdup(env); -# endif - Free oldEnv(this->Release(newEnv)); - this->insert(newEnv); -# if defined(_WIN32) - return _wputenv(newEnv) == 0; -# else - return putenv(newEnv) == 0; -# endif - } - bool UnPut(const char* env) - { -# if defined(_WIN32) - const std::wstring wEnv = Encoding::ToWide(env); - Free oldEnv(this->Release(wEnv.c_str())); -# else - Free oldEnv(this->Release(env)); -# endif - return kwsysUnPutEnv(env) == 0; - } -}; - -static kwsysEnv kwsysEnvInstance; - -bool SystemTools::PutEnv(const std::string& env) -{ - return kwsysEnvInstance.Put(env.c_str()); -} - -bool SystemTools::UnPutEnv(const std::string& env) -{ - return kwsysEnvInstance.UnPut(env.c_str()); -} - -#endif - -const char* SystemTools::GetExecutableExtension() -{ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(__VMS) - return ".exe"; -#else - return ""; -#endif -} - -FILE* SystemTools::Fopen(const std::string& file, const char* mode) -{ -#ifdef _WIN32 - return _wfopen(Encoding::ToWindowsExtendedPath(file).c_str(), - Encoding::ToWide(mode).c_str()); -#else - return fopen(file.c_str(), mode); -#endif -} - -bool SystemTools::MakeDirectory(const char* path, const mode_t* mode) -{ - if (!path) { - return false; - } - return SystemTools::MakeDirectory(std::string(path), mode); -} - -bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode) -{ - if (SystemTools::PathExists(path)) { - return SystemTools::FileIsDirectory(path); - } - if (path.empty()) { - return false; - } - std::string dir = path; - SystemTools::ConvertToUnixSlashes(dir); - - std::string::size_type pos = 0; - std::string topdir; - while ((pos = dir.find('/', pos)) != std::string::npos) { - topdir = dir.substr(0, pos); - - if (Mkdir(topdir) == 0 && mode != nullptr) { - SystemTools::SetPermissions(topdir, *mode); - } - - ++pos; - } - topdir = dir; - if (Mkdir(topdir) != 0) { - // There is a bug in the Borland Run time library which makes MKDIR - // return EACCES when it should return EEXISTS - // if it is some other error besides directory exists - // then return false - if ((errno != EEXIST) -#ifdef __BORLANDC__ - && (errno != EACCES) -#endif - ) { - return false; - } - } else if (mode != nullptr) { - SystemTools::SetPermissions(topdir, *mode); - } - - return true; -} - -// replace replace with with as many times as it shows up in source. -// write the result into source. -void SystemTools::ReplaceString(std::string& source, - const std::string& replace, - const std::string& with) -{ - // do while hangs if replaceSize is 0 - if (replace.empty()) { - return; - } - - SystemToolsStatic::ReplaceString(source, replace.c_str(), replace.size(), - with); -} - -void SystemTools::ReplaceString(std::string& source, const char* replace, - const char* with) -{ - // do while hangs if replaceSize is 0 - if (!*replace) { - return; - } - - SystemToolsStatic::ReplaceString(source, replace, strlen(replace), - with ? with : ""); -} - -void SystemToolsStatic::ReplaceString(std::string& source, const char* replace, - size_t replaceSize, - const std::string& with) -{ - const char* src = source.c_str(); - char* searchPos = const_cast<char*>(strstr(src, replace)); - - // get out quick if string is not found - if (!searchPos) { - return; - } - - // perform replacements until done - char* orig = strdup(src); - char* currentPos = orig; - searchPos = searchPos - src + orig; - - // initialize the result - source.erase(source.begin(), source.end()); - do { - *searchPos = '\0'; - source += currentPos; - currentPos = searchPos + replaceSize; - // replace - source += with; - searchPos = strstr(currentPos, replace); - } while (searchPos); - - // copy any trailing text - source += currentPos; - free(orig); -} - -#if defined(_WIN32) && !defined(__CYGWIN__) - -# if defined(KEY_WOW64_32KEY) && defined(KEY_WOW64_64KEY) -# define KWSYS_ST_KEY_WOW64_32KEY KEY_WOW64_32KEY -# define KWSYS_ST_KEY_WOW64_64KEY KEY_WOW64_64KEY -# else -# define KWSYS_ST_KEY_WOW64_32KEY 0x0200 -# define KWSYS_ST_KEY_WOW64_64KEY 0x0100 -# endif - -static bool SystemToolsParseRegistryKey(const std::string& key, - HKEY& primaryKey, std::string& second, - std::string& valuename) -{ - std::string primary = key; - - size_t start = primary.find('\\'); - if (start == std::string::npos) { - return false; - } - - size_t valuenamepos = primary.find(';'); - if (valuenamepos != std::string::npos) { - valuename = primary.substr(valuenamepos + 1); - } - - second = primary.substr(start + 1, valuenamepos - start - 1); - primary = primary.substr(0, start); - - if (primary == "HKEY_CURRENT_USER") { - primaryKey = HKEY_CURRENT_USER; - } - if (primary == "HKEY_CURRENT_CONFIG") { - primaryKey = HKEY_CURRENT_CONFIG; - } - if (primary == "HKEY_CLASSES_ROOT") { - primaryKey = HKEY_CLASSES_ROOT; - } - if (primary == "HKEY_LOCAL_MACHINE") { - primaryKey = HKEY_LOCAL_MACHINE; - } - if (primary == "HKEY_USERS") { - primaryKey = HKEY_USERS; - } - - return true; -} - -static DWORD SystemToolsMakeRegistryMode(DWORD mode, - SystemTools::KeyWOW64 view) -{ - // only add the modes when on a system that supports Wow64. - static FARPROC wow64p = - GetProcAddress(GetModuleHandleW(L"kernel32"), "IsWow64Process"); - if (wow64p == nullptr) { - return mode; - } - - if (view == SystemTools::KeyWOW64_32) { - return mode | KWSYS_ST_KEY_WOW64_32KEY; - } else if (view == SystemTools::KeyWOW64_64) { - return mode | KWSYS_ST_KEY_WOW64_64KEY; - } - return mode; -} -#endif - -#if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::GetRegistrySubKeys(const std::string& key, - std::vector<std::string>& subkeys, - KeyWOW64 view) -{ - HKEY primaryKey = HKEY_CURRENT_USER; - std::string second; - std::string valuename; - if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) { - return false; - } - - HKEY hKey; - if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0, - SystemToolsMakeRegistryMode(KEY_READ, view), - &hKey) != ERROR_SUCCESS) { - return false; - } else { - wchar_t name[1024]; - DWORD dwNameSize = sizeof(name) / sizeof(name[0]); - - DWORD i = 0; - while (RegEnumKeyW(hKey, i, name, dwNameSize) == ERROR_SUCCESS) { - subkeys.push_back(Encoding::ToNarrow(name)); - ++i; - } - - RegCloseKey(hKey); - } - - return true; -} -#else -bool SystemTools::GetRegistrySubKeys(const std::string&, - std::vector<std::string>&, KeyWOW64) -{ - return false; -} -#endif - -// Read a registry value. -// Example : -// HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath -// => will return the data of the "default" value of the key -// HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root -// => will return the data of the "Root" value of the key - -#if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::ReadRegistryValue(const std::string& key, std::string& value, - KeyWOW64 view) -{ - bool valueset = false; - HKEY primaryKey = HKEY_CURRENT_USER; - std::string second; - std::string valuename; - if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) { - return false; - } - - HKEY hKey; - if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0, - SystemToolsMakeRegistryMode(KEY_READ, view), - &hKey) != ERROR_SUCCESS) { - return false; - } else { - DWORD dwType, dwSize; - dwSize = 1023; - wchar_t data[1024]; - if (RegQueryValueExW(hKey, Encoding::ToWide(valuename).c_str(), nullptr, - &dwType, (BYTE*)data, &dwSize) == ERROR_SUCCESS) { - if (dwType == REG_SZ) { - value = Encoding::ToNarrow(data); - valueset = true; - } else if (dwType == REG_EXPAND_SZ) { - wchar_t expanded[1024]; - DWORD dwExpandedSize = sizeof(expanded) / sizeof(expanded[0]); - if (ExpandEnvironmentStringsW(data, expanded, dwExpandedSize)) { - value = Encoding::ToNarrow(expanded); - valueset = true; - } - } - } - - RegCloseKey(hKey); - } - - return valueset; -} -#else -bool SystemTools::ReadRegistryValue(const std::string&, std::string&, KeyWOW64) -{ - return false; -} -#endif - -// Write a registry value. -// Example : -// HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath -// => will set the data of the "default" value of the key -// HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root -// => will set the data of the "Root" value of the key - -#if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::WriteRegistryValue(const std::string& key, - const std::string& value, KeyWOW64 view) -{ - HKEY primaryKey = HKEY_CURRENT_USER; - std::string second; - std::string valuename; - if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) { - return false; - } - - HKEY hKey; - DWORD dwDummy; - wchar_t lpClass[] = L""; - if (RegCreateKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0, lpClass, - REG_OPTION_NON_VOLATILE, - SystemToolsMakeRegistryMode(KEY_WRITE, view), nullptr, - &hKey, &dwDummy) != ERROR_SUCCESS) { - return false; - } - - std::wstring wvalue = Encoding::ToWide(value); - if (RegSetValueExW(hKey, Encoding::ToWide(valuename).c_str(), 0, REG_SZ, - (CONST BYTE*)wvalue.c_str(), - (DWORD)(sizeof(wchar_t) * (wvalue.size() + 1))) == - ERROR_SUCCESS) { - return true; - } - return false; -} -#else -bool SystemTools::WriteRegistryValue(const std::string&, const std::string&, - KeyWOW64) -{ - return false; -} -#endif - -// Delete a registry value. -// Example : -// HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath -// => will delete the data of the "default" value of the key -// HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root -// => will delete the data of the "Root" value of the key - -#if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::DeleteRegistryValue(const std::string& key, KeyWOW64 view) -{ - HKEY primaryKey = HKEY_CURRENT_USER; - std::string second; - std::string valuename; - if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) { - return false; - } - - HKEY hKey; - if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0, - SystemToolsMakeRegistryMode(KEY_WRITE, view), - &hKey) != ERROR_SUCCESS) { - return false; - } else { - if (RegDeleteValue(hKey, (LPTSTR)valuename.c_str()) == ERROR_SUCCESS) { - RegCloseKey(hKey); - return true; - } - } - return false; -} -#else -bool SystemTools::DeleteRegistryValue(const std::string&, KeyWOW64) -{ - return false; -} -#endif - -bool SystemTools::SameFile(const std::string& file1, const std::string& file2) -{ -#ifdef _WIN32 - HANDLE hFile1, hFile2; - - hFile1 = - CreateFileW(Encoding::ToWide(file1).c_str(), GENERIC_READ, FILE_SHARE_READ, - nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); - hFile2 = - CreateFileW(Encoding::ToWide(file2).c_str(), GENERIC_READ, FILE_SHARE_READ, - nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); - if (hFile1 == INVALID_HANDLE_VALUE || hFile2 == INVALID_HANDLE_VALUE) { - if (hFile1 != INVALID_HANDLE_VALUE) { - CloseHandle(hFile1); - } - if (hFile2 != INVALID_HANDLE_VALUE) { - CloseHandle(hFile2); - } - return false; - } - - BY_HANDLE_FILE_INFORMATION fiBuf1; - BY_HANDLE_FILE_INFORMATION fiBuf2; - GetFileInformationByHandle(hFile1, &fiBuf1); - GetFileInformationByHandle(hFile2, &fiBuf2); - CloseHandle(hFile1); - CloseHandle(hFile2); - return (fiBuf1.dwVolumeSerialNumber == fiBuf2.dwVolumeSerialNumber && - fiBuf1.nFileIndexHigh == fiBuf2.nFileIndexHigh && - fiBuf1.nFileIndexLow == fiBuf2.nFileIndexLow); -#else - struct stat fileStat1, fileStat2; - if (stat(file1.c_str(), &fileStat1) == 0 && - stat(file2.c_str(), &fileStat2) == 0) { - // see if the files are the same file - // check the device inode and size - if (memcmp(&fileStat2.st_dev, &fileStat1.st_dev, - sizeof(fileStat1.st_dev)) == 0 && - memcmp(&fileStat2.st_ino, &fileStat1.st_ino, - sizeof(fileStat1.st_ino)) == 0 && - fileStat2.st_size == fileStat1.st_size) { - return true; - } - } - return false; -#endif -} - -bool SystemTools::PathExists(const std::string& path) -{ - if (path.empty()) { - return false; - } -#if defined(__CYGWIN__) - // Convert path to native windows path if possible. - char winpath[MAX_PATH]; - if (SystemTools::PathCygwinToWin32(path.c_str(), winpath)) { - return (GetFileAttributesA(winpath) != INVALID_FILE_ATTRIBUTES); - } - struct stat st; - return lstat(path.c_str(), &st) == 0; -#elif defined(_WIN32) - return (GetFileAttributesW(Encoding::ToWindowsExtendedPath(path).c_str()) != - INVALID_FILE_ATTRIBUTES); -#else - struct stat st; - return lstat(path.c_str(), &st) == 0; -#endif -} - -bool SystemTools::FileExists(const char* filename) -{ - if (!filename) { - return false; - } - return SystemTools::FileExists(std::string(filename)); -} - -bool SystemTools::FileExists(const std::string& filename) -{ - if (filename.empty()) { - return false; - } -#if defined(__CYGWIN__) - // Convert filename to native windows path if possible. - char winpath[MAX_PATH]; - if (SystemTools::PathCygwinToWin32(filename.c_str(), winpath)) { - return (GetFileAttributesA(winpath) != INVALID_FILE_ATTRIBUTES); - } - return access(filename.c_str(), R_OK) == 0; -#elif defined(_WIN32) - DWORD attr = - GetFileAttributesW(Encoding::ToWindowsExtendedPath(filename).c_str()); - if (attr == INVALID_FILE_ATTRIBUTES) { - return false; - } - - if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { - // Using 0 instead of GENERIC_READ as it allows reading of file attributes - // even if we do not have permission to read the file itself - HANDLE handle = - CreateFileW(Encoding::ToWindowsExtendedPath(filename).c_str(), 0, 0, - nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); - - if (handle == INVALID_HANDLE_VALUE) { - return false; - } - - CloseHandle(handle); - } - - return true; -#else -// SCO OpenServer 5.0.7/3.2's command has 711 permission. -# if defined(_SCO_DS) - return access(filename.c_str(), F_OK) == 0; -# else - return access(filename.c_str(), R_OK) == 0; -# endif -#endif -} - -bool SystemTools::FileExists(const char* filename, bool isFile) -{ - if (!filename) { - return false; - } - return SystemTools::FileExists(std::string(filename), isFile); -} - -bool SystemTools::FileExists(const std::string& filename, bool isFile) -{ - if (SystemTools::FileExists(filename)) { - // If isFile is set return not FileIsDirectory, - // so this will only be true if it is a file - return !isFile || !SystemTools::FileIsDirectory(filename); - } - return false; -} - -bool SystemTools::TestFileAccess(const char* filename, - TestFilePermissions permissions) -{ - if (!filename) { - return false; - } - return SystemTools::TestFileAccess(std::string(filename), permissions); -} - -bool SystemTools::TestFileAccess(const std::string& filename, - TestFilePermissions permissions) -{ - if (filename.empty()) { - return false; - } -#if defined(_WIN32) && !defined(__CYGWIN__) - // If execute set, change to read permission (all files on Windows - // are executable if they are readable). The CRT will always fail - // if you pass an execute bit. - if (permissions & TEST_FILE_EXECUTE) { - permissions &= ~TEST_FILE_EXECUTE; - permissions |= TEST_FILE_READ; - } - return _waccess(Encoding::ToWindowsExtendedPath(filename).c_str(), - permissions) == 0; -#else - return access(filename.c_str(), permissions) == 0; -#endif -} - -int SystemTools::Stat(const char* path, SystemTools::Stat_t* buf) -{ - if (!path) { - errno = EFAULT; - return -1; - } - return SystemTools::Stat(std::string(path), buf); -} - -int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf) -{ - if (path.empty()) { - errno = ENOENT; - return -1; - } -#if defined(_WIN32) && !defined(__CYGWIN__) - // Ideally we should use Encoding::ToWindowsExtendedPath to support - // long paths, but _wstat64 rejects paths with '?' in them, thinking - // they are wildcards. - std::wstring const& wpath = Encoding::ToWide(path); -# if defined(__BORLANDC__) - return _wstati64(wpath.c_str(), buf); -# else - return _wstat64(wpath.c_str(), buf); -# endif -#else - return stat(path.c_str(), buf); -#endif -} - -#ifdef __CYGWIN__ -bool SystemTools::PathCygwinToWin32(const char* path, char* win32_path) -{ - auto itr = SystemTools::Statics->Cyg2Win32Map.find(path); - if (itr != SystemTools::Statics->Cyg2Win32Map.end()) { - strncpy(win32_path, itr->second.c_str(), MAX_PATH); - } else { - if (cygwin_conv_path(CCP_POSIX_TO_WIN_A, path, win32_path, MAX_PATH) != - 0) { - win32_path[0] = 0; - } - SystemTools::Statics->Cyg2Win32Map.insert( - SystemToolsStatic::StringMap::value_type(path, win32_path)); - } - return win32_path[0] != 0; -} -#endif - -bool SystemTools::Touch(const std::string& filename, bool create) -{ - if (!SystemTools::PathExists(filename)) { - if (create) { - FILE* file = Fopen(filename, "a+b"); - if (file) { - fclose(file); - return true; - } - return false; - } else { - return true; - } - } -#if defined(_WIN32) && !defined(__CYGWIN__) - HANDLE h = CreateFileW(Encoding::ToWindowsExtendedPath(filename).c_str(), - FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); - if (!h) { - return false; - } - FILETIME mtime; - GetSystemTimeAsFileTime(&mtime); - if (!SetFileTime(h, 0, 0, &mtime)) { - CloseHandle(h); - return false; - } - CloseHandle(h); -#elif KWSYS_CXX_HAS_UTIMENSAT - // utimensat is only available on newer Unixes and macOS 10.13+ - if (utimensat(AT_FDCWD, filename.c_str(), nullptr, 0) < 0) { - return false; - } -#else - // fall back to utimes - if (utimes(filename.c_str(), nullptr) < 0) { - return false; - } -#endif - return true; -} - -bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2, - int* result) -{ - // Default to same time. - *result = 0; -#if !defined(_WIN32) || defined(__CYGWIN__) - // POSIX version. Use stat function to get file modification time. - struct stat s1; - if (stat(f1.c_str(), &s1) != 0) { - return false; - } - struct stat s2; - if (stat(f2.c_str(), &s2) != 0) { - return false; - } -# if KWSYS_CXX_STAT_HAS_ST_MTIM - // Compare using nanosecond resolution. - if (s1.st_mtim.tv_sec < s2.st_mtim.tv_sec) { - *result = -1; - } else if (s1.st_mtim.tv_sec > s2.st_mtim.tv_sec) { - *result = 1; - } else if (s1.st_mtim.tv_nsec < s2.st_mtim.tv_nsec) { - *result = -1; - } else if (s1.st_mtim.tv_nsec > s2.st_mtim.tv_nsec) { - *result = 1; - } -# elif KWSYS_CXX_STAT_HAS_ST_MTIMESPEC - // Compare using nanosecond resolution. - if (s1.st_mtimespec.tv_sec < s2.st_mtimespec.tv_sec) { - *result = -1; - } else if (s1.st_mtimespec.tv_sec > s2.st_mtimespec.tv_sec) { - *result = 1; - } else if (s1.st_mtimespec.tv_nsec < s2.st_mtimespec.tv_nsec) { - *result = -1; - } else if (s1.st_mtimespec.tv_nsec > s2.st_mtimespec.tv_nsec) { - *result = 1; - } -# else - // Compare using 1 second resolution. - if (s1.st_mtime < s2.st_mtime) { - *result = -1; - } else if (s1.st_mtime > s2.st_mtime) { - *result = 1; - } -# endif -#else - // Windows version. Get the modification time from extended file attributes. - WIN32_FILE_ATTRIBUTE_DATA f1d; - WIN32_FILE_ATTRIBUTE_DATA f2d; - if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f1).c_str(), - GetFileExInfoStandard, &f1d)) { - return false; - } - if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f2).c_str(), - GetFileExInfoStandard, &f2d)) { - return false; - } - - // Compare the file times using resolution provided by system call. - *result = (int)CompareFileTime(&f1d.ftLastWriteTime, &f2d.ftLastWriteTime); -#endif - return true; -} - -// Return a capitalized string (i.e the first letter is uppercased, all other -// are lowercased) -std::string SystemTools::Capitalized(const std::string& s) -{ - std::string n; - if (s.empty()) { - return n; - } - n.resize(s.size()); - n[0] = static_cast<std::string::value_type>(toupper(s[0])); - for (size_t i = 1; i < s.size(); i++) { - n[i] = static_cast<std::string::value_type>(tolower(s[i])); - } - return n; -} - -// Return capitalized words -std::string SystemTools::CapitalizedWords(const std::string& s) -{ - std::string n(s); - for (size_t i = 0; i < s.size(); i++) { -#if defined(_MSC_VER) && defined(_MT) && defined(_DEBUG) - // MS has an assert that will fail if s[i] < 0; setting - // LC_CTYPE using setlocale() does *not* help. Painful. - if ((int)s[i] >= 0 && isalpha(s[i]) && - (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1])))) -#else - if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1]))) -#endif - { - n[i] = static_cast<std::string::value_type>(toupper(s[i])); - } - } - return n; -} - -// Return uncapitalized words -std::string SystemTools::UnCapitalizedWords(const std::string& s) -{ - std::string n(s); - for (size_t i = 0; i < s.size(); i++) { -#if defined(_MSC_VER) && defined(_MT) && defined(_DEBUG) - // MS has an assert that will fail if s[i] < 0; setting - // LC_CTYPE using setlocale() does *not* help. Painful. - if ((int)s[i] >= 0 && isalpha(s[i]) && - (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1])))) -#else - if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1]))) -#endif - { - n[i] = static_cast<std::string::value_type>(tolower(s[i])); - } - } - return n; -} - -// only works for words with at least two letters -std::string SystemTools::AddSpaceBetweenCapitalizedWords(const std::string& s) -{ - std::string n; - if (!s.empty()) { - n.reserve(s.size()); - n += s[0]; - for (size_t i = 1; i < s.size(); i++) { - if (isupper(s[i]) && !isspace(s[i - 1]) && !isupper(s[i - 1])) { - n += ' '; - } - n += s[i]; - } - } - return n; -} - -char* SystemTools::AppendStrings(const char* str1, const char* str2) -{ - if (!str1) { - return SystemTools::DuplicateString(str2); - } - if (!str2) { - return SystemTools::DuplicateString(str1); - } - size_t len1 = strlen(str1); - char* newstr = new char[len1 + strlen(str2) + 1]; - if (!newstr) { - return nullptr; - } - strcpy(newstr, str1); - strcat(newstr + len1, str2); - return newstr; -} - -char* SystemTools::AppendStrings(const char* str1, const char* str2, - const char* str3) -{ - if (!str1) { - return SystemTools::AppendStrings(str2, str3); - } - if (!str2) { - return SystemTools::AppendStrings(str1, str3); - } - if (!str3) { - return SystemTools::AppendStrings(str1, str2); - } - - size_t len1 = strlen(str1), len2 = strlen(str2); - char* newstr = new char[len1 + len2 + strlen(str3) + 1]; - if (!newstr) { - return nullptr; - } - strcpy(newstr, str1); - strcat(newstr + len1, str2); - strcat(newstr + len1 + len2, str3); - return newstr; -} - -// Return a lower case string -std::string SystemTools::LowerCase(const std::string& s) -{ - std::string n; - n.resize(s.size()); - for (size_t i = 0; i < s.size(); i++) { - n[i] = static_cast<std::string::value_type>(tolower(s[i])); - } - return n; -} - -// Return a lower case string -std::string SystemTools::UpperCase(const std::string& s) -{ - std::string n; - n.resize(s.size()); - for (size_t i = 0; i < s.size(); i++) { - n[i] = static_cast<std::string::value_type>(toupper(s[i])); - } - return n; -} - -// Count char in string -size_t SystemTools::CountChar(const char* str, char c) -{ - size_t count = 0; - - if (str) { - while (*str) { - if (*str == c) { - ++count; - } - ++str; - } - } - return count; -} - -// Remove chars in string -char* SystemTools::RemoveChars(const char* str, const char* toremove) -{ - if (!str) { - return nullptr; - } - char* clean_str = new char[strlen(str) + 1]; - char* ptr = clean_str; - while (*str) { - const char* str2 = toremove; - while (*str2 && *str != *str2) { - ++str2; - } - if (!*str2) { - *ptr++ = *str; - } - ++str; - } - *ptr = '\0'; - return clean_str; -} - -// Remove chars in string -char* SystemTools::RemoveCharsButUpperHex(const char* str) -{ - if (!str) { - return nullptr; - } - char* clean_str = new char[strlen(str) + 1]; - char* ptr = clean_str; - while (*str) { - if ((*str >= '0' && *str <= '9') || (*str >= 'A' && *str <= 'F')) { - *ptr++ = *str; - } - ++str; - } - *ptr = '\0'; - return clean_str; -} - -// Replace chars in string -char* SystemTools::ReplaceChars(char* str, const char* toreplace, - char replacement) -{ - if (str) { - char* ptr = str; - while (*ptr) { - const char* ptr2 = toreplace; - while (*ptr2) { - if (*ptr == *ptr2) { - *ptr = replacement; - } - ++ptr2; - } - ++ptr; - } - } - return str; -} - -// Returns if string starts with another string -bool SystemTools::StringStartsWith(const char* str1, const char* str2) -{ - if (!str1 || !str2) { - return false; - } - size_t len1 = strlen(str1), len2 = strlen(str2); - return len1 >= len2 && !strncmp(str1, str2, len2) ? true : false; -} - -// Returns if string starts with another string -bool SystemTools::StringStartsWith(const std::string& str1, const char* str2) -{ - if (!str2) { - return false; - } - size_t len1 = str1.size(), len2 = strlen(str2); - return len1 >= len2 && !strncmp(str1.c_str(), str2, len2) ? true : false; -} - -// Returns if string ends with another string -bool SystemTools::StringEndsWith(const char* str1, const char* str2) -{ - if (!str1 || !str2) { - return false; - } - size_t len1 = strlen(str1), len2 = strlen(str2); - return len1 >= len2 && !strncmp(str1 + (len1 - len2), str2, len2) ? true - : false; -} - -// Returns if string ends with another string -bool SystemTools::StringEndsWith(const std::string& str1, const char* str2) -{ - if (!str2) { - return false; - } - size_t len1 = str1.size(), len2 = strlen(str2); - return len1 >= len2 && !strncmp(str1.c_str() + (len1 - len2), str2, len2) - ? true - : false; -} - -// Returns a pointer to the last occurrence of str2 in str1 -const char* SystemTools::FindLastString(const char* str1, const char* str2) -{ - if (!str1 || !str2) { - return nullptr; - } - - size_t len1 = strlen(str1), len2 = strlen(str2); - if (len1 >= len2) { - const char* ptr = str1 + len1 - len2; - do { - if (!strncmp(ptr, str2, len2)) { - return ptr; - } - } while (ptr-- != str1); - } - - return nullptr; -} - -// Duplicate string -char* SystemTools::DuplicateString(const char* str) -{ - if (str) { - char* newstr = new char[strlen(str) + 1]; - return strcpy(newstr, str); - } - return nullptr; -} - -// Return a cropped string -std::string SystemTools::CropString(const std::string& s, size_t max_len) -{ - if (!s.size() || max_len == 0 || max_len >= s.size()) { - return s; - } - - std::string n; - n.reserve(max_len); - - size_t middle = max_len / 2; - - n += s.substr(0, middle); - n += s.substr(s.size() - (max_len - middle)); - - if (max_len > 2) { - n[middle] = '.'; - if (max_len > 3) { - n[middle - 1] = '.'; - if (max_len > 4) { - n[middle + 1] = '.'; - } - } - } - - return n; -} - -std::vector<std::string> SystemTools::SplitString(const std::string& p, - char sep, bool isPath) -{ - std::string path = p; - std::vector<std::string> paths; - if (path.empty()) { - return paths; - } - if (isPath && path[0] == '/') { - path.erase(path.begin()); - paths.push_back("/"); - } - std::string::size_type pos1 = 0; - std::string::size_type pos2 = path.find(sep, pos1 + 1); - while (pos2 != std::string::npos) { - paths.push_back(path.substr(pos1, pos2 - pos1)); - pos1 = pos2 + 1; - pos2 = path.find(sep, pos1 + 1); - } - paths.push_back(path.substr(pos1, pos2 - pos1)); - - return paths; -} - -int SystemTools::EstimateFormatLength(const char* format, va_list ap) -{ - if (!format) { - return 0; - } - - // Quick-hack attempt at estimating the length of the string. - // Should never under-estimate. - - // Start with the length of the format string itself. - - size_t length = strlen(format); - - // Increase the length for every argument in the format. - - const char* cur = format; - while (*cur) { - if (*cur++ == '%') { - // Skip "%%" since it doesn't correspond to a va_arg. - if (*cur != '%') { - while (!int(isalpha(*cur))) { - ++cur; - } - switch (*cur) { - case 's': { - // Check the length of the string. - char* s = va_arg(ap, char*); - if (s) { - length += strlen(s); - } - } break; - case 'e': - case 'f': - case 'g': { - // Assume the argument contributes no more than 64 characters. - length += 64; - - // Eat the argument. - static_cast<void>(va_arg(ap, double)); - } break; - default: { - // Assume the argument contributes no more than 64 characters. - length += 64; - - // Eat the argument. - static_cast<void>(va_arg(ap, int)); - } break; - } - } - - // Move past the characters just tested. - ++cur; - } - } - - return static_cast<int>(length); -} - -std::string SystemTools::EscapeChars(const char* str, - const char* chars_to_escape, - char escape_char) -{ - std::string n; - if (str) { - if (!chars_to_escape || !*chars_to_escape) { - n.append(str); - } else { - n.reserve(strlen(str)); - while (*str) { - const char* ptr = chars_to_escape; - while (*ptr) { - if (*str == *ptr) { - n += escape_char; - break; - } - ++ptr; - } - n += *str; - ++str; - } - } - } - return n; -} - -#ifdef __VMS -static void ConvertVMSToUnix(std::string& path) -{ - std::string::size_type rootEnd = path.find(":["); - std::string::size_type pathEnd = path.find("]"); - if (rootEnd != std::string::npos) { - std::string root = path.substr(0, rootEnd); - std::string pathPart = path.substr(rootEnd + 2, pathEnd - rootEnd - 2); - const char* pathCString = pathPart.c_str(); - const char* pos0 = pathCString; - for (std::string::size_type pos = 0; *pos0; ++pos) { - if (*pos0 == '.') { - pathPart[pos] = '/'; - } - pos0++; - } - path = "/" + root + "/" + pathPart; - } -} -#endif - -// convert windows slashes to unix slashes -void SystemTools::ConvertToUnixSlashes(std::string& path) -{ - if (path.empty()) { - return; - } - - const char* pathCString = path.c_str(); - bool hasDoubleSlash = false; -#ifdef __VMS - ConvertVMSToUnix(path); -#else - const char* pos0 = pathCString; - for (std::string::size_type pos = 0; *pos0; ++pos) { - if (*pos0 == '\\') { - path[pos] = '/'; - } - - // Also, reuse the loop to check for slash followed by another slash - if (!hasDoubleSlash && *(pos0 + 1) == '/' && *(pos0 + 2) == '/') { -# ifdef _WIN32 - // However, on windows if the first characters are both slashes, - // then keep them that way, so that network paths can be handled. - if (pos > 0) { - hasDoubleSlash = true; - } -# else - hasDoubleSlash = true; -# endif - } - - pos0++; - } - - if (hasDoubleSlash) { - SystemTools::ReplaceString(path, "//", "/"); - } -#endif - - // remove any trailing slash - // if there is a tilda ~ then replace it with HOME - pathCString = path.c_str(); - if (pathCString[0] == '~' && - (pathCString[1] == '/' || pathCString[1] == '\0')) { - std::string homeEnv; - if (SystemTools::GetEnv("HOME", homeEnv)) { - path.replace(0, 1, homeEnv); - } - } -#ifdef HAVE_GETPWNAM - else if (pathCString[0] == '~') { - std::string::size_type idx = path.find_first_of("/\0"); - std::string user = path.substr(1, idx - 1); - passwd* pw = getpwnam(user.c_str()); - if (pw) { - path.replace(0, idx, pw->pw_dir); - } - } -#endif - // remove trailing slash if the path is more than - // a single / - pathCString = path.c_str(); - size_t size = path.size(); - if (size > 1 && path.back() == '/') { - // if it is c:/ then do not remove the trailing slash - if (!((size == 3 && pathCString[1] == ':'))) { - path.resize(size - 1); - } - } -} - -#ifdef _WIN32 -std::wstring SystemTools::ConvertToWindowsExtendedPath( - const std::string& source) -{ - return Encoding::ToWindowsExtendedPath(source); -} -#endif - -// change // to /, and escape any spaces in the path -std::string SystemTools::ConvertToUnixOutputPath(const std::string& path) -{ - std::string ret = path; - - // remove // except at the beginning might be a cygwin drive - std::string::size_type pos = 1; - while ((pos = ret.find("//", pos)) != std::string::npos) { - ret.erase(pos, 1); - } - // escape spaces and () in the path - if (ret.find_first_of(" ") != std::string::npos) { - std::string result; - char lastch = 1; - for (const char* ch = ret.c_str(); *ch != '\0'; ++ch) { - // if it is already escaped then don't try to escape it again - if ((*ch == ' ') && lastch != '\\') { - result += '\\'; - } - result += *ch; - lastch = *ch; - } - ret = result; - } - return ret; -} - -std::string SystemTools::ConvertToOutputPath(const std::string& path) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - return SystemTools::ConvertToWindowsOutputPath(path); -#else - return SystemTools::ConvertToUnixOutputPath(path); -#endif -} - -// remove double slashes not at the start -std::string SystemTools::ConvertToWindowsOutputPath(const std::string& path) -{ - std::string ret; - // make it big enough for all of path and double quotes - ret.reserve(path.size() + 3); - // put path into the string - ret = path; - std::string::size_type pos = 0; - // first convert all of the slashes - while ((pos = ret.find('/', pos)) != std::string::npos) { - ret[pos] = '\\'; - pos++; - } - // check for really small paths - if (ret.size() < 2) { - return ret; - } - // now clean up a bit and remove double slashes - // Only if it is not the first position in the path which is a network - // path on windows - pos = 1; // start at position 1 - if (ret[0] == '\"') { - pos = 2; // if the string is already quoted then start at 2 - if (ret.size() < 3) { - return ret; - } - } - while ((pos = ret.find("\\\\", pos)) != std::string::npos) { - ret.erase(pos, 1); - } - // now double quote the path if it has spaces in it - // and is not already double quoted - if (ret.find(' ') != std::string::npos && ret[0] != '\"') { - ret.insert(static_cast<std::string::size_type>(0), - static_cast<std::string::size_type>(1), '\"'); - ret.append(1, '\"'); - } - return ret; -} - -/** - * Append the filename from the path source to the directory name dir. - */ -static std::string FileInDir(const std::string& source, const std::string& dir) -{ - std::string new_destination = dir; - SystemTools::ConvertToUnixSlashes(new_destination); - return new_destination + '/' + SystemTools::GetFilenameName(source); -} - -bool SystemTools::CopyFileIfDifferent(const std::string& source, - const std::string& destination) -{ - // special check for a destination that is a directory - // FilesDiffer does not handle file to directory compare - if (SystemTools::FileIsDirectory(destination)) { - const std::string new_destination = FileInDir(source, destination); - return SystemTools::CopyFileIfDifferent(source, new_destination); - } - // source and destination are files so do a copy if they - // are different - if (SystemTools::FilesDiffer(source, destination)) { - return SystemTools::CopyFileAlways(source, destination); - } - // at this point the files must be the same so return true - return true; -} - -#define KWSYS_ST_BUFFER 4096 - -bool SystemTools::FilesDiffer(const std::string& source, - const std::string& destination) -{ - -#if defined(_WIN32) - WIN32_FILE_ATTRIBUTE_DATA statSource; - if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(source).c_str(), - GetFileExInfoStandard, &statSource) == 0) { - return true; - } - - WIN32_FILE_ATTRIBUTE_DATA statDestination; - if (GetFileAttributesExW( - Encoding::ToWindowsExtendedPath(destination).c_str(), - GetFileExInfoStandard, &statDestination) == 0) { - return true; - } - - if (statSource.nFileSizeHigh != statDestination.nFileSizeHigh || - statSource.nFileSizeLow != statDestination.nFileSizeLow) { - return true; - } - - if (statSource.nFileSizeHigh == 0 && statSource.nFileSizeLow == 0) { - return false; - } - off_t nleft = - ((__int64)statSource.nFileSizeHigh << 32) + statSource.nFileSizeLow; - -#else - - struct stat statSource; - if (stat(source.c_str(), &statSource) != 0) { - return true; - } - - struct stat statDestination; - if (stat(destination.c_str(), &statDestination) != 0) { - return true; - } - - if (statSource.st_size != statDestination.st_size) { - return true; - } - - if (statSource.st_size == 0) { - return false; - } - off_t nleft = statSource.st_size; -#endif - -#if defined(_WIN32) - kwsys::ifstream finSource(source.c_str(), (std::ios::binary | std::ios::in)); - kwsys::ifstream finDestination(destination.c_str(), - (std::ios::binary | std::ios::in)); -#else - kwsys::ifstream finSource(source.c_str()); - kwsys::ifstream finDestination(destination.c_str()); -#endif - if (!finSource || !finDestination) { - return true; - } - - // Compare the files a block at a time. - char source_buf[KWSYS_ST_BUFFER]; - char dest_buf[KWSYS_ST_BUFFER]; - while (nleft > 0) { - // Read a block from each file. - std::streamsize nnext = (nleft > KWSYS_ST_BUFFER) - ? KWSYS_ST_BUFFER - : static_cast<std::streamsize>(nleft); - finSource.read(source_buf, nnext); - finDestination.read(dest_buf, nnext); - - // If either failed to read assume they are different. - if (static_cast<std::streamsize>(finSource.gcount()) != nnext || - static_cast<std::streamsize>(finDestination.gcount()) != nnext) { - return true; - } - - // If this block differs the file differs. - if (memcmp(static_cast<const void*>(source_buf), - static_cast<const void*>(dest_buf), - static_cast<size_t>(nnext)) != 0) { - return true; - } - - // Update the byte count remaining. - nleft -= nnext; - } - - // No differences found. - return false; -} - -bool SystemTools::TextFilesDiffer(const std::string& path1, - const std::string& path2) -{ - kwsys::ifstream if1(path1.c_str()); - kwsys::ifstream if2(path2.c_str()); - if (!if1 || !if2) { - return true; - } - - for (;;) { - std::string line1, line2; - bool hasData1 = GetLineFromStream(if1, line1); - bool hasData2 = GetLineFromStream(if2, line2); - if (hasData1 != hasData2) { - return true; - } - if (!hasData1) { - break; - } - if (line1 != line2) { - return true; - } - } - return false; -} - -/** - * Blockwise copy source to destination file - */ -static bool CopyFileContentBlockwise(const std::string& source, - const std::string& destination) -{ -// Open files -#if defined(_WIN32) - kwsys::ifstream fin( - Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(source)).c_str(), - std::ios::in | std::ios::binary); -#else - kwsys::ifstream fin(source.c_str(), std::ios::in | std::ios::binary); -#endif - if (!fin) { - return false; - } - - // try and remove the destination file so that read only destination files - // can be written to. - // If the remove fails continue so that files in read only directories - // that do not allow file removal can be modified. - SystemTools::RemoveFile(destination); - -#if defined(_WIN32) - kwsys::ofstream fout( - Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(destination)).c_str(), - std::ios::out | std::ios::trunc | std::ios::binary); -#else - kwsys::ofstream fout(destination.c_str(), - std::ios::out | std::ios::trunc | std::ios::binary); -#endif - if (!fout) { - return false; - } - - // This copy loop is very sensitive on certain platforms with - // slightly broken stream libraries (like HPUX). Normally, it is - // incorrect to not check the error condition on the fin.read() - // before using the data, but the fin.gcount() will be zero if an - // error occurred. Therefore, the loop should be safe everywhere. - while (fin) { - const int bufferSize = 4096; - char buffer[bufferSize]; - - fin.read(buffer, bufferSize); - if (fin.gcount()) { - fout.write(buffer, fin.gcount()); - } else { - break; - } - } - - // Make sure the operating system has finished writing the file - // before closing it. This will ensure the file is finished before - // the check below. - fout.flush(); - - fin.close(); - fout.close(); - - if (!fout) { - return false; - } - - return true; -} - -/** - * Clone the source file to the destination file - * - * If available, the Linux FICLONE ioctl is used to create a check - * copy-on-write clone of the source file. - * - * The method returns false for the following cases: - * - The code has not been compiled on Linux or the ioctl was unknown - * - The source and destination is on different file systems - * - The underlying filesystem does not support file cloning - * - An unspecified error occurred - */ -static bool CloneFileContent(const std::string& source, - const std::string& destination) -{ -#if defined(__linux) && defined(FICLONE) - int in = open(source.c_str(), O_RDONLY); - if (in < 0) { - return false; - } - - SystemTools::RemoveFile(destination); - - int out = - open(destination.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); - if (out < 0) { - close(in); - return false; - } - - int result = ioctl(out, FICLONE, in); - close(in); - close(out); - - if (result < 0) { - return false; - } - - return true; -#else - (void)source; - (void)destination; - return false; -#endif -} - -/** - * Copy a file named by "source" to the file named by "destination". - */ -bool SystemTools::CopyFileAlways(const std::string& source, - const std::string& destination) -{ - mode_t perm = 0; - bool perms = SystemTools::GetPermissions(source, perm); - std::string real_destination = destination; - - if (SystemTools::FileIsDirectory(source)) { - SystemTools::MakeDirectory(destination); - } else { - // If destination is a directory, try to create a file with the same - // name as the source in that directory. - - std::string destination_dir; - if (SystemTools::FileIsDirectory(destination)) { - destination_dir = real_destination; - SystemTools::ConvertToUnixSlashes(real_destination); - real_destination += '/'; - std::string source_name = source; - real_destination += SystemTools::GetFilenameName(source_name); - } else { - destination_dir = SystemTools::GetFilenamePath(destination); - } - // If files are the same do not copy - if (SystemTools::SameFile(source, real_destination)) { - return true; - } - - // Create destination directory - - SystemTools::MakeDirectory(destination_dir); - - if (!CloneFileContent(source, real_destination)) { - // if cloning did not succeed, fall back to blockwise copy - if (!CopyFileContentBlockwise(source, real_destination)) { - return false; - } - } - } - if (perms) { - if (!SystemTools::SetPermissions(real_destination, perm)) { - return false; - } - } - return true; -} - -bool SystemTools::CopyAFile(const std::string& source, - const std::string& destination, bool always) -{ - if (always) { - return SystemTools::CopyFileAlways(source, destination); - } else { - return SystemTools::CopyFileIfDifferent(source, destination); - } -} - -/** - * Copy a directory content from "source" directory to the directory named by - * "destination". - */ -bool SystemTools::CopyADirectory(const std::string& source, - const std::string& destination, bool always) -{ - Directory dir; - if (dir.Load(source) == 0) { - return false; - } - size_t fileNum; - if (!SystemTools::MakeDirectory(destination)) { - return false; - } - for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) { - if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") && - strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..")) { - std::string fullPath = source; - fullPath += "/"; - fullPath += dir.GetFile(static_cast<unsigned long>(fileNum)); - if (SystemTools::FileIsDirectory(fullPath)) { - std::string fullDestPath = destination; - fullDestPath += "/"; - fullDestPath += dir.GetFile(static_cast<unsigned long>(fileNum)); - if (!SystemTools::CopyADirectory(fullPath, fullDestPath, always)) { - return false; - } - } else { - if (!SystemTools::CopyAFile(fullPath, destination, always)) { - return false; - } - } - } - } - - return true; -} - -// return size of file; also returns zero if no file exists -unsigned long SystemTools::FileLength(const std::string& filename) -{ - unsigned long length = 0; -#ifdef _WIN32 - WIN32_FILE_ATTRIBUTE_DATA fs; - if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(filename).c_str(), - GetFileExInfoStandard, &fs) != 0) { - /* To support the full 64-bit file size, use fs.nFileSizeHigh - * and fs.nFileSizeLow to construct the 64 bit size - - length = ((__int64)fs.nFileSizeHigh << 32) + fs.nFileSizeLow; - */ - length = static_cast<unsigned long>(fs.nFileSizeLow); - } -#else - struct stat fs; - if (stat(filename.c_str(), &fs) == 0) { - length = static_cast<unsigned long>(fs.st_size); - } -#endif - return length; -} - -int SystemTools::Strucmp(const char* l, const char* r) -{ - int lc; - int rc; - do { - lc = tolower(*l++); - rc = tolower(*r++); - } while (lc == rc && lc); - return lc - rc; -} - -// return file's modified time -long int SystemTools::ModifiedTime(const std::string& filename) -{ - long int mt = 0; -#ifdef _WIN32 - WIN32_FILE_ATTRIBUTE_DATA fs; - if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(filename).c_str(), - GetFileExInfoStandard, &fs) != 0) { - mt = windows_filetime_to_posix_time(fs.ftLastWriteTime); - } -#else - struct stat fs; - if (stat(filename.c_str(), &fs) == 0) { - mt = static_cast<long int>(fs.st_mtime); - } -#endif - return mt; -} - -// return file's creation time -long int SystemTools::CreationTime(const std::string& filename) -{ - long int ct = 0; -#ifdef _WIN32 - WIN32_FILE_ATTRIBUTE_DATA fs; - if (GetFileAttributesExW(Encoding::ToWindowsExtendedPath(filename).c_str(), - GetFileExInfoStandard, &fs) != 0) { - ct = windows_filetime_to_posix_time(fs.ftCreationTime); - } -#else - struct stat fs; - if (stat(filename.c_str(), &fs) == 0) { - ct = fs.st_ctime >= 0 ? static_cast<long int>(fs.st_ctime) : 0; - } -#endif - return ct; -} - -std::string SystemTools::GetLastSystemError() -{ - int e = errno; - return strerror(e); -} - -bool SystemTools::RemoveFile(const std::string& source) -{ -#ifdef _WIN32 - std::wstring const& ws = Encoding::ToWindowsExtendedPath(source); - if (DeleteFileW(ws.c_str())) { - return true; - } - DWORD err = GetLastError(); - if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) { - return true; - } - if (err != ERROR_ACCESS_DENIED) { - return false; - } - /* The file may be read-only. Try adding write permission. */ - mode_t mode; - if (!SystemTools::GetPermissions(source, mode) || - !SystemTools::SetPermissions(source, S_IWRITE)) { - SetLastError(err); - return false; - } - - const DWORD DIRECTORY_SOFT_LINK_ATTRS = - FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT; - DWORD attrs = GetFileAttributesW(ws.c_str()); - if (attrs != INVALID_FILE_ATTRIBUTES && - (attrs & DIRECTORY_SOFT_LINK_ATTRS) == DIRECTORY_SOFT_LINK_ATTRS && - RemoveDirectoryW(ws.c_str())) { - return true; - } - if (DeleteFileW(ws.c_str()) || GetLastError() == ERROR_FILE_NOT_FOUND || - GetLastError() == ERROR_PATH_NOT_FOUND) { - return true; - } - /* Try to restore the original permissions. */ - SystemTools::SetPermissions(source, mode); - SetLastError(err); - return false; -#else - return unlink(source.c_str()) == 0 || errno == ENOENT; -#endif -} - -bool SystemTools::RemoveADirectory(const std::string& source) -{ - // Add write permission to the directory so we can modify its - // content to remove files and directories from it. - mode_t mode; - if (SystemTools::GetPermissions(source, mode)) { -#if defined(_WIN32) && !defined(__CYGWIN__) - mode |= S_IWRITE; -#else - mode |= S_IWUSR; -#endif - SystemTools::SetPermissions(source, mode); - } - - Directory dir; - dir.Load(source); - size_t fileNum; - for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) { - if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") && - strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..")) { - std::string fullPath = source; - fullPath += "/"; - fullPath += dir.GetFile(static_cast<unsigned long>(fileNum)); - if (SystemTools::FileIsDirectory(fullPath) && - !SystemTools::FileIsSymlink(fullPath)) { - if (!SystemTools::RemoveADirectory(fullPath)) { - return false; - } - } else { - if (!SystemTools::RemoveFile(fullPath)) { - return false; - } - } - } - } - - return (Rmdir(source) == 0); -} - -/** - */ -size_t SystemTools::GetMaximumFilePathLength() -{ - return KWSYS_SYSTEMTOOLS_MAXPATH; -} - -/** - * Find the file the given name. Searches the given path and then - * the system search path. Returns the full path to the file if it is - * found. Otherwise, the empty string is returned. - */ -std::string SystemToolsStatic::FindName( - const std::string& name, const std::vector<std::string>& userPaths, - bool no_system_path) -{ - // Add the system search path to our path first - std::vector<std::string> path; - if (!no_system_path) { - SystemTools::GetPath(path, "CMAKE_FILE_PATH"); - SystemTools::GetPath(path); - } - // now add the additional paths - path.reserve(path.size() + userPaths.size()); - path.insert(path.end(), userPaths.begin(), userPaths.end()); - // now look for the file - std::string tryPath; - for (std::string const& p : path) { - tryPath = p; - if (tryPath.empty() || tryPath.back() != '/') { - tryPath += '/'; - } - tryPath += name; - if (SystemTools::FileExists(tryPath)) { - return tryPath; - } - } - // Couldn't find the file. - return ""; -} - -/** - * Find the file the given name. Searches the given path and then - * the system search path. Returns the full path to the file if it is - * found. Otherwise, the empty string is returned. - */ -std::string SystemTools::FindFile(const std::string& name, - const std::vector<std::string>& userPaths, - bool no_system_path) -{ - std::string tryPath = - SystemToolsStatic::FindName(name, userPaths, no_system_path); - if (!tryPath.empty() && !SystemTools::FileIsDirectory(tryPath)) { - return SystemTools::CollapseFullPath(tryPath); - } - // Couldn't find the file. - return ""; -} - -/** - * Find the directory the given name. Searches the given path and then - * the system search path. Returns the full path to the directory if it is - * found. Otherwise, the empty string is returned. - */ -std::string SystemTools::FindDirectory( - const std::string& name, const std::vector<std::string>& userPaths, - bool no_system_path) -{ - std::string tryPath = - SystemToolsStatic::FindName(name, userPaths, no_system_path); - if (!tryPath.empty() && SystemTools::FileIsDirectory(tryPath)) { - return SystemTools::CollapseFullPath(tryPath); - } - // Couldn't find the file. - return ""; -} - -/** - * Find the executable with the given name. Searches the given path and then - * the system search path. Returns the full path to the executable if it is - * found. Otherwise, the empty string is returned. - */ -std::string SystemTools::FindProgram(const char* nameIn, - const std::vector<std::string>& userPaths, - bool no_system_path) -{ - if (!nameIn || !*nameIn) { - return ""; - } - return SystemTools::FindProgram(std::string(nameIn), userPaths, - no_system_path); -} - -std::string SystemTools::FindProgram(const std::string& name, - const std::vector<std::string>& userPaths, - bool no_system_path) -{ - std::string tryPath; - -#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) - std::vector<std::string> extensions; - // check to see if the name already has a .xxx at - // the end of it - // on windows try .com then .exe - if (name.size() <= 3 || name[name.size() - 4] != '.') { - extensions.emplace_back(".com"); - extensions.emplace_back(".exe"); - - // first try with extensions if the os supports them - for (std::string const& ext : extensions) { - tryPath = name; - tryPath += ext; - if (SystemTools::FileExists(tryPath, true)) { - return SystemTools::CollapseFullPath(tryPath); - } - } - } -#endif - - // now try just the name - if (SystemTools::FileExists(name, true)) { - return SystemTools::CollapseFullPath(name); - } - // now construct the path - std::vector<std::string> path; - // Add the system search path to our path. - if (!no_system_path) { - SystemTools::GetPath(path); - } - // now add the additional paths - path.reserve(path.size() + userPaths.size()); - path.insert(path.end(), userPaths.begin(), userPaths.end()); - // Add a trailing slash to all paths to aid the search process. - for (std::string& p : path) { - if (p.empty() || p.back() != '/') { - p += '/'; - } - } - // Try each path - for (std::string& p : path) { -#ifdef _WIN32 - // Remove double quotes from the path on windows - SystemTools::ReplaceString(p, "\"", ""); -#endif -#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) - // first try with extensions - for (std::string const& ext : extensions) { - tryPath = p; - tryPath += name; - tryPath += ext; - if (SystemTools::FileExists(tryPath, true)) { - return SystemTools::CollapseFullPath(tryPath); - } - } -#endif - // now try it without them - tryPath = p; - tryPath += name; - if (SystemTools::FileExists(tryPath, true)) { - return SystemTools::CollapseFullPath(tryPath); - } - } - // Couldn't find the program. - return ""; -} - -std::string SystemTools::FindProgram(const std::vector<std::string>& names, - const std::vector<std::string>& path, - bool noSystemPath) -{ - for (std::string const& name : names) { - // Try to find the program. - std::string result = SystemTools::FindProgram(name, path, noSystemPath); - if (!result.empty()) { - return result; - } - } - return ""; -} - -/** - * Find the library with the given name. Searches the given path and then - * the system search path. Returns the full path to the library if it is - * found. Otherwise, the empty string is returned. - */ -std::string SystemTools::FindLibrary(const std::string& name, - const std::vector<std::string>& userPaths) -{ - // See if the executable exists as written. - if (SystemTools::FileExists(name, true)) { - return SystemTools::CollapseFullPath(name); - } - - // Add the system search path to our path. - std::vector<std::string> path; - SystemTools::GetPath(path); - // now add the additional paths - path.reserve(path.size() + userPaths.size()); - path.insert(path.end(), userPaths.begin(), userPaths.end()); - // Add a trailing slash to all paths to aid the search process. - for (std::string& p : path) { - if (p.empty() || p.back() != '/') { - p += '/'; - } - } - std::string tryPath; - for (std::string const& p : path) { -#if defined(__APPLE__) - tryPath = p; - tryPath += name; - tryPath += ".framework"; - if (SystemTools::FileIsDirectory(tryPath)) { - return SystemTools::CollapseFullPath(tryPath); - } -#endif -#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__) - tryPath = p; - tryPath += name; - tryPath += ".lib"; - if (SystemTools::FileExists(tryPath, true)) { - return SystemTools::CollapseFullPath(tryPath); - } -#else - tryPath = p; - tryPath += "lib"; - tryPath += name; - tryPath += ".so"; - if (SystemTools::FileExists(tryPath, true)) { - return SystemTools::CollapseFullPath(tryPath); - } - tryPath = p; - tryPath += "lib"; - tryPath += name; - tryPath += ".a"; - if (SystemTools::FileExists(tryPath, true)) { - return SystemTools::CollapseFullPath(tryPath); - } - tryPath = p; - tryPath += "lib"; - tryPath += name; - tryPath += ".sl"; - if (SystemTools::FileExists(tryPath, true)) { - return SystemTools::CollapseFullPath(tryPath); - } - tryPath = p; - tryPath += "lib"; - tryPath += name; - tryPath += ".dylib"; - if (SystemTools::FileExists(tryPath, true)) { - return SystemTools::CollapseFullPath(tryPath); - } - tryPath = p; - tryPath += "lib"; - tryPath += name; - tryPath += ".dll"; - if (SystemTools::FileExists(tryPath, true)) { - return SystemTools::CollapseFullPath(tryPath); - } -#endif - } - - // Couldn't find the library. - return ""; -} - -std::string SystemTools::GetRealPath(const std::string& path, - std::string* errorMessage) -{ - std::string ret; - Realpath(path, ret, errorMessage); - return ret; -} - -bool SystemTools::FileIsDirectory(const std::string& inName) -{ - if (inName.empty()) { - return false; - } - size_t length = inName.size(); - const char* name = inName.c_str(); - - // Remove any trailing slash from the name except in a root component. - char local_buffer[KWSYS_SYSTEMTOOLS_MAXPATH]; - std::string string_buffer; - size_t last = length - 1; - if (last > 0 && (name[last] == '/' || name[last] == '\\') && - strcmp(name, "/") != 0 && name[last - 1] != ':') { - if (last < sizeof(local_buffer)) { - memcpy(local_buffer, name, last); - local_buffer[last] = '\0'; - name = local_buffer; - } else { - string_buffer.append(name, last); - name = string_buffer.c_str(); - } - } - -// Now check the file node type. -#if defined(_WIN32) - DWORD attr = - GetFileAttributesW(Encoding::ToWindowsExtendedPath(name).c_str()); - if (attr != INVALID_FILE_ATTRIBUTES) { - return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0; -#else - struct stat fs; - if (stat(name, &fs) == 0) { - return S_ISDIR(fs.st_mode); -#endif - } else { - return false; - } -} - -bool SystemTools::FileIsSymlink(const std::string& name) -{ -#if defined(_WIN32) - std::wstring path = Encoding::ToWindowsExtendedPath(name); - DWORD attr = GetFileAttributesW(path.c_str()); - if (attr != INVALID_FILE_ATTRIBUTES) { - if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { - // FILE_ATTRIBUTE_REPARSE_POINT means: - // * a file or directory that has an associated reparse point, or - // * a file that is a symbolic link. - HANDLE hFile = CreateFileW( - path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, nullptr); - if (hFile == INVALID_HANDLE_VALUE) { - return false; - } - byte buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - DWORD bytesReturned = 0; - if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, nullptr, 0, buffer, - MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned, - nullptr)) { - CloseHandle(hFile); - // Since FILE_ATTRIBUTE_REPARSE_POINT is set this file must be - // a symbolic link if it is not a reparse point. - return GetLastError() == ERROR_NOT_A_REPARSE_POINT; - } - CloseHandle(hFile); - ULONG reparseTag = - reinterpret_cast<PREPARSE_GUID_DATA_BUFFER>(&buffer[0])->ReparseTag; - return (reparseTag == IO_REPARSE_TAG_SYMLINK) || - (reparseTag == IO_REPARSE_TAG_MOUNT_POINT); - } - return false; - } else { - return false; - } -#else - struct stat fs; - if (lstat(name.c_str(), &fs) == 0) { - return S_ISLNK(fs.st_mode); - } else { - return false; - } -#endif -} - -bool SystemTools::FileIsFIFO(const std::string& name) -{ -#if defined(_WIN32) - HANDLE hFile = - CreateFileW(Encoding::ToWide(name).c_str(), GENERIC_READ, FILE_SHARE_READ, - nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr); - if (hFile == INVALID_HANDLE_VALUE) { - return false; - } - const DWORD type = GetFileType(hFile); - CloseHandle(hFile); - return type == FILE_TYPE_PIPE; -#else - struct stat fs; - if (lstat(name.c_str(), &fs) == 0) { - return S_ISFIFO(fs.st_mode); - } else { - return false; - } -#endif -} - -#if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::CreateSymlink(const std::string&, const std::string&) -{ - return false; -} -#else -bool SystemTools::CreateSymlink(const std::string& origName, - const std::string& newName) -{ - return symlink(origName.c_str(), newName.c_str()) >= 0; -} -#endif - -#if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::ReadSymlink(const std::string&, std::string&) -{ - return false; -} -#else -bool SystemTools::ReadSymlink(const std::string& newName, - std::string& origName) -{ - char buf[KWSYS_SYSTEMTOOLS_MAXPATH + 1]; - int count = static_cast<int>( - readlink(newName.c_str(), buf, KWSYS_SYSTEMTOOLS_MAXPATH)); - if (count >= 0) { - // Add null-terminator. - buf[count] = 0; - origName = buf; - return true; - } else { - return false; - } -} -#endif - -int SystemTools::ChangeDirectory(const std::string& dir) -{ - return Chdir(dir); -} - -std::string SystemTools::GetCurrentWorkingDirectory(bool collapse) -{ - char buf[2048]; - const char* cwd = Getcwd(buf, 2048); - std::string path; - if (cwd) { - path = cwd; - } - if (collapse) { - return SystemTools::CollapseFullPath(path); - } - return path; -} - -std::string SystemTools::GetProgramPath(const std::string& in_name) -{ - std::string dir, file; - SystemTools::SplitProgramPath(in_name, dir, file); - return dir; -} - -bool SystemTools::SplitProgramPath(const std::string& in_name, - std::string& dir, std::string& file, bool) -{ - dir = in_name; - file = ""; - SystemTools::ConvertToUnixSlashes(dir); - - if (!SystemTools::FileIsDirectory(dir)) { - std::string::size_type slashPos = dir.rfind("/"); - if (slashPos != std::string::npos) { - file = dir.substr(slashPos + 1); - dir = dir.substr(0, slashPos); - } else { - file = dir; - dir = ""; - } - } - if (!(dir.empty()) && !SystemTools::FileIsDirectory(dir)) { - std::string oldDir = in_name; - SystemTools::ConvertToUnixSlashes(oldDir); - dir = in_name; - return false; - } - return true; -} - -bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut, - std::string& errorMsg, const char* exeName, - const char* buildDir, - const char* installPrefix) -{ - std::vector<std::string> failures; - std::string self = argv0 ? argv0 : ""; - failures.push_back(self); - SystemTools::ConvertToUnixSlashes(self); - self = SystemTools::FindProgram(self); - if (!SystemTools::FileExists(self)) { - if (buildDir) { - std::string intdir = "."; -#ifdef CMAKE_INTDIR - intdir = CMAKE_INTDIR; -#endif - self = buildDir; - self += "/bin/"; - self += intdir; - self += "/"; - self += exeName; - self += SystemTools::GetExecutableExtension(); - } - } - if (installPrefix) { - if (!SystemTools::FileExists(self)) { - failures.push_back(self); - self = installPrefix; - self += "/bin/"; - self += exeName; - } - } - if (!SystemTools::FileExists(self)) { - failures.push_back(self); - std::ostringstream msg; - msg << "Can not find the command line program "; - if (exeName) { - msg << exeName; - } - msg << "\n"; - if (argv0) { - msg << " argv[0] = \"" << argv0 << "\"\n"; - } - msg << " Attempted paths:\n"; - for (std::string const& ff : failures) { - msg << " \"" << ff << "\"\n"; - } - errorMsg = msg.str(); - return false; - } - pathOut = self; - return true; -} - -std::string SystemTools::CollapseFullPath(const std::string& in_relative) -{ - return SystemTools::CollapseFullPath(in_relative, nullptr); -} - -#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP -void SystemTools::AddTranslationPath(const std::string& a, - const std::string& b) -{ - std::string path_a = a; - std::string path_b = b; - SystemTools::ConvertToUnixSlashes(path_a); - SystemTools::ConvertToUnixSlashes(path_b); - // First check this is a directory path, since we don't want the table to - // grow too fat - if (SystemTools::FileIsDirectory(path_a)) { - // Make sure the path is a full path and does not contain no '..' - // Ken--the following code is incorrect. .. can be in a valid path - // for example /home/martink/MyHubba...Hubba/Src - if (SystemTools::FileIsFullPath(path_b) && - path_b.find("..") == std::string::npos) { - // Before inserting make sure path ends with '/' - if (!path_a.empty() && path_a.back() != '/') { - path_a += '/'; - } - if (!path_b.empty() && path_b.back() != '/') { - path_b += '/'; - } - if (!(path_a == path_b)) { - SystemTools::Statics->TranslationMap.insert( - SystemToolsStatic::StringMap::value_type(std::move(path_a), - std::move(path_b))); - } - } - } -} - -void SystemTools::AddKeepPath(const std::string& dir) -{ - std::string cdir; - Realpath(SystemTools::CollapseFullPath(dir), cdir); - SystemTools::AddTranslationPath(cdir, dir); -} - -void SystemTools::CheckTranslationPath(std::string& path) -{ - // Do not translate paths that are too short to have meaningful - // translations. - if (path.size() < 2) { - return; - } - - // Always add a trailing slash before translation. It does not - // matter if this adds an extra slash, but we do not want to - // translate part of a directory (like the foo part of foo-dir). - path += '/'; - - // In case a file was specified we still have to go through this: - // Now convert any path found in the table back to the one desired: - for (auto const& pair : SystemTools::Statics->TranslationMap) { - // We need to check of the path is a substring of the other path - if (path.find(pair.first) == 0) { - path = path.replace(0, pair.first.size(), pair.second); - } - } - - // Remove the trailing slash we added before. - path.pop_back(); -} -#endif - -static void SystemToolsAppendComponents( - std::vector<std::string>& out_components, - std::vector<std::string>::iterator first, - std::vector<std::string>::iterator last) -{ - static const std::string up = ".."; - static const std::string cur = "."; - for (std::vector<std::string>::const_iterator i = first; i != last; ++i) { - if (*i == up) { - // Remove the previous component if possible. Ignore ../ components - // that try to go above the root. Keep ../ components if they are - // at the beginning of a relative path (base path is relative). - if (out_components.size() > 1 && out_components.back() != up) { - out_components.resize(out_components.size() - 1); - } else if (!out_components.empty() && out_components[0].empty()) { - out_components.emplace_back(std::move(*i)); - } - } else if (!i->empty() && *i != cur) { - out_components.emplace_back(std::move(*i)); - } - } -} - -std::string SystemTools::CollapseFullPath(const std::string& in_path, - const char* in_base) -{ - // Use the current working directory as a base path. - char buf[2048]; - const char* res_in_base = in_base; - if (!res_in_base) { - if (const char* cwd = Getcwd(buf, 2048)) { - res_in_base = cwd; - } else { - res_in_base = ""; - } - } - - return SystemTools::CollapseFullPath(in_path, std::string(res_in_base)); -} - -std::string SystemTools::CollapseFullPath(const std::string& in_path, - const std::string& in_base) -{ - // Collect the output path components. - std::vector<std::string> out_components; - - // Split the input path components. - std::vector<std::string> path_components; - SystemTools::SplitPath(in_path, path_components); - out_components.reserve(path_components.size()); - - // If the input path is relative, start with a base path. - if (path_components[0].empty()) { - std::vector<std::string> base_components; - // Use the given base path. - SystemTools::SplitPath(in_base, base_components); - - // Append base path components to the output path. - out_components.push_back(base_components[0]); - SystemToolsAppendComponents(out_components, base_components.begin() + 1, - base_components.end()); - } - - // Append input path components to the output path. - SystemToolsAppendComponents(out_components, path_components.begin(), - path_components.end()); - - // Transform the path back to a string. - std::string newPath = SystemTools::JoinPath(out_components); - -#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP - // Update the translation table with this potentially new path. I am not - // sure why this line is here, it seems really questionable, but yet I - // would put good money that if I remove it something will break, basically - // from what I can see it created a mapping from the collapsed path, to be - // replaced by the input path, which almost completely does the opposite of - // this function, the only thing preventing this from happening a lot is - // that if the in_path has a .. in it, then it is not added to the - // translation table. So for most calls this either does nothing due to the - // .. or it adds a translation between identical paths as nothing was - // collapsed, so I am going to try to comment it out, and see what hits the - // fan, hopefully quickly. - // Commented out line below: - // SystemTools::AddTranslationPath(newPath, in_path); - - SystemTools::CheckTranslationPath(newPath); -#endif -#ifdef _WIN32 - newPath = SystemTools::Statics->GetActualCaseForPathCached(newPath); - SystemTools::ConvertToUnixSlashes(newPath); -#endif - // Return the reconstructed path. - return newPath; -} - -// compute the relative path from here to there -std::string SystemTools::RelativePath(const std::string& local, - const std::string& remote) -{ - if (!SystemTools::FileIsFullPath(local)) { - return ""; - } - if (!SystemTools::FileIsFullPath(remote)) { - return ""; - } - - std::string l = SystemTools::CollapseFullPath(local); - std::string r = SystemTools::CollapseFullPath(remote); - - // split up both paths into arrays of strings using / as a separator - std::vector<std::string> localSplit = SystemTools::SplitString(l, '/', true); - std::vector<std::string> remoteSplit = - SystemTools::SplitString(r, '/', true); - std::vector<std::string> - commonPath; // store shared parts of path in this array - std::vector<std::string> finalPath; // store the final relative path here - // count up how many matching directory names there are from the start - unsigned int sameCount = 0; - while (((sameCount <= (localSplit.size() - 1)) && - (sameCount <= (remoteSplit.size() - 1))) && -// for Windows and Apple do a case insensitive string compare -#if defined(_WIN32) || defined(__APPLE__) - SystemTools::Strucmp(localSplit[sameCount].c_str(), - remoteSplit[sameCount].c_str()) == 0 -#else - localSplit[sameCount] == remoteSplit[sameCount] -#endif - ) { - // put the common parts of the path into the commonPath array - commonPath.push_back(localSplit[sameCount]); - // erase the common parts of the path from the original path arrays - localSplit[sameCount] = ""; - remoteSplit[sameCount] = ""; - sameCount++; - } - - // If there is nothing in common at all then just return the full - // path. This is the case only on windows when the paths have - // different drive letters. On unix two full paths always at least - // have the root "/" in common so we will return a relative path - // that passes through the root directory. - if (sameCount == 0) { - return remote; - } - - // for each entry that is not common in the local path - // add a ../ to the finalpath array, this gets us out of the local - // path into the remote dir - for (std::string const& lp : localSplit) { - if (!lp.empty()) { - finalPath.emplace_back("../"); - } - } - // for each entry that is not common in the remote path add it - // to the final path. - for (std::string const& rp : remoteSplit) { - if (!rp.empty()) { - finalPath.push_back(rp); - } - } - std::string relativePath; // result string - // now turn the array of directories into a unix path by puttint / - // between each entry that does not already have one - for (std::string const& fp : finalPath) { - if (!relativePath.empty() && relativePath.back() != '/') { - relativePath += '/'; - } - relativePath += fp; - } - return relativePath; -} - -std::string SystemTools::GetActualCaseForPath(const std::string& p) -{ -#ifdef _WIN32 - return SystemToolsStatic::GetCasePathName(p); -#else - return p; -#endif -} - -const char* SystemTools::SplitPathRootComponent(const std::string& p, - std::string* root) -{ - // Identify the root component. - const char* c = p.c_str(); - if ((c[0] == '/' && c[1] == '/') || (c[0] == '\\' && c[1] == '\\')) { - // Network path. - if (root) { - *root = "//"; - } - c += 2; - } else if (c[0] == '/' || c[0] == '\\') { - // Unix path (or Windows path w/out drive letter). - if (root) { - *root = "/"; - } - c += 1; - } else if (c[0] && c[1] == ':' && (c[2] == '/' || c[2] == '\\')) { - // Windows path. - if (root) { - (*root) = "_:/"; - (*root)[0] = c[0]; - } - c += 3; - } else if (c[0] && c[1] == ':') { - // Path relative to a windows drive working directory. - if (root) { - (*root) = "_:"; - (*root)[0] = c[0]; - } - c += 2; - } else if (c[0] == '~') { - // Home directory. The returned root should always have a - // trailing slash so that appending components as - // c[0]c[1]/c[2]/... works. The remaining path returned should - // skip the first slash if it exists: - // - // "~" : root = "~/" , return "" - // "~/ : root = "~/" , return "" - // "~/x : root = "~/" , return "x" - // "~u" : root = "~u/", return "" - // "~u/" : root = "~u/", return "" - // "~u/x" : root = "~u/", return "x" - size_t n = 1; - while (c[n] && c[n] != '/') { - ++n; - } - if (root) { - root->assign(c, n); - *root += '/'; - } - if (c[n] == '/') { - ++n; - } - c += n; - } else { - // Relative path. - if (root) { - *root = ""; - } - } - - // Return the remaining path. - return c; -} - -void SystemTools::SplitPath(const std::string& p, - std::vector<std::string>& components, - bool expand_home_dir) -{ - const char* c; - components.clear(); - - // Identify the root component. - { - std::string root; - c = SystemTools::SplitPathRootComponent(p, &root); - - // Expand home directory references if requested. - if (expand_home_dir && !root.empty() && root[0] == '~') { - std::string homedir; - root = root.substr(0, root.size() - 1); - if (root.size() == 1) { -#if defined(_WIN32) && !defined(__CYGWIN__) - if (!SystemTools::GetEnv("USERPROFILE", homedir)) -#endif - SystemTools::GetEnv("HOME", homedir); - } -#ifdef HAVE_GETPWNAM - else if (passwd* pw = getpwnam(root.c_str() + 1)) { - if (pw->pw_dir) { - homedir = pw->pw_dir; - } - } -#endif - if (!homedir.empty() && - (homedir.back() == '/' || homedir.back() == '\\')) { - homedir.resize(homedir.size() - 1); - } - SystemTools::SplitPath(homedir, components); - } else { - components.push_back(root); - } - } - - // Parse the remaining components. - const char* first = c; - const char* last = first; - for (; *last; ++last) { - if (*last == '/' || *last == '\\') { - // End of a component. Save it. - components.push_back(std::string(first, last)); - first = last + 1; - } - } - - // Save the last component unless there were no components. - if (last != c) { - components.push_back(std::string(first, last)); - } -} - -std::string SystemTools::JoinPath(const std::vector<std::string>& components) -{ - return SystemTools::JoinPath(components.begin(), components.end()); -} - -std::string SystemTools::JoinPath( - std::vector<std::string>::const_iterator first, - std::vector<std::string>::const_iterator last) -{ - // Construct result in a single string. - std::string result; - size_t len = 0; - for (std::vector<std::string>::const_iterator i = first; i != last; ++i) { - len += 1 + i->size(); - } - result.reserve(len); - - // The first two components do not add a slash. - if (first != last) { - result.append(*first++); - } - if (first != last) { - result.append(*first++); - } - - // All remaining components are always separated with a slash. - while (first != last) { - result.push_back('/'); - result.append((*first++)); - } - - // Return the concatenated result. - return result; -} - -bool SystemTools::ComparePath(const std::string& c1, const std::string& c2) -{ -#if defined(_WIN32) || defined(__APPLE__) -# ifdef _MSC_VER - return _stricmp(c1.c_str(), c2.c_str()) == 0; -# elif defined(__APPLE__) || defined(__GNUC__) - return strcasecmp(c1.c_str(), c2.c_str()) == 0; -# else - return SystemTools::Strucmp(c1.c_str(), c2.c_str()) == 0; -# endif -#else - return c1 == c2; -#endif -} - -bool SystemTools::Split(const std::string& str, - std::vector<std::string>& lines, char separator) -{ - std::string data(str); - std::string::size_type lpos = 0; - while (lpos < data.length()) { - std::string::size_type rpos = data.find_first_of(separator, lpos); - if (rpos == std::string::npos) { - // String ends at end of string without a separator. - lines.push_back(data.substr(lpos)); - return false; - } else { - // String ends in a separator, remove the character. - lines.push_back(data.substr(lpos, rpos - lpos)); - } - lpos = rpos + 1; - } - return true; -} - -bool SystemTools::Split(const std::string& str, - std::vector<std::string>& lines) -{ - std::string data(str); - std::string::size_type lpos = 0; - while (lpos < data.length()) { - std::string::size_type rpos = data.find_first_of('\n', lpos); - if (rpos == std::string::npos) { - // Line ends at end of string without a newline. - lines.push_back(data.substr(lpos)); - return false; - } - if ((rpos > lpos) && (data[rpos - 1] == '\r')) { - // Line ends in a "\r\n" pair, remove both characters. - lines.push_back(data.substr(lpos, (rpos - 1) - lpos)); - } else { - // Line ends in a "\n", remove the character. - lines.push_back(data.substr(lpos, rpos - lpos)); - } - lpos = rpos + 1; - } - return true; -} - -/** - * Return path of a full filename (no trailing slashes). - * Warning: returned path is converted to Unix slashes format. - */ -std::string SystemTools::GetFilenamePath(const std::string& filename) -{ - std::string fn = filename; - SystemTools::ConvertToUnixSlashes(fn); - - std::string::size_type slash_pos = fn.rfind("/"); - if (slash_pos != std::string::npos) { - std::string ret = fn.substr(0, slash_pos); - if (ret.size() == 2 && ret[1] == ':') { - return ret + '/'; - } - if (ret.empty()) { - return "/"; - } - return ret; - } else { - return ""; - } -} - -/** - * Return file name of a full filename (i.e. file name without path). - */ -std::string SystemTools::GetFilenameName(const std::string& filename) -{ -#if defined(_WIN32) || defined(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES) - const char* separators = "/\\"; -#else - char separators = '/'; -#endif - std::string::size_type slash_pos = filename.find_last_of(separators); - if (slash_pos != std::string::npos) { - return filename.substr(slash_pos + 1); - } else { - return filename; - } -} - -/** - * Return file extension of a full filename (dot included). - * Warning: this is the longest extension (for example: .tar.gz) - */ -std::string SystemTools::GetFilenameExtension(const std::string& filename) -{ - std::string name = SystemTools::GetFilenameName(filename); - std::string::size_type dot_pos = name.find('.'); - if (dot_pos != std::string::npos) { - return name.substr(dot_pos); - } else { - return ""; - } -} - -/** - * Return file extension of a full filename (dot included). - * Warning: this is the shortest extension (for example: .gz of .tar.gz) - */ -std::string SystemTools::GetFilenameLastExtension(const std::string& filename) -{ - std::string name = SystemTools::GetFilenameName(filename); - std::string::size_type dot_pos = name.rfind('.'); - if (dot_pos != std::string::npos) { - return name.substr(dot_pos); - } else { - return ""; - } -} - -/** - * Return file name without extension of a full filename (i.e. without path). - * Warning: it considers the longest extension (for example: .tar.gz) - */ -std::string SystemTools::GetFilenameWithoutExtension( - const std::string& filename) -{ - std::string name = SystemTools::GetFilenameName(filename); - std::string::size_type dot_pos = name.find('.'); - if (dot_pos != std::string::npos) { - return name.substr(0, dot_pos); - } else { - return name; - } -} - -/** - * Return file name without extension of a full filename (i.e. without path). - * Warning: it considers the last extension (for example: removes .gz - * from .tar.gz) - */ -std::string SystemTools::GetFilenameWithoutLastExtension( - const std::string& filename) -{ - std::string name = SystemTools::GetFilenameName(filename); - std::string::size_type dot_pos = name.rfind('.'); - if (dot_pos != std::string::npos) { - return name.substr(0, dot_pos); - } else { - return name; - } -} - -bool SystemTools::FileHasSignature(const char* filename, const char* signature, - long offset) -{ - if (!filename || !signature) { - return false; - } - - FILE* fp = Fopen(filename, "rb"); - if (!fp) { - return false; - } - - fseek(fp, offset, SEEK_SET); - - bool res = false; - size_t signature_len = strlen(signature); - char* buffer = new char[signature_len]; - - if (fread(buffer, 1, signature_len, fp) == signature_len) { - res = (!strncmp(buffer, signature, signature_len) ? true : false); - } - - delete[] buffer; - - fclose(fp); - return res; -} - -SystemTools::FileTypeEnum SystemTools::DetectFileType(const char* filename, - unsigned long length, - double percent_bin) -{ - if (!filename || percent_bin < 0) { - return SystemTools::FileTypeUnknown; - } - - if (SystemTools::FileIsDirectory(filename)) { - return SystemTools::FileTypeUnknown; - } - - FILE* fp = Fopen(filename, "rb"); - if (!fp) { - return SystemTools::FileTypeUnknown; - } - - // Allocate buffer and read bytes - - unsigned char* buffer = new unsigned char[length]; - size_t read_length = fread(buffer, 1, length, fp); - fclose(fp); - if (read_length == 0) { - delete[] buffer; - return SystemTools::FileTypeUnknown; - } - - // Loop over contents and count - - size_t text_count = 0; - - const unsigned char* ptr = buffer; - const unsigned char* buffer_end = buffer + read_length; - - while (ptr != buffer_end) { - if ((*ptr >= 0x20 && *ptr <= 0x7F) || *ptr == '\n' || *ptr == '\r' || - *ptr == '\t') { - text_count++; - } - ptr++; - } - - delete[] buffer; - - double current_percent_bin = (static_cast<double>(read_length - text_count) / - static_cast<double>(read_length)); - - if (current_percent_bin >= percent_bin) { - return SystemTools::FileTypeBinary; - } - - return SystemTools::FileTypeText; -} - -bool SystemTools::LocateFileInDir(const char* filename, const char* dir, - std::string& filename_found, - int try_filename_dirs) -{ - if (!filename || !dir) { - return false; - } - - // Get the basename of 'filename' - - std::string filename_base = SystemTools::GetFilenameName(filename); - - // Check if 'dir' is really a directory - // If win32 and matches something like C:, accept it as a dir - - std::string real_dir; - if (!SystemTools::FileIsDirectory(dir)) { -#if defined(_WIN32) - size_t dir_len = strlen(dir); - if (dir_len < 2 || dir[dir_len - 1] != ':') { -#endif - real_dir = SystemTools::GetFilenamePath(dir); - dir = real_dir.c_str(); -#if defined(_WIN32) - } -#endif - } - - // Try to find the file in 'dir' - - bool res = false; - if (!filename_base.empty() && dir) { - size_t dir_len = strlen(dir); - int need_slash = - (dir_len && dir[dir_len - 1] != '/' && dir[dir_len - 1] != '\\'); - - std::string temp = dir; - if (need_slash) { - temp += "/"; - } - temp += filename_base; - - if (SystemTools::FileExists(temp)) { - res = true; - filename_found = temp; - } - - // If not found, we can try harder by appending part of the file to - // to the directory to look inside. - // Example: if we were looking for /foo/bar/yo.txt in /d1/d2, then - // try to find yo.txt in /d1/d2/bar, then /d1/d2/foo/bar, etc. - - else if (try_filename_dirs) { - std::string filename_dir(filename); - std::string filename_dir_base; - std::string filename_dir_bases; - do { - filename_dir = SystemTools::GetFilenamePath(filename_dir); - filename_dir_base = SystemTools::GetFilenameName(filename_dir); -#if defined(_WIN32) - if (filename_dir_base.empty() || filename_dir_base.back() == ':') -#else - if (filename_dir_base.empty()) -#endif - { - break; - } - - filename_dir_bases = filename_dir_base + "/" + filename_dir_bases; - - temp = dir; - if (need_slash) { - temp += "/"; - } - temp += filename_dir_bases; - - res = SystemTools::LocateFileInDir(filename_base.c_str(), temp.c_str(), - filename_found, 0); - - } while (!res && !filename_dir_base.empty()); - } - } - - return res; -} - -bool SystemTools::FileIsFullPath(const std::string& in_name) -{ - return SystemToolsStatic::FileIsFullPath(in_name.c_str(), in_name.size()); -} - -bool SystemTools::FileIsFullPath(const char* in_name) -{ - return SystemToolsStatic::FileIsFullPath( - in_name, in_name[0] ? (in_name[1] ? 2 : 1) : 0); -} - -bool SystemToolsStatic::FileIsFullPath(const char* in_name, size_t len) -{ -#if defined(_WIN32) || defined(__CYGWIN__) - // On Windows, the name must be at least two characters long. - if (len < 2) { - return false; - } - if (in_name[1] == ':') { - return true; - } - if (in_name[0] == '\\') { - return true; - } -#else - // On UNIX, the name must be at least one character long. - if (len < 1) { - return false; - } -#endif -#if !defined(_WIN32) - if (in_name[0] == '~') { - return true; - } -#endif - // On UNIX, the name must begin in a '/'. - // On Windows, if the name begins in a '/', then it is a full - // network path. - if (in_name[0] == '/') { - return true; - } - return false; -} - -bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - std::string tempPath = path; // create a buffer - - // if the path passed in has quotes around it, first remove the quotes - if (!path.empty() && path[0] == '"' && path.back() == '"') { - tempPath = path.substr(1, path.length() - 2); - } - - std::wstring wtempPath = Encoding::ToWide(tempPath); - DWORD ret = GetShortPathNameW(wtempPath.c_str(), nullptr, 0); - std::vector<wchar_t> buffer(ret); - if (ret != 0) { - ret = GetShortPathNameW(wtempPath.c_str(), &buffer[0], - static_cast<DWORD>(buffer.size())); - } - - if (ret == 0) { - return false; - } else { - shortPath = Encoding::ToNarrow(&buffer[0]); - return true; - } -#else - shortPath = path; - return true; -#endif -} - -std::string SystemTools::GetCurrentDateTime(const char* format) -{ - char buf[1024]; - time_t t; - time(&t); - strftime(buf, sizeof(buf), format, localtime(&t)); - return std::string(buf); -} - -std::string SystemTools::MakeCidentifier(const std::string& s) -{ - std::string str(s); - if (str.find_first_of("0123456789") == 0) { - str = "_" + str; - } - - std::string permited_chars("_" - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"); - std::string::size_type pos = 0; - while ((pos = str.find_first_not_of(permited_chars, pos)) != - std::string::npos) { - str[pos] = '_'; - } - return str; -} - -// Convenience function around std::getline which removes a trailing carriage -// return and can truncate the buffer as needed. Returns true -// if any data were read before the end-of-file was reached. -bool SystemTools::GetLineFromStream(std::istream& is, std::string& line, - bool* has_newline /* = 0 */, - long sizeLimit /* = -1 */) -{ - // Start with an empty line. - line = ""; - - // Early short circuit return if stream is no good. Just return - // false and the empty line. (Probably means caller tried to - // create a file stream with a non-existent file name...) - // - if (!is) { - if (has_newline) { - *has_newline = false; - } - return false; - } - - std::getline(is, line); - bool haveData = !line.empty() || !is.eof(); - if (!line.empty()) { - // Avoid storing a carriage return character. - if (line.back() == '\r') { - line.resize(line.size() - 1); - } - - // if we read too much then truncate the buffer - if (sizeLimit >= 0 && line.size() >= static_cast<size_t>(sizeLimit)) { - line.resize(sizeLimit); - } - } - - // Return the results. - if (has_newline) { - *has_newline = !is.eof(); - } - return haveData; -} - -int SystemTools::GetTerminalWidth() -{ - int width = -1; -#ifdef HAVE_TTY_INFO - struct winsize ws; - std::string columns; /* Unix98 environment variable */ - if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col > 0 && ws.ws_row > 0) { - width = ws.ws_col; - } - if (!isatty(STDOUT_FILENO)) { - width = -1; - } - if (SystemTools::GetEnv("COLUMNS", columns) && !columns.empty()) { - long t; - char* endptr; - t = strtol(columns.c_str(), &endptr, 0); - if (endptr && !*endptr && (t > 0) && (t < 1000)) { - width = static_cast<int>(t); - } - } - if (width < 9) { - width = -1; - } -#endif - return width; -} - -bool SystemTools::GetPermissions(const char* file, mode_t& mode) -{ - if (!file) { - return false; - } - return SystemTools::GetPermissions(std::string(file), mode); -} - -bool SystemTools::GetPermissions(const std::string& file, mode_t& mode) -{ -#if defined(_WIN32) - DWORD attr = - GetFileAttributesW(Encoding::ToWindowsExtendedPath(file).c_str()); - if (attr == INVALID_FILE_ATTRIBUTES) { - return false; - } - if ((attr & FILE_ATTRIBUTE_READONLY) != 0) { - mode = (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6)); - } else { - mode = (_S_IWRITE | (_S_IWRITE >> 3) | (_S_IWRITE >> 6)) | - (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6)); - } - if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { - mode |= S_IFDIR | (_S_IEXEC | (_S_IEXEC >> 3) | (_S_IEXEC >> 6)); - } else { - mode |= S_IFREG; - } - size_t dotPos = file.rfind('.'); - const char* ext = dotPos == std::string::npos ? 0 : (file.c_str() + dotPos); - if (ext && - (Strucmp(ext, ".exe") == 0 || Strucmp(ext, ".com") == 0 || - Strucmp(ext, ".cmd") == 0 || Strucmp(ext, ".bat") == 0)) { - mode |= (_S_IEXEC | (_S_IEXEC >> 3) | (_S_IEXEC >> 6)); - } -#else - struct stat st; - if (stat(file.c_str(), &st) < 0) { - return false; - } - mode = st.st_mode; -#endif - return true; -} - -bool SystemTools::SetPermissions(const char* file, mode_t mode, - bool honor_umask) -{ - if (!file) { - return false; - } - return SystemTools::SetPermissions(std::string(file), mode, honor_umask); -} - -bool SystemTools::SetPermissions(const std::string& file, mode_t mode, - bool honor_umask) -{ - if (!SystemTools::PathExists(file)) { - return false; - } - if (honor_umask) { - mode_t currentMask = umask(0); - umask(currentMask); - mode &= ~currentMask; - } -#ifdef _WIN32 - if (_wchmod(Encoding::ToWindowsExtendedPath(file).c_str(), mode) < 0) -#else - if (chmod(file.c_str(), mode) < 0) -#endif - { - return false; - } - - return true; -} - -std::string SystemTools::GetParentDirectory(const std::string& fileOrDir) -{ - return SystemTools::GetFilenamePath(fileOrDir); -} - -bool SystemTools::IsSubDirectory(const std::string& cSubdir, - const std::string& cDir) -{ - if (cDir.empty()) { - return false; - } - std::string subdir = cSubdir; - std::string dir = cDir; - SystemTools::ConvertToUnixSlashes(subdir); - SystemTools::ConvertToUnixSlashes(dir); - if (subdir.size() <= dir.size() || dir.empty()) { - return false; - } - bool isRootPath = dir.back() == '/'; // like "/" or "C:/" - size_t expectedSlashPosition = isRootPath ? dir.size() - 1u : dir.size(); - if (subdir[expectedSlashPosition] != '/') { - return false; - } - std::string s = subdir.substr(0, dir.size()); - return SystemTools::ComparePath(s, dir); -} - -void SystemTools::Delay(unsigned int msec) -{ -#ifdef _WIN32 - Sleep(msec); -#else - // The sleep function gives 1 second resolution and the usleep - // function gives 1e-6 second resolution but on some platforms has a - // maximum sleep time of 1 second. This could be re-implemented to - // use select with masked signals or pselect to mask signals - // atomically. If select is given empty sets and zero as the max - // file descriptor but a non-zero timeout it can be used to block - // for a precise amount of time. - if (msec >= 1000) { - sleep(msec / 1000); - usleep((msec % 1000) * 1000); - } else { - usleep(msec * 1000); - } -#endif -} - -std::string SystemTools::GetOperatingSystemNameAndVersion() -{ - std::string res; - -#ifdef _WIN32 - char buffer[256]; - - OSVERSIONINFOEXA osvi; - BOOL bOsVersionInfoEx; - - ZeroMemory(&osvi, sizeof(osvi)); - osvi.dwOSVersionInfoSize = sizeof(osvi); - -# ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx -# pragma warning(push) -# ifdef __INTEL_COMPILER -# pragma warning(disable : 1478) -# elif defined __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" -# else -# pragma warning(disable : 4996) -# endif -# endif - bOsVersionInfoEx = GetVersionExA((OSVERSIONINFOA*)&osvi); - if (!bOsVersionInfoEx) { - return 0; - } -# ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx -# ifdef __clang__ -# pragma clang diagnostic pop -# else -# pragma warning(pop) -# endif -# endif - - switch (osvi.dwPlatformId) { - // Test for the Windows NT product family. - - case VER_PLATFORM_WIN32_NT: - - // Test for the specific product family. - if (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - res += "Microsoft Windows 10"; - } else { - res += "Microsoft Windows Server 2016 family"; - } - } - - if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 3) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - res += "Microsoft Windows 8.1"; - } else { - res += "Microsoft Windows Server 2012 R2 family"; - } - } - - if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - res += "Microsoft Windows 8"; - } else { - res += "Microsoft Windows Server 2012 family"; - } - } - - if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - res += "Microsoft Windows 7"; - } else { - res += "Microsoft Windows Server 2008 R2 family"; - } - } - - if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - res += "Microsoft Windows Vista"; - } else { - res += "Microsoft Windows Server 2008 family"; - } - } - - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) { - res += "Microsoft Windows Server 2003 family"; - } - - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) { - res += "Microsoft Windows XP"; - } - - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) { - res += "Microsoft Windows 2000"; - } - - if (osvi.dwMajorVersion <= 4) { - res += "Microsoft Windows NT"; - } - - // Test for specific product on Windows NT 4.0 SP6 and later. - - if (bOsVersionInfoEx) { - // Test for the workstation type. - - if (osvi.wProductType == VER_NT_WORKSTATION) { - if (osvi.dwMajorVersion == 4) { - res += " Workstation 4.0"; - } else if (osvi.dwMajorVersion == 5) { - if (osvi.wSuiteMask & VER_SUITE_PERSONAL) { - res += " Home Edition"; - } else { - res += " Professional"; - } - } - } - - // Test for the server type. - - else if (osvi.wProductType == VER_NT_SERVER) { - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) { - if (osvi.wSuiteMask & VER_SUITE_DATACENTER) { - res += " Datacenter Edition"; - } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) { - res += " Enterprise Edition"; - } else if (osvi.wSuiteMask == VER_SUITE_BLADE) { - res += " Web Edition"; - } else { - res += " Standard Edition"; - } - } - - else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) { - if (osvi.wSuiteMask & VER_SUITE_DATACENTER) { - res += " Datacenter Server"; - } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) { - res += " Advanced Server"; - } else { - res += " Server"; - } - } - - else if (osvi.dwMajorVersion <= 4) // Windows NT 4.0 - { - if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) { - res += " Server 4.0, Enterprise Edition"; - } else { - res += " Server 4.0"; - } - } - } - } - - // Test for specific product on Windows NT 4.0 SP5 and earlier - - else { - HKEY hKey; -# define BUFSIZE 80 - wchar_t szProductType[BUFSIZE]; - DWORD dwBufLen = BUFSIZE; - LONG lRet; - - lRet = - RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", - 0, KEY_QUERY_VALUE, &hKey); - if (lRet != ERROR_SUCCESS) { - return 0; - } - - lRet = RegQueryValueExW(hKey, L"ProductType", nullptr, nullptr, - (LPBYTE)szProductType, &dwBufLen); - - if ((lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE)) { - return 0; - } - - RegCloseKey(hKey); - - if (lstrcmpiW(L"WINNT", szProductType) == 0) { - res += " Workstation"; - } - if (lstrcmpiW(L"LANMANNT", szProductType) == 0) { - res += " Server"; - } - if (lstrcmpiW(L"SERVERNT", szProductType) == 0) { - res += " Advanced Server"; - } - - res += " "; - sprintf(buffer, "%ld", osvi.dwMajorVersion); - res += buffer; - res += "."; - sprintf(buffer, "%ld", osvi.dwMinorVersion); - res += buffer; - } - - // Display service pack (if any) and build number. - - if (osvi.dwMajorVersion == 4 && - lstrcmpiA(osvi.szCSDVersion, "Service Pack 6") == 0) { - HKEY hKey; - LONG lRet; - - // Test for SP6 versus SP6a. - - lRet = RegOpenKeyExW( - HKEY_LOCAL_MACHINE, - L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009", - 0, KEY_QUERY_VALUE, &hKey); - - if (lRet == ERROR_SUCCESS) { - res += " Service Pack 6a (Build "; - sprintf(buffer, "%ld", osvi.dwBuildNumber & 0xFFFF); - res += buffer; - res += ")"; - } else // Windows NT 4.0 prior to SP6a - { - res += " "; - res += osvi.szCSDVersion; - res += " (Build "; - sprintf(buffer, "%ld", osvi.dwBuildNumber & 0xFFFF); - res += buffer; - res += ")"; - } - - RegCloseKey(hKey); - } else // Windows NT 3.51 and earlier or Windows 2000 and later - { - res += " "; - res += osvi.szCSDVersion; - res += " (Build "; - sprintf(buffer, "%ld", osvi.dwBuildNumber & 0xFFFF); - res += buffer; - res += ")"; - } - - break; - - // Test for the Windows 95 product family. - - case VER_PLATFORM_WIN32_WINDOWS: - - if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) { - res += "Microsoft Windows 95"; - if (osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B') { - res += " OSR2"; - } - } - - if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) { - res += "Microsoft Windows 98"; - if (osvi.szCSDVersion[1] == 'A') { - res += " SE"; - } - } - - if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) { - res += "Microsoft Windows Millennium Edition"; - } - break; - - case VER_PLATFORM_WIN32s: - - res += "Microsoft Win32s"; - break; - } -#endif - - return res; -} - -bool SystemTools::ParseURLProtocol(const std::string& URL, - std::string& protocol, - std::string& dataglom) -{ - // match 0 entire url - // match 1 protocol - // match 2 dataglom following protocol:// - kwsys::RegularExpression urlRe(VTK_URL_PROTOCOL_REGEX); - - if (!urlRe.find(URL)) - return false; - - protocol = urlRe.match(1); - dataglom = urlRe.match(2); - - return true; -} - -bool SystemTools::ParseURL(const std::string& URL, std::string& protocol, - std::string& username, std::string& password, - std::string& hostname, std::string& dataport, - std::string& database) -{ - kwsys::RegularExpression urlRe(VTK_URL_REGEX); - if (!urlRe.find(URL)) - return false; - - // match 0 URL - // match 1 protocol - // match 2 mangled user - // match 3 username - // match 4 mangled password - // match 5 password - // match 6 hostname - // match 7 mangled port - // match 8 dataport - // match 9 database name - - protocol = urlRe.match(1); - username = urlRe.match(3); - password = urlRe.match(5); - hostname = urlRe.match(6); - dataport = urlRe.match(8); - database = urlRe.match(9); - - return true; -} - -// These must NOT be initialized. Default initialization to zero is -// necessary. -static unsigned int SystemToolsManagerCount; -SystemToolsStatic* SystemTools::Statics; - -// SystemToolsManager manages the SystemTools singleton. -// SystemToolsManager should be included in any translation unit -// that will use SystemTools or that implements the singleton -// pattern. It makes sure that the SystemTools singleton is created -// before and destroyed after all other singletons in CMake. - -SystemToolsManager::SystemToolsManager() -{ - if (++SystemToolsManagerCount == 1) { - SystemTools::ClassInitialize(); - } -} - -SystemToolsManager::~SystemToolsManager() -{ - if (--SystemToolsManagerCount == 0) { - SystemTools::ClassFinalize(); - } -} - -#if defined(__VMS) -// On VMS we configure the run time C library to be more UNIX like. -// http://h71000.www7.hp.com/doc/732final/5763/5763pro_004.html -extern "C" int decc$feature_get_index(char* name); -extern "C" int decc$feature_set_value(int index, int mode, int value); -static int SetVMSFeature(char* name, int value) -{ - int i; - errno = 0; - i = decc$feature_get_index(name); - return i >= 0 && (decc$feature_set_value(i, 1, value) >= 0 || errno == 0); -} -#endif - -void SystemTools::ClassInitialize() -{ -#ifdef __VMS - SetVMSFeature("DECC$FILENAME_UNIX_ONLY", 1); -#endif - - // Create statics singleton instance - SystemTools::Statics = new SystemToolsStatic; - -#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP -// Add some special translation paths for unix. These are not added -// for windows because drive letters need to be maintained. Also, -// there are not sym-links and mount points on windows anyway. -# if !defined(_WIN32) || defined(__CYGWIN__) - // The tmp path is frequently a logical path so always keep it: - SystemTools::AddKeepPath("/tmp/"); - - // If the current working directory is a logical path then keep the - // logical name. - std::string pwd_str; - if (SystemTools::GetEnv("PWD", pwd_str)) { - char buf[2048]; - if (const char* cwd = Getcwd(buf, 2048)) { - // The current working directory may be a logical path. Find - // the shortest logical path that still produces the correct - // physical path. - std::string cwd_changed; - std::string pwd_changed; - - // Test progressively shorter logical-to-physical mappings. - std::string cwd_str = cwd; - std::string pwd_path; - Realpath(pwd_str, pwd_path); - while (cwd_str == pwd_path && cwd_str != pwd_str) { - // The current pair of paths is a working logical mapping. - cwd_changed = cwd_str; - pwd_changed = pwd_str; - - // Strip off one directory level and see if the logical - // mapping still works. - pwd_str = SystemTools::GetFilenamePath(pwd_str); - cwd_str = SystemTools::GetFilenamePath(cwd_str); - Realpath(pwd_str, pwd_path); - } - - // Add the translation to keep the logical path name. - if (!cwd_changed.empty() && !pwd_changed.empty()) { - SystemTools::AddTranslationPath(cwd_changed, pwd_changed); - } - } - } -# endif -#endif -} - -void SystemTools::ClassFinalize() -{ - delete SystemTools::Statics; -} - -} // namespace KWSYS_NAMESPACE - -#if defined(_MSC_VER) && defined(_DEBUG) -# include <crtdbg.h> -# include <stdio.h> -# include <stdlib.h> -namespace KWSYS_NAMESPACE { - -static int SystemToolsDebugReport(int, char* message, int*) -{ - fprintf(stderr, "%s", message); - fflush(stderr); - return 1; // no further reporting required -} - -void SystemTools::EnableMSVCDebugHook() -{ - if (SystemTools::HasEnv("DART_TEST_FROM_DART") || - SystemTools::HasEnv("DASHBOARD_TEST_FROM_CTEST")) { - _CrtSetReportHook(SystemToolsDebugReport); - } -} - -} // namespace KWSYS_NAMESPACE -#else -namespace KWSYS_NAMESPACE { -void SystemTools::EnableMSVCDebugHook() -{ -} -} // namespace KWSYS_NAMESPACE -#endif diff --git a/test/API/driver/kwsys/SystemTools.hxx.in b/test/API/driver/kwsys/SystemTools.hxx.in deleted file mode 100644 index c4ab9d4..0000000 --- a/test/API/driver/kwsys/SystemTools.hxx.in +++ /dev/null @@ -1,981 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_SystemTools_hxx -#define @KWSYS_NAMESPACE@_SystemTools_hxx - -#include <@KWSYS_NAMESPACE@/Configure.hxx> - -#include <iosfwd> -#include <map> -#include <string> -#include <vector> - -#include <sys/types.h> -// include sys/stat.h after sys/types.h -#include <sys/stat.h> - -#if !defined(_WIN32) || defined(__CYGWIN__) -# include <unistd.h> // For access permissions for use with access() -#endif - -// Required for va_list -#include <stdarg.h> -// Required for FILE* -#include <stdio.h> -#if !defined(va_list) -// Some compilers move va_list into the std namespace and there is no way to -// tell that this has been done. Playing with things being included before or -// after stdarg.h does not solve things because we do not have control over -// what the user does. This hack solves this problem by moving va_list to our -// own namespace that is local for kwsys. -namespace std { -} // Required for platforms that do not have std namespace -namespace @KWSYS_NAMESPACE@_VA_LIST { -using namespace std; -typedef va_list hack_va_list; -} -namespace @KWSYS_NAMESPACE@ { -typedef @KWSYS_NAMESPACE@_VA_LIST::hack_va_list va_list; -} -#endif // va_list - -namespace @KWSYS_NAMESPACE@ { - -class SystemToolsStatic; - -/** \class SystemToolsManager - * \brief Use to make sure SystemTools is initialized before it is used - * and is the last static object destroyed - */ -class @KWSYS_NAMESPACE@_EXPORT SystemToolsManager -{ -public: - SystemToolsManager(); - ~SystemToolsManager(); - - SystemToolsManager(const SystemToolsManager&) = delete; - SystemToolsManager& operator=(const SystemToolsManager&) = delete; -}; - -// This instance will show up in any translation unit that uses -// SystemTools. It will make sure SystemTools is initialized -// before it is used and is the last static object destroyed. -static SystemToolsManager SystemToolsManagerInstance; - -// Flags for use with TestFileAccess. Use a typedef in case any operating -// system in the future needs a special type. These are flags that may be -// combined using the | operator. -typedef int TestFilePermissions; -#if defined(_WIN32) && !defined(__CYGWIN__) -// On Windows (VC and Borland), no system header defines these constants... -static const TestFilePermissions TEST_FILE_OK = 0; -static const TestFilePermissions TEST_FILE_READ = 4; -static const TestFilePermissions TEST_FILE_WRITE = 2; -static const TestFilePermissions TEST_FILE_EXECUTE = 1; -#else -// Standard POSIX constants -static const TestFilePermissions TEST_FILE_OK = F_OK; -static const TestFilePermissions TEST_FILE_READ = R_OK; -static const TestFilePermissions TEST_FILE_WRITE = W_OK; -static const TestFilePermissions TEST_FILE_EXECUTE = X_OK; -#endif - -/** \class SystemTools - * \brief A collection of useful platform-independent system functions. - */ -class @KWSYS_NAMESPACE@_EXPORT SystemTools -{ -public: - /** ----------------------------------------------------------------- - * String Manipulation Routines - * ----------------------------------------------------------------- - */ - - /** - * Replace symbols in str that are not valid in C identifiers as - * defined by the 1999 standard, ie. anything except [A-Za-z0-9_]. - * They are replaced with `_' and if the first character is a digit - * then an underscore is prepended. Note that this can produce - * identifiers that the standard reserves (_[A-Z].* and __.*). - */ - static std::string MakeCidentifier(const std::string& s); - - static std::string MakeCindentifier(const std::string& s) - { - return MakeCidentifier(s); - } - - /** - * Replace replace all occurrences of the string in the source string. - */ - static void ReplaceString(std::string& source, const char* replace, - const char* with); - static void ReplaceString(std::string& source, const std::string& replace, - const std::string& with); - - /** - * Return a capitalized string (i.e the first letter is uppercased, - * all other are lowercased). - */ - static std::string Capitalized(const std::string&); - - /** - * Return a 'capitalized words' string (i.e the first letter of each word - * is uppercased all other are left untouched though). - */ - static std::string CapitalizedWords(const std::string&); - - /** - * Return a 'uncapitalized words' string (i.e the first letter of each word - * is lowercased all other are left untouched though). - */ - static std::string UnCapitalizedWords(const std::string&); - - /** - * Return a lower case string - */ - static std::string LowerCase(const std::string&); - - /** - * Return a lower case string - */ - static std::string UpperCase(const std::string&); - - /** - * Count char in string - */ - static size_t CountChar(const char* str, char c); - - /** - * Remove some characters from a string. - * Return a pointer to the new resulting string (allocated with 'new') - */ - static char* RemoveChars(const char* str, const char* toremove); - - /** - * Remove remove all but 0->9, A->F characters from a string. - * Return a pointer to the new resulting string (allocated with 'new') - */ - static char* RemoveCharsButUpperHex(const char* str); - - /** - * Replace some characters by another character in a string (in-place) - * Return a pointer to string - */ - static char* ReplaceChars(char* str, const char* toreplace, - char replacement); - - /** - * Returns true if str1 starts (respectively ends) with str2 - */ - static bool StringStartsWith(const char* str1, const char* str2); - static bool StringStartsWith(const std::string& str1, const char* str2); - static bool StringEndsWith(const char* str1, const char* str2); - static bool StringEndsWith(const std::string& str1, const char* str2); - - /** - * Returns a pointer to the last occurrence of str2 in str1 - */ - static const char* FindLastString(const char* str1, const char* str2); - - /** - * Make a duplicate of the string similar to the strdup C function - * but use new to create the 'new' string, so one can use - * 'delete' to remove it. Returns 0 if the input is empty. - */ - static char* DuplicateString(const char* str); - - /** - * Return the string cropped to a given length by removing chars in the - * center of the string and replacing them with an ellipsis (...) - */ - static std::string CropString(const std::string&, size_t max_len); - - /** split a path by separator into an array of strings, default is /. - If isPath is true then the string is treated like a path and if - s starts with a / then the first element of the returned array will - be /, so /foo/bar will be [/, foo, bar] - */ - static std::vector<std::string> SplitString(const std::string& s, - char separator = '/', - bool isPath = false); - /** - * Perform a case-independent string comparison - */ - static int Strucmp(const char* s1, const char* s2); - - /** - * Split a string on its newlines into multiple lines - * Return false only if the last line stored had no newline - */ - static bool Split(const std::string& s, std::vector<std::string>& l); - static bool Split(const std::string& s, std::vector<std::string>& l, - char separator); - - /** - * Return string with space added between capitalized words - * (i.e. EatMyShorts becomes Eat My Shorts ) - * (note that IEatShorts becomes IEat Shorts) - */ - static std::string AddSpaceBetweenCapitalizedWords(const std::string&); - - /** - * Append two or more strings and produce new one. - * Programmer must 'delete []' the resulting string, which was allocated - * with 'new'. - * Return 0 if inputs are empty or there was an error - */ - static char* AppendStrings(const char* str1, const char* str2); - static char* AppendStrings(const char* str1, const char* str2, - const char* str3); - - /** - * Estimate the length of the string that will be produced - * from printing the given format string and arguments. The - * returned length will always be at least as large as the string - * that will result from printing. - * WARNING: since va_arg is called to iterate of the argument list, - * you will not be able to use this 'ap' anymore from the beginning. - * It's up to you to call va_end though. - */ - static int EstimateFormatLength(const char* format, va_list ap); - - /** - * Escape specific characters in 'str'. - */ - static std::string EscapeChars(const char* str, const char* chars_to_escape, - char escape_char = '\\'); - - /** ----------------------------------------------------------------- - * Filename Manipulation Routines - * ----------------------------------------------------------------- - */ - - /** - * Replace Windows file system slashes with Unix-style slashes. - */ - static void ConvertToUnixSlashes(std::string& path); - -#ifdef _WIN32 - /** Calls Encoding::ToWindowsExtendedPath. */ - static std::wstring ConvertToWindowsExtendedPath(const std::string&); -#endif - - /** - * For windows this calls ConvertToWindowsOutputPath and for unix - * it calls ConvertToUnixOutputPath - */ - static std::string ConvertToOutputPath(const std::string&); - - /** - * Convert the path to a string that can be used in a unix makefile. - * double slashes are removed, and spaces are escaped. - */ - static std::string ConvertToUnixOutputPath(const std::string&); - - /** - * Convert the path to string that can be used in a windows project or - * makefile. Double slashes are removed if they are not at the start of - * the string, the slashes are converted to windows style backslashes, and - * if there are spaces in the string it is double quoted. - */ - static std::string ConvertToWindowsOutputPath(const std::string&); - - /** - * Return true if a path with the given name exists in the current directory. - */ - static bool PathExists(const std::string& path); - - /** - * Return true if a file exists in the current directory. - * If isFile = true, then make sure the file is a file and - * not a directory. If isFile = false, then return true - * if it is a file or a directory. Note that the file will - * also be checked for read access. (Currently, this check - * for read access is only done on POSIX systems.) - */ - static bool FileExists(const char* filename, bool isFile); - static bool FileExists(const std::string& filename, bool isFile); - static bool FileExists(const char* filename); - static bool FileExists(const std::string& filename); - - /** - * Test if a file exists and can be accessed with the requested - * permissions. Symbolic links are followed. Returns true if - * the access test was successful. - * - * On POSIX systems (including Cygwin), this maps to the access - * function. On Windows systems, all existing files are - * considered readable, and writable files are considered to - * have the read-only file attribute cleared. - */ - static bool TestFileAccess(const char* filename, - TestFilePermissions permissions); - static bool TestFileAccess(const std::string& filename, - TestFilePermissions permissions); -/** - * Cross platform wrapper for stat struct - */ -#if defined(_WIN32) && !defined(__CYGWIN__) -# if defined(__BORLANDC__) - typedef struct stati64 Stat_t; -# else - typedef struct _stat64 Stat_t; -# endif -#else - typedef struct stat Stat_t; -#endif - - /** - * Cross platform wrapper for stat system call - * - * On Windows this may not work for paths longer than 250 characters - * due to limitations of the underlying '_wstat64' call. - */ - static int Stat(const char* path, Stat_t* buf); - static int Stat(const std::string& path, Stat_t* buf); - -/** - * Converts Cygwin path to Win32 path. Uses dictionary container for - * caching and calls to cygwin_conv_to_win32_path from Cygwin dll - * for actual translation. Returns true on success, else false. - */ -#ifdef __CYGWIN__ - static bool PathCygwinToWin32(const char* path, char* win32_path); -#endif - - /** - * Return file length - */ - static unsigned long FileLength(const std::string& filename); - - /** - Change the modification time or create a file - */ - static bool Touch(const std::string& filename, bool create); - - /** - * Compare file modification times. - * Return true for successful comparison and false for error. - * When true is returned, result has -1, 0, +1 for - * f1 older, same, or newer than f2. - */ - static bool FileTimeCompare(const std::string& f1, const std::string& f2, - int* result); - - /** - * Get the file extension (including ".") needed for an executable - * on the current platform ("" for unix, ".exe" for Windows). - */ - static const char* GetExecutableExtension(); - - /** - * 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); - - /** - * Given the path to a program executable, get the directory part of - * the path with the file stripped off. If there is no directory - * part, the empty string is returned. - */ - static std::string GetProgramPath(const std::string&); - static bool SplitProgramPath(const std::string& in_name, std::string& dir, - std::string& file, bool errorReport = true); - - /** - * Given argv[0] for a unix program find the full path to a running - * executable. argv0 can be null for windows WinMain programs - * in this case GetModuleFileName will be used to find the path - * to the running executable. If argv0 is not a full path, - * then this will try to find the full path. If the path is not - * found false is returned, if found true is returned. An error - * message of the attempted paths is stored in errorMsg. - * exeName is the name of the executable. - * buildDir is a possibly null path to the build directory. - * installPrefix is a possibly null pointer to the install directory. - */ - static bool FindProgramPath(const char* argv0, std::string& pathOut, - std::string& errorMsg, - const char* exeName = nullptr, - const char* buildDir = nullptr, - const char* installPrefix = nullptr); - - /** - * Given a path to a file or directory, convert it to a full path. - * This collapses away relative paths relative to the cwd argument - * (which defaults to the current working directory). The full path - * is returned. - */ - static std::string CollapseFullPath(const std::string& in_relative); - static std::string CollapseFullPath(const std::string& in_relative, - const char* in_base); - static std::string CollapseFullPath(const std::string& in_relative, - const std::string& in_base); - - /** - * Get the real path for a given path, removing all symlinks. In - * the event of an error (non-existent path, permissions issue, - * etc.) the original path is returned if errorMessage pointer is - * nullptr. Otherwise empty string is returned and errorMessage - * contains error description. - */ - static std::string GetRealPath(const std::string& path, - std::string* errorMessage = nullptr); - - /** - * Split a path name into its root component and the rest of the - * path. The root component is one of the following: - * "/" = UNIX full path - * "c:/" = Windows full path (can be any drive letter) - * "c:" = Windows drive-letter relative path (can be any drive letter) - * "//" = Network path - * "~/" = Home path for current user - * "~u/" = Home path for user 'u' - * "" = Relative path - * - * A pointer to the rest of the path after the root component is - * returned. The root component is stored in the "root" string if - * given. - */ - static const char* SplitPathRootComponent(const std::string& p, - std::string* root = nullptr); - - /** - * Split a path name into its basic components. The first component - * always exists and is the root returned by SplitPathRootComponent. - * The remaining components form the path. If there is a trailing - * slash then the last component is the empty string. The - * components can be recombined as "c[0]c[1]/c[2]/.../c[n]" to - * produce the original path. Home directory references are - * automatically expanded if expand_home_dir is true and this - * platform supports them. - * - * This does *not* normalize the input path. All components are - * preserved, including empty ones. Typically callers should use - * this only on paths that have already been normalized. - */ - static void SplitPath(const std::string& p, - std::vector<std::string>& components, - bool expand_home_dir = true); - - /** - * Join components of a path name into a single string. See - * SplitPath for the format of the components. - * - * This does *not* normalize the input path. All components are - * preserved, including empty ones. Typically callers should use - * this only on paths that have already been normalized. - */ - static std::string JoinPath(const std::vector<std::string>& components); - static std::string JoinPath(std::vector<std::string>::const_iterator first, - std::vector<std::string>::const_iterator last); - - /** - * Compare a path or components of a path. - */ - static bool ComparePath(const std::string& c1, const std::string& c2); - - /** - * Return path of a full filename (no trailing slashes) - */ - static std::string GetFilenamePath(const std::string&); - - /** - * Return file name of a full filename (i.e. file name without path) - */ - static std::string GetFilenameName(const std::string&); - - /** - * Return longest file extension of a full filename (dot included) - */ - static std::string GetFilenameExtension(const std::string&); - - /** - * Return shortest file extension of a full filename (dot included) - */ - static std::string GetFilenameLastExtension(const std::string& filename); - - /** - * Return file name without extension of a full filename - */ - static std::string GetFilenameWithoutExtension(const std::string&); - - /** - * Return file name without its last (shortest) extension - */ - static std::string GetFilenameWithoutLastExtension(const std::string&); - - /** - * Return whether the path represents a full path (not relative) - */ - static bool FileIsFullPath(const std::string&); - static bool FileIsFullPath(const char*); - - /** - * For windows return the short path for the given path, - * Unix just a pass through - */ - static bool GetShortPath(const std::string& path, std::string& result); - - /** - * Read line from file. Make sure to read a full line and truncates it if - * requested via sizeLimit. Returns true if any data were read before the - * end-of-file was reached. If the has_newline argument is specified, it will - * be true when the line read had a newline character. - */ - static bool GetLineFromStream(std::istream& istr, std::string& line, - bool* has_newline = nullptr, - long sizeLimit = -1); - - /** - * Get the parent directory of the directory or file - */ - static std::string GetParentDirectory(const std::string& fileOrDir); - - /** - * Check if the given file or directory is in subdirectory of dir - */ - static bool IsSubDirectory(const std::string& fileOrDir, - const std::string& dir); - - /** ----------------------------------------------------------------- - * File Manipulation Routines - * ----------------------------------------------------------------- - */ - - /** - * Open a file considering unicode. - */ - static FILE* Fopen(const std::string& file, const char* mode); - -/** - * Visual C++ does not define mode_t (note that Borland does, however). - */ -#if defined(_MSC_VER) - typedef unsigned short mode_t; -#endif - - /** - * Make a new directory if it is not there. This function - * can make a full path even if none of the directories existed - * prior to calling this function. - */ - static bool MakeDirectory(const char* path, const mode_t* mode = nullptr); - static bool MakeDirectory(const std::string& path, - const mode_t* mode = nullptr); - - /** - * Copy the source file to the destination file only - * if the two files differ. - */ - static bool CopyFileIfDifferent(const std::string& source, - const std::string& destination); - - /** - * Compare the contents of two files. Return true if different - */ - static bool FilesDiffer(const std::string& source, - const std::string& destination); - - /** - * Compare the contents of two files, ignoring line ending differences. - * Return true if different - */ - static bool TextFilesDiffer(const std::string& path1, - const std::string& path2); - - /** - * Return true if the two files are the same file - */ - static bool SameFile(const std::string& file1, const std::string& file2); - - /** - * Copy a file. - */ - static bool CopyFileAlways(const std::string& source, - const std::string& destination); - - /** - * Copy a file. If the "always" argument is true the file is always - * copied. If it is false, the file is copied only if it is new or - * has changed. - */ - static bool CopyAFile(const std::string& source, - const std::string& destination, bool always = true); - - /** - * Copy content directory to another directory with all files and - * subdirectories. If the "always" argument is true all files are - * always copied. If it is false, only files that have changed or - * are new are copied. - */ - static bool CopyADirectory(const std::string& source, - const std::string& destination, - bool always = true); - - /** - * Remove a file - */ - static bool RemoveFile(const std::string& source); - - /** - * Remove a directory - */ - static bool RemoveADirectory(const std::string& source); - - /** - * Get the maximum full file path length - */ - static size_t GetMaximumFilePathLength(); - - /** - * Find a file in the system PATH, with optional extra paths - */ - static std::string FindFile( - const std::string& name, - const std::vector<std::string>& path = std::vector<std::string>(), - bool no_system_path = false); - - /** - * Find a directory in the system PATH, with optional extra paths - */ - static std::string FindDirectory( - const std::string& name, - const std::vector<std::string>& path = std::vector<std::string>(), - bool no_system_path = false); - - /** - * Find an executable in the system PATH, with optional extra paths - */ - static std::string FindProgram( - const char* name, - const std::vector<std::string>& path = std::vector<std::string>(), - bool no_system_path = false); - static std::string FindProgram( - const std::string& name, - const std::vector<std::string>& path = std::vector<std::string>(), - bool no_system_path = false); - static std::string FindProgram( - const std::vector<std::string>& names, - const std::vector<std::string>& path = std::vector<std::string>(), - bool no_system_path = false); - - /** - * Find a library in the system PATH, with optional extra paths - */ - static std::string FindLibrary(const std::string& name, - const std::vector<std::string>& path); - - /** - * Return true if the file is a directory - */ - static bool FileIsDirectory(const std::string& name); - - /** - * Return true if the file is a symlink - */ - static bool FileIsSymlink(const std::string& name); - - /** - * Return true if the file is a FIFO - */ - static bool FileIsFIFO(const std::string& name); - - /** - * Return true if the file has a given signature (first set of bytes) - */ - static bool FileHasSignature(const char* filename, const char* signature, - long offset = 0); - - /** - * Attempt to detect and return the type of a file. - * Up to 'length' bytes are read from the file, if more than 'percent_bin' % - * of the bytes are non-textual elements, the file is considered binary, - * otherwise textual. Textual elements are bytes in the ASCII [0x20, 0x7E] - * range, but also \\n, \\r, \\t. - * The algorithm is simplistic, and should probably check for usual file - * extensions, 'magic' signature, unicode, etc. - */ - enum FileTypeEnum - { - FileTypeUnknown, - FileTypeBinary, - FileTypeText - }; - static SystemTools::FileTypeEnum DetectFileType(const char* filename, - unsigned long length = 256, - double percent_bin = 0.05); - - /** - * Create a symbolic link if the platform supports it. Returns whether - * creation succeeded. - */ - static bool CreateSymlink(const std::string& origName, - const std::string& newName); - - /** - * Read the contents of a symbolic link. Returns whether reading - * succeeded. - */ - static bool ReadSymlink(const std::string& newName, std::string& origName); - - /** - * Try to locate the file 'filename' in the directory 'dir'. - * If 'filename' is a fully qualified filename, the basename of the file is - * used to check for its existence in 'dir'. - * If 'dir' is not a directory, GetFilenamePath() is called on 'dir' to - * get its directory first (thus, you can pass a filename as 'dir', as - * a convenience). - * 'filename_found' is assigned the fully qualified name/path of the file - * if it is found (not touched otherwise). - * If 'try_filename_dirs' is true, try to find the file using the - * components of its path, i.e. if we are looking for c:/foo/bar/bill.txt, - * first look for bill.txt in 'dir', then in 'dir'/bar, then in 'dir'/foo/bar - * etc. - * Return true if the file was found, false otherwise. - */ - static bool LocateFileInDir(const char* filename, const char* dir, - std::string& filename_found, - int try_filename_dirs = 0); - - /** compute the relative path from local to remote. local must - be a directory. remote can be a file or a directory. - Both remote and local must be full paths. Basically, if - you are in directory local and you want to access the file in remote - what is the relative path to do that. For example: - /a/b/c/d to /a/b/c1/d1 -> ../../c1/d1 - from /usr/src to /usr/src/test/blah/foo.cpp -> test/blah/foo.cpp - */ - static std::string RelativePath(const std::string& local, - const std::string& remote); - - /** - * Return file's modified time - */ - static long int ModifiedTime(const std::string& filename); - - /** - * Return file's creation time (Win32: works only for NTFS, not FAT) - */ - static long int CreationTime(const std::string& filename); - - /** - * Get and set permissions of the file. If honor_umask is set, the umask - * is queried and applied to the given permissions. Returns false if - * failure. - * - * WARNING: A non-thread-safe method is currently used to get the umask - * if a honor_umask parameter is set to true. - */ - static bool GetPermissions(const char* file, mode_t& mode); - static bool GetPermissions(const std::string& file, mode_t& mode); - static bool SetPermissions(const char* file, mode_t mode, - bool honor_umask = false); - static bool SetPermissions(const std::string& file, mode_t mode, - bool honor_umask = false); - - /** ----------------------------------------------------------------- - * Time Manipulation Routines - * ----------------------------------------------------------------- - */ - - /** Get current time in seconds since Posix Epoch (Jan 1, 1970). */ - static double GetTime(); - - /** - * Get current date/time - */ - static std::string GetCurrentDateTime(const char* format); - - /** ----------------------------------------------------------------- - * Registry Manipulation Routines - * ----------------------------------------------------------------- - */ - - /** - * Specify access to the 32-bit or 64-bit application view of - * registry values. The default is to match the currently running - * binary type. - */ - enum KeyWOW64 - { - KeyWOW64_Default, - KeyWOW64_32, - KeyWOW64_64 - }; - - /** - * Get a list of subkeys. - */ - static bool GetRegistrySubKeys(const std::string& key, - std::vector<std::string>& subkeys, - KeyWOW64 view = KeyWOW64_Default); - - /** - * Read a registry value - */ - static bool ReadRegistryValue(const std::string& key, std::string& value, - KeyWOW64 view = KeyWOW64_Default); - - /** - * Write a registry value - */ - static bool WriteRegistryValue(const std::string& key, - const std::string& value, - KeyWOW64 view = KeyWOW64_Default); - - /** - * Delete a registry value - */ - static bool DeleteRegistryValue(const std::string& key, - KeyWOW64 view = KeyWOW64_Default); - - /** ----------------------------------------------------------------- - * Environment Manipulation Routines - * ----------------------------------------------------------------- - */ - - /** - * Add the paths from the environment variable PATH to the - * string vector passed in. If env is set then the value - * of env will be used instead of PATH. - */ - static void GetPath(std::vector<std::string>& path, - const char* env = nullptr); - - /** - * Read an environment variable - */ - static const char* GetEnv(const char* key); - static const char* GetEnv(const std::string& key); - static bool GetEnv(const char* key, std::string& result); - static bool GetEnv(const std::string& key, std::string& result); - static bool HasEnv(const char* key); - static bool HasEnv(const std::string& key); - - /** Put a string into the environment - of the form var=value */ - static bool PutEnv(const std::string& env); - - /** Remove a string from the environment. - Input is of the form "var" or "var=value" (value is ignored). */ - static bool UnPutEnv(const std::string& env); - - /** - * Get current working directory CWD - */ - static std::string GetCurrentWorkingDirectory(bool collapse = true); - - /** - * Change directory to the directory specified - */ - static int ChangeDirectory(const std::string& dir); - - /** - * Get the result of strerror(errno) - */ - static std::string GetLastSystemError(); - - /** - * When building DEBUG with MSVC, this enables a hook that prevents - * error dialogs from popping up if the program is being run from - * DART. - */ - static void EnableMSVCDebugHook(); - - /** - * Get the width of the terminal window. The code may or may not work, so - * make sure you have some reasonable defaults prepared if the code returns - * some bogus size. - */ - static int GetTerminalWidth(); - -#if @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP - /** - * Add an entry in the path translation table. - */ - static void AddTranslationPath(const std::string& dir, - const std::string& refdir); - - /** - * If dir is different after CollapseFullPath is called, - * Then insert it into the path translation table - */ - static void AddKeepPath(const std::string& dir); - - /** - * Update path by going through the Path Translation table; - */ - static void CheckTranslationPath(std::string& path); -#endif - - /** - * Delay the execution for a specified amount of time specified - * in milliseconds - */ - static void Delay(unsigned int msec); - - /** - * Get the operating system name and version - * This is implemented for Win32 only for the moment - */ - static std::string GetOperatingSystemNameAndVersion(); - - /** ----------------------------------------------------------------- - * URL Manipulation Routines - * ----------------------------------------------------------------- - */ - - /** - * Parse a character string : - * protocol://dataglom - * and fill protocol as appropriate. - * Return false if the URL does not have the required form, true otherwise. - */ - static bool ParseURLProtocol(const std::string& URL, std::string& protocol, - std::string& dataglom); - - /** - * Parse a string (a URL without protocol prefix) with the form: - * protocol://[[username[':'password]'@']hostname[':'dataport]]'/'[datapath] - * and fill protocol, username, password, hostname, dataport, and datapath - * when values are found. - * Return true if the string matches the format; false otherwise. - */ - static bool ParseURL(const std::string& URL, std::string& protocol, - std::string& username, std::string& password, - std::string& hostname, std::string& dataport, - std::string& datapath); - -private: - /** - * Allocate the stl map that serve as the Path Translation table. - */ - static void ClassInitialize(); - - /** - * Deallocate the stl map that serve as the Path Translation table. - */ - static void ClassFinalize(); - - /** - * This method prevents warning on SGI - */ - SystemToolsManager* GetSystemToolsManager() - { - return &SystemToolsManagerInstance; - } - - static SystemToolsStatic* Statics; - friend class SystemToolsStatic; - friend class SystemToolsManager; -}; - -} // namespace @KWSYS_NAMESPACE@ - -#endif diff --git a/test/API/driver/kwsys/Terminal.c b/test/API/driver/kwsys/Terminal.c deleted file mode 100644 index 4dd2461..0000000 --- a/test/API/driver/kwsys/Terminal.c +++ /dev/null @@ -1,414 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Terminal.h) - -/* Work-around CMake dependency scanning limitation. This must - duplicate the above list of headers. */ -#if 0 -# include "Terminal.h.in" -#endif - -/* Configure support for this platform. */ -#if defined(_WIN32) || defined(__CYGWIN__) -# define KWSYS_TERMINAL_SUPPORT_CONSOLE -#endif -#if !defined(_WIN32) -# define KWSYS_TERMINAL_ISATTY_WORKS -#endif - -/* Include needed system APIs. */ - -#include <stdarg.h> /* va_list */ -#include <stdlib.h> /* getenv */ -#include <string.h> /* strcmp */ - -#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE) -# include <io.h> /* _get_osfhandle */ -# include <windows.h> /* SetConsoleTextAttribute */ -#endif - -#if defined(KWSYS_TERMINAL_ISATTY_WORKS) -# include <unistd.h> /* isatty */ -#else -# include <sys/stat.h> /* fstat */ -#endif - -static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100, - int default_tty); -static void kwsysTerminalSetVT100Color(FILE* stream, int color); -#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE) -static HANDLE kwsysTerminalGetStreamHandle(FILE* stream); -static void kwsysTerminalSetConsoleColor(HANDLE hOut, - CONSOLE_SCREEN_BUFFER_INFO* hOutInfo, - FILE* stream, int color); -#endif - -void kwsysTerminal_cfprintf(int color, FILE* stream, const char* format, ...) -{ - /* Setup the stream with the given color if possible. */ - int pipeIsConsole = 0; - int pipeIsVT100 = 0; - int default_vt100 = color & kwsysTerminal_Color_AssumeVT100; - int default_tty = color & kwsysTerminal_Color_AssumeTTY; -#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE) - CONSOLE_SCREEN_BUFFER_INFO hOutInfo; - HANDLE hOut = kwsysTerminalGetStreamHandle(stream); - if (GetConsoleScreenBufferInfo(hOut, &hOutInfo)) { - pipeIsConsole = 1; - kwsysTerminalSetConsoleColor(hOut, &hOutInfo, stream, color); - } -#endif - if (!pipeIsConsole && - kwsysTerminalStreamIsVT100(stream, default_vt100, default_tty)) { - pipeIsVT100 = 1; - kwsysTerminalSetVT100Color(stream, color); - } - - /* Format the text into the stream. */ - { - va_list var_args; - va_start(var_args, format); - vfprintf(stream, format, var_args); - va_end(var_args); - } - -/* Restore the normal color state for the stream. */ -#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE) - if (pipeIsConsole) { - kwsysTerminalSetConsoleColor(hOut, &hOutInfo, stream, - kwsysTerminal_Color_Normal); - } -#endif - if (pipeIsVT100) { - kwsysTerminalSetVT100Color(stream, kwsysTerminal_Color_Normal); - } -} - -/* Detect cases when a stream is definitely not interactive. */ -#if !defined(KWSYS_TERMINAL_ISATTY_WORKS) -static int kwsysTerminalStreamIsNotInteractive(FILE* stream) -{ - /* The given stream is definitely not interactive if it is a regular - file. */ - struct stat stream_stat; - if (fstat(fileno(stream), &stream_stat) == 0) { - if (stream_stat.st_mode & S_IFREG) { - return 1; - } - } - return 0; -} -#endif - -/* List of terminal names known to support VT100 color escape sequences. */ -static const char* kwsysTerminalVT100Names[] = { "Eterm", - "alacritty", - "alacritty-direct", - "ansi", - "color-xterm", - "con132x25", - "con132x30", - "con132x43", - "con132x60", - "con80x25", - "con80x28", - "con80x30", - "con80x43", - "con80x50", - "con80x60", - "cons25", - "console", - "cygwin", - "dtterm", - "eterm-color", - "gnome", - "gnome-256color", - "konsole", - "konsole-256color", - "kterm", - "linux", - "msys", - "linux-c", - "mach-color", - "mlterm", - "putty", - "putty-256color", - "rxvt", - "rxvt-256color", - "rxvt-cygwin", - "rxvt-cygwin-native", - "rxvt-unicode", - "rxvt-unicode-256color", - "screen", - "screen-256color", - "screen-256color-bce", - "screen-bce", - "screen-w", - "screen.linux", - "tmux", - "tmux-256color", - "vt100", - "xterm", - "xterm-16color", - "xterm-256color", - "xterm-88color", - "xterm-color", - "xterm-debian", - "xterm-kitty", - "xterm-termite", - 0 }; - -/* Detect whether a stream is displayed in a VT100-compatible terminal. */ -static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100, - int default_tty) -{ - /* Force color according to http://bixense.com/clicolors/ convention. */ - { - const char* clicolor_force = getenv("CLICOLOR_FORCE"); - if (clicolor_force && *clicolor_force && - strcmp(clicolor_force, "0") != 0) { - return 1; - } - } - - /* If running inside emacs the terminal is not VT100. Some emacs - seem to claim the TERM is xterm even though they do not support - VT100 escapes. */ - { - const char* emacs = getenv("EMACS"); - if (emacs && *emacs == 't') { - return 0; - } - } - - /* Check for a valid terminal. */ - if (!default_vt100) { - const char** t = 0; - const char* term = getenv("TERM"); - if (term) { - for (t = kwsysTerminalVT100Names; *t && strcmp(term, *t) != 0; ++t) { - } - } - if (!(t && *t)) { - return 0; - } - } - -#if defined(KWSYS_TERMINAL_ISATTY_WORKS) - /* Make sure the stream is a tty. */ - (void)default_tty; - return isatty(fileno(stream)) ? 1 : 0; -#else - /* Check for cases in which the stream is definitely not a tty. */ - if (kwsysTerminalStreamIsNotInteractive(stream)) { - return 0; - } - - /* Use the provided default for whether this is a tty. */ - return default_tty; -#endif -} - -/* VT100 escape sequence strings. */ -#if defined(__MVS__) -/* if building on z/OS (aka MVS), assume we are using EBCDIC */ -# define ESCAPE_CHAR "\47" -#else -# define ESCAPE_CHAR "\33" -#endif - -#define KWSYS_TERMINAL_VT100_NORMAL ESCAPE_CHAR "[0m" -#define KWSYS_TERMINAL_VT100_BOLD ESCAPE_CHAR "[1m" -#define KWSYS_TERMINAL_VT100_UNDERLINE ESCAPE_CHAR "[4m" -#define KWSYS_TERMINAL_VT100_BLINK ESCAPE_CHAR "[5m" -#define KWSYS_TERMINAL_VT100_INVERSE ESCAPE_CHAR "[7m" -#define KWSYS_TERMINAL_VT100_FOREGROUND_BLACK ESCAPE_CHAR "[30m" -#define KWSYS_TERMINAL_VT100_FOREGROUND_RED ESCAPE_CHAR "[31m" -#define KWSYS_TERMINAL_VT100_FOREGROUND_GREEN ESCAPE_CHAR "[32m" -#define KWSYS_TERMINAL_VT100_FOREGROUND_YELLOW ESCAPE_CHAR "[33m" -#define KWSYS_TERMINAL_VT100_FOREGROUND_BLUE ESCAPE_CHAR "[34m" -#define KWSYS_TERMINAL_VT100_FOREGROUND_MAGENTA ESCAPE_CHAR "[35m" -#define KWSYS_TERMINAL_VT100_FOREGROUND_CYAN ESCAPE_CHAR "[36m" -#define KWSYS_TERMINAL_VT100_FOREGROUND_WHITE ESCAPE_CHAR "[37m" -#define KWSYS_TERMINAL_VT100_BACKGROUND_BLACK ESCAPE_CHAR "[40m" -#define KWSYS_TERMINAL_VT100_BACKGROUND_RED ESCAPE_CHAR "[41m" -#define KWSYS_TERMINAL_VT100_BACKGROUND_GREEN ESCAPE_CHAR "[42m" -#define KWSYS_TERMINAL_VT100_BACKGROUND_YELLOW ESCAPE_CHAR "[43m" -#define KWSYS_TERMINAL_VT100_BACKGROUND_BLUE ESCAPE_CHAR "[44m" -#define KWSYS_TERMINAL_VT100_BACKGROUND_MAGENTA ESCAPE_CHAR "[45m" -#define KWSYS_TERMINAL_VT100_BACKGROUND_CYAN ESCAPE_CHAR "[46m" -#define KWSYS_TERMINAL_VT100_BACKGROUND_WHITE ESCAPE_CHAR "[47m" - -/* Write VT100 escape sequences to the stream for the given color. */ -static void kwsysTerminalSetVT100Color(FILE* stream, int color) -{ - if (color == kwsysTerminal_Color_Normal) { - fprintf(stream, KWSYS_TERMINAL_VT100_NORMAL); - return; - } - - switch (color & kwsysTerminal_Color_ForegroundMask) { - case kwsysTerminal_Color_Normal: - fprintf(stream, KWSYS_TERMINAL_VT100_NORMAL); - break; - case kwsysTerminal_Color_ForegroundBlack: - fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_BLACK); - break; - case kwsysTerminal_Color_ForegroundRed: - fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_RED); - break; - case kwsysTerminal_Color_ForegroundGreen: - fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_GREEN); - break; - case kwsysTerminal_Color_ForegroundYellow: - fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_YELLOW); - break; - case kwsysTerminal_Color_ForegroundBlue: - fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_BLUE); - break; - case kwsysTerminal_Color_ForegroundMagenta: - fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_MAGENTA); - break; - case kwsysTerminal_Color_ForegroundCyan: - fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_CYAN); - break; - case kwsysTerminal_Color_ForegroundWhite: - fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_WHITE); - break; - } - switch (color & kwsysTerminal_Color_BackgroundMask) { - case kwsysTerminal_Color_BackgroundBlack: - fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_BLACK); - break; - case kwsysTerminal_Color_BackgroundRed: - fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_RED); - break; - case kwsysTerminal_Color_BackgroundGreen: - fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_GREEN); - break; - case kwsysTerminal_Color_BackgroundYellow: - fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_YELLOW); - break; - case kwsysTerminal_Color_BackgroundBlue: - fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_BLUE); - break; - case kwsysTerminal_Color_BackgroundMagenta: - fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_MAGENTA); - break; - case kwsysTerminal_Color_BackgroundCyan: - fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_CYAN); - break; - case kwsysTerminal_Color_BackgroundWhite: - fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_WHITE); - break; - } - if (color & kwsysTerminal_Color_ForegroundBold) { - fprintf(stream, KWSYS_TERMINAL_VT100_BOLD); - } -} - -#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE) - -# define KWSYS_TERMINAL_MASK_FOREGROUND \ - (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | \ - FOREGROUND_INTENSITY) -# define KWSYS_TERMINAL_MASK_BACKGROUND \ - (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | \ - BACKGROUND_INTENSITY) - -/* Get the Windows handle for a FILE stream. */ -static HANDLE kwsysTerminalGetStreamHandle(FILE* stream) -{ - /* Get the C-library file descriptor from the stream. */ - int fd = fileno(stream); - -# if defined(__CYGWIN__) - /* Cygwin seems to have an extra pipe level. If the file descriptor - corresponds to stdout or stderr then obtain the matching windows - handle directly. */ - if (fd == fileno(stdout)) { - return GetStdHandle(STD_OUTPUT_HANDLE); - } else if (fd == fileno(stderr)) { - return GetStdHandle(STD_ERROR_HANDLE); - } -# endif - - /* Get the underlying Windows handle for the descriptor. */ - return (HANDLE)_get_osfhandle(fd); -} - -/* Set color attributes in a Windows console. */ -static void kwsysTerminalSetConsoleColor(HANDLE hOut, - CONSOLE_SCREEN_BUFFER_INFO* hOutInfo, - FILE* stream, int color) -{ - WORD attributes = 0; - switch (color & kwsysTerminal_Color_ForegroundMask) { - case kwsysTerminal_Color_Normal: - attributes |= hOutInfo->wAttributes & KWSYS_TERMINAL_MASK_FOREGROUND; - break; - case kwsysTerminal_Color_ForegroundBlack: - attributes |= 0; - break; - case kwsysTerminal_Color_ForegroundRed: - attributes |= FOREGROUND_RED; - break; - case kwsysTerminal_Color_ForegroundGreen: - attributes |= FOREGROUND_GREEN; - break; - case kwsysTerminal_Color_ForegroundYellow: - attributes |= FOREGROUND_RED | FOREGROUND_GREEN; - break; - case kwsysTerminal_Color_ForegroundBlue: - attributes |= FOREGROUND_BLUE; - break; - case kwsysTerminal_Color_ForegroundMagenta: - attributes |= FOREGROUND_RED | FOREGROUND_BLUE; - break; - case kwsysTerminal_Color_ForegroundCyan: - attributes |= FOREGROUND_BLUE | FOREGROUND_GREEN; - break; - case kwsysTerminal_Color_ForegroundWhite: - attributes |= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - break; - } - switch (color & kwsysTerminal_Color_BackgroundMask) { - case kwsysTerminal_Color_Normal: - attributes |= hOutInfo->wAttributes & KWSYS_TERMINAL_MASK_BACKGROUND; - break; - case kwsysTerminal_Color_BackgroundBlack: - attributes |= 0; - break; - case kwsysTerminal_Color_BackgroundRed: - attributes |= BACKGROUND_RED; - break; - case kwsysTerminal_Color_BackgroundGreen: - attributes |= BACKGROUND_GREEN; - break; - case kwsysTerminal_Color_BackgroundYellow: - attributes |= BACKGROUND_RED | BACKGROUND_GREEN; - break; - case kwsysTerminal_Color_BackgroundBlue: - attributes |= BACKGROUND_BLUE; - break; - case kwsysTerminal_Color_BackgroundMagenta: - attributes |= BACKGROUND_RED | BACKGROUND_BLUE; - break; - case kwsysTerminal_Color_BackgroundCyan: - attributes |= BACKGROUND_BLUE | BACKGROUND_GREEN; - break; - case kwsysTerminal_Color_BackgroundWhite: - attributes |= BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED; - break; - } - if (color & kwsysTerminal_Color_ForegroundBold) { - attributes |= FOREGROUND_INTENSITY; - } - if (color & kwsysTerminal_Color_BackgroundBold) { - attributes |= BACKGROUND_INTENSITY; - } - fflush(stream); - SetConsoleTextAttribute(hOut, attributes); -} -#endif diff --git a/test/API/driver/kwsys/Terminal.h.in b/test/API/driver/kwsys/Terminal.h.in deleted file mode 100644 index 1a2c745..0000000 --- a/test/API/driver/kwsys/Terminal.h.in +++ /dev/null @@ -1,170 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_Terminal_h -#define @KWSYS_NAMESPACE@_Terminal_h - -#include <@KWSYS_NAMESPACE@/Configure.h> - -#include <stdio.h> /* For file stream type FILE. */ - -/* Redefine all public interface symbol names to be in the proper - namespace. These macros are used internally to kwsys only, and are - not visible to user code. Use kwsysHeaderDump.pl to reproduce - these macros after making changes to the interface. */ -#if !defined(KWSYS_NAMESPACE) -# define kwsys_ns(x) @KWSYS_NAMESPACE@##x -# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT -#endif -#if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# define kwsysTerminal_cfprintf kwsys_ns(Terminal_cfprintf) -# define kwsysTerminal_Color_e kwsys_ns(Terminal_Color_e) -# define kwsysTerminal_Color_Normal kwsys_ns(Terminal_Color_Normal) -# define kwsysTerminal_Color_ForegroundBlack \ - kwsys_ns(Terminal_Color_ForegroundBlack) -# define kwsysTerminal_Color_ForegroundRed \ - kwsys_ns(Terminal_Color_ForegroundRed) -# define kwsysTerminal_Color_ForegroundGreen \ - kwsys_ns(Terminal_Color_ForegroundGreen) -# define kwsysTerminal_Color_ForegroundYellow \ - kwsys_ns(Terminal_Color_ForegroundYellow) -# define kwsysTerminal_Color_ForegroundBlue \ - kwsys_ns(Terminal_Color_ForegroundBlue) -# define kwsysTerminal_Color_ForegroundMagenta \ - kwsys_ns(Terminal_Color_ForegroundMagenta) -# define kwsysTerminal_Color_ForegroundCyan \ - kwsys_ns(Terminal_Color_ForegroundCyan) -# define kwsysTerminal_Color_ForegroundWhite \ - kwsys_ns(Terminal_Color_ForegroundWhite) -# define kwsysTerminal_Color_ForegroundMask \ - kwsys_ns(Terminal_Color_ForegroundMask) -# define kwsysTerminal_Color_BackgroundBlack \ - kwsys_ns(Terminal_Color_BackgroundBlack) -# define kwsysTerminal_Color_BackgroundRed \ - kwsys_ns(Terminal_Color_BackgroundRed) -# define kwsysTerminal_Color_BackgroundGreen \ - kwsys_ns(Terminal_Color_BackgroundGreen) -# define kwsysTerminal_Color_BackgroundYellow \ - kwsys_ns(Terminal_Color_BackgroundYellow) -# define kwsysTerminal_Color_BackgroundBlue \ - kwsys_ns(Terminal_Color_BackgroundBlue) -# define kwsysTerminal_Color_BackgroundMagenta \ - kwsys_ns(Terminal_Color_BackgroundMagenta) -# define kwsysTerminal_Color_BackgroundCyan \ - kwsys_ns(Terminal_Color_BackgroundCyan) -# define kwsysTerminal_Color_BackgroundWhite \ - kwsys_ns(Terminal_Color_BackgroundWhite) -# define kwsysTerminal_Color_BackgroundMask \ - kwsys_ns(Terminal_Color_BackgroundMask) -# define kwsysTerminal_Color_ForegroundBold \ - kwsys_ns(Terminal_Color_ForegroundBold) -# define kwsysTerminal_Color_BackgroundBold \ - kwsys_ns(Terminal_Color_BackgroundBold) -# define kwsysTerminal_Color_AssumeTTY kwsys_ns(Terminal_Color_AssumeTTY) -# define kwsysTerminal_Color_AssumeVT100 kwsys_ns(Terminal_Color_AssumeVT100) -# define kwsysTerminal_Color_AttributeMask \ - kwsys_ns(Terminal_Color_AttributeMask) -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -/** - * Write colored and formatted text to a stream. Color is used only - * for streams supporting it. The color specification is constructed - * by bitwise-OR-ing enumeration values. At most one foreground and - * one background value may be given. - * - * Whether the a stream supports color is usually automatically - * detected, but with two exceptions: - * - * - When the stream is displayed in a terminal supporting VT100 - * color but using an intermediate pipe for communication the - * detection of a tty fails. (This typically occurs for a shell - * running in an rxvt terminal in MSYS.) If the caller knows this - * to be the case, the attribute Color_AssumeTTY may be included in - * the color specification. - * - * - When the stream is displayed in a terminal whose TERM - * environment variable is not set or is set to a value that is not - * known to support VT100 colors. If the caller knows this to be - * the case, the attribute Color_AssumeVT100 may be included in the - * color specification. - */ -kwsysEXPORT void kwsysTerminal_cfprintf(int color, FILE* stream, - const char* format, ...); -enum kwsysTerminal_Color_e -{ - /* Normal Text */ - kwsysTerminal_Color_Normal = 0, - - /* Foreground Color */ - kwsysTerminal_Color_ForegroundBlack = 0x1, - kwsysTerminal_Color_ForegroundRed = 0x2, - kwsysTerminal_Color_ForegroundGreen = 0x3, - kwsysTerminal_Color_ForegroundYellow = 0x4, - kwsysTerminal_Color_ForegroundBlue = 0x5, - kwsysTerminal_Color_ForegroundMagenta = 0x6, - kwsysTerminal_Color_ForegroundCyan = 0x7, - kwsysTerminal_Color_ForegroundWhite = 0x8, - kwsysTerminal_Color_ForegroundMask = 0xF, - - /* Background Color */ - kwsysTerminal_Color_BackgroundBlack = 0x10, - kwsysTerminal_Color_BackgroundRed = 0x20, - kwsysTerminal_Color_BackgroundGreen = 0x30, - kwsysTerminal_Color_BackgroundYellow = 0x40, - kwsysTerminal_Color_BackgroundBlue = 0x50, - kwsysTerminal_Color_BackgroundMagenta = 0x60, - kwsysTerminal_Color_BackgroundCyan = 0x70, - kwsysTerminal_Color_BackgroundWhite = 0x80, - kwsysTerminal_Color_BackgroundMask = 0xF0, - - /* Attributes */ - kwsysTerminal_Color_ForegroundBold = 0x100, - kwsysTerminal_Color_BackgroundBold = 0x200, - kwsysTerminal_Color_AssumeTTY = 0x400, - kwsysTerminal_Color_AssumeVT100 = 0x800, - kwsysTerminal_Color_AttributeMask = 0xF00 -}; - -#if defined(__cplusplus) -} /* extern "C" */ -#endif - -/* If we are building a kwsys .c or .cxx file, let it use these macros. - Otherwise, undefine them to keep the namespace clean. */ -#if !defined(KWSYS_NAMESPACE) -# undef kwsys_ns -# undef kwsysEXPORT -# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS -# undef kwsysTerminal_cfprintf -# undef kwsysTerminal_Color_e -# undef kwsysTerminal_Color_Normal -# undef kwsysTerminal_Color_ForegroundBlack -# undef kwsysTerminal_Color_ForegroundRed -# undef kwsysTerminal_Color_ForegroundGreen -# undef kwsysTerminal_Color_ForegroundYellow -# undef kwsysTerminal_Color_ForegroundBlue -# undef kwsysTerminal_Color_ForegroundMagenta -# undef kwsysTerminal_Color_ForegroundCyan -# undef kwsysTerminal_Color_ForegroundWhite -# undef kwsysTerminal_Color_ForegroundMask -# undef kwsysTerminal_Color_BackgroundBlack -# undef kwsysTerminal_Color_BackgroundRed -# undef kwsysTerminal_Color_BackgroundGreen -# undef kwsysTerminal_Color_BackgroundYellow -# undef kwsysTerminal_Color_BackgroundBlue -# undef kwsysTerminal_Color_BackgroundMagenta -# undef kwsysTerminal_Color_BackgroundCyan -# undef kwsysTerminal_Color_BackgroundWhite -# undef kwsysTerminal_Color_BackgroundMask -# undef kwsysTerminal_Color_ForegroundBold -# undef kwsysTerminal_Color_BackgroundBold -# undef kwsysTerminal_Color_AssumeTTY -# undef kwsysTerminal_Color_AssumeVT100 -# undef kwsysTerminal_Color_AttributeMask -# endif -#endif - -#endif diff --git a/test/API/driver/kwsys/clang-format.bash b/test/API/driver/kwsys/clang-format.bash deleted file mode 100644 index b0282ab..0000000 --- a/test/API/driver/kwsys/clang-format.bash +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env bash -#============================================================================= -# Copyright 2015-2017 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -usage='usage: clang-format.bash [<options>] [--] - - --help Print usage plus more detailed help. - - --clang-format <tool> Use given clang-format tool. - - --amend Filter files changed by HEAD. - --cached Filter files locally staged for commit. - --modified Filter files locally modified from HEAD. - --tracked Filter files tracked by Git. -' - -help="$usage"' -Example to format locally modified files: - - ./clang-format.bash --modified - -Example to format locally modified files staged for commit: - - ./clang-format.bash --cached - -Example to format files modified by the most recent commit: - - ./clang-format.bash --amend - -Example to format all files: - - ./clang-format.bash --tracked - -Example to format the current topic: - - git filter-branch \ - --tree-filter "./clang-format.bash --tracked" \ - master.. -' - -die() { - echo "$@" 1>&2; exit 1 -} - -#----------------------------------------------------------------------------- - -# Parse command-line arguments. -clang_format='' -mode='' -while test "$#" != 0; do - case "$1" in - --amend) mode="amend" ;; - --cached) mode="cached" ;; - --clang-format) shift; clang_format="$1" ;; - --help) echo "$help"; exit 0 ;; - --modified) mode="modified" ;; - --tracked) mode="tracked" ;; - --) shift ; break ;; - -*) die "$usage" ;; - *) break ;; - esac - shift -done -test "$#" = 0 || die "$usage" - -# Find a default tool. -tools=' - clang-format-6.0 - clang-format -' -if test "x$clang_format" = "x"; then - for tool in $tools; do - if type -p "$tool" >/dev/null; then - clang_format="$tool" - break - fi - done -fi - -# Verify that we have a tool. -if ! type -p "$clang_format" >/dev/null; then - echo "Unable to locate a 'clang-format' tool." - exit 1 -fi - -if ! "$clang_format" --version | grep 'clang-format version 6\.0' >/dev/null 2>/dev/null; then - echo "clang-format version 6.0 is required (exactly)" - exit 1 -fi - -# Select listing mode. -case "$mode" in - '') echo "$usage"; exit 0 ;; - amend) git_ls='git diff-tree --diff-filter=AM --name-only HEAD -r --no-commit-id' ;; - cached) git_ls='git diff-index --diff-filter=AM --name-only HEAD --cached' ;; - modified) git_ls='git diff-index --diff-filter=AM --name-only HEAD' ;; - tracked) git_ls='git ls-files' ;; - *) die "invalid mode: $mode" ;; -esac - -# List files as selected above. -list_files() { - $git_ls | - - # Select sources with our attribute. - git check-attr --stdin format.clang-format | - sed -n '/: format\.clang-format: set$/ {s/:[^:]*:[^:]*$//p}' -} - -# Transform configured sources to protect @SYMBOLS@. -list_files | xargs -d '\n' sed -i 's/@\(KWSYS_[A-Z0-9_]\+\)@/x\1x/g' -# Update sources in-place. -list_files | xargs -d '\n' "$clang_format" -i -# Transform configured sources to restore @SYMBOLS@. -list_files | xargs -d '\n' sed -i 's/x\(KWSYS_[A-Z0-9_]\+\)x/@\1@/g' diff --git a/test/API/driver/kwsys/hash_fun.hxx.in b/test/API/driver/kwsys/hash_fun.hxx.in deleted file mode 100644 index 8626c2a..0000000 --- a/test/API/driver/kwsys/hash_fun.hxx.in +++ /dev/null @@ -1,166 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -/* - * Copyright (c) 1996 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ -#ifndef @KWSYS_NAMESPACE@_hash_fun_hxx -#define @KWSYS_NAMESPACE@_hash_fun_hxx - -#include <@KWSYS_NAMESPACE@/Configure.hxx> - -#include <stddef.h> // size_t -#include <string> - -namespace @KWSYS_NAMESPACE@ { - -template <class _Key> -struct hash -{ -}; - -inline size_t _stl_hash_string(const char* __s) -{ - unsigned long __h = 0; - for (; *__s; ++__s) - __h = 5 * __h + *__s; - - return size_t(__h); -} - -template <> -struct hash<char*> -{ - size_t operator()(const char* __s) const { return _stl_hash_string(__s); } -}; - -template <> -struct hash<const char*> -{ - size_t operator()(const char* __s) const { return _stl_hash_string(__s); } -}; - -template <> -struct hash<std::string> -{ - size_t operator()(const std::string& __s) const - { - return _stl_hash_string(__s.c_str()); - } -}; - -#if !defined(__BORLANDC__) -template <> -struct hash<const std::string> -{ - size_t operator()(const std::string& __s) const - { - return _stl_hash_string(__s.c_str()); - } -}; -#endif - -template <> -struct hash<char> -{ - size_t operator()(char __x) const { return __x; } -}; - -template <> -struct hash<unsigned char> -{ - size_t operator()(unsigned char __x) const { return __x; } -}; - -template <> -struct hash<signed char> -{ - size_t operator()(unsigned char __x) const { return __x; } -}; - -template <> -struct hash<short> -{ - size_t operator()(short __x) const { return __x; } -}; - -template <> -struct hash<unsigned short> -{ - size_t operator()(unsigned short __x) const { return __x; } -}; - -template <> -struct hash<int> -{ - size_t operator()(int __x) const { return __x; } -}; - -template <> -struct hash<unsigned int> -{ - size_t operator()(unsigned int __x) const { return __x; } -}; - -template <> -struct hash<long> -{ - size_t operator()(long __x) const { return __x; } -}; - -template <> -struct hash<unsigned long> -{ - size_t operator()(unsigned long __x) const { return __x; } -}; - -// use long long or __int64 -#if @KWSYS_USE_LONG_LONG@ -template <> -struct hash<long long> -{ - size_t operator()(long long __x) const { return __x; } -}; - -template <> -struct hash<unsigned long long> -{ - size_t operator()(unsigned long long __x) const { return __x; } -}; -#elif @KWSYS_USE___INT64@ -template <> -struct hash<__int64> -{ - size_t operator()(__int64 __x) const { return __x; } -}; -template <> -struct hash<unsigned __int64> -{ - size_t operator()(unsigned __int64 __x) const { return __x; } -}; -#endif // use long long or __int64 - -} // namespace @KWSYS_NAMESPACE@ - -#endif diff --git a/test/API/driver/kwsys/hash_map.hxx.in b/test/API/driver/kwsys/hash_map.hxx.in deleted file mode 100644 index 5f04e9c..0000000 --- a/test/API/driver/kwsys/hash_map.hxx.in +++ /dev/null @@ -1,423 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -/* - * Copyright (c) 1996 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ -#ifndef @KWSYS_NAMESPACE@_hash_map_hxx -#define @KWSYS_NAMESPACE@_hash_map_hxx - -#include <@KWSYS_NAMESPACE@/hashtable.hxx> - -#include <@KWSYS_NAMESPACE@/hash_fun.hxx> - -#include <functional> // equal_to - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4284) -# pragma warning(disable : 4786) -#endif - -#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) -# pragma set woff 1174 -# pragma set woff 1375 -#endif - -namespace @KWSYS_NAMESPACE@ { - -// select1st is an extension: it is not part of the standard. -template <class T1, class T2> -struct hash_select1st -{ - const T1& operator()(const std::pair<T1, T2>& __x) const - { - return __x.first; - } -}; - -// Forward declaration of equality operator; needed for friend declaration. - -template <class _Key, class _Tp, class _HashFcn = hash<_Key>, - class _EqualKey = std::equal_to<_Key>, - class _Alloc = std::allocator<char> > -class hash_map; - -template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> -bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&, - const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&); - -template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc> -class hash_map -{ -private: - typedef hashtable<std::pair<const _Key, _Tp>, _Key, _HashFcn, - hash_select1st<const _Key, _Tp>, _EqualKey, _Alloc> - _Ht; - _Ht _M_ht; - -public: - typedef typename _Ht::key_type key_type; - typedef _Tp data_type; - typedef _Tp mapped_type; - typedef typename _Ht::value_type value_type; - typedef typename _Ht::hasher hasher; - typedef typename _Ht::key_equal key_equal; - - typedef typename _Ht::size_type size_type; - typedef typename _Ht::difference_type difference_type; - typedef typename _Ht::pointer pointer; - typedef typename _Ht::const_pointer const_pointer; - typedef typename _Ht::reference reference; - typedef typename _Ht::const_reference const_reference; - - typedef typename _Ht::iterator iterator; - typedef typename _Ht::const_iterator const_iterator; - - typedef typename _Ht::allocator_type allocator_type; - - hasher hash_funct() const { return _M_ht.hash_funct(); } - key_equal key_eq() const { return _M_ht.key_eq(); } - allocator_type get_allocator() const { return _M_ht.get_allocator(); } - -public: - hash_map() - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { - } - explicit hash_map(size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { - } - hash_map(size_type __n, const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { - } - hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) - : _M_ht(__n, __hf, __eql, __a) - { - } - - template <class _InputIterator> - hash_map(_InputIterator __f, _InputIterator __l) - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { - _M_ht.insert_unique(__f, __l); - } - template <class _InputIterator> - hash_map(_InputIterator __f, _InputIterator __l, size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { - _M_ht.insert_unique(__f, __l); - } - template <class _InputIterator> - hash_map(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { - _M_ht.insert_unique(__f, __l); - } - template <class _InputIterator> - hash_map(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) - : _M_ht(__n, __hf, __eql, __a) - { - _M_ht.insert_unique(__f, __l); - } - -public: - size_type size() const { return _M_ht.size(); } - size_type max_size() const { return _M_ht.max_size(); } - bool empty() const { return _M_ht.empty(); } - void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); } - - friend bool operator==<>(const hash_map&, const hash_map&); - - iterator begin() { return _M_ht.begin(); } - iterator end() { return _M_ht.end(); } - const_iterator begin() const { return _M_ht.begin(); } - const_iterator end() const { return _M_ht.end(); } - -public: - std::pair<iterator, bool> insert(const value_type& __obj) - { - return _M_ht.insert_unique(__obj); - } - template <class _InputIterator> - void insert(_InputIterator __f, _InputIterator __l) - { - _M_ht.insert_unique(__f, __l); - } - std::pair<iterator, bool> insert_noresize(const value_type& __obj) - { - return _M_ht.insert_unique_noresize(__obj); - } - - iterator find(const key_type& __key) { return _M_ht.find(__key); } - const_iterator find(const key_type& __key) const - { - return _M_ht.find(__key); - } - - _Tp& operator[](const key_type& __key) - { - return _M_ht.find_or_insert(value_type(__key, _Tp())).second; - } - - size_type count(const key_type& __key) const { return _M_ht.count(__key); } - - std::pair<iterator, iterator> equal_range(const key_type& __key) - { - return _M_ht.equal_range(__key); - } - std::pair<const_iterator, const_iterator> equal_range( - const key_type& __key) const - { - return _M_ht.equal_range(__key); - } - - size_type erase(const key_type& __key) { return _M_ht.erase(__key); } - void erase(iterator __it) { _M_ht.erase(__it); } - void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } - void clear() { _M_ht.clear(); } - - void resize(size_type __hint) { _M_ht.resize(__hint); } - size_type bucket_count() const { return _M_ht.bucket_count(); } - size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } - size_type elems_in_bucket(size_type __n) const - { - return _M_ht.elems_in_bucket(__n); - } -}; - -template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -bool operator==(const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1, - const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2) -{ - return __hm1._M_ht == __hm2._M_ht; -} - -template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -inline bool operator!=( - const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1, - const hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2) -{ - return !(__hm1 == __hm2); -} - -template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -inline void swap(hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1, - hash_map<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2) -{ - __hm1.swap(__hm2); -} - -// Forward declaration of equality operator; needed for friend declaration. - -template <class _Key, class _Tp, class _HashFcn = hash<_Key>, - class _EqualKey = std::equal_to<_Key>, - class _Alloc = std::allocator<char> > -class hash_multimap; - -template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> -bool operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, - const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2); - -template <class _Key, class _Tp, class _HashFcn, class _EqualKey, class _Alloc> -class hash_multimap -{ -private: - typedef hashtable<std::pair<const _Key, _Tp>, _Key, _HashFcn, - hash_select1st<const _Key, _Tp>, _EqualKey, _Alloc> - _Ht; - _Ht _M_ht; - -public: - typedef typename _Ht::key_type key_type; - typedef _Tp data_type; - typedef _Tp mapped_type; - typedef typename _Ht::value_type value_type; - typedef typename _Ht::hasher hasher; - typedef typename _Ht::key_equal key_equal; - - typedef typename _Ht::size_type size_type; - typedef typename _Ht::difference_type difference_type; - typedef typename _Ht::pointer pointer; - typedef typename _Ht::const_pointer const_pointer; - typedef typename _Ht::reference reference; - typedef typename _Ht::const_reference const_reference; - - typedef typename _Ht::iterator iterator; - typedef typename _Ht::const_iterator const_iterator; - - typedef typename _Ht::allocator_type allocator_type; - - hasher hash_funct() const { return _M_ht.hash_funct(); } - key_equal key_eq() const { return _M_ht.key_eq(); } - allocator_type get_allocator() const { return _M_ht.get_allocator(); } - -public: - hash_multimap() - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { - } - explicit hash_multimap(size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { - } - hash_multimap(size_type __n, const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { - } - hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) - : _M_ht(__n, __hf, __eql, __a) - { - } - - template <class _InputIterator> - hash_multimap(_InputIterator __f, _InputIterator __l) - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { - _M_ht.insert_equal(__f, __l); - } - template <class _InputIterator> - hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { - _M_ht.insert_equal(__f, __l); - } - template <class _InputIterator> - hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { - _M_ht.insert_equal(__f, __l); - } - template <class _InputIterator> - hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) - : _M_ht(__n, __hf, __eql, __a) - { - _M_ht.insert_equal(__f, __l); - } - -public: - size_type size() const { return _M_ht.size(); } - size_type max_size() const { return _M_ht.max_size(); } - bool empty() const { return _M_ht.empty(); } - void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); } - - friend bool operator==<>(const hash_multimap&, const hash_multimap&); - - iterator begin() { return _M_ht.begin(); } - iterator end() { return _M_ht.end(); } - const_iterator begin() const { return _M_ht.begin(); } - const_iterator end() const { return _M_ht.end(); } - -public: - iterator insert(const value_type& __obj) - { - return _M_ht.insert_equal(__obj); - } - template <class _InputIterator> - void insert(_InputIterator __f, _InputIterator __l) - { - _M_ht.insert_equal(__f, __l); - } - iterator insert_noresize(const value_type& __obj) - { - return _M_ht.insert_equal_noresize(__obj); - } - - iterator find(const key_type& __key) { return _M_ht.find(__key); } - const_iterator find(const key_type& __key) const - { - return _M_ht.find(__key); - } - - size_type count(const key_type& __key) const { return _M_ht.count(__key); } - - std::pair<iterator, iterator> equal_range(const key_type& __key) - { - return _M_ht.equal_range(__key); - } - std::pair<const_iterator, const_iterator> equal_range( - const key_type& __key) const - { - return _M_ht.equal_range(__key); - } - - size_type erase(const key_type& __key) { return _M_ht.erase(__key); } - void erase(iterator __it) { _M_ht.erase(__it); } - void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } - void clear() { _M_ht.clear(); } - -public: - void resize(size_type __hint) { _M_ht.resize(__hint); } - size_type bucket_count() const { return _M_ht.bucket_count(); } - size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } - size_type elems_in_bucket(size_type __n) const - { - return _M_ht.elems_in_bucket(__n); - } -}; - -template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> -bool operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, - const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) -{ - return __hm1._M_ht == __hm2._M_ht; -} - -template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> -inline bool operator!=( - const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, - const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) -{ - return !(__hm1 == __hm2); -} - -template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc> -inline void swap(hash_multimap<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm1, - hash_multimap<_Key, _Tp, _HashFcn, _EqlKey, _Alloc>& __hm2) -{ - __hm1.swap(__hm2); -} - -} // namespace @KWSYS_NAMESPACE@ - -#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) -# pragma reset woff 1174 -# pragma reset woff 1375 -#endif - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif - -#endif diff --git a/test/API/driver/kwsys/hash_set.hxx.in b/test/API/driver/kwsys/hash_set.hxx.in deleted file mode 100644 index f4a37ee..0000000 --- a/test/API/driver/kwsys/hash_set.hxx.in +++ /dev/null @@ -1,392 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -/* - * Copyright (c) 1996 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ -#ifndef @KWSYS_NAMESPACE@_hash_set_hxx -#define @KWSYS_NAMESPACE@_hash_set_hxx - -#include <@KWSYS_NAMESPACE@/hashtable.hxx> - -#include <@KWSYS_NAMESPACE@/hash_fun.hxx> - -#include <functional> // equal_to - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4284) -# pragma warning(disable : 4786) -#endif - -#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) -# pragma set woff 1174 -# pragma set woff 1375 -#endif - -namespace @KWSYS_NAMESPACE@ { - -// identity is an extension: it is not part of the standard. -template <class _Tp> -struct _Identity -{ - const _Tp& operator()(const _Tp& __x) const { return __x; } -}; - -// Forward declaration of equality operator; needed for friend declaration. - -template <class _Value, class _HashFcn = hash<_Value>, - class _EqualKey = std::equal_to<_Value>, - class _Alloc = std::allocator<char> > -class hash_set; - -template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, - const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2); - -template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -class hash_set -{ -private: - typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, - _Alloc> - _Ht; - _Ht _M_ht; - -public: - typedef typename _Ht::key_type key_type; - typedef typename _Ht::value_type value_type; - typedef typename _Ht::hasher hasher; - typedef typename _Ht::key_equal key_equal; - - typedef typename _Ht::size_type size_type; - typedef typename _Ht::difference_type difference_type; - typedef typename _Ht::const_pointer pointer; - typedef typename _Ht::const_pointer const_pointer; - typedef typename _Ht::const_reference reference; - typedef typename _Ht::const_reference const_reference; - - typedef typename _Ht::const_iterator iterator; - typedef typename _Ht::const_iterator const_iterator; - - typedef typename _Ht::allocator_type allocator_type; - - hasher hash_funct() const { return _M_ht.hash_funct(); } - key_equal key_eq() const { return _M_ht.key_eq(); } - allocator_type get_allocator() const { return _M_ht.get_allocator(); } - -public: - hash_set() - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { - } - explicit hash_set(size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { - } - hash_set(size_type __n, const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { - } - hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) - : _M_ht(__n, __hf, __eql, __a) - { - } - - template <class _InputIterator> - hash_set(_InputIterator __f, _InputIterator __l) - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { - _M_ht.insert_unique(__f, __l); - } - template <class _InputIterator> - hash_set(_InputIterator __f, _InputIterator __l, size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { - _M_ht.insert_unique(__f, __l); - } - template <class _InputIterator> - hash_set(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { - _M_ht.insert_unique(__f, __l); - } - template <class _InputIterator> - hash_set(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) - : _M_ht(__n, __hf, __eql, __a) - { - _M_ht.insert_unique(__f, __l); - } - -public: - size_type size() const { return _M_ht.size(); } - size_type max_size() const { return _M_ht.max_size(); } - bool empty() const { return _M_ht.empty(); } - void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } - - friend bool operator==<>(const hash_set&, const hash_set&); - - iterator begin() const { return _M_ht.begin(); } - iterator end() const { return _M_ht.end(); } - -public: - std::pair<iterator, bool> insert(const value_type& __obj) - { - typedef typename _Ht::iterator _Ht_iterator; - std::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique(__obj); - return std::pair<iterator, bool>(__p.first, __p.second); - } - template <class _InputIterator> - void insert(_InputIterator __f, _InputIterator __l) - { - _M_ht.insert_unique(__f, __l); - } - std::pair<iterator, bool> insert_noresize(const value_type& __obj) - { - typedef typename _Ht::iterator _Ht_iterator; - std::pair<_Ht_iterator, bool> __p = _M_ht.insert_unique_noresize(__obj); - return std::pair<iterator, bool>(__p.first, __p.second); - } - - iterator find(const key_type& __key) const { return _M_ht.find(__key); } - - size_type count(const key_type& __key) const { return _M_ht.count(__key); } - - std::pair<iterator, iterator> equal_range(const key_type& __key) const - { - return _M_ht.equal_range(__key); - } - - size_type erase(const key_type& __key) { return _M_ht.erase(__key); } - void erase(iterator __it) { _M_ht.erase(__it); } - void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } - void clear() { _M_ht.clear(); } - -public: - void resize(size_type __hint) { _M_ht.resize(__hint); } - size_type bucket_count() const { return _M_ht.bucket_count(); } - size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } - size_type elems_in_bucket(size_type __n) const - { - return _M_ht.elems_in_bucket(__n); - } -}; - -template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -bool operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, - const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) -{ - return __hs1._M_ht == __hs2._M_ht; -} - -template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -inline bool operator!=( - const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1, - const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2) -{ - return !(__hs1 == __hs2); -} - -template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline void swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, - hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) -{ - __hs1.swap(__hs2); -} - -template <class _Value, class _HashFcn = hash<_Value>, - class _EqualKey = std::equal_to<_Value>, - class _Alloc = std::allocator<char> > -class hash_multiset; - -template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, - const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2); - -template <class _Value, class _HashFcn, class _EqualKey, class _Alloc> -class hash_multiset -{ -private: - typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, _EqualKey, - _Alloc> - _Ht; - _Ht _M_ht; - -public: - typedef typename _Ht::key_type key_type; - typedef typename _Ht::value_type value_type; - typedef typename _Ht::hasher hasher; - typedef typename _Ht::key_equal key_equal; - - typedef typename _Ht::size_type size_type; - typedef typename _Ht::difference_type difference_type; - typedef typename _Ht::const_pointer pointer; - typedef typename _Ht::const_pointer const_pointer; - typedef typename _Ht::const_reference reference; - typedef typename _Ht::const_reference const_reference; - - typedef typename _Ht::const_iterator iterator; - typedef typename _Ht::const_iterator const_iterator; - - typedef typename _Ht::allocator_type allocator_type; - - hasher hash_funct() const { return _M_ht.hash_funct(); } - key_equal key_eq() const { return _M_ht.key_eq(); } - allocator_type get_allocator() const { return _M_ht.get_allocator(); } - -public: - hash_multiset() - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { - } - explicit hash_multiset(size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { - } - hash_multiset(size_type __n, const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { - } - hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) - : _M_ht(__n, __hf, __eql, __a) - { - } - - template <class _InputIterator> - hash_multiset(_InputIterator __f, _InputIterator __l) - : _M_ht(100, hasher(), key_equal(), allocator_type()) - { - _M_ht.insert_equal(__f, __l); - } - template <class _InputIterator> - hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) - : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { - _M_ht.insert_equal(__f, __l); - } - template <class _InputIterator> - hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { - _M_ht.insert_equal(__f, __l); - } - template <class _InputIterator> - hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) - : _M_ht(__n, __hf, __eql, __a) - { - _M_ht.insert_equal(__f, __l); - } - -public: - size_type size() const { return _M_ht.size(); } - size_type max_size() const { return _M_ht.max_size(); } - bool empty() const { return _M_ht.empty(); } - void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } - - friend bool operator==<>(const hash_multiset&, const hash_multiset&); - - iterator begin() const { return _M_ht.begin(); } - iterator end() const { return _M_ht.end(); } - -public: - iterator insert(const value_type& __obj) - { - return _M_ht.insert_equal(__obj); - } - template <class _InputIterator> - void insert(_InputIterator __f, _InputIterator __l) - { - _M_ht.insert_equal(__f, __l); - } - iterator insert_noresize(const value_type& __obj) - { - return _M_ht.insert_equal_noresize(__obj); - } - - iterator find(const key_type& __key) const { return _M_ht.find(__key); } - - size_type count(const key_type& __key) const { return _M_ht.count(__key); } - - std::pair<iterator, iterator> equal_range(const key_type& __key) const - { - return _M_ht.equal_range(__key); - } - - size_type erase(const key_type& __key) { return _M_ht.erase(__key); } - void erase(iterator __it) { _M_ht.erase(__it); } - void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } - void clear() { _M_ht.clear(); } - -public: - void resize(size_type __hint) { _M_ht.resize(__hint); } - size_type bucket_count() const { return _M_ht.bucket_count(); } - size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } - size_type elems_in_bucket(size_type __n) const - { - return _M_ht.elems_in_bucket(__n); - } -}; - -template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -bool operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, - const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) -{ - return __hs1._M_ht == __hs2._M_ht; -} - -template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline bool operator!=( - const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, - const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) -{ - return !(__hs1 == __hs2); -} - -template <class _Val, class _HashFcn, class _EqualKey, class _Alloc> -inline void swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1, - hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2) -{ - __hs1.swap(__hs2); -} - -} // namespace @KWSYS_NAMESPACE@ - -#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) -# pragma reset woff 1174 -# pragma reset woff 1375 -#endif - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif - -#endif diff --git a/test/API/driver/kwsys/hashtable.hxx.in b/test/API/driver/kwsys/hashtable.hxx.in deleted file mode 100644 index 8c4b002..0000000 --- a/test/API/driver/kwsys/hashtable.hxx.in +++ /dev/null @@ -1,995 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -/* - * Copyright (c) 1996 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ -#ifdef __BORLANDC__ -# pragma warn - 8027 /* 'for' not inlined. */ -# pragma warn - 8026 /* 'exception' not inlined. */ -#endif - -#ifndef @KWSYS_NAMESPACE@_hashtable_hxx -# define @KWSYS_NAMESPACE@_hashtable_hxx - -# include <@KWSYS_NAMESPACE@/Configure.hxx> - -# include <algorithm> // lower_bound -# include <iterator> // iterator_traits -# include <memory> // allocator -# include <stddef.h> // size_t -# include <utility> // pair -# include <vector> // vector - -# if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4284) -# pragma warning(disable : 4786) -# pragma warning(disable : 4512) /* no assignment operator for class */ -# endif -# if defined(__sgi) && !defined(__GNUC__) -# pragma set woff 3970 /* pointer to int conversion */ 3321 3968 -# endif - -// In C++11, clang will warn about using dynamic exception specifications -// as they are deprecated. But as this class is trying to faithfully -// mimic unordered_set and unordered_map, we want to keep the 'throw()' -// decorations below. So we suppress the warning. -# if defined(__clang__) && defined(__has_warning) -# if __has_warning("-Wdeprecated") -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated" -# endif -# endif - -namespace @KWSYS_NAMESPACE@ { - -template <class _Val> -struct _Hashtable_node -{ - _Hashtable_node* _M_next; - _Val _M_val; - void public_method_to_quiet_warning_about_all_methods_private(); - -private: - void operator=(_Hashtable_node<_Val> const&) = delete; -}; - -template <class _Val, class _Key, class _HashFcn, class _ExtractKey, - class _EqualKey, class _Alloc = std::allocator<char> > -class hashtable; - -template <class _Val, class _Key, class _HashFcn, class _ExtractKey, - class _EqualKey, class _Alloc> -struct _Hashtable_iterator; - -template <class _Val, class _Key, class _HashFcn, class _ExtractKey, - class _EqualKey, class _Alloc> -struct _Hashtable_const_iterator; - -template <class _Val, class _Key, class _HashFcn, class _ExtractKey, - class _EqualKey, class _Alloc> -struct _Hashtable_iterator -{ - typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> - _Hashtable; - typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, - _Alloc> - iterator; - typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, - _EqualKey, _Alloc> - const_iterator; - typedef _Hashtable_node<_Val> _Node; - - typedef std::forward_iterator_tag iterator_category; - typedef _Val value_type; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - typedef _Val& reference; - typedef _Val* pointer; - - _Node* _M_cur; - _Hashtable* _M_ht; - - _Hashtable_iterator(_Node* __n, _Hashtable* __tab) - : _M_cur(__n) - , _M_ht(__tab) - { - } - _Hashtable_iterator() {} - reference operator*() const { return _M_cur->_M_val; } - pointer operator->() const { return &(operator*()); } - iterator& operator++(); - iterator operator++(int); - bool operator==(const iterator& __it) const { return _M_cur == __it._M_cur; } - bool operator!=(const iterator& __it) const { return _M_cur != __it._M_cur; } -}; - -template <class _Val, class _Key, class _HashFcn, class _ExtractKey, - class _EqualKey, class _Alloc> -struct _Hashtable_const_iterator -{ - typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> - _Hashtable; - typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, - _Alloc> - iterator; - typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, - _EqualKey, _Alloc> - const_iterator; - typedef _Hashtable_node<_Val> _Node; - - typedef std::forward_iterator_tag iterator_category; - typedef _Val value_type; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - typedef const _Val& reference; - typedef const _Val* pointer; - - const _Node* _M_cur; - const _Hashtable* _M_ht; - - _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) - : _M_cur(__n) - , _M_ht(__tab) - { - } - _Hashtable_const_iterator() {} - _Hashtable_const_iterator(const iterator& __it) - : _M_cur(__it._M_cur) - , _M_ht(__it._M_ht) - { - } - reference operator*() const { return _M_cur->_M_val; } - pointer operator->() const { return &(operator*()); } - const_iterator& operator++(); - const_iterator operator++(int); - bool operator==(const const_iterator& __it) const - { - return _M_cur == __it._M_cur; - } - bool operator!=(const const_iterator& __it) const - { - return _M_cur != __it._M_cur; - } -}; - -// Note: assumes long is at least 32 bits. -enum -{ - _stl_num_primes = 31 -}; - -// create a function with a static local to that function that returns -// the static -static inline const unsigned long* get_stl_prime_list() -{ - - static const unsigned long _stl_prime_list[_stl_num_primes] = { - 5ul, 11ul, 23ul, 53ul, 97ul, - 193ul, 389ul, 769ul, 1543ul, 3079ul, - 6151ul, 12289ul, 24593ul, 49157ul, 98317ul, - 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul, - 6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul, - 201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul, - 4294967291ul - }; - - return &_stl_prime_list[0]; -} - -static inline size_t _stl_next_prime(size_t __n) -{ - const unsigned long* __first = get_stl_prime_list(); - const unsigned long* __last = get_stl_prime_list() + (int)_stl_num_primes; - const unsigned long* pos = std::lower_bound(__first, __last, __n); - return pos == __last ? *(__last - 1) : *pos; -} - -// Forward declaration of operator==. - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -class hashtable; - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, - const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2); - -// Hashtables handle allocators a bit differently than other containers -// do. If we're using standard-conforming allocators, then a hashtable -// unconditionally has a member variable to hold its allocator, even if -// it so happens that all instances of the allocator type are identical. -// This is because, for hashtables, this extra storage is negligible. -// Additionally, a base class wouldn't serve any other purposes; it -// wouldn't, for example, simplify the exception-handling code. - -template <class _Val, class _Key, class _HashFcn, class _ExtractKey, - class _EqualKey, class _Alloc> -class hashtable -{ -public: - typedef _Key key_type; - typedef _Val value_type; - typedef _HashFcn hasher; - typedef _EqualKey key_equal; - - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - - hasher hash_funct() const { return _M_hash; } - key_equal key_eq() const { return _M_equals; } - -private: - typedef _Hashtable_node<_Val> _Node; - -public: - typedef typename _Alloc::template rebind<_Val>::other allocator_type; - allocator_type get_allocator() const { return _M_node_allocator; } - -private: - typedef - typename _Alloc::template rebind<_Node>::other _M_node_allocator_type; - typedef - typename _Alloc::template rebind<_Node*>::other _M_node_ptr_allocator_type; - typedef std::vector<_Node*, _M_node_ptr_allocator_type> _M_buckets_type; - -private: - _M_node_allocator_type _M_node_allocator; - hasher _M_hash; - key_equal _M_equals; - _ExtractKey _M_get_key; - _M_buckets_type _M_buckets; - size_type _M_num_elements; - - _Node* _M_get_node() { return _M_node_allocator.allocate(1); } - void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } - -public: - typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, - _Alloc> - iterator; - typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, - _EqualKey, _Alloc> - const_iterator; - - friend struct _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, - _EqualKey, _Alloc>; - friend struct _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, - _EqualKey, _Alloc>; - -public: - hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql, - const _ExtractKey& __ext, - const allocator_type& __a = allocator_type()) - : _M_node_allocator(__a) - , _M_hash(__hf) - , _M_equals(__eql) - , _M_get_key(__ext) - , _M_buckets(__a) - , _M_num_elements(0) - { - _M_initialize_buckets(__n); - } - - hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql, - const allocator_type& __a = allocator_type()) - : _M_node_allocator(__a) - , _M_hash(__hf) - , _M_equals(__eql) - , _M_get_key(_ExtractKey()) - , _M_buckets(__a) - , _M_num_elements(0) - { - _M_initialize_buckets(__n); - } - - hashtable(const hashtable& __ht) - : _M_node_allocator(__ht.get_allocator()) - , _M_hash(__ht._M_hash) - , _M_equals(__ht._M_equals) - , _M_get_key(__ht._M_get_key) - , _M_buckets(__ht.get_allocator()) - , _M_num_elements(0) - { - _M_copy_from(__ht); - } - - hashtable& operator=(const hashtable& __ht) - { - if (&__ht != this) { - clear(); - _M_hash = __ht._M_hash; - _M_equals = __ht._M_equals; - _M_get_key = __ht._M_get_key; - _M_copy_from(__ht); - } - return *this; - } - - ~hashtable() { clear(); } - - size_type size() const { return _M_num_elements; } - size_type max_size() const { return size_type(-1); } - bool empty() const { return size() == 0; } - - void swap(hashtable& __ht) - { - std::swap(_M_hash, __ht._M_hash); - std::swap(_M_equals, __ht._M_equals); - std::swap(_M_get_key, __ht._M_get_key); - _M_buckets.swap(__ht._M_buckets); - std::swap(_M_num_elements, __ht._M_num_elements); - } - - iterator begin() - { - for (size_type __n = 0; __n < _M_buckets.size(); ++__n) - if (_M_buckets[__n]) - return iterator(_M_buckets[__n], this); - return end(); - } - - iterator end() { return iterator(nullptr, this); } - - const_iterator begin() const - { - for (size_type __n = 0; __n < _M_buckets.size(); ++__n) - if (_M_buckets[__n]) - return const_iterator(_M_buckets[__n], this); - return end(); - } - - const_iterator end() const { return const_iterator(nullptr, this); } - - friend bool operator==<>(const hashtable&, const hashtable&); - -public: - size_type bucket_count() const { return _M_buckets.size(); } - - size_type max_bucket_count() const - { - return get_stl_prime_list()[(int)_stl_num_primes - 1]; - } - - size_type elems_in_bucket(size_type __bucket) const - { - size_type __result = 0; - for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next) - __result += 1; - return __result; - } - - std::pair<iterator, bool> insert_unique(const value_type& __obj) - { - resize(_M_num_elements + 1); - return insert_unique_noresize(__obj); - } - - iterator insert_equal(const value_type& __obj) - { - resize(_M_num_elements + 1); - return insert_equal_noresize(__obj); - } - - std::pair<iterator, bool> insert_unique_noresize(const value_type& __obj); - iterator insert_equal_noresize(const value_type& __obj); - - template <class _InputIterator> - void insert_unique(_InputIterator __f, _InputIterator __l) - { - insert_unique( - __f, __l, - typename std::iterator_traits<_InputIterator>::iterator_category()); - } - - template <class _InputIterator> - void insert_equal(_InputIterator __f, _InputIterator __l) - { - insert_equal( - __f, __l, - typename std::iterator_traits<_InputIterator>::iterator_category()); - } - - template <class _InputIterator> - void insert_unique(_InputIterator __f, _InputIterator __l, - std::input_iterator_tag) - { - for (; __f != __l; ++__f) - insert_unique(*__f); - } - - template <class _InputIterator> - void insert_equal(_InputIterator __f, _InputIterator __l, - std::input_iterator_tag) - { - for (; __f != __l; ++__f) - insert_equal(*__f); - } - - template <class _ForwardIterator> - void insert_unique(_ForwardIterator __f, _ForwardIterator __l, - std::forward_iterator_tag) - { - size_type __n = 0; - std::distance(__f, __l, __n); - resize(_M_num_elements + __n); - for (; __n > 0; --__n, ++__f) - insert_unique_noresize(*__f); - } - - template <class _ForwardIterator> - void insert_equal(_ForwardIterator __f, _ForwardIterator __l, - std::forward_iterator_tag) - { - size_type __n = 0; - std::distance(__f, __l, __n); - resize(_M_num_elements + __n); - for (; __n > 0; --__n, ++__f) - insert_equal_noresize(*__f); - } - - reference find_or_insert(const value_type& __obj); - - iterator find(const key_type& __key) - { - size_type __n = _M_bkt_num_key(__key); - _Node* __first; - for (__first = _M_buckets[__n]; - __first && !_M_equals(_M_get_key(__first->_M_val), __key); - __first = __first->_M_next) { - } - return iterator(__first, this); - } - - const_iterator find(const key_type& __key) const - { - size_type __n = _M_bkt_num_key(__key); - const _Node* __first; - for (__first = _M_buckets[__n]; - __first && !_M_equals(_M_get_key(__first->_M_val), __key); - __first = __first->_M_next) { - } - return const_iterator(__first, this); - } - - size_type count(const key_type& __key) const - { - const size_type __n = _M_bkt_num_key(__key); - size_type __result = 0; - - for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), __key)) - ++__result; - return __result; - } - - std::pair<iterator, iterator> equal_range(const key_type& __key); - - std::pair<const_iterator, const_iterator> equal_range( - const key_type& __key) const; - - size_type erase(const key_type& __key); - void erase(const iterator& __it); - void erase(iterator __first, iterator __last); - - void erase(const const_iterator& __it); - void erase(const_iterator __first, const_iterator __last); - - void resize(size_type __num_elements_hint); - void clear(); - -private: - size_type _M_next_size(size_type __n) const { return _stl_next_prime(__n); } - - void _M_initialize_buckets(size_type __n) - { - const size_type __n_buckets = _M_next_size(__n); - _M_buckets.reserve(__n_buckets); - _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*)nullptr); - _M_num_elements = 0; - } - - size_type _M_bkt_num_key(const key_type& __key) const - { - return _M_bkt_num_key(__key, _M_buckets.size()); - } - - size_type _M_bkt_num(const value_type& __obj) const - { - return _M_bkt_num_key(_M_get_key(__obj)); - } - - size_type _M_bkt_num_key(const key_type& __key, size_t __n) const - { - return _M_hash(__key) % __n; - } - - size_type _M_bkt_num(const value_type& __obj, size_t __n) const - { - return _M_bkt_num_key(_M_get_key(__obj), __n); - } - - void construct(_Val* p, const _Val& v) { new (p) _Val(v); } - void destroy(_Val* p) - { - (void)p; - p->~_Val(); - } - - _Node* _M_new_node(const value_type& __obj) - { - _Node* __n = _M_get_node(); - __n->_M_next = nullptr; - try { - construct(&__n->_M_val, __obj); - return __n; - } catch (...) { - _M_put_node(__n); - throw; - } - } - - void _M_delete_node(_Node* __n) - { - destroy(&__n->_M_val); - _M_put_node(__n); - } - - void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); - void _M_erase_bucket(const size_type __n, _Node* __last); - - void _M_copy_from(const hashtable& __ht); -}; - -template <class _Val, class _Key, class _HF, class _ExK, class _EqK, - class _All> -_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& -_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++() -{ - const _Node* __old = _M_cur; - _M_cur = _M_cur->_M_next; - if (!_M_cur) { - size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); - while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) - _M_cur = _M_ht->_M_buckets[__bucket]; - } - return *this; -} - -template <class _Val, class _Key, class _HF, class _ExK, class _EqK, - class _All> -inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> -_Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++(int) -{ - iterator __tmp = *this; - ++*this; - return __tmp; -} - -template <class _Val, class _Key, class _HF, class _ExK, class _EqK, - class _All> -_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& -_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++() -{ - const _Node* __old = _M_cur; - _M_cur = _M_cur->_M_next; - if (!_M_cur) { - size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); - while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) - _M_cur = _M_ht->_M_buckets[__bucket]; - } - return *this; -} - -template <class _Val, class _Key, class _HF, class _ExK, class _EqK, - class _All> -inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> -_Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>::operator++(int) -{ - const_iterator __tmp = *this; - ++*this; - return __tmp; -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, - const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) -{ - typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node; - if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) - return false; - for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) { - _Node* __cur1 = __ht1._M_buckets[__n]; - _Node* __cur2 = __ht2._M_buckets[__n]; - for (; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val; - __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) { - } - if (__cur1 || __cur2) - return false; - } - return true; -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -inline bool operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, - const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) -{ - return !(__ht1 == __ht2); -} - -template <class _Val, class _Key, class _HF, class _Extract, class _EqKey, - class _All> -inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, - hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) -{ - __ht1.swap(__ht2); -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool> -hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::insert_unique_noresize( - const value_type& __obj) -{ - const size_type __n = _M_bkt_num(__obj); - _Node* __first = _M_buckets[__n]; - - for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) - return std::pair<iterator, bool>(iterator(__cur, this), false); - - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __first; - _M_buckets[__n] = __tmp; - ++_M_num_elements; - return std::pair<iterator, bool>(iterator(__tmp, this), true); -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator -hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::insert_equal_noresize( - const value_type& __obj) -{ - const size_type __n = _M_bkt_num(__obj); - _Node* __first = _M_buckets[__n]; - - for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) { - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __cur->_M_next; - __cur->_M_next = __tmp; - ++_M_num_elements; - return iterator(__tmp, this); - } - - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __first; - _M_buckets[__n] = __tmp; - ++_M_num_elements; - return iterator(__tmp, this); -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference -hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::find_or_insert( - const value_type& __obj) -{ - resize(_M_num_elements + 1); - - size_type __n = _M_bkt_num(__obj); - _Node* __first = _M_buckets[__n]; - - for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) - return __cur->_M_val; - - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __first; - _M_buckets[__n] = __tmp; - ++_M_num_elements; - return __tmp->_M_val; -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator> -hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(const key_type& __key) -{ - typedef std::pair<iterator, iterator> _Pii; - const size_type __n = _M_bkt_num_key(__key); - - for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) - if (_M_equals(_M_get_key(__first->_M_val), __key)) { - for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) - if (!_M_equals(_M_get_key(__cur->_M_val), __key)) - return _Pii(iterator(__first, this), iterator(__cur, this)); - for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) - if (_M_buckets[__m]) - return _Pii(iterator(__first, this), - iterator(_M_buckets[__m], this)); - return _Pii(iterator(__first, this), end()); - } - return _Pii(end(), end()); -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator, - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator> -hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range( - const key_type& __key) const -{ - typedef std::pair<const_iterator, const_iterator> _Pii; - const size_type __n = _M_bkt_num_key(__key); - - for (const _Node* __first = _M_buckets[__n]; __first; - __first = __first->_M_next) { - if (_M_equals(_M_get_key(__first->_M_val), __key)) { - for (const _Node* __cur = __first->_M_next; __cur; - __cur = __cur->_M_next) - if (!_M_equals(_M_get_key(__cur->_M_val), __key)) - return _Pii(const_iterator(__first, this), - const_iterator(__cur, this)); - for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) - if (_M_buckets[__m]) - return _Pii(const_iterator(__first, this), - const_iterator(_M_buckets[__m], this)); - return _Pii(const_iterator(__first, this), end()); - } - } - return _Pii(end(), end()); -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type -hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const key_type& __key) -{ - const size_type __n = _M_bkt_num_key(__key); - _Node* __first = _M_buckets[__n]; - size_type __erased = 0; - - if (__first) { - _Node* __cur = __first; - _Node* __next = __cur->_M_next; - while (__next) { - if (_M_equals(_M_get_key(__next->_M_val), __key)) { - __cur->_M_next = __next->_M_next; - _M_delete_node(__next); - __next = __cur->_M_next; - ++__erased; - --_M_num_elements; - } else { - __cur = __next; - __next = __cur->_M_next; - } - } - if (_M_equals(_M_get_key(__first->_M_val), __key)) { - _M_buckets[__n] = __first->_M_next; - _M_delete_node(__first); - ++__erased; - --_M_num_elements; - } - } - return __erased; -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const iterator& __it) -{ - _Node* __p = __it._M_cur; - if (__p) { - const size_type __n = _M_bkt_num(__p->_M_val); - _Node* __cur = _M_buckets[__n]; - - if (__cur == __p) { - _M_buckets[__n] = __cur->_M_next; - _M_delete_node(__cur); - --_M_num_elements; - } else { - _Node* __next = __cur->_M_next; - while (__next) { - if (__next == __p) { - __cur->_M_next = __next->_M_next; - _M_delete_node(__next); - --_M_num_elements; - break; - } else { - __cur = __next; - __next = __cur->_M_next; - } - } - } - } -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(iterator __first, - iterator __last) -{ - size_type __f_bucket = - __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); - size_type __l_bucket = - __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); - - if (__first._M_cur == __last._M_cur) - return; - else if (__f_bucket == __l_bucket) - _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); - else { - _M_erase_bucket(__f_bucket, __first._M_cur, nullptr); - for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) - _M_erase_bucket(__n, nullptr); - if (__l_bucket != _M_buckets.size()) - _M_erase_bucket(__l_bucket, __last._M_cur); - } -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase( - const_iterator __first, const_iterator __last) -{ - erase(iterator(const_cast<_Node*>(__first._M_cur), - const_cast<hashtable*>(__first._M_ht)), - iterator(const_cast<_Node*>(__last._M_cur), - const_cast<hashtable*>(__last._M_ht))); -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase( - const const_iterator& __it) -{ - erase(iterator(const_cast<_Node*>(__it._M_cur), - const_cast<hashtable*>(__it._M_ht))); -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::resize( - size_type __num_elements_hint) -{ - const size_type __old_n = _M_buckets.size(); - if (__num_elements_hint > __old_n) { - const size_type __n = _M_next_size(__num_elements_hint); - if (__n > __old_n) { - _M_buckets_type __tmp(__n, (_Node*)(nullptr), - _M_buckets.get_allocator()); - try { - for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { - _Node* __first = _M_buckets[__bucket]; - while (__first) { - size_type __new_bucket = _M_bkt_num(__first->_M_val, __n); - _M_buckets[__bucket] = __first->_M_next; - __first->_M_next = __tmp[__new_bucket]; - __tmp[__new_bucket] = __first; - __first = _M_buckets[__bucket]; - } - } - _M_buckets.swap(__tmp); - } catch (...) { - for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) { - while (__tmp[__bucket]) { - _Node* __next = __tmp[__bucket]->_M_next; - _M_delete_node(__tmp[__bucket]); - __tmp[__bucket] = __next; - } - } - throw; - } - } - } -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket( - const size_type __n, _Node* __first, _Node* __last) -{ - _Node* __cur = _M_buckets[__n]; - if (__cur == __first) - _M_erase_bucket(__n, __last); - else { - _Node* __next; - for (__next = __cur->_M_next; __next != __first; - __cur = __next, __next = __cur->_M_next) - ; - while (__next != __last) { - __cur->_M_next = __next->_M_next; - _M_delete_node(__next); - __next = __cur->_M_next; - --_M_num_elements; - } - } -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket( - const size_type __n, _Node* __last) -{ - _Node* __cur = _M_buckets[__n]; - while (__cur != __last) { - _Node* __next = __cur->_M_next; - _M_delete_node(__cur); - __cur = __next; - _M_buckets[__n] = __cur; - --_M_num_elements; - } -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::clear() -{ - for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { - _Node* __cur = _M_buckets[__i]; - while (__cur != nullptr) { - _Node* __next = __cur->_M_next; - _M_delete_node(__cur); - __cur = __next; - } - _M_buckets[__i] = nullptr; - } - _M_num_elements = 0; -} - -template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> -void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_copy_from( - const hashtable& __ht) -{ - _M_buckets.clear(); - _M_buckets.reserve(__ht._M_buckets.size()); - _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*)nullptr); - try { - for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { - const _Node* __cur = __ht._M_buckets[__i]; - if (__cur) { - _Node* __copy = _M_new_node(__cur->_M_val); - _M_buckets[__i] = __copy; - - for (_Node* __next = __cur->_M_next; __next; - __cur = __next, __next = __cur->_M_next) { - __copy->_M_next = _M_new_node(__next->_M_val); - __copy = __copy->_M_next; - } - } - } - _M_num_elements = __ht._M_num_elements; - } catch (...) { - clear(); - throw; - } -} - -} // namespace @KWSYS_NAMESPACE@ - -// Undo warning suppression. -# if defined(__clang__) && defined(__has_warning) -# if __has_warning("-Wdeprecated") -# pragma clang diagnostic pop -# endif -# endif - -# if defined(_MSC_VER) -# pragma warning(pop) -# endif - -#endif diff --git a/test/API/driver/kwsys/kwsysHeaderDump.pl b/test/API/driver/kwsys/kwsysHeaderDump.pl deleted file mode 100644 index e3391e7..0000000 --- a/test/API/driver/kwsys/kwsysHeaderDump.pl +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/perl -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing#kwsys for details. - -if ( $#ARGV+1 < 2 ) -{ - print "Usage: ./kwsysHeaderDump.pl <name> <header>\n"; - exit(1); -} - -$name = $ARGV[0]; -$max = 0; -open(INFILE, $ARGV[1]); -while (chomp ($line = <INFILE>)) -{ - if (($line !~ /^\#/) && - ($line =~ s/.*kwsys${name}_([A-Za-z0-9_]*).*/\1/) && - ($i{$line}++ < 1)) - { - push(@lines, "$line"); - if (length($line) > $max) - { - $max = length($line); - } - } -} -close(INFILE); - -$width = $max + 13; -print sprintf("#define %-${width}s kwsys_ns(${name})\n", "kwsys${name}"); -foreach $l (@lines) -{ - print sprintf("#define %-${width}s kwsys_ns(${name}_$l)\n", - "kwsys${name}_$l"); -} -print "\n"; -print sprintf("# undef kwsys${name}\n"); -foreach $l (@lines) -{ - print sprintf("# undef kwsys${name}_$l\n"); -} diff --git a/test/API/driver/kwsys/kwsysPlatformTests.cmake b/test/API/driver/kwsys/kwsysPlatformTests.cmake deleted file mode 100644 index 28d3f68..0000000 --- a/test/API/driver/kwsys/kwsysPlatformTests.cmake +++ /dev/null @@ -1,216 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing#kwsys for details. - -SET(KWSYS_PLATFORM_TEST_FILE_C kwsysPlatformTestsC.c) -SET(KWSYS_PLATFORM_TEST_FILE_CXX kwsysPlatformTestsCXX.cxx) - -MACRO(KWSYS_PLATFORM_TEST lang var description invert) - IF(NOT DEFINED ${var}_COMPILED) - MESSAGE(STATUS "${description}") - set(maybe_cxx_standard "") - if(CMAKE_VERSION VERSION_LESS 3.8 AND CMAKE_CXX_STANDARD) - set(maybe_cxx_standard "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}") - endif() - TRY_COMPILE(${var}_COMPILED - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}} - COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS} - CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=${KWSYS_PLATFORM_TEST_LINK_LIBRARIES}" - ${maybe_cxx_standard} - OUTPUT_VARIABLE OUTPUT) - IF(${var}_COMPILED) - FILE(APPEND - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "${description} compiled with the following output:\n${OUTPUT}\n\n") - ELSE() - FILE(APPEND - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "${description} failed to compile with the following output:\n${OUTPUT}\n\n") - ENDIF() - IF(${invert} MATCHES INVERT) - IF(${var}_COMPILED) - MESSAGE(STATUS "${description} - no") - ELSE() - MESSAGE(STATUS "${description} - yes") - ENDIF() - ELSE() - IF(${var}_COMPILED) - MESSAGE(STATUS "${description} - yes") - ELSE() - MESSAGE(STATUS "${description} - no") - ENDIF() - ENDIF() - ENDIF() - IF(${invert} MATCHES INVERT) - IF(${var}_COMPILED) - SET(${var} 0) - ELSE() - SET(${var} 1) - ENDIF() - ELSE() - IF(${var}_COMPILED) - SET(${var} 1) - ELSE() - SET(${var} 0) - ENDIF() - ENDIF() -ENDMACRO() - -MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert) - IF(NOT DEFINED ${var}) - MESSAGE(STATUS "${description}") - TRY_RUN(${var} ${var}_COMPILED - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}} - COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS} - OUTPUT_VARIABLE OUTPUT) - - # Note that ${var} will be a 0 return value on success. - IF(${var}_COMPILED) - IF(${var}) - FILE(APPEND - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "${description} compiled but failed to run with the following output:\n${OUTPUT}\n\n") - ELSE() - FILE(APPEND - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "${description} compiled and ran with the following output:\n${OUTPUT}\n\n") - ENDIF() - ELSE() - FILE(APPEND - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "${description} failed to compile with the following output:\n${OUTPUT}\n\n") - SET(${var} -1 CACHE INTERNAL "${description} failed to compile.") - ENDIF() - - IF(${invert} MATCHES INVERT) - IF(${var}_COMPILED) - IF(${var}) - MESSAGE(STATUS "${description} - yes") - ELSE() - MESSAGE(STATUS "${description} - no") - ENDIF() - ELSE() - MESSAGE(STATUS "${description} - failed to compile") - ENDIF() - ELSE() - IF(${var}_COMPILED) - IF(${var}) - MESSAGE(STATUS "${description} - no") - ELSE() - MESSAGE(STATUS "${description} - yes") - ENDIF() - ELSE() - MESSAGE(STATUS "${description} - failed to compile") - ENDIF() - ENDIF() - ENDIF() - - IF(${invert} MATCHES INVERT) - IF(${var}_COMPILED) - IF(${var}) - SET(${var} 1) - ELSE() - SET(${var} 0) - ENDIF() - ELSE() - SET(${var} 1) - ENDIF() - ELSE() - IF(${var}_COMPILED) - IF(${var}) - SET(${var} 0) - ELSE() - SET(${var} 1) - ENDIF() - ELSE() - SET(${var} 0) - ENDIF() - ENDIF() -ENDMACRO() - -MACRO(KWSYS_PLATFORM_C_TEST var description invert) - SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES}) - SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS}) - KWSYS_PLATFORM_TEST(C "${var}" "${description}" "${invert}") - SET(KWSYS_PLATFORM_TEST_DEFINES) - SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS) -ENDMACRO() - -MACRO(KWSYS_PLATFORM_C_TEST_RUN var description invert) - SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES}) - SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS}) - KWSYS_PLATFORM_TEST_RUN(C "${var}" "${description}" "${invert}") - SET(KWSYS_PLATFORM_TEST_DEFINES) - SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS) -ENDMACRO() - -MACRO(KWSYS_PLATFORM_CXX_TEST var description invert) - SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES}) - SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS}) - SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES ${KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES}) - KWSYS_PLATFORM_TEST(CXX "${var}" "${description}" "${invert}") - SET(KWSYS_PLATFORM_TEST_DEFINES) - SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS) - SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES) -ENDMACRO() - -MACRO(KWSYS_PLATFORM_CXX_TEST_RUN var description invert) - SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES}) - SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS}) - KWSYS_PLATFORM_TEST_RUN(CXX "${var}" "${description}" "${invert}") - SET(KWSYS_PLATFORM_TEST_DEFINES) - SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS) -ENDMACRO() - -#----------------------------------------------------------------------------- -# KWSYS_PLATFORM_INFO_TEST(lang var description) -# -# Compile test named by ${var} and store INFO strings extracted from binary. -MACRO(KWSYS_PLATFORM_INFO_TEST lang var description) - # We can implement this macro on CMake 2.6 and above. - IF("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6) - SET(${var} "") - ELSE() - # Choose a location for the result binary. - SET(KWSYS_PLATFORM_INFO_FILE - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/${var}.bin) - - # Compile the test binary. - IF(NOT EXISTS ${KWSYS_PLATFORM_INFO_FILE}) - MESSAGE(STATUS "${description}") - TRY_COMPILE(${var}_COMPILED - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}} - COMPILE_DEFINITIONS -DTEST_${var} - ${KWSYS_PLATFORM_${lang}_TEST_DEFINES} - ${KWSYS_PLATFORM_${lang}_TEST_EXTRA_FLAGS} - OUTPUT_VARIABLE OUTPUT - COPY_FILE ${KWSYS_PLATFORM_INFO_FILE} - ) - IF(${var}_COMPILED) - FILE(APPEND - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "${description} compiled with the following output:\n${OUTPUT}\n\n") - ELSE() - FILE(APPEND - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "${description} failed to compile with the following output:\n${OUTPUT}\n\n") - ENDIF() - IF(${var}_COMPILED) - MESSAGE(STATUS "${description} - compiled") - ELSE() - MESSAGE(STATUS "${description} - failed") - ENDIF() - ENDIF() - - # Parse info strings out of the compiled binary. - IF(${var}_COMPILED) - FILE(STRINGS ${KWSYS_PLATFORM_INFO_FILE} ${var} REGEX "INFO:[A-Za-z0-9]+\\[[^]]*\\]") - ELSE() - SET(${var} "") - ENDIF() - - SET(KWSYS_PLATFORM_INFO_FILE) - ENDIF() -ENDMACRO() diff --git a/test/API/driver/kwsys/kwsysPlatformTestsC.c b/test/API/driver/kwsys/kwsysPlatformTestsC.c deleted file mode 100644 index b0cf7ad..0000000 --- a/test/API/driver/kwsys/kwsysPlatformTestsC.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -/* - Macros to define main() in a cross-platform way. - - Usage: - - int KWSYS_PLATFORM_TEST_C_MAIN() - { - return 0; - } - - int KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) - { - (void)argc; (void)argv; - return 0; - } -*/ -#if defined(__CLASSIC_C__) -# define KWSYS_PLATFORM_TEST_C_MAIN() main() -# define KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) \ - main(argc, argv) int argc; \ - char* argv[]; -#else -# define KWSYS_PLATFORM_TEST_C_MAIN() main(void) -# define KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) \ - main(int argc, char* argv[]) -#endif - -#ifdef TEST_KWSYS_C_HAS_PTRDIFF_T -# include <stddef.h> -int f(ptrdiff_t n) -{ - return n > 0; -} -int KWSYS_PLATFORM_TEST_C_MAIN() -{ - char* p = 0; - ptrdiff_t d = p - p; - (void)d; - return f(p - p); -} -#endif - -#ifdef TEST_KWSYS_C_HAS_SSIZE_T -# include <unistd.h> -int f(ssize_t n) -{ - return (int)n; -} -int KWSYS_PLATFORM_TEST_C_MAIN() -{ - ssize_t n = 0; - return f(n); -} -#endif - -#ifdef TEST_KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC -# if defined(__APPLE__) -# include <AvailabilityMacros.h> -# if MAC_OS_X_VERSION_MIN_REQUIRED < 101200 -# error "clock_gettime not available on macOS < 10.12" -# endif -# endif -# include <time.h> -int KWSYS_PLATFORM_TEST_C_MAIN() -{ - struct timespec ts; - return clock_gettime(CLOCK_MONOTONIC, &ts); -} -#endif - -#ifdef TEST_KWSYS_C_TYPE_MACROS -char* info_macros = -# if defined(__SIZEOF_SHORT__) - "INFO:macro[__SIZEOF_SHORT__]\n" -# endif -# if defined(__SIZEOF_INT__) - "INFO:macro[__SIZEOF_INT__]\n" -# endif -# if defined(__SIZEOF_LONG__) - "INFO:macro[__SIZEOF_LONG__]\n" -# endif -# if defined(__SIZEOF_LONG_LONG__) - "INFO:macro[__SIZEOF_LONG_LONG__]\n" -# endif -# if defined(__SHORT_MAX__) - "INFO:macro[__SHORT_MAX__]\n" -# endif -# if defined(__INT_MAX__) - "INFO:macro[__INT_MAX__]\n" -# endif -# if defined(__LONG_MAX__) - "INFO:macro[__LONG_MAX__]\n" -# endif -# if defined(__LONG_LONG_MAX__) - "INFO:macro[__LONG_LONG_MAX__]\n" -# endif - ""; - -int KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) -{ - int require = 0; - require += info_macros[argc]; - (void)argv; - return require; -} -#endif diff --git a/test/API/driver/kwsys/kwsysPlatformTestsCXX.cxx b/test/API/driver/kwsys/kwsysPlatformTestsCXX.cxx deleted file mode 100644 index cfd5666..0000000 --- a/test/API/driver/kwsys/kwsysPlatformTestsCXX.cxx +++ /dev/null @@ -1,335 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifdef TEST_KWSYS_CXX_HAS_CSTDIO -# include <cstdio> -int main() -{ - return 0; -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_LONG_LONG -long long f(long long n) -{ - return n; -} -int main() -{ - long long n = 0; - return static_cast<int>(f(n)); -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS___INT64 -__int64 f(__int64 n) -{ - return n; -} -int main() -{ - __int64 n = 0; - return static_cast<int>(f(n)); -} -#endif - -#ifdef TEST_KWSYS_CXX_STAT_HAS_ST_MTIM -# include <sys/types.h> - -# include <sys/stat.h> -# include <unistd.h> -int main() -{ - struct stat stat1; - (void)stat1.st_mtim.tv_sec; - (void)stat1.st_mtim.tv_nsec; - return 0; -} -#endif - -#ifdef TEST_KWSYS_CXX_STAT_HAS_ST_MTIMESPEC -# include <sys/types.h> - -# include <sys/stat.h> -# include <unistd.h> -int main() -{ - struct stat stat1; - (void)stat1.st_mtimespec.tv_sec; - (void)stat1.st_mtimespec.tv_nsec; - return 0; -} -#endif - -#ifdef TEST_KWSYS_CXX_SAME_LONG_AND___INT64 -void function(long**) -{ -} -int main() -{ - __int64** p = 0; - function(p); - return 0; -} -#endif - -#ifdef TEST_KWSYS_CXX_SAME_LONG_LONG_AND___INT64 -void function(long long**) -{ -} -int main() -{ - __int64** p = 0; - function(p); - return 0; -} -#endif - -#ifdef TEST_KWSYS_IOS_HAS_ISTREAM_LONG_LONG -# include <iostream> -int test_istream(std::istream& is, long long& x) -{ - return (is >> x) ? 1 : 0; -} -int main() -{ - long long x = 0; - return test_istream(std::cin, x); -} -#endif - -#ifdef TEST_KWSYS_IOS_HAS_OSTREAM_LONG_LONG -# include <iostream> -int test_ostream(std::ostream& os, long long x) -{ - return (os << x) ? 1 : 0; -} -int main() -{ - long long x = 0; - return test_ostream(std::cout, x); -} -#endif - -#ifdef TEST_KWSYS_IOS_HAS_ISTREAM___INT64 -# include <iostream> -int test_istream(std::istream& is, __int64& x) -{ - return (is >> x) ? 1 : 0; -} -int main() -{ - __int64 x = 0; - return test_istream(std::cin, x); -} -#endif - -#ifdef TEST_KWSYS_IOS_HAS_OSTREAM___INT64 -# include <iostream> -int test_ostream(std::ostream& os, __int64 x) -{ - return (os << x) ? 1 : 0; -} -int main() -{ - __int64 x = 0; - return test_ostream(std::cout, x); -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_SETENV -# include <stdlib.h> -int main() -{ - return setenv("A", "B", 1); -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_UNSETENV -# include <stdlib.h> -int main() -{ - unsetenv("A"); - return 0; -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H -# include <stdlib.h> -int main() -{ - char* e = environ[0]; - return e ? 0 : 1; -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_GETLOADAVG -// Match feature definitions from SystemInformation.cxx -# if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE) -# define _GNU_SOURCE -# endif -# include <stdlib.h> -int main() -{ - double loadavg[3] = { 0.0, 0.0, 0.0 }; - return getloadavg(loadavg, 3); -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_RLIMIT64 -# include <sys/resource.h> -int main() -{ - struct rlimit64 rlim; - return getrlimit64(0, &rlim); -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_ATOLL -# include <stdlib.h> -int main() -{ - const char* str = "1024"; - return static_cast<int>(atoll(str)); -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_ATOL -# include <stdlib.h> -int main() -{ - const char* str = "1024"; - return static_cast<int>(atol(str)); -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS__ATOI64 -# include <stdlib.h> -int main() -{ - const char* str = "1024"; - return static_cast<int>(_atoi64(str)); -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_UTIMES -# include <sys/time.h> -int main() -{ - struct timeval* current_time = 0; - return utimes("/example", current_time); -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_UTIMENSAT -# include <fcntl.h> -# include <sys/stat.h> -# if defined(__APPLE__) -# include <AvailabilityMacros.h> -# if MAC_OS_X_VERSION_MIN_REQUIRED < 101300 -# error "utimensat not available on macOS < 10.13" -# endif -# endif -int main() -{ - struct timespec times[2] = { { 0, UTIME_OMIT }, { 0, UTIME_NOW } }; - return utimensat(AT_FDCWD, "/example", times, AT_SYMLINK_NOFOLLOW); -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_BACKTRACE -# if defined(__PATHSCALE__) || defined(__PATHCC__) || \ - (defined(__LSB_VERSION__) && (__LSB_VERSION__ < 41)) -backtrace does not work with this compiler or os -# endif -# if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE) -# define _GNU_SOURCE -# endif -# include <execinfo.h> -int main() -{ - void* stackSymbols[256]; - backtrace(stackSymbols, 256); - backtrace_symbols(&stackSymbols[0], 1); - return 0; -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_DLADDR -# if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE) -# define _GNU_SOURCE -# endif -# include <dlfcn.h> -int main() -{ - Dl_info info; - int ierr = dladdr((void*)main, &info); - return 0; -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_CXXABI -# if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE) -# define _GNU_SOURCE -# endif -# if defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5130 && __linux && \ - __SUNPRO_CC_COMPAT == 'G' -# include <iostream> -# endif -# include <cxxabi.h> -int main() -{ - int status = 0; - size_t bufferLen = 512; - char buffer[512] = { '\0' }; - const char* function = "_ZN5kwsys17SystemInformation15GetProgramStackEii"; - char* demangledFunction = - abi::__cxa_demangle(function, buffer, &bufferLen, &status); - return status; -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM -int main() -{ - int a = 1; - __asm { - xor EBX, EBX; - mov a, EBX; - } - - return a; -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM_CPUID -int main() -{ - int a = 0; - __asm { - xor EAX, EAX; - cpuid; - mov a, EAX; - } - - return a; -} -#endif - -#ifdef TEST_KWSYS_STL_HAS_WSTRING -# include <string> -void f(std::wstring*) -{ -} -int main() -{ - return 0; -} -#endif - -#ifdef TEST_KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H -# include <ext/stdio_filebuf.h> -int main() -{ - return 0; -} -#endif diff --git a/test/API/driver/kwsys/kwsysPrivate.h b/test/API/driver/kwsys/kwsysPrivate.h deleted file mode 100644 index dd9c127..0000000 --- a/test/API/driver/kwsys/kwsysPrivate.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef KWSYS_NAMESPACE -# error "Do not include kwsysPrivate.h outside of kwsys c and cxx files." -#endif - -#ifndef _kwsysPrivate_h -# define _kwsysPrivate_h - -/* - Define KWSYS_HEADER macro to help the c and cxx files include kwsys - headers from the configured namespace directory. The macro can be - used like this: - - #include KWSYS_HEADER(Directory.hxx) - #include KWSYS_HEADER(std/vector) -*/ -/* clang-format off */ -#define KWSYS_HEADER(x) KWSYS_HEADER0(KWSYS_NAMESPACE/x) -/* clang-format on */ -# define KWSYS_HEADER0(x) KWSYS_HEADER1(x) -# define KWSYS_HEADER1(x) <x> - -/* - Define KWSYS_NAMESPACE_STRING to be a string constant containing the - name configured for this instance of the kwsys library. -*/ -# define KWSYS_NAMESPACE_STRING KWSYS_NAMESPACE_STRING0(KWSYS_NAMESPACE) -# define KWSYS_NAMESPACE_STRING0(x) KWSYS_NAMESPACE_STRING1(x) -# define KWSYS_NAMESPACE_STRING1(x) # x - -#else -# error "kwsysPrivate.h included multiple times." -#endif diff --git a/test/API/driver/kwsys/testCommandLineArguments.cxx b/test/API/driver/kwsys/testCommandLineArguments.cxx deleted file mode 100644 index 1778a9b..0000000 --- a/test/API/driver/kwsys/testCommandLineArguments.cxx +++ /dev/null @@ -1,209 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(CommandLineArguments.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "CommandLineArguments.hxx.in" -#endif - -#include <iostream> -#include <vector> - -#include <stddef.h> /* size_t */ -#include <string.h> /* strcmp */ - -static void* random_ptr = reinterpret_cast<void*>(0x123); - -static int argument(const char* arg, const char* value, void* call_data) -{ - std::cout << "Got argument: \"" << arg << "\" value: \"" - << (value ? value : "(null)") << "\"" << std::endl; - if (call_data != random_ptr) { - std::cerr << "Problem processing call_data" << std::endl; - return 0; - } - return 1; -} - -static int unknown_argument(const char* argument, void* call_data) -{ - std::cout << "Got unknown argument: \"" << argument << "\"" << std::endl; - if (call_data != random_ptr) { - std::cerr << "Problem processing call_data" << std::endl; - return 0; - } - return 1; -} - -static bool CompareTwoItemsOnList(bool i1, bool i2) -{ - return i1 == i2; -} -static bool CompareTwoItemsOnList(int i1, int i2) -{ - return i1 == i2; -} -static bool CompareTwoItemsOnList(double i1, double i2) -{ - return i1 == i2; -} -static bool CompareTwoItemsOnList(const char* i1, const char* i2) -{ - return strcmp(i1, i2) == 0; -} -static bool CompareTwoItemsOnList(const std::string& i1, const std::string& i2) -{ - return i1 == i2; -} - -int testCommandLineArguments(int argc, char* argv[]) -{ - // Example run: ./testCommandLineArguments --some-int-variable 4 - // --another-bool-variable --some-bool-variable=yes - // --some-stl-string-variable=foobar --set-bool-arg1 --set-bool-arg2 - // --some-string-variable=hello - - int res = 0; - kwsys::CommandLineArguments arg; - arg.Initialize(argc, argv); - - // For error handling - arg.SetClientData(random_ptr); - arg.SetUnknownArgumentCallback(unknown_argument); - - int some_int_variable = 10; - double some_double_variable = 10.10; - char* some_string_variable = nullptr; - std::string some_stl_string_variable; - bool some_bool_variable = false; - bool some_bool_variable1 = false; - bool bool_arg1 = false; - int bool_arg2 = 0; - - std::vector<int> numbers_argument; - int valid_numbers[] = { 5, 1, 8, 3, 7, 1, 3, 9, 7, 1 }; - - std::vector<double> doubles_argument; - double valid_doubles[] = { 12.5, 1.31, 22 }; - - std::vector<bool> bools_argument; - bool valid_bools[] = { true, true, false }; - - std::vector<char*> strings_argument; - const char* valid_strings[] = { "andy", "bill", "brad", "ken" }; - - std::vector<std::string> stl_strings_argument; - std::string valid_stl_strings[] = { "ken", "brad", "bill", "andy" }; - - typedef kwsys::CommandLineArguments argT; - - arg.AddArgument("--some-int-variable", argT::SPACE_ARGUMENT, - &some_int_variable, "Set some random int variable"); - arg.AddArgument("--some-double-variable", argT::CONCAT_ARGUMENT, - &some_double_variable, "Set some random double variable"); - arg.AddArgument("--some-string-variable", argT::EQUAL_ARGUMENT, - &some_string_variable, "Set some random string variable"); - arg.AddArgument("--some-stl-string-variable", argT::EQUAL_ARGUMENT, - &some_stl_string_variable, - "Set some random stl string variable"); - arg.AddArgument("--some-bool-variable", argT::EQUAL_ARGUMENT, - &some_bool_variable, "Set some random bool variable"); - arg.AddArgument("--another-bool-variable", argT::NO_ARGUMENT, - &some_bool_variable1, "Set some random bool variable 1"); - arg.AddBooleanArgument("--set-bool-arg1", &bool_arg1, - "Test AddBooleanArgument 1"); - arg.AddBooleanArgument("--set-bool-arg2", &bool_arg2, - "Test AddBooleanArgument 2"); - arg.AddArgument("--some-multi-argument", argT::MULTI_ARGUMENT, - &numbers_argument, "Some multiple values variable"); - arg.AddArgument("-N", argT::SPACE_ARGUMENT, &doubles_argument, - "Some explicit multiple values variable"); - arg.AddArgument("-BB", argT::CONCAT_ARGUMENT, &bools_argument, - "Some explicit multiple values variable"); - arg.AddArgument("-SS", argT::EQUAL_ARGUMENT, &strings_argument, - "Some explicit multiple values variable"); - arg.AddArgument("-SSS", argT::MULTI_ARGUMENT, &stl_strings_argument, - "Some explicit multiple values variable"); - - arg.AddCallback("-A", argT::NO_ARGUMENT, argument, random_ptr, - "Some option -A. This option has a multiline comment. It " - "should demonstrate how the code splits lines."); - arg.AddCallback("-B", argT::SPACE_ARGUMENT, argument, random_ptr, - "Option -B takes argument with space"); - arg.AddCallback("-C", argT::EQUAL_ARGUMENT, argument, random_ptr, - "Option -C takes argument after ="); - arg.AddCallback("-D", argT::CONCAT_ARGUMENT, argument, random_ptr, - "This option takes concatenated argument"); - arg.AddCallback("--long1", argT::NO_ARGUMENT, argument, random_ptr, "-A"); - arg.AddCallback("--long2", argT::SPACE_ARGUMENT, argument, random_ptr, "-B"); - arg.AddCallback("--long3", argT::EQUAL_ARGUMENT, argument, random_ptr, - "Same as -C but a bit different"); - arg.AddCallback("--long4", argT::CONCAT_ARGUMENT, argument, random_ptr, - "-C"); - - if (!arg.Parse()) { - std::cerr << "Problem parsing arguments" << std::endl; - res = 1; - } - std::cout << "Help: " << arg.GetHelp() << std::endl; - - std::cout << "Some int variable was set to: " << some_int_variable - << std::endl; - std::cout << "Some double variable was set to: " << some_double_variable - << std::endl; - if (some_string_variable && - strcmp(some_string_variable, "test string with space") == 0) { - std::cout << "Some string variable was set to: " << some_string_variable - << std::endl; - delete[] some_string_variable; - } else { - std::cerr << "Problem setting string variable" << std::endl; - res = 1; - } - size_t cc; -#define CompareTwoLists(list1, list_valid, lsize) \ - do { \ - if (list1.size() != lsize) { \ - std::cerr << "Problem setting " #list1 ". Size is: " << list1.size() \ - << " should be: " << lsize << std::endl; \ - res = 1; \ - } else { \ - std::cout << #list1 " argument set:"; \ - for (cc = 0; cc < lsize; ++cc) { \ - std::cout << " " << list1[cc]; \ - if (!CompareTwoItemsOnList(list1[cc], list_valid[cc])) { \ - std::cerr << "Problem setting " #list1 ". Value of " << cc \ - << " is: [" << list1[cc] << "] <> [" << list_valid[cc] \ - << "]" << std::endl; \ - res = 1; \ - break; \ - } \ - } \ - std::cout << std::endl; \ - } \ - } while (0) - CompareTwoLists(numbers_argument, valid_numbers, 10); - CompareTwoLists(doubles_argument, valid_doubles, 3); - CompareTwoLists(bools_argument, valid_bools, 3); - CompareTwoLists(strings_argument, valid_strings, 4); - CompareTwoLists(stl_strings_argument, valid_stl_strings, 4); - - std::cout << "Some STL String variable was set to: " - << some_stl_string_variable << std::endl; - std::cout << "Some bool variable was set to: " << some_bool_variable - << std::endl; - std::cout << "Some bool variable was set to: " << some_bool_variable1 - << std::endl; - std::cout << "bool_arg1 variable was set to: " << bool_arg1 << std::endl; - std::cout << "bool_arg2 variable was set to: " << bool_arg2 << std::endl; - std::cout << std::endl; - - for (cc = 0; cc < strings_argument.size(); ++cc) { - delete[] strings_argument[cc]; - strings_argument[cc] = nullptr; - } - return res; -} diff --git a/test/API/driver/kwsys/testCommandLineArguments1.cxx b/test/API/driver/kwsys/testCommandLineArguments1.cxx deleted file mode 100644 index 64561b1..0000000 --- a/test/API/driver/kwsys/testCommandLineArguments1.cxx +++ /dev/null @@ -1,93 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(CommandLineArguments.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "CommandLineArguments.hxx.in" -#endif - -#include <iostream> -#include <vector> - -#include <assert.h> /* assert */ -#include <string.h> /* strcmp */ - -int testCommandLineArguments1(int argc, char* argv[]) -{ - kwsys::CommandLineArguments arg; - arg.Initialize(argc, argv); - - int n = 0; - char* m = nullptr; - std::string p; - int res = 0; - - typedef kwsys::CommandLineArguments argT; - arg.AddArgument("-n", argT::SPACE_ARGUMENT, &n, "Argument N"); - arg.AddArgument("-m", argT::EQUAL_ARGUMENT, &m, "Argument M"); - arg.AddBooleanArgument("-p", &p, "Argument P"); - - arg.StoreUnusedArguments(true); - - if (!arg.Parse()) { - std::cerr << "Problem parsing arguments" << std::endl; - res = 1; - } - if (n != 24) { - std::cout << "Problem setting N. Value of N: " << n << std::endl; - res = 1; - } - if (!m || strcmp(m, "test value") != 0) { - std::cout << "Problem setting M. Value of M: " << m << std::endl; - res = 1; - } - if (p != "1") { - std::cout << "Problem setting P. Value of P: " << p << std::endl; - res = 1; - } - std::cout << "Value of N: " << n << std::endl; - std::cout << "Value of M: " << m << std::endl; - std::cout << "Value of P: " << p << std::endl; - if (m) { - delete[] m; - } - - char** newArgv = nullptr; - int newArgc = 0; - arg.GetUnusedArguments(&newArgc, &newArgv); - int cc; - const char* valid_unused_args[9] = { nullptr, - "--ignored", - "--second-ignored", - "third-ignored", - "some", - "junk", - "at", - "the", - "end" }; - if (newArgc != 9) { - std::cerr << "Bad number of unused arguments: " << newArgc << std::endl; - res = 1; - } - for (cc = 0; cc < newArgc; ++cc) { - assert(newArgv[cc]); /* Quiet Clang scan-build. */ - std::cout << "Unused argument[" << cc << "] = [" << newArgv[cc] << "]" - << std::endl; - if (cc >= 9) { - std::cerr << "Too many unused arguments: " << cc << std::endl; - res = 1; - } else if (valid_unused_args[cc] && - strcmp(valid_unused_args[cc], newArgv[cc]) != 0) { - std::cerr << "Bad unused argument [" << cc << "] \"" << newArgv[cc] - << "\" should be: \"" << valid_unused_args[cc] << "\"" - << std::endl; - res = 1; - } - } - arg.DeleteRemainingArguments(newArgc, &newArgv); - - return res; -} diff --git a/test/API/driver/kwsys/testConfigure.cxx b/test/API/driver/kwsys/testConfigure.cxx deleted file mode 100644 index a3c2ed3..0000000 --- a/test/API/driver/kwsys/testConfigure.cxx +++ /dev/null @@ -1,30 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying -file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Configure.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Configure.hxx.in" -#endif - -static bool testFallthrough(int n) -{ - int r = 0; - switch (n) { - case 1: - ++r; - KWSYS_FALLTHROUGH; - default: - ++r; - } - return r == 2; -} - -int testConfigure(int, char* []) -{ - bool res = true; - res = testFallthrough(1) && res; - return res ? 0 : 1; -} diff --git a/test/API/driver/kwsys/testConsoleBuf.cxx b/test/API/driver/kwsys/testConsoleBuf.cxx deleted file mode 100644 index 4b7ddf0..0000000 --- a/test/API/driver/kwsys/testConsoleBuf.cxx +++ /dev/null @@ -1,782 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#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 <algorithm> -# include <iomanip> -# include <iostream> -# include <stdexcept> -# include <string.h> -# include <wchar.h> -# include <windows.h> - -# 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 beforeInputEvent; -static HANDLE afterOutputEvent; -static std::string encodedInputTestString; -static std::string encodedTestString; - -static void displayError(DWORD errorCode) -{ - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "Failed with error: 0x" << errorCode << "!" << std::endl; - LPWSTR message; - if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - nullptr, errorCode, 0, (LPWSTR)&message, 0, nullptr)) { - 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); -} - -std::basic_streambuf<char>* errstream(const char* unused) -{ - static_cast<void>(unused); - return std::cerr.rdbuf(); -} - -std::basic_streambuf<wchar_t>* errstream(const wchar_t* unused) -{ - static_cast<void>(unused); - return std::wcerr.rdbuf(); -} - -template <typename T> -static void dumpBuffers(const T* expected, const T* received, size_t size) -{ - std::basic_ostream<T> err(errstream(expected)); - err << "Expected output: '" << std::basic_string<T>(expected, size) << "'" - << std::endl; - if (err.fail()) { - err.clear(); - err << "--- Error while outputting ---" << std::endl; - } - err << "Received output: '" << std::basic_string<T>(received, size) << "'" - << std::endl; - if (err.fail()) { - err.clear(); - err << "--- Error while outputting ---" << std::endl; - } - std::cerr << "Expected output | Received output" << std::endl; - for (size_t i = 0; i < size; i++) { - std::cerr << std::setbase(16) << std::setfill('0') << " " - << "0x" << std::setw(8) << static_cast<unsigned int>(expected[i]) - << " | " - << "0x" << std::setw(8) - << static_cast<unsigned int>(received[i]); - if (static_cast<unsigned int>(expected[i]) != - static_cast<unsigned int>(received[i])) { - std::cerr << " MISMATCH!"; - } - std::cerr << std::endl; - } - std::cerr << std::endl; -} - -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(nullptr, 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(nullptr, // No module name (use command line) - cmd, // Command line - nullptr, // Process handle not inheritable - nullptr, // Thread handle not inheritable - bInheritHandles, // Set handle inheritance - dwCreationFlags, - nullptr, // Use parent's environment block - nullptr, // Use parent's starting directory - &startupInfo, // Pointer to STARTUPINFO structure - &processInfo) != - 0; // Pointer to PROCESS_INFORMATION structure - if (!success) { - DWORD lastError = GetLastError(); - std::cerr << "CreateProcess(" << kwsys::Encoding::ToNarrow(cmd) << ")" - << std::endl; - displayError(lastError); - } - 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 = nullptr; - 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 = nullptr; - - 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, - nullptr); // no template - if (file == INVALID_HANDLE_VALUE) { - DWORD lastError = GetLastError(); - std::cerr << "CreateFile(" << kwsys::Encoding::ToNarrow(fileName) << ")" - << std::endl; - displayError(lastError); - } - 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]; - char buffer2[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, - nullptr) || - bytesWritten == 0) { - throw std::runtime_error("WriteFile failed!"); - } - - if (createProcess(inPipeRead, outPipeWrite, errPipeWrite)) { - try { - DWORD status; - if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != - WAIT_OBJECT_0) { - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "WaitForSingleObject returned unexpected status 0x" - << status << std::endl; - std::cerr.unsetf(std::ios::hex); - throw std::runtime_error("WaitForSingleObject failed!"); - } - DWORD bytesRead = 0; - if (!ReadFile(outPipeRead, buffer, sizeof(buffer), &bytesRead, - nullptr) || - bytesRead == 0) { - throw std::runtime_error("ReadFile#1 failed!"); - } - buffer[bytesRead] = 0; - if ((bytesRead < - encodedTestString.size() + 1 + encodedInputTestString.size() && - !ReadFile(outPipeRead, buffer + bytesRead, - sizeof(buffer) - bytesRead, &bytesRead, nullptr)) || - bytesRead == 0) { - throw std::runtime_error("ReadFile#2 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, buffer2, sizeof(buffer2), &bytesRead, - nullptr) || - bytesRead == 0) { - throw std::runtime_error("ReadFile#3 failed!"); - } - buffer2[bytesRead] = 0; - didFail = encodedTestString.compare(0, std::string::npos, buffer2, - encodedTestString.size()) == 0 - ? 0 - : 1; - } - if (didFail != 0) { - std::cerr << "Pipe's output didn't match expected output!" - << std::endl; - dumpBuffers<char>(encodedTestString.c_str(), buffer, - encodedTestString.size()); - dumpBuffers<char>(encodedInputTestString.c_str(), - buffer + encodedTestString.size() + 1, - encodedInputTestString.size()); - dumpBuffers<char>(encodedTestString.c_str(), buffer2, - encodedTestString.size()); - } - } catch (const std::runtime_error& ex) { - DWORD lastError = GetLastError(); - std::cerr << "In function testPipe, line " << __LINE__ << ": " - << ex.what() << std::endl; - displayError(lastError); - } - finishProcess(didFail == 0); - } - } catch (const std::runtime_error& ex) { - DWORD lastError = GetLastError(); - std::cerr << "In function testPipe, line " << __LINE__ << ": " << ex.what() - << std::endl; - displayError(lastError); - } - 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!"); - } - DWORD bytesWritten = 0; - char buffer[200]; - char buffer2[200]; - - int length; - if ((length = WideCharToMultiByte(TestCodepage, 0, UnicodeInputTestString, - -1, buffer, sizeof(buffer), nullptr, - nullptr)) == 0) { - throw std::runtime_error("WideCharToMultiByte failed!"); - } - buffer[length - 1] = '\n'; - if (!WriteFile(inFile, buffer, length, &bytesWritten, nullptr) || - 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 { - DWORD status; - if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != - WAIT_OBJECT_0) { - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "WaitForSingleObject returned unexpected status 0x" - << status << std::endl; - std::cerr.unsetf(std::ios::hex); - throw std::runtime_error("WaitForSingleObject failed!"); - } - if (SetFilePointer(outFile, 0, 0, FILE_BEGIN) == - INVALID_SET_FILE_POINTER) { - throw std::runtime_error("SetFilePointer#1 failed!"); - } - if (!ReadFile(outFile, buffer, sizeof(buffer), &bytesRead, nullptr) || - bytesRead == 0) { - throw std::runtime_error("ReadFile#1 failed!"); - } - buffer[bytesRead] = 0; - if (memcmp(buffer, encodedTestString.c_str(), - encodedTestString.size()) == 0 && - memcmp(buffer + encodedTestString.size() + 1, - encodedInputTestString.c_str(), - encodedInputTestString.size()) == 0) { - bytesRead = 0; - if (SetFilePointer(errFile, 0, 0, FILE_BEGIN) == - INVALID_SET_FILE_POINTER) { - throw std::runtime_error("SetFilePointer#2 failed!"); - } - - if (!ReadFile(errFile, buffer2, sizeof(buffer2), &bytesRead, - nullptr) || - bytesRead == 0) { - throw std::runtime_error("ReadFile#2 failed!"); - } - buffer2[bytesRead] = 0; - didFail = encodedTestString.compare(0, std::string::npos, buffer2, - encodedTestString.size()) == 0 - ? 0 - : 1; - } - if (didFail != 0) { - std::cerr << "File's output didn't match expected output!" - << std::endl; - dumpBuffers<char>(encodedTestString.c_str(), buffer, - encodedTestString.size()); - dumpBuffers<char>(encodedInputTestString.c_str(), - buffer + encodedTestString.size() + 1, - encodedInputTestString.size()); - dumpBuffers<char>(encodedTestString.c_str(), buffer2, - encodedTestString.size()); - } - } catch (const std::runtime_error& ex) { - DWORD lastError = GetLastError(); - std::cerr << "In function testFile, line " << __LINE__ << ": " - << ex.what() << std::endl; - displayError(lastError); - } - finishProcess(didFail == 0); - } - } catch (const std::runtime_error& ex) { - DWORD lastError = GetLastError(); - std::cerr << "In function testFile, line " << __LINE__ << ": " << ex.what() - << std::endl; - displayError(lastError); - } - 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]; - FaceName[0] = 0; - 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) -# elif defined __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" -# else -# pragma warning(disable : 4996) -# endif -# endif - const bool isVistaOrGreater = - LOBYTE(LOWORD(GetVersion())) >= HIBYTE(_WIN32_WINNT_VISTA); -# ifdef KWSYS_WINDOWS_DEPRECATED_GetVersion -# ifdef __clang__ -# pragma clang diagnostic pop -# else -# pragma warning(pop) -# endif -# 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", nullptr, nullptr, - (LPBYTE)&FontFamily, &dwordSize) == ERROR_SUCCESS) { - if (FontFamily != TestFontFamily) { - RegQueryValueExW(hConsoleKey, L"FaceName", nullptr, nullptr, - (LPBYTE)FaceName, &FaceNameSize); - RegQueryValueExW(hConsoleKey, L"FontSize", nullptr, nullptr, - (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; - } - RegCloseKey(hConsoleKey); - } else { - std::cerr << "RegOpenKeyExW(HKEY_CURRENT_USER\\Console) failed!" - << std::endl; - } - } - if (forceNewConsole || GetConsoleMode(parentOut, &consoleMode) == 0) { - // Not a real console, let's create new one. - FreeConsole(); - if (!AllocConsole()) { - std::cerr << "AllocConsole failed!" << std::endl; - return didFail; - } - SECURITY_ATTRIBUTES securityAttributes; - securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); - securityAttributes.bInheritHandle = TRUE; - securityAttributes.lpSecurityDescriptor = nullptr; - hIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes, - OPEN_EXISTING, 0, nullptr); - if (hIn == INVALID_HANDLE_VALUE) { - DWORD lastError = GetLastError(); - std::cerr << "CreateFile(CONIN$)" << std::endl; - displayError(lastError); - } - hOut = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, &securityAttributes, - OPEN_EXISTING, 0, nullptr); - if (hOut == INVALID_HANDLE_VALUE) { - DWORD lastError = GetLastError(); - std::cerr << "CreateFile(CONOUT$)" << std::endl; - displayError(lastError); - } - 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; - } - } - } else { - std::cerr << "GetCurrentConsoleFontEx failed!" << std::endl; - } - } 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)); - if (FaceName[0] != 0) { - RegSetValueExW(hConsoleKey, L"FaceName", 0, REG_SZ, (BYTE*)FaceName, - FaceNameSize); - } else { - RegDeleteValueW(hConsoleKey, L"FaceName"); - } - RegSetValueExW(hConsoleKey, L"FontSize", 0, REG_DWORD, (BYTE*)&FontSize, - sizeof(FontSize)); - RegCloseKey(hConsoleKey); - } -# if _WIN32_WINNT >= _WIN32_WINNT_VISTA - } -# endif - - if (createProcess(nullptr, nullptr, nullptr)) { - try { - DWORD status; - if ((status = WaitForSingleObject(beforeInputEvent, waitTimeout)) != - WAIT_OBJECT_0) { - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "WaitForSingleObject returned unexpected status 0x" - << status << std::endl; - std::cerr.unsetf(std::ios::hex); - throw std::runtime_error("WaitForSingleObject#1 failed!"); - } - INPUT_RECORD inputBuffer[(sizeof(UnicodeInputTestString) / - sizeof(UnicodeInputTestString[0])) * - 2]; - memset(&inputBuffer, 0, sizeof(inputBuffer)); - unsigned int i; - 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; - // We need to wait a bit before writing to console so child process have - // started waiting for input on stdin. - Sleep(300); - if (!WriteConsoleInputW(hIn, inputBuffer, - sizeof(inputBuffer) / sizeof(inputBuffer[0]), - &eventsWritten) || - eventsWritten == 0) { - throw std::runtime_error("WriteConsoleInput failed!"); - } - if ((status = WaitForSingleObject(afterOutputEvent, waitTimeout)) != - WAIT_OBJECT_0) { - std::cerr.setf(std::ios::hex, std::ios::basefield); - std::cerr << "WaitForSingleObject returned unexpected status 0x" - << status << std::endl; - std::cerr.unsetf(std::ios::hex); - throw std::runtime_error("WaitForSingleObject#2 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::replace(wideTestString.begin(), wideTestString.end(), '\0', ' '); - std::wstring wideInputTestString = - kwsys::Encoding::ToWide(encodedInputTestString); - if (memcmp(outputBuffer, wideTestString.c_str(), - wideTestString.size() * sizeof(wchar_t)) == 0 && - memcmp(outputBuffer + screenBufferInfo.dwSize.X * 1, - wideTestString.c_str(), - wideTestString.size() * sizeof(wchar_t)) == 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) * sizeof(wchar_t)) == 0) { - didFail = 0; - } else { - std::cerr << "Console's output didn't match expected output!" - << std::endl; - dumpBuffers<wchar_t>(wideTestString.c_str(), outputBuffer, - wideTestString.size()); - dumpBuffers<wchar_t>(wideTestString.c_str(), - outputBuffer + screenBufferInfo.dwSize.X * 1, - wideTestString.size()); - dumpBuffers<wchar_t>( - UnicodeInputTestString, outputBuffer + screenBufferInfo.dwSize.X * 2, - (sizeof(UnicodeInputTestString) - 1) / sizeof(WCHAR)); - dumpBuffers<wchar_t>(wideInputTestString.c_str(), - outputBuffer + screenBufferInfo.dwSize.X * 3, - wideInputTestString.size() - 1); - } - delete[] outputBuffer; - } catch (const std::runtime_error& ex) { - DWORD lastError = GetLastError(); - std::cerr << "In function testConsole, line " << __LINE__ << ": " - << ex.what() << std::endl; - displayError(lastError); - } - 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) - beforeInputEvent = CreateEventW(nullptr, - FALSE, // auto-reset event - FALSE, // initial state is nonsignaled - BeforeInputEventName); // object name - if (!beforeInputEvent) { - std::cerr << "CreateEvent#1 failed " << GetLastError() << std::endl; - return 1; - } - - afterOutputEvent = CreateEventW(nullptr, FALSE, FALSE, AfterOutputEventName); - if (!afterOutputEvent) { - std::cerr << "CreateEvent#2 failed " << GetLastError() << std::endl; - return 1; - } - - encodedTestString = kwsys::Encoding::ToNarrow(std::wstring( - UnicodeTestString, sizeof(UnicodeTestString) / sizeof(wchar_t) - 1)); - encodedInputTestString = kwsys::Encoding::ToNarrow( - std::wstring(UnicodeInputTestString, - sizeof(UnicodeInputTestString) / sizeof(wchar_t) - 1)); - encodedInputTestString += "\n"; - - ret |= testPipe(); - ret |= testFile(); - ret |= testConsole(); - - CloseHandle(beforeInputEvent); - CloseHandle(afterOutputEvent); -#endif - - return ret; -} diff --git a/test/API/driver/kwsys/testConsoleBuf.hxx b/test/API/driver/kwsys/testConsoleBuf.hxx deleted file mode 100644 index e93cb4f..0000000 --- a/test/API/driver/kwsys/testConsoleBuf.hxx +++ /dev/null @@ -1,17 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef testConsoleBuf_hxx -#define testConsoleBuf_hxx - -static const wchar_t cmdConsoleBufChild[] = L"testConsoleBufChild"; - -static const wchar_t BeforeInputEventName[] = L"BeforeInputEvent"; -static const wchar_t AfterOutputEventName[] = L"AfterOutputEvent"; - -// यूनिकोड είναι здорово! -static const wchar_t UnicodeTestString[] = - L"\u092F\u0942\u0928\u093F\u0915\u094B\u0921 " - L"\u03B5\u03AF\u03BD\0\u03B1\u03B9 " - L"\u0437\u0434\u043E\u0440\u043E\u0432\u043E!"; - -#endif diff --git a/test/API/driver/kwsys/testConsoleBufChild.cxx b/test/API/driver/kwsys/testConsoleBufChild.cxx deleted file mode 100644 index 3c8fdc2..0000000 --- a/test/API/driver/kwsys/testConsoleBufChild.cxx +++ /dev/null @@ -1,55 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#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(std::wstring( - UnicodeTestString, sizeof(UnicodeTestString) / sizeof(wchar_t) - 1)); - std::cout << str << std::endl; - std::cerr << str << std::endl; - } - - std::string input; - HANDLE event = OpenEventW(EVENT_MODIFY_STATE, FALSE, BeforeInputEventName); - if (event) { - SetEvent(event); - CloseHandle(event); - } - - std::cin >> input; - std::cout << input << std::endl; - event = OpenEventW(EVENT_MODIFY_STATE, FALSE, AfterOutputEventName); - if (event) { - SetEvent(event); - CloseHandle(event); - } -#else - static_cast<void>(argc); - static_cast<void>(argv); -#endif - return 0; -} diff --git a/test/API/driver/kwsys/testDirectory.cxx b/test/API/driver/kwsys/testDirectory.cxx deleted file mode 100644 index b1ab0c8..0000000 --- a/test/API/driver/kwsys/testDirectory.cxx +++ /dev/null @@ -1,110 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying -file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Directory.hxx) -#include KWSYS_HEADER(Encoding.hxx) -#include KWSYS_HEADER(SystemTools.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Directory.hxx.in" -# include "Encoding.hxx.in" -# include "SystemTools.hxx.in" -#endif - -#include <fstream> -#include <iostream> -#include <sstream> - -#include <testSystemTools.h> - -int _doLongPathTest() -{ - using namespace kwsys; - static const int LONG_PATH_THRESHOLD = 512; - int res = 0; - std::string topdir(TEST_SYSTEMTOOLS_BINARY_DIR "/directory_testing/"); - std::stringstream testpathstrm; - std::string testdirpath; - std::string extendedtestdirpath; - - testpathstrm << topdir; - size_t pathlen = testpathstrm.str().length(); - testpathstrm.seekp(0, std::ios_base::end); - while (pathlen < LONG_PATH_THRESHOLD) { - testpathstrm << "0123456789/"; - pathlen = testpathstrm.str().length(); - } - - testdirpath = testpathstrm.str(); -#ifdef _WIN32 - extendedtestdirpath = - Encoding::ToNarrow(SystemTools::ConvertToWindowsExtendedPath(testdirpath)); -#else - extendedtestdirpath = testdirpath; -#endif - - if (SystemTools::MakeDirectory(extendedtestdirpath)) { - std::ofstream testfile1( - (extendedtestdirpath + "longfilepathtest1.txt").c_str()); - std::ofstream testfile2( - (extendedtestdirpath + "longfilepathtest2.txt").c_str()); - testfile1 << "foo"; - testfile2 << "bar"; - testfile1.close(); - testfile2.close(); - - Directory testdir; - // Set res to failure if the directory doesn't load - res += !testdir.Load(testdirpath); - // Increment res failure if the directory appears empty - res += testdir.GetNumberOfFiles() == 0; - // Increment res failures if the path has changed from - // what was provided. - res += testdirpath != testdir.GetPath(); - - SystemTools::RemoveADirectory(topdir); - } else { - std::cerr << "Failed to create directory with long path: " - << extendedtestdirpath << std::endl; - res += 1; - } - return res; -} - -int _copyDirectoryTest() -{ - using namespace kwsys; - const std::string source(TEST_SYSTEMTOOLS_BINARY_DIR - "/directory_testing/copyDirectoryTestSrc"); - if (SystemTools::PathExists(source)) { - std::cerr << source << " shouldn't exist before test" << std::endl; - return 1; - } - const std::string destination(TEST_SYSTEMTOOLS_BINARY_DIR - "/directory_testing/copyDirectoryTestDst"); - if (SystemTools::PathExists(destination)) { - std::cerr << destination << " shouldn't exist before test" << std::endl; - return 2; - } - const bool copysuccess = SystemTools::CopyADirectory(source, destination); - const bool destinationexists = SystemTools::PathExists(destination); - if (copysuccess) { - std::cerr << "CopyADirectory should have returned false" << std::endl; - SystemTools::RemoveADirectory(destination); - return 3; - } - if (destinationexists) { - std::cerr << "CopyADirectory returned false, but destination directory" - << " has been created" << std::endl; - SystemTools::RemoveADirectory(destination); - return 4; - } - return 0; -} - -int testDirectory(int, char* []) -{ - return _doLongPathTest() + _copyDirectoryTest(); -} diff --git a/test/API/driver/kwsys/testDynamicLoader.cxx b/test/API/driver/kwsys/testDynamicLoader.cxx deleted file mode 100644 index 2421ac0..0000000 --- a/test/API/driver/kwsys/testDynamicLoader.cxx +++ /dev/null @@ -1,133 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" - -#include KWSYS_HEADER(DynamicLoader.hxx) - -#if defined(__BEOS__) || defined(__HAIKU__) -# include <be/kernel/OS.h> /* disable_debugger() API. */ -#endif - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "DynamicLoader.hxx.in" -#endif - -#include <iostream> -#include <string> - -// Include with <> instead of "" to avoid getting any in-source copy -// left on disk. -#include <testSystemTools.h> - -static std::string GetLibName(const char* lname, const char* subdir = nullptr) -{ - // Construct proper name of lib - std::string slname; - slname = EXECUTABLE_OUTPUT_PATH; - if (subdir) { - slname += "/"; - slname += subdir; - } -#ifdef CMAKE_INTDIR - slname += "/"; - slname += CMAKE_INTDIR; -#endif - slname += "/"; - slname += kwsys::DynamicLoader::LibPrefix(); - slname += lname; - slname += kwsys::DynamicLoader::LibExtension(); - - return slname; -} - -/* libname = Library name (proper prefix, proper extension) - * System = symbol to lookup in libname - * r1: should OpenLibrary succeed ? - * r2: should GetSymbolAddress succeed ? - * r3: should CloseLibrary succeed ? - */ -static int TestDynamicLoader(const char* libname, const char* symbol, int r1, - int r2, int r3, int flags = 0) -{ - std::cerr << "Testing: " << libname << std::endl; - kwsys::DynamicLoader::LibraryHandle l = - kwsys::DynamicLoader::OpenLibrary(libname, flags); - // If result is incompatible with expectation just fails (xor): - if ((r1 && !l) || (!r1 && l)) { - std::cerr << "OpenLibrary: " << kwsys::DynamicLoader::LastError() - << std::endl; - return 1; - } - kwsys::DynamicLoader::SymbolPointer f = - kwsys::DynamicLoader::GetSymbolAddress(l, symbol); - if ((r2 && !f) || (!r2 && f)) { - std::cerr << "GetSymbolAddress: " << kwsys::DynamicLoader::LastError() - << std::endl; - return 1; - } -#ifndef __APPLE__ - int s = kwsys::DynamicLoader::CloseLibrary(l); - if ((r3 && !s) || (!r3 && s)) { - std::cerr << "CloseLibrary: " << kwsys::DynamicLoader::LastError() - << std::endl; - return 1; - } -#else - (void)r3; -#endif - return 0; -} - -int testDynamicLoader(int argc, char* argv[]) -{ -#if defined(_WIN32) - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); -#elif defined(__BEOS__) || defined(__HAIKU__) - disable_debugger(1); -#endif - int res = 0; - if (argc == 3) { - // User specify a libname and symbol to check. - res = TestDynamicLoader(argv[1], argv[2], 1, 1, 1); - return res; - } - -// dlopen() on Syllable before 11/22/2007 doesn't return 0 on error -#ifndef __SYLLABLE__ - // Make sure that inexistent lib is giving correct result - res += TestDynamicLoader("azerty_", "foo_bar", 0, 0, 0); - // Make sure that random binary file cannot be assimilated as dylib - res += TestDynamicLoader(TEST_SYSTEMTOOLS_SOURCE_DIR "/testSystemTools.bin", - "wp", 0, 0, 0); -#endif - -#ifdef __linux__ - // This one is actually fun to test, since dlopen is by default - // loaded...wonder why :) - res += TestDynamicLoader("foobar.lib", "dlopen", 0, 1, 0); - res += TestDynamicLoader("libdl.so", "dlopen", 1, 1, 1); - res += TestDynamicLoader("libdl.so", "TestDynamicLoader", 1, 0, 1); -#endif - // Now try on the generated library - std::string libname = GetLibName(KWSYS_NAMESPACE_STRING "TestDynload"); - res += TestDynamicLoader(libname.c_str(), "dummy", 1, 0, 1); - res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderSymbolPointer", - 1, 1, 1); - res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderSymbolPointer", - 1, 0, 1); - res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderData", 1, 1, 1); - res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderData", 1, 0, 1); - -#ifdef _WIN32 - libname = GetLibName(KWSYS_NAMESPACE_STRING "TestDynloadUse", "dynloaddir"); - res += TestDynamicLoader(libname.c_str(), "dummy", 0, 0, 0); - res += TestDynamicLoader(libname.c_str(), "TestLoad", 1, 1, 1, - kwsys::DynamicLoader::SearchBesideLibrary); - res += TestDynamicLoader(libname.c_str(), "_TestLoad", 1, 0, 1, - kwsys::DynamicLoader::SearchBesideLibrary); -#endif - - return res; -} diff --git a/test/API/driver/kwsys/testDynload.c b/test/API/driver/kwsys/testDynload.c deleted file mode 100644 index c49f747..0000000 --- a/test/API/driver/kwsys/testDynload.c +++ /dev/null @@ -1,13 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifdef _WIN32 -# define DL_EXPORT __declspec(dllexport) -#else -# define DL_EXPORT -#endif - -DL_EXPORT int TestDynamicLoaderData = 0; - -DL_EXPORT void TestDynamicLoaderSymbolPointer() -{ -} diff --git a/test/API/driver/kwsys/testDynloadImpl.c b/test/API/driver/kwsys/testDynloadImpl.c deleted file mode 100644 index 2b9069b..0000000 --- a/test/API/driver/kwsys/testDynloadImpl.c +++ /dev/null @@ -1,10 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ - -#include "testDynloadImpl.h" - -int TestDynamicLoaderImplData = 0; - -void TestDynamicLoaderImplSymbolPointer() -{ -} diff --git a/test/API/driver/kwsys/testDynloadImpl.h b/test/API/driver/kwsys/testDynloadImpl.h deleted file mode 100644 index d0c9dfb..0000000 --- a/test/API/driver/kwsys/testDynloadImpl.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifdef _WIN32 -# ifdef BUILDING_TestDynloadImpl -# define DLIMPL_EXPORT __declspec(dllexport) -# else -# define DLIMPL_EXPORT __declspec(dllimport) -# endif -#else -# define DLIMPL_EXPORT -#endif - -DLIMPL_EXPORT int TestDynamicLoaderImplData; - -DLIMPL_EXPORT void TestDynamicLoaderImplSymbolPointer(); diff --git a/test/API/driver/kwsys/testDynloadUse.c b/test/API/driver/kwsys/testDynloadUse.c deleted file mode 100644 index 5402add..0000000 --- a/test/API/driver/kwsys/testDynloadUse.c +++ /dev/null @@ -1,15 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "testDynloadImpl.h" - -#ifdef _WIN32 -# define DL_EXPORT __declspec(dllexport) -#else -# define DL_EXPORT -#endif - -DL_EXPORT int TestLoad() -{ - TestDynamicLoaderImplSymbolPointer(); - return TestDynamicLoaderImplData; -} diff --git a/test/API/driver/kwsys/testEncode.c b/test/API/driver/kwsys/testEncode.c deleted file mode 100644 index b7b6dd8..0000000 --- a/test/API/driver/kwsys/testEncode.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(MD5.h) - -/* Work-around CMake dependency scanning limitation. This must - duplicate the above list of headers. */ -#if 0 -# include "MD5.h.in" -#endif - -#include <stdio.h> -#include <string.h> - -static const unsigned char testMD5input1[] = - " A quick brown fox jumps over the lazy dog.\n" - " This is sample text for MD5 sum input.\n"; -static const char testMD5output1[] = "8f146af46ed4f267921bb937d4d3500c"; - -static const int testMD5input2len = 28; -static const unsigned char testMD5input2[] = "the cow jumped over the moon"; -static const char testMD5output2[] = "a2ad137b746138fae4e5adca9c85d3ae"; - -static int testMD5_1(kwsysMD5* md5) -{ - char md5out[33]; - kwsysMD5_Initialize(md5); - kwsysMD5_Append(md5, testMD5input1, -1); - kwsysMD5_FinalizeHex(md5, md5out); - md5out[32] = 0; - printf("md5sum 1: expected [%s]\n" - " got [%s]\n", - testMD5output1, md5out); - return (strcmp(md5out, testMD5output1) != 0) ? 1 : 0; -} - -static int testMD5_2(kwsysMD5* md5) -{ - unsigned char digest[16]; - char md5out[33]; - kwsysMD5_Initialize(md5); - kwsysMD5_Append(md5, testMD5input2, testMD5input2len); - kwsysMD5_Finalize(md5, digest); - kwsysMD5_DigestToHex(digest, md5out); - md5out[32] = 0; - printf("md5sum 2: expected [%s]\n" - " got [%s]\n", - testMD5output2, md5out); - return (strcmp(md5out, testMD5output2) != 0) ? 1 : 0; -} - -int testEncode(int argc, char* argv[]) -{ - int result = 0; - (void)argc; - (void)argv; - - /* Test MD5 digest. */ - { - kwsysMD5* md5 = kwsysMD5_New(); - result |= testMD5_1(md5); - result |= testMD5_2(md5); - kwsysMD5_Delete(md5); - } - - return result; -} diff --git a/test/API/driver/kwsys/testEncoding.cxx b/test/API/driver/kwsys/testEncoding.cxx deleted file mode 100644 index 988697b..0000000 --- a/test/API/driver/kwsys/testEncoding.cxx +++ /dev/null @@ -1,286 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" - -#if defined(_MSC_VER) -# pragma warning(disable : 4786) -#endif - -#include KWSYS_HEADER(Encoding.hxx) -#include KWSYS_HEADER(Encoding.h) - -#include <algorithm> -#include <iostream> -#include <locale.h> -#include <stdlib.h> -#include <string.h> - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Encoding.h.in" -# include "Encoding.hxx.in" -#endif - -static const unsigned char helloWorldStrings[][32] = { - // English - { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0 }, - // Japanese - { 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x93, 0xE3, 0x81, 0xAB, 0xE3, 0x81, - 0xA1, 0xE3, 0x81, 0xAF, 0xE4, 0xB8, 0x96, 0xE7, 0x95, 0x8C, 0 }, - // Arabic - { 0xD9, 0x85, 0xD8, 0xB1, 0xD8, 0xAD, 0xD8, 0xA8, 0xD8, 0xA7, 0x20, 0xD8, - 0xA7, 0xD9, 0x84, 0xD8, 0xB9, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x85, 0 }, - // Yiddish - { 0xD7, 0x94, 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0x90, 0x20, 0xD7, - 0x95, 0xD7, 0x95, 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0x98, 0 }, - // Russian - { 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB2, 0xD0, 0xB5, - 0xD1, 0x82, 0x20, 0xD0, 0xBC, 0xD0, 0xB8, 0xD1, 0x80, 0 }, - // Latin - { 0x4D, 0x75, 0x6E, 0x64, 0x75, 0x73, 0x20, 0x73, 0x61, 0x6C, 0x76, 0x65, - 0 }, - // Swahili - { 0x68, 0x75, 0x6A, 0x61, 0x6D, 0x62, 0x6F, 0x20, 0x44, 0x75, 0x6E, 0x69, - 0x61, 0 }, - // Icelandic - { 0x48, 0x61, 0x6C, 0x6C, 0xC3, 0xB3, 0x20, 0x68, 0x65, 0x69, 0x6D, 0x75, - 0x72, 0 }, - { 0 } -}; - -static int testHelloWorldEncoding() -{ - int ret = 0; - for (int i = 0; helloWorldStrings[i][0] != 0; i++) { - std::string str = reinterpret_cast<const char*>(helloWorldStrings[i]); - std::cout << str << std::endl; - std::wstring wstr = kwsys::Encoding::ToWide(str); - std::string str2 = kwsys::Encoding::ToNarrow(wstr); - wchar_t* c_wstr = kwsysEncoding_DupToWide(str.c_str()); - char* c_str2 = kwsysEncoding_DupToNarrow(c_wstr); - if (!wstr.empty() && (str != str2 || strcmp(c_str2, str.c_str()))) { - std::cout << "converted string was different: " << str2 << std::endl; - std::cout << "converted string was different: " << c_str2 << std::endl; - ret++; - } - free(c_wstr); - free(c_str2); - } - return ret; -} - -static int testRobustEncoding() -{ - // test that the conversion functions handle invalid - // unicode correctly/gracefully - - // we manipulate the format flags of stdout, remember - // the original state here to restore before return - std::ios::fmtflags const& flags = std::cout.flags(); - - int ret = 0; - char cstr[] = { (char)-1, 0 }; - // this conversion could fail - std::wstring wstr = kwsys::Encoding::ToWide(cstr); - - wstr = kwsys::Encoding::ToWide(nullptr); - if (wstr != L"") { - const wchar_t* wcstr = wstr.c_str(); - std::cout << "ToWide(NULL) returned"; - for (size_t i = 0; i < wstr.size(); i++) { - std::cout << " " << std::hex << (int)wcstr[i]; - } - std::cout << std::endl; - ret++; - } - wstr = kwsys::Encoding::ToWide(""); - if (wstr != L"") { - const wchar_t* wcstr = wstr.c_str(); - std::cout << "ToWide(\"\") returned"; - for (size_t i = 0; i < wstr.size(); i++) { - std::cout << " " << std::hex << (int)wcstr[i]; - } - std::cout << std::endl; - ret++; - } - -#ifdef _WIN32 - // 16 bit wchar_t - we make an invalid surrogate pair - wchar_t cwstr[] = { 0xD801, 0xDA00, 0 }; - // this conversion could fail - std::string win_str = kwsys::Encoding::ToNarrow(cwstr); -#endif - - std::string str = kwsys::Encoding::ToNarrow(nullptr); - if (str != "") { - std::cout << "ToNarrow(NULL) returned " << str << std::endl; - ret++; - } - - str = kwsys::Encoding::ToNarrow(L""); - if (wstr != L"") { - std::cout << "ToNarrow(\"\") returned " << str << std::endl; - ret++; - } - - std::cout.flags(flags); - return ret; -} - -static int testWithNulls() -{ - int ret = 0; - std::vector<std::string> strings; - strings.push_back(std::string("ab") + '\0' + 'c'); - strings.push_back(std::string("d") + '\0' + '\0' + 'e'); - strings.push_back(std::string() + '\0' + 'f'); - strings.push_back(std::string() + '\0' + '\0' + "gh"); - strings.push_back(std::string("ij") + '\0'); - strings.push_back(std::string("k") + '\0' + '\0'); - strings.push_back(std::string("\0\0\0\0", 4) + "lmn" + - std::string("\0\0\0\0", 4)); - for (std::vector<std::string>::iterator it = strings.begin(); - it != strings.end(); ++it) { - std::wstring wstr = kwsys::Encoding::ToWide(*it); - std::string str = kwsys::Encoding::ToNarrow(wstr); - std::string s(*it); - std::replace(s.begin(), s.end(), '\0', ' '); - std::cout << "'" << s << "' (" << it->size() << ")" << std::endl; - if (str != *it) { - std::replace(str.begin(), str.end(), '\0', ' '); - std::cout << "string with null was different: '" << str << "' (" - << str.size() << ")" << std::endl; - ret++; - } - } - return ret; -} - -static int testCommandLineArguments() -{ - int status = 0; - - char const* argv[2] = { "./app.exe", (char const*)helloWorldStrings[1] }; - - kwsys::Encoding::CommandLineArguments args(2, argv); - kwsys::Encoding::CommandLineArguments arg2 = - kwsys::Encoding::CommandLineArguments(args); - - char const* const* u8_argv = args.argv(); - for (int i = 0; i < args.argc(); i++) { - char const* u8_arg = u8_argv[i]; - if (strcmp(argv[i], u8_arg) != 0) { - std::cout << "argv[" << i << "] " << argv[i] << " != " << u8_arg - << std::endl; - status++; - } - } - - kwsys::Encoding::CommandLineArguments args3 = - kwsys::Encoding::CommandLineArguments::Main(2, argv); - - return status; -} - -static int testToWindowsExtendedPath() -{ -#ifdef _WIN32 - int ret = 0; - if (kwsys::Encoding::ToWindowsExtendedPath( - "L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") != - L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") { - std::cout << "Problem with ToWindowsExtendedPath " - << "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"" - << std::endl; - ++ret; - } - - if (kwsys::Encoding::ToWindowsExtendedPath( - "L:/Local Mojo/Hex Power Pack/Iffy Voodoo") != - L"\\\\?\\L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") { - std::cout << "Problem with ToWindowsExtendedPath " - << "\"L:/Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl; - ++ret; - } - - if (kwsys::Encoding::ToWindowsExtendedPath( - "\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") != - L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") { - std::cout << "Problem with ToWindowsExtendedPath " - << "\"\\\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"" - << std::endl; - ++ret; - } - - if (kwsys::Encoding::ToWindowsExtendedPath( - "//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo") != - L"\\\\?\\UNC\\Foo\\Local Mojo\\Hex Power Pack\\Iffy Voodoo") { - std::cout << "Problem with ToWindowsExtendedPath " - << "\"//Foo/Local Mojo/Hex Power Pack/Iffy Voodoo\"" - << std::endl; - ++ret; - } - - if (kwsys::Encoding::ToWindowsExtendedPath("//") != L"//") { - std::cout << "Problem with ToWindowsExtendedPath " - << "\"//\"" << std::endl; - ++ret; - } - - if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\") != L"\\\\.\\") { - std::cout << "Problem with ToWindowsExtendedPath " - << "\"\\\\.\\\"" << std::endl; - ++ret; - } - - if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\X") != L"\\\\.\\X") { - std::cout << "Problem with ToWindowsExtendedPath " - << "\"\\\\.\\X\"" << std::endl; - ++ret; - } - - if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\X:") != L"\\\\?\\X:") { - std::cout << "Problem with ToWindowsExtendedPath " - << "\"\\\\.\\X:\"" << std::endl; - ++ret; - } - - if (kwsys::Encoding::ToWindowsExtendedPath("\\\\.\\X:\\") != - L"\\\\?\\X:\\") { - std::cout << "Problem with ToWindowsExtendedPath " - << "\"\\\\.\\X:\\\"" << std::endl; - ++ret; - } - - if (kwsys::Encoding::ToWindowsExtendedPath("NUL") != L"\\\\.\\NUL") { - std::cout << "Problem with ToWindowsExtendedPath " - << "\"NUL\"" << std::endl; - ++ret; - } - - return ret; -#else - return 0; -#endif -} - -int testEncoding(int, char* []) -{ - const char* loc = setlocale(LC_ALL, ""); - if (loc) { - std::cout << "Locale: " << loc << std::endl; - } else { - std::cout << "Locale: None" << std::endl; - } - - int ret = 0; - - ret |= testHelloWorldEncoding(); - ret |= testRobustEncoding(); - ret |= testCommandLineArguments(); - ret |= testWithNulls(); - ret |= testToWindowsExtendedPath(); - - return ret; -} diff --git a/test/API/driver/kwsys/testFStream.cxx b/test/API/driver/kwsys/testFStream.cxx deleted file mode 100644 index 5009e98..0000000 --- a/test/API/driver/kwsys/testFStream.cxx +++ /dev/null @@ -1,113 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" - -#if defined(_MSC_VER) -# pragma warning(disable : 4786) -#endif - -#include KWSYS_HEADER(FStream.hxx) -#include <string.h> -#ifdef __BORLANDC__ -# include <mem.h> /* memcmp */ -#endif - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "FStream.hxx.in" -#endif - -#include <iostream> - -static int testNoFile() -{ - kwsys::ifstream in_file("NoSuchFile.txt"); - if (in_file) { - return 1; - } - - return 0; -} - -static const int num_test_files = 7; -static const int max_test_file_size = 45; - -static kwsys::FStream::BOM expected_bom[num_test_files] = { - kwsys::FStream::BOM_None, kwsys::FStream::BOM_None, - kwsys::FStream::BOM_UTF8, kwsys::FStream::BOM_UTF16LE, - kwsys::FStream::BOM_UTF16BE, kwsys::FStream::BOM_UTF32LE, - kwsys::FStream::BOM_UTF32BE -}; - -static unsigned char expected_bom_data[num_test_files][5] = { - { 0 }, - { 0 }, - { 3, 0xEF, 0xBB, 0xBF }, - { 2, 0xFF, 0xFE }, - { 2, 0xFE, 0xFF }, - { 4, 0xFF, 0xFE, 0x00, 0x00 }, - { 4, 0x00, 0x00, 0xFE, 0xFF }, -}; - -static unsigned char file_data[num_test_files][max_test_file_size] = { - { 1, 'H' }, - { 11, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' }, - { 11, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' }, - { 22, 0x48, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x20, - 0x00, 0x57, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6C, 0x00, 0x64, 0x00 }, - { 22, 0x00, 0x48, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6F, 0x00, - 0x20, 0x00, 0x57, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6C, 0x00, 0x64 }, - { 44, 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, - 0x00, 0x6C, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x57, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, - 0x00, 0x6C, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00 }, - { 44, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, - 0x6C, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00, - 0x72, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x64 }, -}; - -static int testBOM() -{ - // test various encodings in binary mode - for (int i = 0; i < num_test_files; i++) { - { - kwsys::ofstream out("bom.txt", kwsys::ofstream::binary); - out.write(reinterpret_cast<const char*>(expected_bom_data[i] + 1), - *expected_bom_data[i]); - out.write(reinterpret_cast<const char*>(file_data[i] + 1), - file_data[i][0]); - } - - kwsys::ifstream in("bom.txt", kwsys::ofstream::binary); - kwsys::FStream::BOM bom = kwsys::FStream::ReadBOM(in); - if (bom != expected_bom[i]) { - std::cout << "Unexpected BOM " << i << std::endl; - return 1; - } - char data[max_test_file_size]; - in.read(data, file_data[i][0]); - if (!in.good()) { - std::cout << "Unable to read data " << i << std::endl; - return 1; - } - - if (memcmp(data, file_data[i] + 1, file_data[i][0]) != 0) { - std::cout << "Incorrect read data " << i << std::endl; - return 1; - } - } - - return 0; -} - -int testFStream(int, char* []) -{ - int ret = 0; - - ret |= testNoFile(); - ret |= testBOM(); - - return ret; -} diff --git a/test/API/driver/kwsys/testFail.c b/test/API/driver/kwsys/testFail.c deleted file mode 100644 index 82caeac..0000000 --- a/test/API/driver/kwsys/testFail.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -int testFail(int argc, char* argv[]) -{ - char* env = getenv("DASHBOARD_TEST_FROM_CTEST"); - int oldCtest = 0; - if (env) { - if (strcmp(env, "1") == 0) { - oldCtest = 1; - } - printf("DASHBOARD_TEST_FROM_CTEST = %s\n", env); - } - printf("%s: This test intentionally fails\n", argv[0]); - if (oldCtest) { - printf("The version of ctest is not able to handle intentionally failing " - "tests, so pass.\n"); - return 0; - } - return argc; -} diff --git a/test/API/driver/kwsys/testHashSTL.cxx b/test/API/driver/kwsys/testHashSTL.cxx deleted file mode 100644 index 4ed2f89..0000000 --- a/test/API/driver/kwsys/testHashSTL.cxx +++ /dev/null @@ -1,64 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(hash_map.hxx) -#include KWSYS_HEADER(hash_set.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "hash_map.hxx.in" -# include "hash_set.hxx.in" -#endif - -#include <iostream> - -#if defined(_MSC_VER) -# pragma warning(disable : 4786) -#endif - -#if defined(__sgi) && !defined(__GNUC__) -# pragma set woff 1468 /* inline function cannot be explicitly instantiated \ - */ -#endif - -template class kwsys::hash_map<const char*, int>; -template class kwsys::hash_set<int>; - -static bool test_hash_map() -{ - typedef kwsys::hash_map<const char*, int> mtype; - mtype m; - const char* keys[] = { "hello", "world" }; - m[keys[0]] = 1; - m.insert(mtype::value_type(keys[1], 2)); - int sum = 0; - for (mtype::iterator mi = m.begin(); mi != m.end(); ++mi) { - std::cout << "Found entry [" << mi->first << "," << mi->second << "]" - << std::endl; - sum += mi->second; - } - return sum == 3; -} - -static bool test_hash_set() -{ - typedef kwsys::hash_set<int> stype; - stype s; - s.insert(1); - s.insert(2); - int sum = 0; - for (stype::iterator si = s.begin(); si != s.end(); ++si) { - std::cout << "Found entry [" << *si << "]" << std::endl; - sum += *si; - } - return sum == 3; -} - -int testHashSTL(int, char* []) -{ - bool result = true; - result = test_hash_map() && result; - result = test_hash_set() && result; - return result ? 0 : 1; -} diff --git a/test/API/driver/kwsys/testProcess.c b/test/API/driver/kwsys/testProcess.c deleted file mode 100644 index 39aaa23..0000000 --- a/test/API/driver/kwsys/testProcess.c +++ /dev/null @@ -1,728 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Process.h) -#include KWSYS_HEADER(Encoding.h) - -/* Work-around CMake dependency scanning limitation. This must - duplicate the above list of headers. */ -#if 0 -# include "Encoding.h.in" -# include "Process.h.in" -#endif - -#include <assert.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if defined(_WIN32) -# include <windows.h> -#else -# include <signal.h> -# include <unistd.h> -#endif - -#if defined(__BORLANDC__) -# pragma warn - 8060 /* possibly incorrect assignment */ -#endif - -/* Platform-specific sleep functions. */ - -#if defined(__BEOS__) && !defined(__ZETA__) -/* BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. */ -# include <be/kernel/OS.h> -static inline void testProcess_usleep(unsigned int usec) -{ - snooze(usec); -} -#elif defined(_WIN32) -/* Windows can only sleep in millisecond intervals. */ -static void testProcess_usleep(unsigned int usec) -{ - Sleep(usec / 1000); -} -#else -# define testProcess_usleep usleep -#endif - -#if defined(_WIN32) -static void testProcess_sleep(unsigned int sec) -{ - Sleep(sec * 1000); -} -#else -static void testProcess_sleep(unsigned int sec) -{ - sleep(sec); -} -#endif - -int runChild(const char* cmd[], int state, int exception, int value, int share, - int output, int delay, double timeout, int poll, int repeat, - int disown, int createNewGroup, unsigned int interruptDelay); - -static int test1(int argc, const char* argv[]) -{ - /* This is a very basic functional test of kwsysProcess. It is repeated - numerous times to verify that there are no resource leaks in kwsysProcess - that eventually lead to an error. Many versions of OS X will fail after - 256 leaked file handles, so 257 iterations seems to be a good test. On - the other hand, too many iterations will cause the test to time out - - especially if the test is instrumented with e.g. valgrind. - - If you have problems with this test timing out on your system, or want to - run more than 257 iterations, you can change the number of iterations by - setting the KWSYS_TEST_PROCESS_1_COUNT environment variable. */ - (void)argc; - (void)argv; - fprintf(stdout, "Output on stdout from test returning 0.\n"); - fprintf(stderr, "Output on stderr from test returning 0.\n"); - return 0; -} - -static int test2(int argc, const char* argv[]) -{ - (void)argc; - (void)argv; - fprintf(stdout, "Output on stdout from test returning 123.\n"); - fprintf(stderr, "Output on stderr from test returning 123.\n"); - return 123; -} - -static int test3(int argc, const char* argv[]) -{ - (void)argc; - (void)argv; - fprintf(stdout, "Output before sleep on stdout from timeout test.\n"); - fprintf(stderr, "Output before sleep on stderr from timeout test.\n"); - fflush(stdout); - fflush(stderr); - testProcess_sleep(15); - fprintf(stdout, "Output after sleep on stdout from timeout test.\n"); - fprintf(stderr, "Output after sleep on stderr from timeout test.\n"); - return 0; -} - -static int test4(int argc, const char* argv[]) -{ -#ifndef CRASH_USING_ABORT - /* Prepare a pointer to an invalid address. Don't use null, because - dereferencing null is undefined behaviour and compilers are free to - do whatever they want. ex: Clang will warn at compile time, or even - optimize away the write. We hope to 'outsmart' them by using - 'volatile' and a slightly larger address, based on a runtime value. */ - volatile int* invalidAddress = 0; - invalidAddress += argc ? 1 : 2; -#endif - -#if defined(_WIN32) - /* Avoid error diagnostic popups since we are crashing on purpose. */ - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); -#elif defined(__BEOS__) || defined(__HAIKU__) - /* Avoid error diagnostic popups since we are crashing on purpose. */ - disable_debugger(1); -#endif - (void)argc; - (void)argv; - fprintf(stdout, "Output before crash on stdout from crash test.\n"); - fprintf(stderr, "Output before crash on stderr from crash test.\n"); - fflush(stdout); - fflush(stderr); -#ifdef CRASH_USING_ABORT - abort(); -#else - assert(invalidAddress); /* Quiet Clang scan-build. */ - /* Provoke deliberate crash by writing to the invalid address. */ - *invalidAddress = 0; -#endif - fprintf(stdout, "Output after crash on stdout from crash test.\n"); - fprintf(stderr, "Output after crash on stderr from crash test.\n"); - return 0; -} - -static int test5(int argc, const char* argv[]) -{ - int r; - const char* cmd[4]; - (void)argc; - cmd[0] = argv[0]; - cmd[1] = "run"; - cmd[2] = "4"; - cmd[3] = 0; - fprintf(stdout, "Output on stdout before recursive test.\n"); - fprintf(stderr, "Output on stderr before recursive test.\n"); - fflush(stdout); - fflush(stderr); - r = runChild(cmd, kwsysProcess_State_Exception, -#ifdef CRASH_USING_ABORT - kwsysProcess_Exception_Other, -#else - kwsysProcess_Exception_Fault, -#endif - 1, 1, 1, 0, 15, 0, 1, 0, 0, 0); - fprintf(stdout, "Output on stdout after recursive test.\n"); - fprintf(stderr, "Output on stderr after recursive test.\n"); - fflush(stdout); - fflush(stderr); - return r; -} - -#define TEST6_SIZE (4096 * 2) -static void test6(int argc, const char* argv[]) -{ - int i; - char runaway[TEST6_SIZE + 1]; - (void)argc; - (void)argv; - for (i = 0; i < TEST6_SIZE; ++i) { - runaway[i] = '.'; - } - runaway[TEST6_SIZE] = '\n'; - - /* Generate huge amounts of output to test killing. */ - for (;;) { - fwrite(runaway, 1, TEST6_SIZE + 1, stdout); - fflush(stdout); - } -} - -/* Define MINPOLL to be one more than the number of times output is - written. Define MAXPOLL to be the largest number of times a loop - delaying 1/10th of a second should ever have to poll. */ -#define MINPOLL 5 -#define MAXPOLL 20 -static int test7(int argc, const char* argv[]) -{ - (void)argc; - (void)argv; - fprintf(stdout, "Output on stdout before sleep.\n"); - fprintf(stderr, "Output on stderr before sleep.\n"); - fflush(stdout); - fflush(stderr); - /* Sleep for 1 second. */ - testProcess_sleep(1); - fprintf(stdout, "Output on stdout after sleep.\n"); - fprintf(stderr, "Output on stderr after sleep.\n"); - fflush(stdout); - fflush(stderr); - return 0; -} - -static int test8(int argc, const char* argv[]) -{ - /* Create a disowned grandchild to test handling of processes - that exit before their children. */ - int r; - const char* cmd[4]; - (void)argc; - cmd[0] = argv[0]; - cmd[1] = "run"; - cmd[2] = "108"; - cmd[3] = 0; - fprintf(stdout, "Output on stdout before grandchild test.\n"); - fprintf(stderr, "Output on stderr before grandchild test.\n"); - fflush(stdout); - fflush(stderr); - r = runChild(cmd, kwsysProcess_State_Disowned, kwsysProcess_Exception_None, - 1, 1, 1, 0, 10, 0, 1, 1, 0, 0); - fprintf(stdout, "Output on stdout after grandchild test.\n"); - fprintf(stderr, "Output on stderr after grandchild test.\n"); - fflush(stdout); - fflush(stderr); - return r; -} - -static int test8_grandchild(int argc, const char* argv[]) -{ - (void)argc; - (void)argv; - fprintf(stdout, "Output on stdout from grandchild before sleep.\n"); - fprintf(stderr, "Output on stderr from grandchild before sleep.\n"); - fflush(stdout); - fflush(stderr); - /* TODO: Instead of closing pipes here leave them open to make sure - the grandparent can stop listening when the parent exits. This - part of the test cannot be enabled until the feature is - implemented. */ - fclose(stdout); - fclose(stderr); - testProcess_sleep(15); - return 0; -} - -static int test9(int argc, const char* argv[]) -{ - /* Test Ctrl+C behavior: the root test program will send a Ctrl+C to this - process. Here, we start a child process that sleeps for a long time - while ignoring signals. The test is successful if this process waits - for the child to return before exiting from the Ctrl+C handler. - - WARNING: This test will falsely pass if the share parameter of runChild - was set to 0 when invoking the test9 process. */ - int r; - const char* cmd[4]; - (void)argc; - cmd[0] = argv[0]; - cmd[1] = "run"; - cmd[2] = "109"; - cmd[3] = 0; - fprintf(stdout, "Output on stdout before grandchild test.\n"); - fprintf(stderr, "Output on stderr before grandchild test.\n"); - fflush(stdout); - fflush(stderr); - r = runChild(cmd, kwsysProcess_State_Exited, kwsysProcess_Exception_None, 0, - 1, 1, 0, 30, 0, 1, 0, 0, 0); - /* This sleep will avoid a race condition between this function exiting - normally and our Ctrl+C handler exiting abnormally after the process - exits. */ - testProcess_sleep(1); - fprintf(stdout, "Output on stdout after grandchild test.\n"); - fprintf(stderr, "Output on stderr after grandchild test.\n"); - fflush(stdout); - fflush(stderr); - return r; -} - -#if defined(_WIN32) -static BOOL WINAPI test9_grandchild_handler(DWORD dwCtrlType) -{ - /* Ignore all Ctrl+C/Break signals. We must use an actual handler function - instead of using SetConsoleCtrlHandler(NULL, TRUE) so that we can also - ignore Ctrl+Break in addition to Ctrl+C. */ - (void)dwCtrlType; - return TRUE; -} -#endif - -static int test9_grandchild(int argc, const char* argv[]) -{ - /* The grandchild just sleeps for a few seconds while ignoring signals. */ - (void)argc; - (void)argv; -#if defined(_WIN32) - if (!SetConsoleCtrlHandler(test9_grandchild_handler, TRUE)) { - return 1; - } -#else - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - sigemptyset(&sa.sa_mask); - if (sigaction(SIGINT, &sa, 0) < 0) { - return 1; - } -#endif - fprintf(stdout, "Output on stdout from grandchild before sleep.\n"); - fprintf(stderr, "Output on stderr from grandchild before sleep.\n"); - fflush(stdout); - fflush(stderr); - /* Sleep for 9 seconds. */ - testProcess_sleep(9); - fprintf(stdout, "Output on stdout from grandchild after sleep.\n"); - fprintf(stderr, "Output on stderr from grandchild after sleep.\n"); - fflush(stdout); - fflush(stderr); - return 0; -} - -static int test10(int argc, const char* argv[]) -{ - /* Test Ctrl+C behavior: the root test program will send a Ctrl+C to this - process. Here, we start a child process that sleeps for a long time and - processes signals normally. However, this grandchild is created in a new - process group - ensuring that Ctrl+C we receive is sent to our process - groups. We make sure it exits anyway. */ - int r; - const char* cmd[4]; - (void)argc; - cmd[0] = argv[0]; - cmd[1] = "run"; - cmd[2] = "110"; - cmd[3] = 0; - fprintf(stdout, "Output on stdout before grandchild test.\n"); - fprintf(stderr, "Output on stderr before grandchild test.\n"); - fflush(stdout); - fflush(stderr); - r = - runChild(cmd, kwsysProcess_State_Exception, - kwsysProcess_Exception_Interrupt, 0, 1, 1, 0, 30, 0, 1, 0, 1, 0); - fprintf(stdout, "Output on stdout after grandchild test.\n"); - fprintf(stderr, "Output on stderr after grandchild test.\n"); - fflush(stdout); - fflush(stderr); - return r; -} - -static int test10_grandchild(int argc, const char* argv[]) -{ - /* The grandchild just sleeps for a few seconds and handles signals. */ - (void)argc; - (void)argv; - fprintf(stdout, "Output on stdout from grandchild before sleep.\n"); - fprintf(stderr, "Output on stderr from grandchild before sleep.\n"); - fflush(stdout); - fflush(stderr); - /* Sleep for 6 seconds. */ - testProcess_sleep(6); - fprintf(stdout, "Output on stdout from grandchild after sleep.\n"); - fprintf(stderr, "Output on stderr from grandchild after sleep.\n"); - fflush(stdout); - fflush(stderr); - return 0; -} - -static int runChild2(kwsysProcess* kp, const char* cmd[], int state, - int exception, int value, int share, int output, - int delay, double timeout, int poll, int disown, - int createNewGroup, unsigned int interruptDelay) -{ - int result = 0; - char* data = 0; - int length = 0; - double userTimeout = 0; - double* pUserTimeout = 0; - kwsysProcess_SetCommand(kp, cmd); - if (timeout >= 0) { - kwsysProcess_SetTimeout(kp, timeout); - } - if (share) { - kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDOUT, 1); - kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDERR, 1); - } - if (disown) { - kwsysProcess_SetOption(kp, kwsysProcess_Option_Detach, 1); - } - if (createNewGroup) { - kwsysProcess_SetOption(kp, kwsysProcess_Option_CreateProcessGroup, 1); - } - kwsysProcess_Execute(kp); - - if (poll) { - pUserTimeout = &userTimeout; - } - - if (interruptDelay) { - testProcess_sleep(interruptDelay); - kwsysProcess_Interrupt(kp); - } - - if (!share && !disown) { - int p; - while ((p = kwsysProcess_WaitForData(kp, &data, &length, pUserTimeout))) { - if (output) { - if (poll && p == kwsysProcess_Pipe_Timeout) { - fprintf(stdout, "WaitForData timeout reached.\n"); - fflush(stdout); - - /* Count the number of times we polled without getting data. - If it is excessive then kill the child and fail. */ - if (++poll >= MAXPOLL) { - fprintf(stdout, "Poll count reached limit %d.\n", MAXPOLL); - kwsysProcess_Kill(kp); - } - } else { - fwrite(data, 1, (size_t)length, stdout); - fflush(stdout); - } - } - if (poll) { - /* Delay to avoid busy loop during polling. */ - testProcess_usleep(100000); - } - if (delay) { -/* Purposely sleeping only on Win32 to let pipe fill up. */ -#if defined(_WIN32) - testProcess_usleep(100000); -#endif - } - } - } - - if (disown) { - kwsysProcess_Disown(kp); - } else { - kwsysProcess_WaitForExit(kp, 0); - } - - switch (kwsysProcess_GetState(kp)) { - case kwsysProcess_State_Starting: - printf("No process has been executed.\n"); - break; - case kwsysProcess_State_Executing: - printf("The process is still executing.\n"); - break; - case kwsysProcess_State_Expired: - printf("Child was killed when timeout expired.\n"); - break; - case kwsysProcess_State_Exited: - printf("Child exited with value = %d\n", kwsysProcess_GetExitValue(kp)); - result = ((exception != kwsysProcess_GetExitException(kp)) || - (value != kwsysProcess_GetExitValue(kp))); - break; - case kwsysProcess_State_Killed: - printf("Child was killed by parent.\n"); - break; - case kwsysProcess_State_Exception: - printf("Child terminated abnormally: %s\n", - kwsysProcess_GetExceptionString(kp)); - result = ((exception != kwsysProcess_GetExitException(kp)) || - (value != kwsysProcess_GetExitValue(kp))); - break; - case kwsysProcess_State_Disowned: - printf("Child was disowned.\n"); - break; - case kwsysProcess_State_Error: - printf("Error in administrating child process: [%s]\n", - kwsysProcess_GetErrorString(kp)); - break; - } - - if (result) { - if (exception != kwsysProcess_GetExitException(kp)) { - fprintf(stderr, - "Mismatch in exit exception. " - "Should have been %d, was %d.\n", - exception, kwsysProcess_GetExitException(kp)); - } - if (value != kwsysProcess_GetExitValue(kp)) { - fprintf(stderr, - "Mismatch in exit value. " - "Should have been %d, was %d.\n", - value, kwsysProcess_GetExitValue(kp)); - } - } - - if (kwsysProcess_GetState(kp) != state) { - fprintf(stderr, - "Mismatch in state. " - "Should have been %d, was %d.\n", - state, kwsysProcess_GetState(kp)); - result = 1; - } - - /* We should have polled more times than there were data if polling - was enabled. */ - if (poll && poll < MINPOLL) { - fprintf(stderr, "Poll count is %d, which is less than %d.\n", poll, - MINPOLL); - result = 1; - } - - return result; -} - -/** - * Runs a child process and blocks until it returns. Arguments as follows: - * - * cmd = Command line to run. - * state = Expected return value of kwsysProcess_GetState after exit. - * exception = Expected return value of kwsysProcess_GetExitException. - * value = Expected return value of kwsysProcess_GetExitValue. - * share = Whether to share stdout/stderr child pipes with our pipes - * by way of kwsysProcess_SetPipeShared. If false, new pipes - * are created. - * output = If !share && !disown, whether to write the child's stdout - * and stderr output to our stdout. - * delay = If !share && !disown, adds an additional short delay to - * the pipe loop to allow the pipes to fill up; Windows only. - * timeout = Non-zero to sets a timeout in seconds via - * kwsysProcess_SetTimeout. - * poll = If !share && !disown, we count the number of 0.1 second - * intervals where the child pipes had no new data. We fail - * if not in the bounds of MINPOLL/MAXPOLL. - * repeat = Number of times to run the process. - * disown = If set, the process is disowned. - * createNewGroup = If set, the process is created in a new process group. - * interruptDelay = If non-zero, number of seconds to delay before - * interrupting the process. Note that this delay will occur - * BEFORE any reading/polling of pipes occurs and before any - * detachment occurs. - */ -int runChild(const char* cmd[], int state, int exception, int value, int share, - int output, int delay, double timeout, int poll, int repeat, - int disown, int createNewGroup, unsigned int interruptDelay) -{ - int result = 1; - kwsysProcess* kp = kwsysProcess_New(); - if (!kp) { - fprintf(stderr, "kwsysProcess_New returned NULL!\n"); - return 1; - } - while (repeat-- > 0) { - result = runChild2(kp, cmd, state, exception, value, share, output, delay, - timeout, poll, disown, createNewGroup, interruptDelay); - if (result) { - break; - } - } - kwsysProcess_Delete(kp); - return result; -} - -int main(int argc, const char* argv[]) -{ - int n = 0; - -#ifdef _WIN32 - int i; - char new_args[10][_MAX_PATH]; - LPWSTR* w_av = CommandLineToArgvW(GetCommandLineW(), &argc); - for (i = 0; i < argc; i++) { - kwsysEncoding_wcstombs(new_args[i], w_av[i], _MAX_PATH); - argv[i] = new_args[i]; - } - LocalFree(w_av); -#endif - -#if 0 - { - HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); - DuplicateHandle(GetCurrentProcess(), out, - GetCurrentProcess(), &out, 0, FALSE, - DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); - SetStdHandle(STD_OUTPUT_HANDLE, out); - } - { - HANDLE out = GetStdHandle(STD_ERROR_HANDLE); - DuplicateHandle(GetCurrentProcess(), out, - GetCurrentProcess(), &out, 0, FALSE, - DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); - SetStdHandle(STD_ERROR_HANDLE, out); - } -#endif - if (argc == 2) { - n = atoi(argv[1]); - } else if (argc == 3 && strcmp(argv[1], "run") == 0) { - n = atoi(argv[2]); - } - /* Check arguments. */ - if (((n >= 1 && n <= 10) || n == 108 || n == 109 || n == 110) && argc == 3) { - /* This is the child process for a requested test number. */ - switch (n) { - case 1: - return test1(argc, argv); - case 2: - return test2(argc, argv); - case 3: - return test3(argc, argv); - case 4: - return test4(argc, argv); - case 5: - return test5(argc, argv); - case 6: - test6(argc, argv); - return 0; - case 7: - return test7(argc, argv); - case 8: - return test8(argc, argv); - case 9: - return test9(argc, argv); - case 10: - return test10(argc, argv); - case 108: - return test8_grandchild(argc, argv); - case 109: - return test9_grandchild(argc, argv); - case 110: - return test10_grandchild(argc, argv); - } - fprintf(stderr, "Invalid test number %d.\n", n); - return 1; - } else if (n >= 1 && n <= 10) { - /* This is the parent process for a requested test number. */ - int states[10] = { - kwsysProcess_State_Exited, kwsysProcess_State_Exited, - kwsysProcess_State_Expired, kwsysProcess_State_Exception, - kwsysProcess_State_Exited, kwsysProcess_State_Expired, - kwsysProcess_State_Exited, kwsysProcess_State_Exited, - kwsysProcess_State_Expired, /* Ctrl+C handler test */ - kwsysProcess_State_Exception /* Process group test */ - }; - int exceptions[10] = { - kwsysProcess_Exception_None, kwsysProcess_Exception_None, - kwsysProcess_Exception_None, -#ifdef CRASH_USING_ABORT - kwsysProcess_Exception_Other, -#else - kwsysProcess_Exception_Fault, -#endif - kwsysProcess_Exception_None, kwsysProcess_Exception_None, - kwsysProcess_Exception_None, kwsysProcess_Exception_None, - kwsysProcess_Exception_None, kwsysProcess_Exception_Interrupt - }; - int values[10] = { 0, 123, 1, 1, 0, 0, 0, 0, 1, 1 }; - int shares[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; - int outputs[10] = { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 }; - int delays[10] = { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }; - double timeouts[10] = { 10, 10, 10, 30, 30, 10, -1, 10, 6, 4 }; - int polls[10] = { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }; - int repeat[10] = { 257, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - int createNewGroups[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; - unsigned int interruptDelays[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 3, 2 }; - int r; - const char* cmd[4]; -#ifdef _WIN32 - char* argv0 = 0; -#endif - char* test1IterationsStr = getenv("KWSYS_TEST_PROCESS_1_COUNT"); - if (test1IterationsStr) { - long int test1Iterations = strtol(test1IterationsStr, 0, 10); - if (test1Iterations > 10 && test1Iterations != LONG_MAX) { - repeat[0] = (int)test1Iterations; - } - } -#ifdef _WIN32 - if (n == 0 && (argv0 = strdup(argv[0]))) { - /* Try converting to forward slashes to see if it works. */ - char* c; - for (c = argv0; *c; ++c) { - if (*c == '\\') { - *c = '/'; - } - } - cmd[0] = argv0; - } else { - cmd[0] = argv[0]; - } -#else - cmd[0] = argv[0]; -#endif - cmd[1] = "run"; - cmd[2] = argv[1]; - cmd[3] = 0; - fprintf(stdout, "Output on stdout before test %d.\n", n); - fprintf(stderr, "Output on stderr before test %d.\n", n); - fflush(stdout); - fflush(stderr); - r = runChild(cmd, states[n - 1], exceptions[n - 1], values[n - 1], - shares[n - 1], outputs[n - 1], delays[n - 1], timeouts[n - 1], - polls[n - 1], repeat[n - 1], 0, createNewGroups[n - 1], - interruptDelays[n - 1]); - fprintf(stdout, "Output on stdout after test %d.\n", n); - fprintf(stderr, "Output on stderr after test %d.\n", n); - fflush(stdout); - fflush(stderr); -#if defined(_WIN32) - free(argv0); -#endif - return r; - } else if (argc > 2 && strcmp(argv[1], "0") == 0) { - /* This is the special debugging test to run a given command - line. */ - const char** cmd = argv + 2; - int state = kwsysProcess_State_Exited; - int exception = kwsysProcess_Exception_None; - int value = 0; - double timeout = 0; - int r = - runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1, 0, 0, 0); - return r; - } else { - /* Improper usage. */ - fprintf(stdout, "Usage: %s <test number>\n", argv[0]); - return 1; - } -} diff --git a/test/API/driver/kwsys/testSharedForward.c.in b/test/API/driver/kwsys/testSharedForward.c.in deleted file mode 100644 index b3eb413..0000000 --- a/test/API/driver/kwsys/testSharedForward.c.in +++ /dev/null @@ -1,27 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#if defined(CMAKE_INTDIR) -# define CONFIG_DIR_PRE CMAKE_INTDIR "/" -# define CONFIG_DIR_POST "/" CMAKE_INTDIR -#else -# define CONFIG_DIR_PRE "" -# define CONFIG_DIR_POST "" -#endif -#define @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD "@EXEC_DIR@" -#define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD "." CONFIG_DIR_POST -#define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL 0 -#define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD \ - CONFIG_DIR_PRE "@KWSYS_NAMESPACE@TestProcess" -#define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL \ - "@KWSYS_NAMESPACE@TestProcess" -#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND "--command" -#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT "--print" -#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD "--ldd" -#if defined(CMAKE_INTDIR) -# define @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME CMAKE_INTDIR -#endif -#include <@KWSYS_NAMESPACE@/SharedForward.h> -int main(int argc, char** argv) -{ - return @KWSYS_NAMESPACE@_shared_forward_to_real(argc, argv); -} diff --git a/test/API/driver/kwsys/testSystemInformation.cxx b/test/API/driver/kwsys/testSystemInformation.cxx deleted file mode 100644 index 154517e..0000000 --- a/test/API/driver/kwsys/testSystemInformation.cxx +++ /dev/null @@ -1,106 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(SystemInformation.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "SystemInformation.hxx.in" -#endif - -#include <iostream> - -#if defined(KWSYS_USE_LONG_LONG) -# if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG) -# define iostreamLongLong(x) (x) -# else -# define iostreamLongLong(x) ((long)x) -# endif -#elif defined(KWSYS_USE___INT64) -# if defined(KWSYS_IOS_HAS_OSTREAM___INT64) -# define iostreamLongLong(x) (x) -# else -# define iostreamLongLong(x) ((long)x) -# endif -#else -# error "No Long Long" -#endif - -#define printMethod(info, m) std::cout << #m << ": " << info.m() << "\n" - -#define printMethod2(info, m, unit) \ - std::cout << #m << ": " << info.m() << " " << unit << "\n" - -#define printMethod3(info, m, unit) \ - std::cout << #m << ": " << iostreamLongLong(info.m) << " " << unit << "\n" - -int testSystemInformation(int, char* []) -{ - std::cout << "CTEST_FULL_OUTPUT\n"; // avoid truncation - - kwsys::SystemInformation info; - info.RunCPUCheck(); - info.RunOSCheck(); - info.RunMemoryCheck(); - printMethod(info, GetOSName); - printMethod(info, GetOSIsLinux); - printMethod(info, GetOSIsApple); - printMethod(info, GetOSIsWindows); - printMethod(info, GetHostname); - printMethod(info, GetFullyQualifiedDomainName); - printMethod(info, GetOSRelease); - printMethod(info, GetOSVersion); - printMethod(info, GetOSPlatform); - printMethod(info, Is64Bits); - printMethod(info, GetVendorString); - printMethod(info, GetVendorID); - printMethod(info, GetTypeID); - printMethod(info, GetFamilyID); - printMethod(info, GetModelID); - printMethod(info, GetExtendedProcessorName); - printMethod(info, GetSteppingCode); - printMethod(info, GetProcessorSerialNumber); - printMethod2(info, GetProcessorCacheSize, "KB"); - printMethod(info, GetLogicalProcessorsPerPhysical); - printMethod2(info, GetProcessorClockFrequency, "MHz"); - printMethod(info, GetNumberOfLogicalCPU); - printMethod(info, GetNumberOfPhysicalCPU); - printMethod(info, DoesCPUSupportCPUID); - printMethod(info, GetProcessorAPICID); - printMethod2(info, GetTotalVirtualMemory, "MB"); - printMethod2(info, GetAvailableVirtualMemory, "MB"); - printMethod2(info, GetTotalPhysicalMemory, "MB"); - printMethod2(info, GetAvailablePhysicalMemory, "MB"); - printMethod3(info, GetHostMemoryTotal(), "KiB"); - printMethod3(info, GetHostMemoryAvailable("KWSHL"), "KiB"); - printMethod3(info, GetProcMemoryAvailable("KWSHL", "KWSPL"), "KiB"); - printMethod3(info, GetHostMemoryUsed(), "KiB"); - printMethod3(info, GetProcMemoryUsed(), "KiB"); - printMethod(info, GetLoadAverage); - - for (long int i = 0; i <= 31; i++) { - if (info.DoesCPUSupportFeature(static_cast<long int>(1) << i)) { - std::cout << "CPU feature " << i << "\n"; - } - } - - /* test stack trace - */ - std::cout << "Program Stack:" << std::endl - << kwsys::SystemInformation::GetProgramStack(0, 0) << std::endl - << std::endl; - - /* test segv handler - info.SetStackTraceOnError(1); - double *d = (double*)100; - *d=0; - */ - - /* test abort handler - info.SetStackTraceOnError(1); - abort(); - */ - - return 0; -} diff --git a/test/API/driver/kwsys/testSystemTools.bin b/test/API/driver/kwsys/testSystemTools.bin Binary files differdeleted file mode 100644 index 961a404..0000000 --- a/test/API/driver/kwsys/testSystemTools.bin +++ /dev/null diff --git a/test/API/driver/kwsys/testSystemTools.cxx b/test/API/driver/kwsys/testSystemTools.cxx deleted file mode 100644 index 1f3a15b..0000000 --- a/test/API/driver/kwsys/testSystemTools.cxx +++ /dev/null @@ -1,1128 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" - -#if defined(_MSC_VER) -# pragma warning(disable : 4786) -#endif - -#include KWSYS_HEADER(FStream.hxx) -#include KWSYS_HEADER(SystemTools.hxx) - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "FStream.hxx.in" -# include "SystemTools.hxx.in" -#endif - -// Include with <> instead of "" to avoid getting any in-source copy -// left on disk. -#include <testSystemTools.h> - -#include <iostream> -#include <sstream> -#include <stdlib.h> /* free */ -#include <string.h> /* strcmp */ -#if defined(_WIN32) && !defined(__CYGWIN__) -# include <io.h> /* _umask (MSVC) / umask (Borland) */ -# ifdef _MSC_VER -# define umask _umask // Note this is still umask on Borland -# endif -#endif -#include <sys/stat.h> /* umask (POSIX), _S_I* constants (Windows) */ -// Visual C++ does not define mode_t (note that Borland does, however). -#if defined(_MSC_VER) -typedef unsigned short mode_t; -#endif - -static const char* toUnixPaths[][2] = { - { "/usr/local/bin/passwd", "/usr/local/bin/passwd" }, - { "/usr/lo cal/bin/pa sswd", "/usr/lo cal/bin/pa sswd" }, - { "/usr/lo\\ cal/bin/pa\\ sswd", "/usr/lo/ cal/bin/pa/ sswd" }, - { "c:/usr/local/bin/passwd", "c:/usr/local/bin/passwd" }, - { "c:/usr/lo cal/bin/pa sswd", "c:/usr/lo cal/bin/pa sswd" }, - { "c:/usr/lo\\ cal/bin/pa\\ sswd", "c:/usr/lo/ cal/bin/pa/ sswd" }, - { "\\usr\\local\\bin\\passwd", "/usr/local/bin/passwd" }, - { "\\usr\\lo cal\\bin\\pa sswd", "/usr/lo cal/bin/pa sswd" }, - { "\\usr\\lo\\ cal\\bin\\pa\\ sswd", "/usr/lo/ cal/bin/pa/ sswd" }, - { "c:\\usr\\local\\bin\\passwd", "c:/usr/local/bin/passwd" }, - { "c:\\usr\\lo cal\\bin\\pa sswd", "c:/usr/lo cal/bin/pa sswd" }, - { "c:\\usr\\lo\\ cal\\bin\\pa\\ sswd", "c:/usr/lo/ cal/bin/pa/ sswd" }, - { "\\\\usr\\local\\bin\\passwd", "//usr/local/bin/passwd" }, - { "\\\\usr\\lo cal\\bin\\pa sswd", "//usr/lo cal/bin/pa sswd" }, - { "\\\\usr\\lo\\ cal\\bin\\pa\\ sswd", "//usr/lo/ cal/bin/pa/ sswd" }, - { nullptr, nullptr } -}; - -static bool CheckConvertToUnixSlashes(std::string const& input, - std::string const& output) -{ - std::string result = input; - kwsys::SystemTools::ConvertToUnixSlashes(result); - if (result != output) { - std::cerr << "Problem with ConvertToUnixSlashes - input: " << input - << " output: " << result << " expected: " << output << std::endl; - return false; - } - return true; -} - -static const char* checkEscapeChars[][4] = { - { "1 foo 2 bar 2", "12", "\\", "\\1 foo \\2 bar \\2" }, - { " {} ", "{}", "#", " #{#} " }, - { nullptr, nullptr, nullptr, nullptr } -}; - -static bool CheckEscapeChars(std::string const& input, - const char* chars_to_escape, char escape_char, - std::string const& output) -{ - std::string result = kwsys::SystemTools::EscapeChars( - input.c_str(), chars_to_escape, escape_char); - if (result != output) { - std::cerr << "Problem with CheckEscapeChars - input: " << input - << " output: " << result << " expected: " << output << std::endl; - return false; - } - return true; -} - -static bool CheckFileOperations() -{ - bool res = true; - const std::string testNonExistingFile(TEST_SYSTEMTOOLS_SOURCE_DIR - "/testSystemToolsNonExistingFile"); - const std::string testDotFile(TEST_SYSTEMTOOLS_SOURCE_DIR "/."); - const std::string testBinFile(TEST_SYSTEMTOOLS_SOURCE_DIR - "/testSystemTools.bin"); - const std::string testTxtFile(TEST_SYSTEMTOOLS_SOURCE_DIR - "/testSystemTools.cxx"); - const std::string testNewDir(TEST_SYSTEMTOOLS_BINARY_DIR - "/testSystemToolsNewDir"); - const std::string testNewFile(testNewDir + "/testNewFile.txt"); - - if (kwsys::SystemTools::DetectFileType(testNonExistingFile.c_str()) != - kwsys::SystemTools::FileTypeUnknown) { - std::cerr << "Problem with DetectFileType - failed to detect type of: " - << testNonExistingFile << std::endl; - res = false; - } - - if (kwsys::SystemTools::DetectFileType(testDotFile.c_str()) != - kwsys::SystemTools::FileTypeUnknown) { - std::cerr << "Problem with DetectFileType - failed to detect type of: " - << testDotFile << std::endl; - res = false; - } - - if (kwsys::SystemTools::DetectFileType(testBinFile.c_str()) != - kwsys::SystemTools::FileTypeBinary) { - std::cerr << "Problem with DetectFileType - failed to detect type of: " - << testBinFile << std::endl; - res = false; - } - - if (kwsys::SystemTools::DetectFileType(testTxtFile.c_str()) != - kwsys::SystemTools::FileTypeText) { - std::cerr << "Problem with DetectFileType - failed to detect type of: " - << testTxtFile << std::endl; - res = false; - } - - if (kwsys::SystemTools::FileLength(testBinFile) != 766) { - std::cerr << "Problem with FileLength - incorrect length for: " - << testBinFile << std::endl; - res = false; - } - - kwsys::SystemTools::Stat_t buf; - if (kwsys::SystemTools::Stat(testTxtFile.c_str(), &buf) != 0) { - std::cerr << "Problem with Stat - unable to stat text file: " - << testTxtFile << std::endl; - res = false; - } - - if (kwsys::SystemTools::Stat(testBinFile, &buf) != 0) { - std::cerr << "Problem with Stat - unable to stat bin file: " << testBinFile - << std::endl; - res = false; - } - - if (!kwsys::SystemTools::MakeDirectory(testNewDir)) { - std::cerr << "Problem with MakeDirectory for: " << testNewDir << std::endl; - res = false; - } - // calling it again should just return true - if (!kwsys::SystemTools::MakeDirectory(testNewDir)) { - std::cerr << "Problem with second call to MakeDirectory for: " - << testNewDir << std::endl; - res = false; - } - // calling with 0 pointer should return false - if (kwsys::SystemTools::MakeDirectory(nullptr)) { - std::cerr << "Problem with MakeDirectory(0)" << std::endl; - res = false; - } - // calling with an empty string should return false - if (kwsys::SystemTools::MakeDirectory(std::string())) { - std::cerr << "Problem with MakeDirectory(std::string())" << std::endl; - res = false; - } - // check existence - if (!kwsys::SystemTools::FileExists(testNewDir.c_str(), false)) { - std::cerr << "Problem with FileExists as C string and not file for: " - << testNewDir << std::endl; - res = false; - } - // check existence - if (!kwsys::SystemTools::PathExists(testNewDir)) { - std::cerr << "Problem with PathExists for: " << testNewDir << std::endl; - res = false; - } - // remove it - if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) { - std::cerr << "Problem with RemoveADirectory for: " << testNewDir - << std::endl; - res = false; - } - // check existence - if (kwsys::SystemTools::FileExists(testNewDir.c_str(), false)) { - std::cerr << "After RemoveADirectory: " - << "Problem with FileExists as C string and not file for: " - << testNewDir << std::endl; - res = false; - } - // check existence - if (kwsys::SystemTools::PathExists(testNewDir)) { - std::cerr << "After RemoveADirectory: " - << "Problem with PathExists for: " << testNewDir << std::endl; - res = false; - } - // create it using the char* version - if (!kwsys::SystemTools::MakeDirectory(testNewDir.c_str())) { - std::cerr << "Problem with second call to MakeDirectory as C string for: " - << testNewDir << std::endl; - res = false; - } - - if (!kwsys::SystemTools::Touch(testNewFile, true)) { - std::cerr << "Problem with Touch for: " << testNewFile << std::endl; - res = false; - } - // calling MakeDirectory with something that is no file should fail - if (kwsys::SystemTools::MakeDirectory(testNewFile)) { - std::cerr << "Problem with to MakeDirectory for: " << testNewFile - << std::endl; - res = false; - } - - // calling with 0 pointer should return false - if (kwsys::SystemTools::FileExists(nullptr)) { - std::cerr << "Problem with FileExists(0)" << std::endl; - res = false; - } - if (kwsys::SystemTools::FileExists(nullptr, true)) { - std::cerr << "Problem with FileExists(0) as file" << std::endl; - res = false; - } - // calling with an empty string should return false - if (kwsys::SystemTools::FileExists(std::string())) { - std::cerr << "Problem with FileExists(std::string())" << std::endl; - res = false; - } - // FileExists(x, true) should return false on a directory - if (kwsys::SystemTools::FileExists(testNewDir, true)) { - std::cerr << "Problem with FileExists as file for: " << testNewDir - << std::endl; - res = false; - } - if (kwsys::SystemTools::FileExists(testNewDir.c_str(), true)) { - std::cerr << "Problem with FileExists as C string and file for: " - << testNewDir << std::endl; - res = false; - } - // FileExists(x, false) should return true even on a directory - if (!kwsys::SystemTools::FileExists(testNewDir, false)) { - std::cerr << "Problem with FileExists as not file for: " << testNewDir - << std::endl; - res = false; - } - if (!kwsys::SystemTools::FileExists(testNewDir.c_str(), false)) { - std::cerr << "Problem with FileExists as C string and not file for: " - << testNewDir << std::endl; - res = false; - } - // should work, was created as new file before - if (!kwsys::SystemTools::FileExists(testNewFile)) { - std::cerr << "Problem with FileExists for: " << testNewFile << std::endl; - res = false; - } - if (!kwsys::SystemTools::FileExists(testNewFile.c_str())) { - std::cerr << "Problem with FileExists as C string for: " << testNewFile - << std::endl; - res = false; - } - if (!kwsys::SystemTools::FileExists(testNewFile, true)) { - std::cerr << "Problem with FileExists as file for: " << testNewFile - << std::endl; - res = false; - } - if (!kwsys::SystemTools::FileExists(testNewFile.c_str(), true)) { - std::cerr << "Problem with FileExists as C string and file for: " - << testNewFile << std::endl; - res = false; - } - - // calling with an empty string should return false - if (kwsys::SystemTools::PathExists(std::string())) { - std::cerr << "Problem with PathExists(std::string())" << std::endl; - res = false; - } - // PathExists(x) should return true on a directory - if (!kwsys::SystemTools::PathExists(testNewDir)) { - std::cerr << "Problem with PathExists for: " << testNewDir << std::endl; - res = false; - } - // should work, was created as new file before - if (!kwsys::SystemTools::PathExists(testNewFile)) { - std::cerr << "Problem with PathExists for: " << testNewFile << std::endl; - res = false; - } - -// Reset umask -#if defined(_WIN32) && !defined(__CYGWIN__) - // NOTE: Windows doesn't support toggling _S_IREAD. - mode_t fullMask = _S_IWRITE; -#else - // On a normal POSIX platform, we can toggle all permissions. - mode_t fullMask = S_IRWXU | S_IRWXG | S_IRWXO; -#endif - mode_t orig_umask = umask(fullMask); - - // Test file permissions without umask - mode_t origPerm, thisPerm; - if (!kwsys::SystemTools::GetPermissions(testNewFile, origPerm)) { - std::cerr << "Problem with GetPermissions (1) for: " << testNewFile - << std::endl; - res = false; - } - - if (!kwsys::SystemTools::SetPermissions(testNewFile, 0)) { - std::cerr << "Problem with SetPermissions (1) for: " << testNewFile - << std::endl; - res = false; - } - - if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm)) { - std::cerr << "Problem with GetPermissions (2) for: " << testNewFile - << std::endl; - res = false; - } - - if ((thisPerm & fullMask) != 0) { - std::cerr << "SetPermissions failed to set permissions (1) for: " - << testNewFile << ": actual = " << thisPerm - << "; expected = " << 0 << std::endl; - res = false; - } - - // While we're at it, check proper TestFileAccess functionality. - if (kwsys::SystemTools::TestFileAccess(testNewFile, - kwsys::TEST_FILE_WRITE)) { - std::cerr - << "TestFileAccess incorrectly indicated that this is a writable file:" - << testNewFile << std::endl; - res = false; - } - - if (!kwsys::SystemTools::TestFileAccess(testNewFile, kwsys::TEST_FILE_OK)) { - std::cerr - << "TestFileAccess incorrectly indicated that this file does not exist:" - << testNewFile << std::endl; - res = false; - } - - // Test restoring/setting full permissions. - if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask)) { - std::cerr << "Problem with SetPermissions (2) for: " << testNewFile - << std::endl; - res = false; - } - - if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm)) { - std::cerr << "Problem with GetPermissions (3) for: " << testNewFile - << std::endl; - res = false; - } - - if ((thisPerm & fullMask) != fullMask) { - std::cerr << "SetPermissions failed to set permissions (2) for: " - << testNewFile << ": actual = " << thisPerm - << "; expected = " << fullMask << std::endl; - res = false; - } - - // Test setting file permissions while honoring umask - if (!kwsys::SystemTools::SetPermissions(testNewFile, fullMask, true)) { - std::cerr << "Problem with SetPermissions (3) for: " << testNewFile - << std::endl; - res = false; - } - - if (!kwsys::SystemTools::GetPermissions(testNewFile, thisPerm)) { - std::cerr << "Problem with GetPermissions (4) for: " << testNewFile - << std::endl; - res = false; - } - - if ((thisPerm & fullMask) != 0) { - std::cerr << "SetPermissions failed to honor umask for: " << testNewFile - << ": actual = " << thisPerm << "; expected = " << 0 - << std::endl; - res = false; - } - - // Restore umask - umask(orig_umask); - - // Restore file permissions - if (!kwsys::SystemTools::SetPermissions(testNewFile, origPerm)) { - std::cerr << "Problem with SetPermissions (4) for: " << testNewFile - << std::endl; - res = false; - } - - // Remove the test file - if (!kwsys::SystemTools::RemoveFile(testNewFile)) { - std::cerr << "Problem with RemoveFile: " << testNewFile << std::endl; - res = false; - } - - std::string const testFileMissing(testNewDir + "/testMissingFile.txt"); - if (!kwsys::SystemTools::RemoveFile(testFileMissing)) { - std::string const& msg = kwsys::SystemTools::GetLastSystemError(); - std::cerr << "RemoveFile(\"" << testFileMissing << "\") failed: " << msg - << "\n"; - res = false; - } - - std::string const testFileMissingDir(testNewDir + "/missing/file.txt"); - if (!kwsys::SystemTools::RemoveFile(testFileMissingDir)) { - std::string const& msg = kwsys::SystemTools::GetLastSystemError(); - std::cerr << "RemoveFile(\"" << testFileMissingDir << "\") failed: " << msg - << "\n"; - res = false; - } - - kwsys::SystemTools::Touch(testNewFile, true); - if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) { - std::cerr << "Problem with RemoveADirectory for: " << testNewDir - << std::endl; - res = false; - } - -#ifdef KWSYS_TEST_SYSTEMTOOLS_LONG_PATHS - // Perform the same file and directory creation and deletion tests but - // with paths > 256 characters in length. - - const std::string testNewLongDir( - TEST_SYSTEMTOOLS_BINARY_DIR - "/" - "012345678901234567890123456789012345678901234567890123456789" - "012345678901234567890123456789012345678901234567890123456789" - "012345678901234567890123456789012345678901234567890123456789" - "012345678901234567890123456789012345678901234567890123456789" - "01234567890123"); - const std::string testNewLongFile( - testNewLongDir + - "/" - "012345678901234567890123456789012345678901234567890123456789" - "012345678901234567890123456789012345678901234567890123456789" - "012345678901234567890123456789012345678901234567890123456789" - "012345678901234567890123456789012345678901234567890123456789" - "0123456789.txt"); - - if (!kwsys::SystemTools::MakeDirectory(testNewLongDir)) { - std::cerr << "Problem with MakeDirectory for: " << testNewLongDir - << std::endl; - res = false; - } - - if (!kwsys::SystemTools::Touch(testNewLongFile.c_str(), true)) { - std::cerr << "Problem with Touch for: " << testNewLongFile << std::endl; - res = false; - } - - if (!kwsys::SystemTools::RemoveFile(testNewLongFile)) { - std::cerr << "Problem with RemoveFile: " << testNewLongFile << std::endl; - res = false; - } - - kwsys::SystemTools::Touch(testNewLongFile.c_str(), true); - if (!kwsys::SystemTools::RemoveADirectory(testNewLongDir)) { - std::cerr << "Problem with RemoveADirectory for: " << testNewLongDir - << std::endl; - res = false; - } -#endif - - return res; -} - -static bool CheckStringOperations() -{ - bool res = true; - - std::string test = "mary had a little lamb."; - if (kwsys::SystemTools::CapitalizedWords(test) != - "Mary Had A Little Lamb.") { - std::cerr << "Problem with CapitalizedWords " << '"' << test << '"' - << std::endl; - res = false; - } - - test = "Mary Had A Little Lamb."; - if (kwsys::SystemTools::UnCapitalizedWords(test) != - "mary had a little lamb.") { - std::cerr << "Problem with UnCapitalizedWords " << '"' << test << '"' - << std::endl; - res = false; - } - - test = "MaryHadTheLittleLamb."; - if (kwsys::SystemTools::AddSpaceBetweenCapitalizedWords(test) != - "Mary Had The Little Lamb.") { - std::cerr << "Problem with AddSpaceBetweenCapitalizedWords " << '"' << test - << '"' << std::endl; - res = false; - } - - char* cres = - kwsys::SystemTools::AppendStrings("Mary Had A", " Little Lamb."); - if (strcmp(cres, "Mary Had A Little Lamb.")) { - std::cerr << "Problem with AppendStrings " - << "\"Mary Had A\" \" Little Lamb.\"" << std::endl; - res = false; - } - delete[] cres; - - cres = kwsys::SystemTools::AppendStrings("Mary Had", " A ", "Little Lamb."); - if (strcmp(cres, "Mary Had A Little Lamb.")) { - std::cerr << "Problem with AppendStrings " - << "\"Mary Had\" \" A \" \"Little Lamb.\"" << std::endl; - res = false; - } - delete[] cres; - - if (kwsys::SystemTools::CountChar("Mary Had A Little Lamb.", 'a') != 3) { - std::cerr << "Problem with CountChar " - << "\"Mary Had A Little Lamb.\"" << std::endl; - res = false; - } - - cres = kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.", "aeiou"); - if (strcmp(cres, "Mry Hd A Lttl Lmb.")) { - std::cerr << "Problem with RemoveChars " - << "\"Mary Had A Little Lamb.\"" << std::endl; - res = false; - } - delete[] cres; - - cres = kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb."); - if (strcmp(cres, "A")) { - std::cerr << "Problem with RemoveCharsButUpperHex " - << "\"Mary Had A Little Lamb.\"" << std::endl; - res = false; - } - delete[] cres; - - char* cres2 = strdup("Mary Had A Little Lamb."); - kwsys::SystemTools::ReplaceChars(cres2, "aeiou", 'X'); - if (strcmp(cres2, "MXry HXd A LXttlX LXmb.")) { - std::cerr << "Problem with ReplaceChars " - << "\"Mary Had A Little Lamb.\"" << std::endl; - res = false; - } - free(cres2); - - if (!kwsys::SystemTools::StringStartsWith("Mary Had A Little Lamb.", - "Mary ")) { - std::cerr << "Problem with StringStartsWith " - << "\"Mary Had A Little Lamb.\"" << std::endl; - res = false; - } - - if (!kwsys::SystemTools::StringEndsWith("Mary Had A Little Lamb.", - " Lamb.")) { - std::cerr << "Problem with StringEndsWith " - << "\"Mary Had A Little Lamb.\"" << std::endl; - res = false; - } - - cres = kwsys::SystemTools::DuplicateString("Mary Had A Little Lamb."); - if (strcmp(cres, "Mary Had A Little Lamb.")) { - std::cerr << "Problem with DuplicateString " - << "\"Mary Had A Little Lamb.\"" << std::endl; - res = false; - } - delete[] cres; - - test = "Mary Had A Little Lamb."; - if (kwsys::SystemTools::CropString(test, 13) != "Mary ...Lamb.") { - std::cerr << "Problem with CropString " - << "\"Mary Had A Little Lamb.\"" << std::endl; - res = false; - } - - std::vector<std::string> lines; - kwsys::SystemTools::Split("Mary Had A Little Lamb.", lines, ' '); - if (lines[0] != "Mary" || lines[1] != "Had" || lines[2] != "A" || - lines[3] != "Little" || lines[4] != "Lamb.") { - std::cerr << "Problem with Split " - << "\"Mary Had A Little Lamb.\"" << std::endl; - res = false; - } - - if (kwsys::SystemTools::ConvertToWindowsOutputPath( - "L://Local Mojo/Hex Power Pack/Iffy Voodoo") != - "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"") { - std::cerr << "Problem with ConvertToWindowsOutputPath " - << "\"L://Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl; - res = false; - } - - if (kwsys::SystemTools::ConvertToWindowsOutputPath( - "//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo") != - "\"\\\\grayson\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"") { - std::cerr << "Problem with ConvertToWindowsOutputPath " - << "\"//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo\"" - << std::endl; - res = false; - } - - if (kwsys::SystemTools::ConvertToUnixOutputPath( - "//Local Mojo/Hex Power Pack/Iffy Voodoo") != - "//Local\\ Mojo/Hex\\ Power\\ Pack/Iffy\\ Voodoo") { - std::cerr << "Problem with ConvertToUnixOutputPath " - << "\"//Local Mojo/Hex Power Pack/Iffy Voodoo\"" << std::endl; - res = false; - } - - return res; -} - -static bool CheckPutEnv(const std::string& env, const char* name, - const char* value) -{ - if (!kwsys::SystemTools::PutEnv(env)) { - std::cerr << "PutEnv(\"" << env << "\") failed!" << std::endl; - return false; - } - std::string v = "(null)"; - kwsys::SystemTools::GetEnv(name, v); - if (v != value) { - std::cerr << "GetEnv(\"" << name << "\") returned \"" << v << "\", not \"" - << value << "\"!" << std::endl; - return false; - } - return true; -} - -static bool CheckUnPutEnv(const char* env, const char* name) -{ - if (!kwsys::SystemTools::UnPutEnv(env)) { - std::cerr << "UnPutEnv(\"" << env << "\") failed!" << std::endl; - return false; - } - std::string v; - if (kwsys::SystemTools::GetEnv(name, v)) { - std::cerr << "GetEnv(\"" << name << "\") returned \"" << v - << "\", not (null)!" << std::endl; - return false; - } - return true; -} - -static bool CheckEnvironmentOperations() -{ - bool res = true; - res &= CheckPutEnv("A=B", "A", "B"); - res &= CheckPutEnv("B=C", "B", "C"); - res &= CheckPutEnv("C=D", "C", "D"); - res &= CheckPutEnv("D=E", "D", "E"); - res &= CheckUnPutEnv("A", "A"); - res &= CheckUnPutEnv("B=", "B"); - res &= CheckUnPutEnv("C=D", "C"); - /* Leave "D=E" in environment so a memory checker can test for leaks. */ - return res; -} - -static bool CheckRelativePath(const std::string& local, - const std::string& remote, - const std::string& expected) -{ - std::string result = kwsys::SystemTools::RelativePath(local, remote); - if (!kwsys::SystemTools::ComparePath(expected, result)) { - std::cerr << "RelativePath(" << local << ", " << remote << ") yielded " - << result << " instead of " << expected << std::endl; - return false; - } - return true; -} - -static bool CheckRelativePaths() -{ - bool res = true; - res &= CheckRelativePath("/usr/share", "/bin/bash", "../../bin/bash"); - res &= CheckRelativePath("/usr/./share/", "/bin/bash", "../../bin/bash"); - res &= CheckRelativePath("/usr//share/", "/bin/bash", "../../bin/bash"); - res &= - CheckRelativePath("/usr/share/../bin/", "/bin/bash", "../../bin/bash"); - res &= CheckRelativePath("/usr/share", "/usr/share//bin", "bin"); - return res; -} - -static bool CheckCollapsePath(const std::string& path, - const std::string& expected, - const char* base = nullptr) -{ - std::string result = kwsys::SystemTools::CollapseFullPath(path, base); - if (!kwsys::SystemTools::ComparePath(expected, result)) { - std::cerr << "CollapseFullPath(" << path << ") yielded " << result - << " instead of " << expected << std::endl; - return false; - } - return true; -} - -static bool CheckCollapsePath() -{ - bool res = true; - res &= CheckCollapsePath("/usr/share/*", "/usr/share/*"); - res &= CheckCollapsePath("C:/Windows/*", "C:/Windows/*"); - res &= CheckCollapsePath("/usr/share/../lib", "/usr/lib"); - res &= CheckCollapsePath("/usr/share/./lib", "/usr/share/lib"); - res &= CheckCollapsePath("/usr/share/../../lib", "/lib"); - res &= CheckCollapsePath("/usr/share/.././../lib", "/lib"); - res &= CheckCollapsePath("/../lib", "/lib"); - res &= CheckCollapsePath("/../lib/", "/lib"); - res &= CheckCollapsePath("/", "/"); - res &= CheckCollapsePath("C:/", "C:/"); - res &= CheckCollapsePath("C:/../", "C:/"); - res &= CheckCollapsePath("C:/../../", "C:/"); - res &= CheckCollapsePath("../b", "../../b", "../"); - res &= CheckCollapsePath("../a/../b", "../b", "../rel"); - res &= CheckCollapsePath("a/../b", "../rel/b", "../rel"); - return res; -} - -static std::string StringVectorToString(const std::vector<std::string>& vec) -{ - std::stringstream ss; - ss << "vector("; - for (std::vector<std::string>::const_iterator i = vec.begin(); - i != vec.end(); ++i) { - if (i != vec.begin()) { - ss << ", "; - } - ss << *i; - } - ss << ")"; - return ss.str(); -} - -static bool CheckGetPath() -{ - const char* envName = "S"; -#ifdef _WIN32 - const char* envValue = "C:\\Somewhere\\something;D:\\Temp"; -#else - const char* envValue = "/Somewhere/something:/tmp"; -#endif - const char* registryPath = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MyApp; MyKey]"; - - std::vector<std::string> originalPaths; - originalPaths.push_back(registryPath); - - std::vector<std::string> expectedPaths; - expectedPaths.push_back(registryPath); -#ifdef _WIN32 - expectedPaths.push_back("C:/Somewhere/something"); - expectedPaths.push_back("D:/Temp"); -#else - expectedPaths.push_back("/Somewhere/something"); - expectedPaths.push_back("/tmp"); -#endif - - bool res = true; - res &= CheckPutEnv(std::string(envName) + "=" + envValue, envName, envValue); - - std::vector<std::string> paths = originalPaths; - kwsys::SystemTools::GetPath(paths, envName); - - if (paths != expectedPaths) { - std::cerr << "GetPath(" << StringVectorToString(originalPaths) << ", " - << envName << ") yielded " << StringVectorToString(paths) - << " instead of " << StringVectorToString(expectedPaths) - << std::endl; - res = false; - } - - res &= CheckUnPutEnv(envName, envName); - return res; -} - -static bool CheckGetFilenameName() -{ - const char* windowsFilepath = "C:\\somewhere\\something"; - const char* unixFilepath = "/somewhere/something"; - -#if defined(_WIN32) || defined(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES) - std::string expectedWindowsFilename = "something"; -#else - std::string expectedWindowsFilename = "C:\\somewhere\\something"; -#endif - std::string expectedUnixFilename = "something"; - - bool res = true; - std::string filename = kwsys::SystemTools::GetFilenameName(windowsFilepath); - if (filename != expectedWindowsFilename) { - std::cerr << "GetFilenameName(" << windowsFilepath << ") yielded " - << filename << " instead of " << expectedWindowsFilename - << std::endl; - res = false; - } - - filename = kwsys::SystemTools::GetFilenameName(unixFilepath); - if (filename != expectedUnixFilename) { - std::cerr << "GetFilenameName(" << unixFilepath << ") yielded " << filename - << " instead of " << expectedUnixFilename << std::endl; - res = false; - } - return res; -} - -static bool CheckFind() -{ - bool res = true; - const std::string testFindFileName("testFindFile.txt"); - const std::string testFindFile(TEST_SYSTEMTOOLS_BINARY_DIR "/" + - testFindFileName); - - if (!kwsys::SystemTools::Touch(testFindFile, true)) { - std::cerr << "Problem with Touch for: " << testFindFile << std::endl; - // abort here as the existence of the file only makes the test meaningful - return false; - } - - std::vector<std::string> searchPaths; - searchPaths.push_back(TEST_SYSTEMTOOLS_BINARY_DIR); - if (kwsys::SystemTools::FindFile(testFindFileName, searchPaths, true) - .empty()) { - std::cerr << "Problem with FindFile without system paths for: " - << testFindFileName << std::endl; - res = false; - } - if (kwsys::SystemTools::FindFile(testFindFileName, searchPaths, false) - .empty()) { - std::cerr << "Problem with FindFile with system paths for: " - << testFindFileName << std::endl; - res = false; - } - - return res; -} - -static bool CheckIsSubDirectory() -{ - bool res = true; - - if (kwsys::SystemTools::IsSubDirectory("/foo", "/") == false) { - std::cerr << "Problem with IsSubDirectory (root - unix): " << std::endl; - res = false; - } - if (kwsys::SystemTools::IsSubDirectory("c:/foo", "c:/") == false) { - std::cerr << "Problem with IsSubDirectory (root - dos): " << std::endl; - res = false; - } - if (kwsys::SystemTools::IsSubDirectory("/foo/bar", "/foo") == false) { - std::cerr << "Problem with IsSubDirectory (deep): " << std::endl; - res = false; - } - if (kwsys::SystemTools::IsSubDirectory("/foo", "/foo") == true) { - std::cerr << "Problem with IsSubDirectory (identity): " << std::endl; - res = false; - } - if (kwsys::SystemTools::IsSubDirectory("/fooo", "/foo") == true) { - std::cerr << "Problem with IsSubDirectory (substring): " << std::endl; - res = false; - } - if (kwsys::SystemTools::IsSubDirectory("/foo/", "/foo") == true) { - std::cerr << "Problem with IsSubDirectory (prepended slash): " - << std::endl; - res = false; - } - - return res; -} - -static bool CheckGetLineFromStream() -{ - const std::string fileWithFiveCharsOnFirstLine(TEST_SYSTEMTOOLS_SOURCE_DIR - "/README.rst"); - - kwsys::ifstream file(fileWithFiveCharsOnFirstLine.c_str(), std::ios::in); - - if (!file) { - std::cerr << "Problem opening: " << fileWithFiveCharsOnFirstLine - << std::endl; - return false; - } - - std::string line; - bool has_newline = false; - bool result; - - file.seekg(0, std::ios::beg); - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1); - if (!result || line.size() != 5) { - std::cerr << "First line does not have five characters: " << line.size() - << std::endl; - return false; - } - - file.seekg(0, std::ios::beg); - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1); - if (!result || line.size() != 5) { - std::cerr << "First line does not have five characters after rewind: " - << line.size() << std::endl; - return false; - } - - bool ret = true; - - for (size_t size = 1; size <= 5; ++size) { - file.seekg(0, std::ios::beg); - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, - static_cast<long>(size)); - if (!result || line.size() != size) { - std::cerr << "Should have read " << size << " characters but got " - << line.size() << std::endl; - ret = false; - } - } - - return ret; -} - -static bool CheckGetLineFromStreamLongLine() -{ - const std::string fileWithLongLine("longlines.txt"); - std::string firstLine, secondLine; - // First line: large buffer, containing a carriage return for some reason. - firstLine.assign(2050, ' '); - firstLine += "\rfirst"; - secondLine.assign(2050, 'y'); - secondLine += "second"; - - // Create file with long lines. - { - kwsys::ofstream out(fileWithLongLine.c_str(), std::ios::binary); - if (!out) { - std::cerr << "Problem opening for write: " << fileWithLongLine - << std::endl; - return false; - } - out << firstLine << "\r\n\n" << secondLine << "\n"; - } - - kwsys::ifstream file(fileWithLongLine.c_str(), std::ios::binary); - if (!file) { - std::cerr << "Problem opening: " << fileWithLongLine << std::endl; - return false; - } - - std::string line; - bool has_newline = false; - bool result; - - // Read first line. - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1); - if (!result || line != firstLine) { - std::cerr << "First line does not match, expected " << firstLine.size() - << " characters, got " << line.size() << std::endl; - return false; - } - if (!has_newline) { - std::cerr << "Expected new line to be read from first line" << std::endl; - return false; - } - - // Read empty line. - has_newline = false; - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1); - if (!result || !line.empty()) { - std::cerr << "Expected successful read with an empty line, got " - << line.size() << " characters" << std::endl; - return false; - } - if (!has_newline) { - std::cerr << "Expected new line to be read for an empty line" << std::endl; - return false; - } - - // Read second line. - has_newline = false; - result = kwsys::SystemTools::GetLineFromStream(file, line, &has_newline, -1); - if (!result || line != secondLine) { - std::cerr << "Second line does not match, expected " << secondLine.size() - << " characters, got " << line.size() << std::endl; - return false; - } - if (!has_newline) { - std::cerr << "Expected new line to be read from second line" << std::endl; - return false; - } - - return true; -} - -static bool writeFile(const char* fileName, const char* data) -{ - kwsys::ofstream out(fileName, std::ios::binary); - out << data; - if (!out) { - std::cerr << "Failed to write file: " << fileName << std::endl; - return false; - } - return true; -} - -static std::string readFile(const char* fileName) -{ - kwsys::ifstream in(fileName, std::ios::binary); - std::stringstream sstr; - sstr << in.rdbuf(); - std::string data = sstr.str(); - if (!in) { - std::cerr << "Failed to read file: " << fileName << std::endl; - return std::string(); - } - return data; -} - -struct -{ - const char* a; - const char* b; - bool differ; -} diff_test_cases[] = { { "one", "one", false }, - { "one", "two", true }, - { "", "", false }, - { "\n", "\r\n", false }, - { "one\n", "one\n", false }, - { "one\r\n", "one\n", false }, - { "one\n", "one", false }, - { "one\ntwo", "one\ntwo", false }, - { "one\ntwo", "one\r\ntwo", false } }; - -static bool CheckTextFilesDiffer() -{ - const int num_test_cases = - sizeof(diff_test_cases) / sizeof(diff_test_cases[0]); - for (int i = 0; i < num_test_cases; ++i) { - if (!writeFile("file_a", diff_test_cases[i].a) || - !writeFile("file_b", diff_test_cases[i].b)) { - return false; - } - if (kwsys::SystemTools::TextFilesDiffer("file_a", "file_b") != - diff_test_cases[i].differ) { - std::cerr << "Incorrect TextFilesDiffer result for test case " << i + 1 - << "." << std::endl; - return false; - } - } - - return true; -} - -static bool CheckCopyFileIfDifferent() -{ - bool ret = true; - const int num_test_cases = - sizeof(diff_test_cases) / sizeof(diff_test_cases[0]); - for (int i = 0; i < num_test_cases; ++i) { - if (!writeFile("file_a", diff_test_cases[i].a) || - !writeFile("file_b", diff_test_cases[i].b)) { - return false; - } - const char* cptarget = - i < 4 ? TEST_SYSTEMTOOLS_BINARY_DIR "/file_b" : "file_b"; - if (!kwsys::SystemTools::CopyFileIfDifferent("file_a", cptarget)) { - std::cerr << "CopyFileIfDifferent() returned false for test case " - << i + 1 << "." << std::endl; - ret = false; - continue; - } - std::string bdata = readFile("file_b"); - if (diff_test_cases[i].a != bdata) { - std::cerr << "Incorrect CopyFileIfDifferent file contents in test case " - << i + 1 << "." << std::endl; - ret = false; - continue; - } - } - - return ret; -} - -int testSystemTools(int, char* []) -{ - bool res = true; - - int cc; - for (cc = 0; toUnixPaths[cc][0]; cc++) { - res &= CheckConvertToUnixSlashes(toUnixPaths[cc][0], toUnixPaths[cc][1]); - } - - // Special check for ~ - std::string output; - if (kwsys::SystemTools::GetEnv("HOME", output)) { - output += "/foo bar/lala"; - res &= CheckConvertToUnixSlashes("~/foo bar/lala", output); - } - - for (cc = 0; checkEscapeChars[cc][0]; cc++) { - res &= CheckEscapeChars(checkEscapeChars[cc][0], checkEscapeChars[cc][1], - *checkEscapeChars[cc][2], checkEscapeChars[cc][3]); - } - - res &= CheckFileOperations(); - - res &= CheckStringOperations(); - - res &= CheckEnvironmentOperations(); - - res &= CheckRelativePaths(); - - res &= CheckCollapsePath(); - - res &= CheckGetPath(); - - res &= CheckFind(); - - res &= CheckIsSubDirectory(); - - res &= CheckGetLineFromStream(); - - res &= CheckGetLineFromStreamLongLine(); - - res &= CheckGetFilenameName(); - - res &= CheckTextFilesDiffer(); - - res &= CheckCopyFileIfDifferent(); - - return res ? 0 : 1; -} diff --git a/test/API/driver/kwsys/testSystemTools.h.in b/test/API/driver/kwsys/testSystemTools.h.in deleted file mode 100644 index 022e36e..0000000 --- a/test/API/driver/kwsys/testSystemTools.h.in +++ /dev/null @@ -1,12 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#ifndef @KWSYS_NAMESPACE@_testSystemtools_h -#define @KWSYS_NAMESPACE@_testSystemtools_h - -#define EXECUTABLE_OUTPUT_PATH "@CMAKE_CURRENT_BINARY_DIR@" - -#define TEST_SYSTEMTOOLS_SOURCE_DIR "@TEST_SYSTEMTOOLS_SOURCE_DIR@" -#define TEST_SYSTEMTOOLS_BINARY_DIR "@TEST_SYSTEMTOOLS_BINARY_DIR@" -#cmakedefine KWSYS_TEST_SYSTEMTOOLS_LONG_PATHS - -#endif diff --git a/test/API/driver/kwsys/testTerminal.c b/test/API/driver/kwsys/testTerminal.c deleted file mode 100644 index 652830c..0000000 --- a/test/API/driver/kwsys/testTerminal.c +++ /dev/null @@ -1,22 +0,0 @@ -/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying - file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Terminal.h) - -/* Work-around CMake dependency scanning limitation. This must - duplicate the above list of headers. */ -#if 0 -# include "Terminal.h.in" -#endif - -int testTerminal(int argc, char* argv[]) -{ - (void)argc; - (void)argv; - kwsysTerminal_cfprintf(kwsysTerminal_Color_ForegroundYellow | - kwsysTerminal_Color_BackgroundBlue | - kwsysTerminal_Color_AssumeTTY, - stdout, "Hello %s!", "World"); - fprintf(stdout, "\n"); - return 0; -} diff --git a/test/API/driver/kwsys/update-gitsetup.bash b/test/API/driver/kwsys/update-gitsetup.bash deleted file mode 100644 index aa83cb8..0000000 --- a/test/API/driver/kwsys/update-gitsetup.bash +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -x -shopt -s dotglob - -readonly name="GitSetup" -readonly ownership="GitSetup Upstream <kwrobot@kitware.com>" -readonly subtree="GitSetup" -readonly repo="https://gitlab.kitware.com/utils/gitsetup.git" -readonly tag="setup" -readonly shortlog=false -readonly paths=" -" - -extract_source () { - git_archive -} - -. "${BASH_SOURCE%/*}/update-third-party.bash" diff --git a/test/API/driver/kwsys/update-third-party.bash b/test/API/driver/kwsys/update-third-party.bash deleted file mode 100644 index 3b8358e..0000000 --- a/test/API/driver/kwsys/update-third-party.bash +++ /dev/null @@ -1,169 +0,0 @@ -#============================================================================= -# Copyright 2015-2016 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -######################################################################## -# Script for updating third party packages. -# -# This script should be sourced in a project-specific script which sets -# the following variables: -# -# name -# The name of the project. -# ownership -# A git author name/email for the commits. -# subtree -# The location of the thirdparty package within the main source -# tree. -# repo -# The git repository to use as upstream. -# tag -# The tag, branch or commit hash to use for upstream. -# shortlog -# Optional. Set to 'true' to get a shortlog in the commit message. -# -# Additionally, an "extract_source" function must be defined. It will be -# run within the checkout of the project on the requested tag. It should -# should place the desired tree into $extractdir/$name-reduced. This -# directory will be used as the newest commit for the project. -# -# For convenience, the function may use the "git_archive" function which -# does a standard "git archive" extraction using the (optional) "paths" -# variable to only extract a subset of the source tree. -######################################################################## - -######################################################################## -# Utility functions -######################################################################## -git_archive () { - git archive --worktree-attributes --prefix="$name-reduced/" HEAD -- $paths | \ - tar -C "$extractdir" -x -} - -die () { - echo >&2 "$@" - exit 1 -} - -warn () { - echo >&2 "warning: $@" -} - -readonly regex_date='20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]' -readonly basehash_regex="$name $regex_date ([0-9a-f]*)" -readonly basehash="$( git rev-list --author="$ownership" --grep="$basehash_regex" -n 1 HEAD )" -readonly upstream_old_short="$( git cat-file commit "$basehash" | sed -n '/'"$basehash_regex"'/ {s/.*(//;s/)//;p}' | egrep '^[0-9a-f]+$' )" - -######################################################################## -# Sanity checking -######################################################################## -[ -n "$name" ] || \ - die "'name' is empty" -[ -n "$ownership" ] || \ - die "'ownership' is empty" -[ -n "$subtree" ] || \ - die "'subtree' is empty" -[ -n "$repo" ] || \ - die "'repo' is empty" -[ -n "$tag" ] || \ - die "'tag' is empty" -[ -n "$basehash" ] || \ - warn "'basehash' is empty; performing initial import" -readonly do_shortlog="${shortlog-false}" - -readonly workdir="$PWD/work" -readonly upstreamdir="$workdir/upstream" -readonly extractdir="$workdir/extract" - -[ -d "$workdir" ] && \ - die "error: workdir '$workdir' already exists" - -trap "rm -rf '$workdir'" EXIT - -# Get upstream -git clone "$repo" "$upstreamdir" - -if [ -n "$basehash" ]; then - # Use the existing package's history - git worktree add "$extractdir" "$basehash" - # Clear out the working tree - pushd "$extractdir" - git ls-files | xargs rm -v - find . -type d -empty -delete - popd -else - # Create a repo to hold this package's history - mkdir -p "$extractdir" - git -C "$extractdir" init -fi - -# Extract the subset of upstream we care about -pushd "$upstreamdir" -git checkout "$tag" -readonly upstream_hash="$( git rev-parse HEAD )" -readonly upstream_hash_short="$( git rev-parse --short=8 "$upstream_hash" )" -readonly upstream_datetime="$( git rev-list "$upstream_hash" --format='%ci' -n 1 | grep -e "^$regex_date" )" -readonly upstream_date="$( echo "$upstream_datetime" | grep -o -e "$regex_date" )" -if $do_shortlog && [ -n "$basehash" ]; then - readonly commit_shortlog=" - -Upstream Shortlog ------------------ - -$( git shortlog --no-merges --abbrev=8 --format='%h %s' "$upstream_old_short".."$upstream_hash" )" -else - readonly commit_shortlog="" -fi -extract_source || \ - die "failed to extract source" -popd - -[ -d "$extractdir/$name-reduced" ] || \ - die "expected directory to extract does not exist" -readonly commit_summary="$name $upstream_date ($upstream_hash_short)" - -# Commit the subset -pushd "$extractdir" -mv -v "$name-reduced/"* . -rmdir "$name-reduced/" -git add -A . -git commit -n --author="$ownership" --date="$upstream_datetime" -F - <<-EOF -$commit_summary - -Code extracted from: - - $repo - -at commit $upstream_hash ($tag).$commit_shortlog -EOF -git branch -f "upstream-$name" -popd - -# Merge the subset into this repository -if [ -n "$basehash" ]; then - git merge --log -s recursive "-Xsubtree=$subtree/" --no-commit "upstream-$name" -else - unrelated_histories_flag="" - if git merge --help | grep -q -e allow-unrelated-histories; then - unrelated_histories_flag="--allow-unrelated-histories " - fi - readonly unrelated_histories_flag - - git fetch "$extractdir" "upstream-$name:upstream-$name" - git merge --log -s ours --no-commit $unrelated_histories_flag "upstream-$name" - git read-tree -u --prefix="$subtree/" "upstream-$name" -fi -git commit --no-edit -git branch -d "upstream-$name" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d52beb0..fe52cd3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -395,24 +395,6 @@ if (HDF5_BUILD_UTILS) set (H5_TESTS ${H5_TESTS} mirror_vfd) endif () -set (HDF5_API_TESTS - attribute - dataset - datatype - file - group - link - misc - object -) - -if (HDF5_TEST_API_ENABLE_ASYNC) - set (HDF5_API_TESTS - ${HDF5_API_TESTS} - async - ) -endif () - macro (ADD_H5_EXE file) add_executable (${file} ${HDF5_TEST_SOURCE_DIR}/${file}.c) target_include_directories (${file} PRIVATE "${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};${HDF5_TEST_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") @@ -897,8 +879,10 @@ if (HDF5_ENABLE_FORMATTERS) clang_format (HDF5_TEST_use_disable_mdc_flushes_FORMAT use_disable_mdc_flushes) endif () -add_subdirectory (API) - if (HDF5_TEST_SERIAL) include (CMakeTests.cmake) endif () + +if (HDF5_TEST_API) + add_subdirectory (API) +endif () diff --git a/testpar/API/CMakeLists.txt b/testpar/API/CMakeLists.txt index 5eb69c4..e907078 100644 --- a/testpar/API/CMakeLists.txt +++ b/testpar/API/CMakeLists.txt @@ -9,16 +9,31 @@ # help@hdfgroup.org. # -#------------------------------------------------------------------------------ -# Set module path -#------------------------------------------------------------------------------ -set(HDF5_TEST_API_CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake") -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${HDF5_TEST_API_CMAKE_MODULE_PATH}) +cmake_minimum_required (VERSION 3.18) +project (HDF5_TEST_PAR_API C) #------------------------------------------------------------------------------ -# Setup for API tests +# Define for API tests #------------------------------------------------------------------------------ +set (HDF5_API_TESTS + attribute + dataset + datatype + file + group + link + misc + object +) + +if (HDF5_TEST_API_ENABLE_ASYNC) + set (HDF5_API_TESTS + ${HDF5_API_TESTS} + async + ) +endif () + # Ported HDF5 tests set (HDF5_API_PAR_TESTS_EXTRA t_bigio diff --git a/testpar/CMakeLists.txt b/testpar/CMakeLists.txt index d34b800..6bb5fa6 100644 --- a/testpar/CMakeLists.txt +++ b/testpar/CMakeLists.txt @@ -104,30 +104,14 @@ set (H5P_TESTS t_vfd ) -set (HDF5_API_TESTS - attribute - dataset - datatype - file - group - link - misc - object -) - -if (HDF5_TEST_API_ENABLE_ASYNC) - set (HDF5_API_TESTS - ${HDF5_API_TESTS} - async - ) -endif () - foreach (h5_testp ${H5P_TESTS}) ADD_H5P_EXE(${h5_testp}) endforeach () -add_subdirectory (API) - if (HDF5_TEST_PARALLEL) include (CMakeTests.cmake) endif () + +if (HDF5_TEST_API) + add_subdirectory (API) +endif () |