mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-03-19 16:50:46 +08:00
Add initial version of HDF5 API tests (#2877)
This commit is contained in:
parent
41fd8e66a9
commit
f8a1b3ceec
2
.github/workflows/codespell.yml
vendored
2
.github/workflows/codespell.yml
vendored
@ -11,5 +11,5 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: codespell-project/actions-codespell@master
|
||||
with:
|
||||
skip: ./bin/trace,./hl/tools/h5watch/h5watch.c,./tools/test/h5jam/tellub.c,./config/sanitizer/LICENSE,./config/sanitizer/sanitizers.cmake,./tools/test/h5repack/testfiles/*.dat
|
||||
skip: ./bin/trace,./hl/tools/h5watch/h5watch.c,./tools/test/h5jam/tellub.c,./config/sanitizer/LICENSE,./config/sanitizer/sanitizers.cmake,./tools/test/h5repack/testfiles/*.dat,./test/API/driver
|
||||
ignore_words_list: isnt,inout,nd,parms,parm,ba,offsetP,ser,ois,had,fiter,fo,clude,refere,minnum,offsetp,creat,ans:,eiter,lastr,ans,isn't,ifset,sur,trun,dne,tthe,hda,filname,te,htmp,minnum,ake,gord,numer,ro,oce,msdos
|
||||
|
@ -208,20 +208,23 @@ set (HDF5_HL_F90_C_LIBSH_TARGET "${HDF5_HL_F90_C_LIB_CORENAME}-shared")
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define some CMake variables for use later in the project
|
||||
#-----------------------------------------------------------------------------
|
||||
set (HDF_CONFIG_DIR ${HDF5_SOURCE_DIR}/config)
|
||||
set (HDF_RESOURCES_DIR ${HDF5_SOURCE_DIR}/config/cmake)
|
||||
set (HDF5_SRC_DIR ${HDF5_SOURCE_DIR}/src)
|
||||
set (HDF5_TEST_SRC_DIR ${HDF5_SOURCE_DIR}/test)
|
||||
set (HDF5_CPP_SRC_DIR ${HDF5_SOURCE_DIR}/c++)
|
||||
set (HDF5_CPP_TST_DIR ${HDF5_SOURCE_DIR}/c++/test)
|
||||
set (HDF5_HL_SRC_DIR ${HDF5_SOURCE_DIR}/hl)
|
||||
set (HDF5_HL_CPP_SRC_DIR ${HDF5_SOURCE_DIR}/hl/c++)
|
||||
set (HDF5_HL_TOOLS_DIR ${HDF5_SOURCE_DIR}/hl/tools)
|
||||
set (HDF5_TOOLS_DIR ${HDF5_SOURCE_DIR}/tools)
|
||||
set (HDF5_TOOLS_SRC_DIR ${HDF5_SOURCE_DIR}/tools/src)
|
||||
set (HDF5_PERFORM_SRC_DIR ${HDF5_SOURCE_DIR}/tools/src/perform)
|
||||
set (HDF5_UTILS_DIR ${HDF5_SOURCE_DIR}/utils)
|
||||
set (HDF5_F90_SRC_DIR ${HDF5_SOURCE_DIR}/fortran)
|
||||
set (HDF_CONFIG_DIR ${HDF5_SOURCE_DIR}/config)
|
||||
set (HDF_RESOURCES_DIR ${HDF5_SOURCE_DIR}/config/cmake)
|
||||
set (HDF5_SRC_DIR ${HDF5_SOURCE_DIR}/src)
|
||||
set (HDF5_TEST_SRC_DIR ${HDF5_SOURCE_DIR}/test)
|
||||
set (HDF5_TEST_PAR_DIR ${HDF5_SOURCE_DIR}/testpar)
|
||||
set (HDF5_TEST_API_SRC_DIR ${HDF5_SOURCE_DIR}/test/API)
|
||||
set (HDF5_TEST_API_PAR_SRC_DIR ${HDF5_SOURCE_DIR}/testpar/API)
|
||||
set (HDF5_CPP_SRC_DIR ${HDF5_SOURCE_DIR}/c++)
|
||||
set (HDF5_CPP_TST_DIR ${HDF5_SOURCE_DIR}/c++/test)
|
||||
set (HDF5_HL_SRC_DIR ${HDF5_SOURCE_DIR}/hl)
|
||||
set (HDF5_HL_CPP_SRC_DIR ${HDF5_SOURCE_DIR}/hl/c++)
|
||||
set (HDF5_HL_TOOLS_DIR ${HDF5_SOURCE_DIR}/hl/tools)
|
||||
set (HDF5_TOOLS_DIR ${HDF5_SOURCE_DIR}/tools)
|
||||
set (HDF5_TOOLS_SRC_DIR ${HDF5_SOURCE_DIR}/tools/src)
|
||||
set (HDF5_PERFORM_SRC_DIR ${HDF5_SOURCE_DIR}/tools/src/perform)
|
||||
set (HDF5_UTILS_DIR ${HDF5_SOURCE_DIR}/utils)
|
||||
set (HDF5_F90_SRC_DIR ${HDF5_SOURCE_DIR}/fortran)
|
||||
set (HDF5_JAVA_JNI_SRC_DIR ${HDF5_SOURCE_DIR}/java/src/jni)
|
||||
set (HDF5_JAVA_HDF5_SRC_DIR ${HDF5_SOURCE_DIR}/java/src/hdf)
|
||||
set (HDF5_JAVA_TEST_SRC_DIR ${HDF5_SOURCE_DIR}/java/test)
|
||||
@ -958,6 +961,25 @@ if (BUILD_TESTING)
|
||||
math (EXPR CTEST_LONG_TIMEOUT "${DART_TESTING_TIMEOUT} * 2")
|
||||
math (EXPR CTEST_VERY_LONG_TIMEOUT "${DART_TESTING_TIMEOUT} * 3")
|
||||
|
||||
option (HDF5_TEST_API "Execute HDF5 API tests" OFF)
|
||||
mark_as_advanced (HDF5_TEST_API)
|
||||
if (HDF5_TEST_API)
|
||||
option (HDF5_TEST_API_INSTALL "Install HDF5 API tests" OFF)
|
||||
mark_as_advanced (HDF5_TEST_API_INSTALL)
|
||||
|
||||
# Enable HDF5 Async API tests
|
||||
option (HDF5_TEST_API_ENABLE_ASYNC "Enable HDF5 Async API tests" OFF)
|
||||
mark_as_advanced (HDF5_TEST_API_ENABLE_ASYNC)
|
||||
|
||||
# Build and use HDF5 test driver program for API tests
|
||||
option (HDF5_TEST_API_ENABLE_DRIVER "Enable HDF5 API test driver program" OFF)
|
||||
mark_as_advanced (HDF5_TEST_API_ENABLE_DRIVER)
|
||||
if (HDF5_TEST_API_ENABLE_DRIVER)
|
||||
set (HDF5_TEST_API_SERVER "" CACHE STRING "Server executable for running API tests")
|
||||
mark_as_advanced (HDF5_TEST_API_SERVER)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
option (HDF5_TEST_VFD "Execute tests with different VFDs" OFF)
|
||||
mark_as_advanced (HDF5_TEST_VFD)
|
||||
if (HDF5_TEST_VFD)
|
||||
@ -1014,11 +1036,11 @@ if (BUILD_TESTING)
|
||||
mark_as_advanced (HDF5_TEST_JAVA)
|
||||
|
||||
if (NOT HDF5_EXTERNALLY_CONFIGURED)
|
||||
if (EXISTS "${HDF5_SOURCE_DIR}/test" AND IS_DIRECTORY "${HDF5_SOURCE_DIR}/test")
|
||||
if (EXISTS "${HDF5_TEST_SRC_DIR}" AND IS_DIRECTORY "${HDF5_TEST_SRC_DIR}")
|
||||
add_subdirectory (test)
|
||||
endif ()
|
||||
if (H5_HAVE_PARALLEL)
|
||||
if (EXISTS "${HDF5_SOURCE_DIR}/testpar" AND IS_DIRECTORY "${HDF5_SOURCE_DIR}/testpar")
|
||||
if (EXISTS "${HDF5_TEST_PAR_DIR}" AND IS_DIRECTORY "${HDF5_TEST_PAR_DIR}")
|
||||
add_subdirectory (testpar)
|
||||
endif ()
|
||||
endif ()
|
||||
|
@ -26,7 +26,7 @@ TEST_PROG=ptableTest
|
||||
check_PROGRAMS=$(TEST_PROG)
|
||||
|
||||
# The tests depend on the hdf5, hdf5 C++, and hdf5_hl libraries
|
||||
LDADD=$(LIBH5CPP_HL) $(LIBH5_HL) $(LIBH5CPP) $(LIBHDF5)
|
||||
LDADD=$(LIBH5CPP_HL) $(LIBH5_HL) $(LIBH5TEST) $(LIBH5CPP) $(LIBHDF5)
|
||||
|
||||
ptableTest_SOURCES=ptableTest.cpp
|
||||
|
||||
|
37
test/API/CMake/CheckAsan.cmake
Normal file
37
test/API/CMake/CheckAsan.cmake
Normal file
@ -0,0 +1,37 @@
|
||||
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()
|
||||
|
37
test/API/CMake/CheckUbsan.cmake
Normal file
37
test/API/CMake/CheckUbsan.cmake
Normal file
@ -0,0 +1,37 @@
|
||||
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()
|
||||
|
314
test/API/CMakeLists.txt
Normal file
314
test/API/CMakeLists.txt
Normal file
@ -0,0 +1,314 @@
|
||||
# Copyright by The HDF Group.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is part of HDF5. The full HDF5 copyright notice, including
|
||||
# terms governing use, modification, and redistribution, is contained in
|
||||
# the COPYING file, which can be found at the root of the source code
|
||||
# distribution tree, or in https://www.hdfgroup.org/licenses.
|
||||
# If you do not have access to either file, you may request a copy from
|
||||
# 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 ()
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 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 ()
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/H5_api_test_config.h.in
|
||||
${HDF5_TEST_BINARY_DIR}/H5_api_test_config.h
|
||||
)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Compile kwsys library and setup TestDriver
|
||||
#------------------------------------------------------------------------------
|
||||
if (HDF5_TEST_API_ENABLE_DRIVER)
|
||||
add_subdirectory (driver)
|
||||
endif ()
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Setup for API tests
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Ported HDF5 tests
|
||||
set (HDF5_API_TESTS_EXTRA
|
||||
testhdf5
|
||||
)
|
||||
|
||||
# List of files generated by the HDF5 API tests which
|
||||
# should be cleaned up in case the test failed to remove
|
||||
# them
|
||||
set (HDF5_API_TESTS_FILES
|
||||
H5_api_test.h5
|
||||
H5_api_async_test.h5
|
||||
H5_api_async_test_0.h5
|
||||
H5_api_async_test_1.h5
|
||||
H5_api_async_test_2.h5
|
||||
H5_api_async_test_3.h5
|
||||
H5_api_async_test_4.h5
|
||||
test_file.h5
|
||||
invalid_params_file.h5
|
||||
excl_flag_file.h5
|
||||
overlapping_file.h5
|
||||
file_permission.h5
|
||||
flush_file.h5
|
||||
property_list_test_file1.h5
|
||||
property_list_test_file2.h5
|
||||
intent_test_file.h5
|
||||
file_obj_count1.h5
|
||||
file_obj_count2.h5
|
||||
file_mount.h5
|
||||
file_name_retrieval.h5
|
||||
filespace_info.h5
|
||||
test_file_id.h5
|
||||
test_close_degree.h5
|
||||
test_free_sections.h5
|
||||
file_size.h5
|
||||
file_info.h5
|
||||
double_group_open.h5
|
||||
ext_link_file.h5
|
||||
ext_link_file_2.h5
|
||||
ext_link_file_3.h5
|
||||
ext_link_file_4.h5
|
||||
ext_link_file_ping_pong_1.h5
|
||||
ext_link_file_ping_pong_2.h5
|
||||
ext_link_invalid_params_file.h5
|
||||
object_copy_test_file.h5
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build the main API test executable
|
||||
#-----------------------------------------------------------------------------
|
||||
foreach (api_test ${HDF5_API_TESTS})
|
||||
set (HDF5_API_TEST_SRCS
|
||||
${HDF5_API_TEST_SRCS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/H5_api_${api_test}_test.c
|
||||
)
|
||||
endforeach ()
|
||||
|
||||
set (HDF5_API_TEST_SRCS
|
||||
${HDF5_API_TEST_SRCS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/H5_api_test.c
|
||||
${HDF5_TEST_API_SRC_DIR}/H5_api_test_util.c
|
||||
)
|
||||
|
||||
add_executable (h5_api_test ${HDF5_API_TEST_SRCS})
|
||||
target_include_directories (
|
||||
h5_api_test
|
||||
PRIVATE
|
||||
"${HDF5_SRC_INCLUDE_DIRS}"
|
||||
"${HDF5_TEST_SRC_DIR}"
|
||||
"${HDF5_TEST_API_SRC_DIR}"
|
||||
"${HDF5_SRC_BINARY_DIR}"
|
||||
"${HDF5_TEST_BINARY_DIR}"
|
||||
)
|
||||
target_compile_options (
|
||||
h5_api_test
|
||||
PRIVATE
|
||||
"${HDF5_CMAKE_C_FLAGS}"
|
||||
)
|
||||
target_compile_definitions (
|
||||
h5_api_test
|
||||
PRIVATE
|
||||
$<$<CONFIG:Developer>:${HDF5_DEVELOPER_DEFS}>
|
||||
)
|
||||
if (NOT BUILD_SHARED_LIBS)
|
||||
TARGET_C_PROPERTIES (h5_api_test STATIC)
|
||||
target_link_libraries (
|
||||
h5_api_test
|
||||
PRIVATE
|
||||
${HDF5_TEST_LIB_TARGET}
|
||||
)
|
||||
else ()
|
||||
TARGET_C_PROPERTIES (h5_api_test SHARED)
|
||||
target_link_libraries (
|
||||
h5_api_test
|
||||
PRIVATE
|
||||
${HDF5_TEST_LIBSH_TARGET}
|
||||
)
|
||||
endif ()
|
||||
set_target_properties (
|
||||
h5_api_test
|
||||
PROPERTIES
|
||||
FOLDER test/API
|
||||
)
|
||||
# Add Target to clang-format
|
||||
if (HDF5_ENABLE_FORMATTERS)
|
||||
clang_format (HDF5_TEST_h5_api_test_FORMAT h5_api_test)
|
||||
endif ()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build the ported HDF5 test executables
|
||||
#-----------------------------------------------------------------------------
|
||||
foreach (api_test_extra ${HDF5_API_TESTS_EXTRA})
|
||||
unset (HDF5_API_TEST_EXTRA_SRCS)
|
||||
|
||||
set (HDF5_API_TEST_EXTRA_SRCS
|
||||
${HDF5_API_TEST_EXTRA_SRCS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${api_test_extra}.c
|
||||
)
|
||||
|
||||
if (${api_test_extra} STREQUAL "testhdf5")
|
||||
set (HDF5_API_TEST_EXTRA_SRCS
|
||||
${HDF5_API_TEST_EXTRA_SRCS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tarray.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tattr.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tchecksum.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tconfig.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tcoords.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tfile.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tgenprop.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/th5o.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/th5s.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tid.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/titerate.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tmisc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/trefer.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tselect.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ttime.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tunicode.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tvlstr.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tvltypes.c
|
||||
)
|
||||
endif ()
|
||||
|
||||
add_executable (h5_api_test_${api_test_extra} ${HDF5_API_TEST_EXTRA_SRCS})
|
||||
target_include_directories (
|
||||
h5_api_test_${api_test_extra}
|
||||
PRIVATE
|
||||
"${HDF5_SRC_INCLUDE_DIRS}"
|
||||
"${HDF5_TEST_SRC_DIR}"
|
||||
"${HDF5_TEST_API_SRC_DIR}"
|
||||
"${HDF5_SRC_BINARY_DIR}"
|
||||
"${HDF5_TEST_BINARY_DIR}"
|
||||
)
|
||||
target_compile_options (
|
||||
h5_api_test_${api_test_extra}
|
||||
PRIVATE
|
||||
"${HDF5_CMAKE_C_FLAGS}"
|
||||
)
|
||||
target_compile_definitions (
|
||||
h5_api_test_${api_test_extra}
|
||||
PRIVATE
|
||||
$<$<CONFIG:Developer>:${HDF5_DEVELOPER_DEFS}>
|
||||
)
|
||||
if (NOT BUILD_SHARED_LIBS)
|
||||
TARGET_C_PROPERTIES (h5_api_test_${api_test_extra} STATIC)
|
||||
target_link_libraries (h5_api_test_${api_test_extra} PRIVATE ${HDF5_TEST_LIB_TARGET})
|
||||
else ()
|
||||
TARGET_C_PROPERTIES (h5_api_test_${api_test_extra} SHARED)
|
||||
target_link_libraries (h5_api_test_${api_test_extra} PRIVATE ${HDF5_TEST_LIBSH_TARGET})
|
||||
endif ()
|
||||
set_target_properties (
|
||||
h5_api_test_${api_test_extra}
|
||||
PROPERTIES
|
||||
FOLDER test/API
|
||||
)
|
||||
# Add Target to clang-format
|
||||
if (HDF5_ENABLE_FORMATTERS)
|
||||
clang_format (HDF5_TEST_h5_api_test_${api_test_extra}_FORMAT h5_api_test_${api_test_extra})
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Add tests if HDF5 serial testing is enabled
|
||||
#-----------------------------------------------------------------------------
|
||||
if (HDF5_TEST_SERIAL)
|
||||
if (HDF5_TEST_API_ENABLE_DRIVER)
|
||||
if ("${HDF5_TEST_API_SERVER}" STREQUAL "")
|
||||
message (FATAL_ERROR "Please set HDF5_TEST_API_SERVER to point to a server executable for the test driver program.")
|
||||
endif ()
|
||||
|
||||
# Driver options
|
||||
if (HDF5_TEST_API_SERVER_ALLOW_ERRORS)
|
||||
set (HDF5_TEST_API_DRIVER_EXTRA_FLAGS --allow-server-errors)
|
||||
endif ()
|
||||
if (HDF5_TEST_API_CLIENT_HELPER)
|
||||
set (HDF5_TEST_API_DRIVER_EXTRA_FLAGS ${HDF5_TEST_API_DRIVER_EXTRA_FLAGS}
|
||||
--client-helper ${HDF5_TEST_API_CLIENT_HELPER}
|
||||
)
|
||||
endif ()
|
||||
if (HDF5_TEST_API_CLIENT_INIT)
|
||||
set (HDF5_TEST_API_DRIVER_EXTRA_FLAGS ${HDF5_TEST_API_DRIVER_EXTRA_FLAGS}
|
||||
--client-init ${HDF5_TEST_API_CLIENT_INIT}
|
||||
)
|
||||
endif ()
|
||||
|
||||
set(last_api_test "")
|
||||
foreach (api_test ${HDF5_API_TESTS})
|
||||
add_test (
|
||||
NAME "h5_api_test_${api_test}"
|
||||
COMMAND $<TARGET_FILE:h5_api_test_driver>
|
||||
--server ${HDF5_TEST_API_SERVER}
|
||||
--client $<TARGET_FILE:h5_api_test> "${api_test}"
|
||||
--serial
|
||||
${HDF5_TEST_API_DRIVER_EXTRA_FLAGS}
|
||||
)
|
||||
|
||||
set_tests_properties("h5_api_test_${api_test}" PROPERTIES DEPENDS "${last_api_test}")
|
||||
|
||||
set(last_api_test "h5_api_test_${api_test}")
|
||||
endforeach ()
|
||||
|
||||
foreach (hdf5_test ${HDF5_API_TESTS_EXTRA})
|
||||
add_test (
|
||||
NAME "h5_api_test_${hdf5_test}"
|
||||
COMMAND $<TARGET_FILE:h5_api_test_driver>
|
||||
--server ${HDF5_TEST_API_SERVER}
|
||||
--client $<TARGET_FILE:h5_api_test_${hdf5_test}>
|
||||
--serial
|
||||
${HDF5_TEST_API_DRIVER_EXTRA_FLAGS}
|
||||
)
|
||||
endforeach ()
|
||||
|
||||
# Hook external tests to same test suite
|
||||
foreach (ext_api_test ${HDF5_API_EXT_SERIAL_TESTS})
|
||||
add_test (
|
||||
NAME "h5_api_ext_test_${ext_api_test}"
|
||||
COMMAND $<TARGET_FILE:h5_api_test_driver>
|
||||
--server ${HDF5_TEST_API_SERVER}
|
||||
--client $<TARGET_FILE:${ext_api_test}>
|
||||
--serial
|
||||
${HDF5_TEST_API_DRIVER_EXTRA_FLAGS}
|
||||
)
|
||||
endforeach ()
|
||||
else ()
|
||||
set(last_api_test "")
|
||||
foreach (api_test ${HDF5_API_TESTS})
|
||||
add_test (
|
||||
NAME "h5_api_test_${api_test}"
|
||||
COMMAND $<TARGET_FILE:h5_api_test> "${api_test}"
|
||||
)
|
||||
|
||||
set_tests_properties("h5_api_test_${api_test}" PROPERTIES DEPENDS "${last_api_test}")
|
||||
|
||||
set(last_api_test "h5_api_test_${api_test}")
|
||||
endforeach ()
|
||||
|
||||
foreach (hdf5_test ${HDF5_API_TESTS_EXTRA})
|
||||
add_test (
|
||||
NAME "h5_api_test_${hdf5_test}"
|
||||
COMMAND $<TARGET_FILE:h5_api_test_${hdf5_test}>
|
||||
)
|
||||
endforeach ()
|
||||
endif ()
|
||||
endif ()
|
2730
test/API/H5_api_async_test.c
Normal file
2730
test/API/H5_api_async_test.c
Normal file
File diff suppressed because it is too large
Load Diff
29
test/API/H5_api_async_test.h
Normal file
29
test/API/H5_api_async_test.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_ASYNC_TEST_H
|
||||
#define H5_API_ASYNC_TEST_H
|
||||
|
||||
#include "H5_api_test.h"
|
||||
|
||||
int H5_api_async_test(void);
|
||||
|
||||
/************************************************
|
||||
* *
|
||||
* API async test defines *
|
||||
* *
|
||||
************************************************/
|
||||
|
||||
#define ASYNC_API_TEST_FILE "H5_api_async_test.h5"
|
||||
#define ASYNC_API_TEST_FILE_PRINTF "H5_api_async_test_%d.h5"
|
||||
|
||||
#endif
|
11027
test/API/H5_api_attribute_test.c
Normal file
11027
test/API/H5_api_attribute_test.c
Normal file
File diff suppressed because it is too large
Load Diff
203
test/API/H5_api_attribute_test.h
Normal file
203
test/API/H5_api_attribute_test.h
Normal file
@ -0,0 +1,203 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_ATTRIBUTE_TEST_H
|
||||
#define H5_API_ATTRIBUTE_TEST_H
|
||||
|
||||
#include "H5_api_test.h"
|
||||
|
||||
int H5_api_attribute_test(void);
|
||||
|
||||
/**************************************************
|
||||
* *
|
||||
* API Attribute test defines *
|
||||
* *
|
||||
**************************************************/
|
||||
|
||||
#define ATTRIBUTE_CREATE_ON_ROOT_SPACE_RANK 1
|
||||
#define ATTRIBUTE_CREATE_ON_ROOT_ATTR_NAME "attr_on_root"
|
||||
#define ATTRIBUTE_CREATE_ON_ROOT_ATTR_NAME2 "attr_on_root2"
|
||||
|
||||
#define ATTRIBUTE_CREATE_ON_DATASET_DSET_SPACE_RANK 2
|
||||
#define ATTRIBUTE_CREATE_ON_DATASET_ATTR_SPACE_RANK 1
|
||||
#define ATTRIBUTE_CREATE_ON_DATASET_GROUP_NAME "attr_on_dataset_test"
|
||||
#define ATTRIBUTE_CREATE_ON_DATASET_DSET_NAME "dataset_with_attr"
|
||||
#define ATTRIBUTE_CREATE_ON_DATASET_ATTR_NAME "attr_on_dataset"
|
||||
#define ATTRIBUTE_CREATE_ON_DATASET_ATTR_NAME2 "attr_on_dataset2"
|
||||
|
||||
#define ATTRIBUTE_CREATE_ON_DATATYPE_SPACE_RANK 1
|
||||
#define ATTRIBUTE_CREATE_ON_DATATYPE_DTYPE_NAME "datatype_with_attr"
|
||||
#define ATTRIBUTE_CREATE_ON_DATATYPE_GROUP_NAME "attr_on_datatype_test"
|
||||
#define ATTRIBUTE_CREATE_ON_DATATYPE_ATTR_NAME "attr_on_datatype"
|
||||
#define ATTRIBUTE_CREATE_ON_DATATYPE_ATTR_NAME2 "attr_on_datatype2"
|
||||
|
||||
#define ATTRIBUTE_CREATE_NULL_DATASPACE_TEST_SUBGROUP_NAME "attr_with_null_space_test"
|
||||
#define ATTRIBUTE_CREATE_NULL_DATASPACE_TEST_ATTR_NAME "attr_with_null_space"
|
||||
|
||||
#define ATTRIBUTE_CREATE_SCALAR_DATASPACE_TEST_SUBGROUP_NAME "attr_with_scalar_space_test"
|
||||
#define ATTRIBUTE_CREATE_SCALAR_DATASPACE_TEST_ATTR_NAME "attr_with_scalar_space"
|
||||
|
||||
#define ATTRIBUTE_CREATE_WITH_SPACE_IN_NAME_SPACE_RANK 1
|
||||
#define ATTRIBUTE_CREATE_WITH_SPACE_IN_NAME_GROUP_NAME "attr_with_space_in_name_test"
|
||||
#define ATTRIBUTE_CREATE_WITH_SPACE_IN_NAME_ATTR_NAME "attr with space in name"
|
||||
|
||||
#define ATTRIBUTE_CREATE_INVALID_PARAMS_SPACE_RANK 1
|
||||
#define ATTRIBUTE_CREATE_INVALID_PARAMS_GROUP_NAME "attribute_create_invalid_params_test"
|
||||
#define ATTRIBUTE_CREATE_INVALID_PARAMS_ATTR_NAME "invalid_params_attr"
|
||||
|
||||
#define ATTRIBUTE_OPEN_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_OPEN_TEST_GROUP_NAME "attribute_open_test"
|
||||
#define ATTRIBUTE_OPEN_TEST_ATTR_NAME "attribute_open_test_attr"
|
||||
#define ATTRIBUTE_OPEN_TEST_ATTR_NAME2 ATTRIBUTE_OPEN_TEST_ATTR_NAME "2"
|
||||
#define ATTRIBUTE_OPEN_TEST_ATTR_NAME3 ATTRIBUTE_OPEN_TEST_ATTR_NAME "3"
|
||||
|
||||
#define ATTRIBUTE_OPEN_INVALID_PARAMS_TEST_GROUP_NAME "attribute_open_invalid_params_test"
|
||||
#define ATTRIBUTE_OPEN_INVALID_PARAMS_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_OPEN_INVALID_PARAMS_TEST_ATTR_NAME "attribute_open_invalid_params_attr"
|
||||
|
||||
#define ATTRIBUTE_WRITE_TEST_ATTR_DTYPE_SIZE sizeof(int)
|
||||
#define ATTRIBUTE_WRITE_TEST_ATTR_DTYPE H5T_NATIVE_INT
|
||||
#define ATTRIBUTE_WRITE_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_WRITE_TEST_GROUP_NAME "attr_write_test"
|
||||
#define ATTRIBUTE_WRITE_TEST_ATTR_NAME "write_test_attr"
|
||||
|
||||
#define ATTRIBUTE_WRITE_INVALID_PARAMS_TEST_ATTR_DTYPE_SIZE sizeof(int)
|
||||
#define ATTRIBUTE_WRITE_INVALID_PARAMS_TEST_ATTR_DTYPE H5T_NATIVE_INT
|
||||
#define ATTRIBUTE_WRITE_INVALID_PARAMS_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_WRITE_INVALID_PARAMS_TEST_GROUP_NAME "attr_write_invalid_params_test"
|
||||
#define ATTRIBUTE_WRITE_INVALID_PARAMS_TEST_ATTR_NAME "invalid_params_write_test_attr"
|
||||
|
||||
#define ATTRIBUTE_READ_TEST_ATTR_DTYPE_SIZE sizeof(int)
|
||||
#define ATTRIBUTE_READ_TEST_ATTR_DTYPE H5T_NATIVE_INT
|
||||
#define ATTRIBUTE_READ_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_READ_TEST_GROUP_NAME "attr_read_test"
|
||||
#define ATTRIBUTE_READ_TEST_ATTR_NAME "read_test_attr"
|
||||
|
||||
#define ATTRIBUTE_READ_INVALID_PARAMS_TEST_ATTR_DTYPE_SIZE sizeof(int)
|
||||
#define ATTRIBUTE_READ_INVALID_PARAMS_TEST_ATTR_DTYPE H5T_NATIVE_INT
|
||||
#define ATTRIBUTE_READ_INVALID_PARAMS_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_READ_INVALID_PARAMS_TEST_GROUP_NAME "attr_read_invalid_params_test"
|
||||
#define ATTRIBUTE_READ_INVALID_PARAMS_TEST_ATTR_NAME "invalid_params_read_test_attr"
|
||||
|
||||
#define ATTRIBUTE_READ_EMPTY_SPACE_RANK 1
|
||||
#define ATTRIBUTE_READ_EMPTY_ATTR_GROUP_NAME "read_empty_attr_test"
|
||||
#define ATTRIBUTE_READ_EMPTY_ATTR_NAME "read_empty_attr"
|
||||
#define ATTRIBUTE_READ_EMPTY_DTYPE H5T_NATIVE_INT
|
||||
#define ATTRIBUTE_READ_EMPTY_DTYPE_SIZE sizeof(int)
|
||||
|
||||
#define ATTRIBUTE_GET_SPACE_TYPE_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_GET_SPACE_TYPE_TEST_GROUP_NAME "get_attr_space_type_test"
|
||||
#define ATTRIBUTE_GET_SPACE_TYPE_TEST_ATTR_NAME "get_space_type_test_attr"
|
||||
|
||||
#define ATTRIBUTE_GET_SPACE_TYPE_INVALID_PARAMS_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_GET_SPACE_TYPE_INVALID_PARAMS_TEST_GROUP_NAME "get_attr_space_type_invalid_params_test"
|
||||
#define ATTRIBUTE_GET_SPACE_TYPE_INVALID_PARAMS_TEST_ATTR_NAME "get_space_type_invalid_params_test_attr"
|
||||
|
||||
#define ATTRIBUTE_PROPERTY_LIST_TEST_ATTRIBUTE_NAME1 "property_list_test_attribute1"
|
||||
#define ATTRIBUTE_PROPERTY_LIST_TEST_ATTRIBUTE_NAME2 "property_list_test_attribute2"
|
||||
#define ATTRIBUTE_PROPERTY_LIST_TEST_SUBGROUP_NAME "attribute_property_list_test_group"
|
||||
#define ATTRIBUTE_PROPERTY_LIST_TEST_SPACE_RANK 1
|
||||
|
||||
#define ATTRIBUTE_GET_NAME_TEST_ATTRIBUTE_NAME "attr_name_retrieval_attr"
|
||||
#define ATTRIBUTE_GET_NAME_TEST_ATTRIBUTE_NAME2 ATTRIBUTE_GET_NAME_TEST_ATTRIBUTE_NAME "2"
|
||||
#define ATTRIBUTE_GET_NAME_TEST_ATTRIBUTE_NAME3 ATTRIBUTE_GET_NAME_TEST_ATTRIBUTE_NAME "3"
|
||||
#define ATTRIBUTE_GET_NAME_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_GET_NAME_TEST_GROUP_NAME "retrieve_attr_name_test"
|
||||
|
||||
#define ATTRIBUTE_GET_NAME_INVALID_PARAMS_TEST_ATTRIBUTE_NAME "invalid_params_attr_name_retrieval_attr"
|
||||
#define ATTRIBUTE_GET_NAME_INVALID_PARAMS_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_GET_NAME_INVALID_PARAMS_TEST_GROUP_NAME "retrieve_attr_name_invalid_params_test"
|
||||
|
||||
#define ATTRIBUTE_GET_INFO_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_GET_INFO_TEST_GROUP_NAME "attr_get_info_test"
|
||||
#define ATTRIBUTE_GET_INFO_TEST_ATTR_NAME "get_info_test_attr"
|
||||
#define ATTRIBUTE_GET_INFO_TEST_ATTR_NAME2 ATTRIBUTE_GET_INFO_TEST_ATTR_NAME "2"
|
||||
#define ATTRIBUTE_GET_INFO_TEST_ATTR_NAME3 ATTRIBUTE_GET_INFO_TEST_ATTR_NAME "3"
|
||||
|
||||
#define ATTRIBUTE_GET_INFO_INVALID_PARAMS_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_GET_INFO_INVALID_PARAMS_TEST_GROUP_NAME "attr_get_info_invalid_params_test"
|
||||
#define ATTRIBUTE_GET_INFO_INVALID_PARAMS_TEST_ATTR_NAME "invalid_params_get_info_test_attr"
|
||||
|
||||
#define ATTRIBUTE_RENAME_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_RENAME_TEST_GROUP_NAME "attr_rename_test"
|
||||
#define ATTRIBUTE_RENAME_TEST_ATTR_NAME "rename_test_attr"
|
||||
#define ATTRIBUTE_RENAME_TEST_ATTR_NAME2 "rename_test_attr2"
|
||||
#define ATTRIBUTE_RENAME_TEST_NEW_NAME "renamed_attr"
|
||||
#define ATTRIBUTE_RENAME_TEST_NEW_NAME2 "renamed_attr2"
|
||||
|
||||
#define ATTRIBUTE_RENAME_INVALID_PARAMS_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_RENAME_INVALID_PARAMS_TEST_GROUP_NAME "attr_rename_invalid_params_test"
|
||||
#define ATTRIBUTE_RENAME_INVALID_PARAMS_TEST_ATTR_NAME "invalid_params_rename_test_attr"
|
||||
#define ATTRIBUTE_RENAME_INVALID_PARAMS_TEST_ATTR_NAME2 "invalid_params_rename_test_attr2"
|
||||
#define ATTRIBUTE_RENAME_INVALID_PARAMS_TEST_NEW_NAME "invalid_params_renamed_attr"
|
||||
#define ATTRIBUTE_RENAME_INVALID_PARAMS_TEST_NEW_NAME2 "invalid_params_renamed_attr2"
|
||||
|
||||
#define ATTRIBUTE_ITERATE_TEST_ATTR_NAME_BUF_SIZE 256
|
||||
#define ATTRIBUTE_ITERATE_TEST_DSET_SPACE_RANK 2
|
||||
#define ATTRIBUTE_ITERATE_TEST_ATTR_SPACE_RANK 1
|
||||
#define ATTRIBUTE_ITERATE_TEST_GRP_SUBGROUP_NAME "attribute_iterate_group_test"
|
||||
#define ATTRIBUTE_ITERATE_TEST_DSET_SUBGROUP_NAME "attribute_iterate_dset_test"
|
||||
#define ATTRIBUTE_ITERATE_TEST_DTYPE_SUBGROUP_NAME "attribute_iterate_datatype_test"
|
||||
#define ATTRIBUTE_ITERATE_TEST_DSET_NAME "attribute_iterate_dset"
|
||||
#define ATTRIBUTE_ITERATE_TEST_DTYPE_NAME "attribute_iterate_dtype"
|
||||
#define ATTRIBUTE_ITERATE_TEST_ATTR_NAME "iter_attr"
|
||||
#define ATTRIBUTE_ITERATE_TEST_NUM_ATTRS 4
|
||||
|
||||
#define ATTRIBUTE_ITERATE_TEST_0_ATTRIBUTES_DSET_SPACE_RANK 2
|
||||
#define ATTRIBUTE_ITERATE_TEST_0_ATTRIBUTES_SUBGROUP_NAME "attribute_iterate_test_0_attributes"
|
||||
#define ATTRIBUTE_ITERATE_TEST_0_ATTRIBUTES_DSET_NAME "attribute_iterate_dset"
|
||||
|
||||
#define ATTRIBUTE_ITERATE_INVALID_PARAMS_TEST_ATTR_SPACE_RANK 1
|
||||
#define ATTRIBUTE_ITERATE_INVALID_PARAMS_TEST_SUBGROUP_NAME "attribute_iterate_invalid_params_test"
|
||||
#define ATTRIBUTE_ITERATE_INVALID_PARAMS_TEST_ATTR_NAME "invalid_params_iter_attr1"
|
||||
#define ATTRIBUTE_ITERATE_INVALID_PARAMS_TEST_ATTR_NAME2 "invalid_params_iter_attr2"
|
||||
#define ATTRIBUTE_ITERATE_INVALID_PARAMS_TEST_ATTR_NAME3 "invalid_params_iter_attr3"
|
||||
#define ATTRIBUTE_ITERATE_INVALID_PARAMS_TEST_ATTR_NAME4 "invalid_params_iter_attr4"
|
||||
|
||||
#define ATTRIBUTE_DELETION_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_DELETION_TEST_GROUP_NAME "attr_deletion_test"
|
||||
#define ATTRIBUTE_DELETION_TEST_ATTR_NAME "attr_to_be_deleted"
|
||||
#define ATTRIBUTE_DELETION_TEST_ATTR_NAME2 ATTRIBUTE_DELETION_TEST_ATTR_NAME "2"
|
||||
#define ATTRIBUTE_DELETION_TEST_ATTR_NAME3 ATTRIBUTE_DELETION_TEST_ATTR_NAME "3"
|
||||
|
||||
#define ATTRIBUTE_DELETION_INVALID_PARAMS_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_DELETION_INVALID_PARAMS_TEST_GROUP_NAME "attr_deletion_invalid_params_test"
|
||||
#define ATTRIBUTE_DELETION_INVALID_PARAMS_TEST_ATTR_NAME "invalid_params_attr_to_be_deleted"
|
||||
|
||||
#define ATTRIBUTE_EXISTS_TEST_GROUP_NAME "attr_exists_test"
|
||||
#define ATTRIBUTE_EXISTS_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_EXISTS_TEST_ATTR_NAME "attr_exists"
|
||||
|
||||
#define ATTRIBUTE_EXISTS_INVALID_PARAMS_TEST_SPACE_RANK 1
|
||||
#define ATTRIBUTE_EXISTS_INVALID_PARAMS_TEST_GROUP_NAME "attr_exists_invalid_params_test"
|
||||
#define ATTRIBUTE_EXISTS_INVALID_PARAMS_TEST_ATTR_NAME "invalid_params_attr_exists"
|
||||
|
||||
#define ATTRIBUTE_MANY_GROUP_NAME "group_for_many_attributes"
|
||||
#define ATTRIBUTE_MANY_NAME_BUF_SIZE 32U
|
||||
#define ATTRIBUTE_MANY_NUMB 64U
|
||||
#define ATTRIBUTE_MANY_SPACE_RANK 1
|
||||
|
||||
#define ATTRIBUTE_DUPLICATE_ID_GRP_NAME "attr_duplicate_open_test"
|
||||
#define ATTRIBUTE_DUPLICATE_ID_ATTR_NAME "attr_duplicated_id"
|
||||
#define ATTRIBUTE_DUPLICATE_ID_SPACE_RANK 1
|
||||
|
||||
#define ATTRIBUTE_GET_NUM_ATTRS_TEST_GRP_NAME "get_num_attrs_test"
|
||||
#define ATTRIBUTE_GET_NUM_ATTRS_TEST_ATTR_NAME "get_num_attrs_test_attribute"
|
||||
#define ATTRIBUTE_GET_NUM_ATTRS_TEST_SPACE_RANK 1
|
||||
|
||||
#define ATTRIBUTE_SHARED_DTYPE_NAME "Datatype"
|
||||
#define ATTRIBUTE_SHARED_DTYPE_GROUP_NAME "shared_dtype_group"
|
||||
#define ATTRIBUTE_SHARED_DTYPE_ATTR_NAME "shared_dtype_attr"
|
||||
#define ATTRIBUTE_SHARED_DTYPE_DSET_NAME "shared_dtype_dset"
|
||||
#define ATTRIBUTE_SHARED_DTYPE_SPACE_RANK 1
|
||||
|
||||
#endif
|
11683
test/API/H5_api_dataset_test.c
Normal file
11683
test/API/H5_api_dataset_test.c
Normal file
File diff suppressed because it is too large
Load Diff
331
test/API/H5_api_dataset_test.h
Normal file
331
test/API/H5_api_dataset_test.h
Normal file
@ -0,0 +1,331 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_DATASET_TEST_H
|
||||
#define H5_API_DATASET_TEST_H
|
||||
|
||||
#include "H5_api_test.h"
|
||||
|
||||
int H5_api_dataset_test(void);
|
||||
|
||||
/************************************************
|
||||
* *
|
||||
* API Dataset test defines *
|
||||
* *
|
||||
************************************************/
|
||||
|
||||
#define DATASET_CREATE_UNDER_ROOT_DSET_NAME "/dset_under_root"
|
||||
#define DATASET_CREATE_UNDER_ROOT_SPACE_RANK 2
|
||||
|
||||
#define DATASET_CREATE_UNDER_EXISTING_SPACE_RANK 2
|
||||
#define DATASET_CREATE_UNDER_EXISTING_GROUP_NAME "dset_under_group_test"
|
||||
#define DATASET_CREATE_UNDER_EXISTING_DSET_NAME "nested_dset"
|
||||
|
||||
#define DATASET_CREATE_INVALID_PARAMS_SPACE_RANK 2
|
||||
#define DATASET_CREATE_INVALID_PARAMS_GROUP_NAME "dset_create_invalid_params_test"
|
||||
#define DATASET_CREATE_INVALID_PARAMS_DSET_NAME "invalid_params_dset"
|
||||
|
||||
#define DATASET_CREATE_ANONYMOUS_DATASET_NAME "anon_dset"
|
||||
#define DATASET_CREATE_ANONYMOUS_GROUP_NAME "anon_dset_creation_test"
|
||||
#define DATASET_CREATE_ANONYMOUS_SPACE_RANK 2
|
||||
|
||||
#define DATASET_CREATE_ANONYMOUS_INVALID_PARAMS_DATASET_NAME "invalid_params_anon_dset"
|
||||
#define DATASET_CREATE_ANONYMOUS_INVALID_PARAMS_GROUP_NAME "anon_dset_creation_invalid_params_test"
|
||||
#define DATASET_CREATE_ANONYMOUS_INVALID_PARAMS_SPACE_RANK 2
|
||||
|
||||
#define DATASET_CREATE_NULL_DATASPACE_TEST_SUBGROUP_NAME "dataset_with_null_space_test"
|
||||
#define DATASET_CREATE_NULL_DATASPACE_TEST_DSET_NAME "dataset_with_null_space"
|
||||
|
||||
#define DATASET_CREATE_SCALAR_DATASPACE_TEST_SUBGROUP_NAME "dataset_with_scalar_space_test"
|
||||
#define DATASET_CREATE_SCALAR_DATASPACE_TEST_DSET_NAME "dataset_with_scalar_space"
|
||||
|
||||
#define ZERO_DIM_DSET_TEST_GROUP_NAME "zero_dim_dset_test"
|
||||
#define ZERO_DIM_DSET_TEST_SPACE_RANK 1
|
||||
#define ZERO_DIM_DSET_TEST_DSET_NAME "zero_dim_dset"
|
||||
|
||||
#define DATASET_MANY_CREATE_GROUP_NAME "group_for_many_datasets"
|
||||
#define DSET_NAME_BUF_SIZE 64u
|
||||
#define DATASET_NUMB 100u
|
||||
|
||||
#define DATASET_SHAPE_TEST_DSET_BASE_NAME "dataset_shape_test"
|
||||
#define DATASET_SHAPE_TEST_SUBGROUP_NAME "dataset_shape_test"
|
||||
#define DATASET_SHAPE_TEST_NUM_ITERATIONS 5
|
||||
#define DATASET_SHAPE_TEST_MAX_DIMS 5
|
||||
|
||||
#define DATASET_PREDEFINED_TYPE_TEST_SPACE_RANK 2
|
||||
#define DATASET_PREDEFINED_TYPE_TEST_BASE_NAME "predefined_type_dset"
|
||||
#define DATASET_PREDEFINED_TYPE_TEST_SUBGROUP_NAME "predefined_type_dataset_test"
|
||||
|
||||
#define DATASET_STRING_TYPE_TEST_STRING_LENGTH 40
|
||||
#define DATASET_STRING_TYPE_TEST_SPACE_RANK 2
|
||||
#define DATASET_STRING_TYPE_TEST_DSET_NAME1 "fixed_length_string_dset"
|
||||
#define DATASET_STRING_TYPE_TEST_DSET_NAME2 "variable_length_string_dset"
|
||||
#define DATASET_STRING_TYPE_TEST_SUBGROUP_NAME "string_type_dataset_test"
|
||||
|
||||
#define DATASET_COMPOUND_TYPE_TEST_SUBGROUP_NAME "compound_type_dataset_test"
|
||||
#define DATASET_COMPOUND_TYPE_TEST_DSET_NAME "compound_type_test"
|
||||
#define DATASET_COMPOUND_TYPE_TEST_MAX_SUBTYPES 5
|
||||
#define DATASET_COMPOUND_TYPE_TEST_MAX_PASSES 5
|
||||
#define DATASET_COMPOUND_TYPE_TEST_DSET_RANK 2
|
||||
|
||||
#define DATASET_ENUM_TYPE_TEST_VAL_BASE_NAME "INDEX"
|
||||
#define DATASET_ENUM_TYPE_TEST_SUBGROUP_NAME "enum_type_dataset_test"
|
||||
#define DATASET_ENUM_TYPE_TEST_NUM_MEMBERS 16
|
||||
#define DATASET_ENUM_TYPE_TEST_SPACE_RANK 2
|
||||
#define DATASET_ENUM_TYPE_TEST_DSET_NAME1 "enum_native_dset"
|
||||
#define DATASET_ENUM_TYPE_TEST_DSET_NAME2 "enum_non_native_dset"
|
||||
|
||||
#define DATASET_ARRAY_TYPE_TEST_SUBGROUP_NAME "array_type_dataset_test"
|
||||
#define DATASET_ARRAY_TYPE_TEST_DSET_NAME1 "array_type_test1"
|
||||
#define DATASET_ARRAY_TYPE_TEST_DSET_NAME2 "array_type_test2"
|
||||
#define DATASET_ARRAY_TYPE_TEST_DSET_NAME3 "array_type_test3"
|
||||
#define DATASET_ARRAY_TYPE_TEST_SPACE_RANK 2
|
||||
#define DATASET_ARRAY_TYPE_TEST_RANK1 2
|
||||
#define DATASET_ARRAY_TYPE_TEST_RANK2 2
|
||||
#define DATASET_ARRAY_TYPE_TEST_RANK3 2
|
||||
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_TRACK_TIMES_YES_DSET_NAME "track_times_true_test"
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_TRACK_TIMES_NO_DSET_NAME "track_times_false_test"
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_PHASE_CHANGE_DSET_NAME "attr_phase_change_test"
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_ALLOC_TIMES_BASE_NAME "alloc_time_test"
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_FILL_TIMES_BASE_NAME "fill_times_test"
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_CRT_ORDER_BASE_NAME "creation_order_test"
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_LAYOUTS_BASE_NAME "layout_test"
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_FILTERS_DSET_NAME "filters_test"
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_GROUP_NAME "creation_properties_test"
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_CHUNK_DIM_RANK DATASET_CREATION_PROPERTIES_TEST_SHAPE_RANK
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_MAX_COMPACT 12
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_MIN_DENSE 8
|
||||
#define DATASET_CREATION_PROPERTIES_TEST_SHAPE_RANK 3
|
||||
|
||||
#define DATASET_OPEN_INVALID_PARAMS_SPACE_RANK 2
|
||||
#define DATASET_OPEN_INVALID_PARAMS_GROUP_NAME "dataset_open_test"
|
||||
#define DATASET_OPEN_INVALID_PARAMS_DSET_NAME "open_test_dataset"
|
||||
|
||||
#define DATASET_GET_SPACE_TYPE_TEST_SPACE_RANK 2
|
||||
#define DATASET_GET_SPACE_TYPE_TEST_GROUP_NAME "get_dset_space_type_test"
|
||||
#define DATASET_GET_SPACE_TYPE_TEST_DSET_NAME "get_space_type_test_dset"
|
||||
|
||||
#define DATASET_GET_SPACE_TYPE_INVALID_PARAMS_TEST_SPACE_RANK 2
|
||||
#define DATASET_GET_SPACE_TYPE_INVALID_PARAMS_TEST_GROUP_NAME "get_dset_space_type_invalid_params_test"
|
||||
#define DATASET_GET_SPACE_TYPE_INVALID_PARAMS_TEST_DSET_NAME "get_space_type_test_invalid_params_dset"
|
||||
|
||||
#define DATASET_PROPERTY_LIST_TEST_SUBGROUP_NAME "dataset_property_list_test_group"
|
||||
#define DATASET_PROPERTY_LIST_TEST_SPACE_RANK 2
|
||||
#define DATASET_PROPERTY_LIST_TEST_DSET_NAME1 "property_list_test_dataset1"
|
||||
#define DATASET_PROPERTY_LIST_TEST_DSET_NAME2 "property_list_test_dataset2"
|
||||
#define DATASET_PROPERTY_LIST_TEST_DSET_NAME3 "property_list_test_dataset3"
|
||||
#define DATASET_PROPERTY_LIST_TEST_DSET_NAME4 "property_list_test_dataset4"
|
||||
|
||||
#define DATASET_SMALL_READ_TEST_ALL_DSET_SPACE_RANK 3
|
||||
#define DATASET_SMALL_READ_TEST_ALL_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_SMALL_READ_TEST_ALL_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_SMALL_READ_TEST_ALL_GROUP_NAME "dataset_small_read_all_test"
|
||||
#define DATASET_SMALL_READ_TEST_ALL_DSET_NAME "dataset_small_read_all_dset"
|
||||
|
||||
#define DATASET_SMALL_READ_TEST_HYPERSLAB_DSET_SPACE_RANK 3
|
||||
#define DATASET_SMALL_READ_TEST_HYPERSLAB_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_SMALL_READ_TEST_HYPERSLAB_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_SMALL_READ_TEST_HYPERSLAB_GROUP_NAME "dataset_small_read_hyperslab_test"
|
||||
#define DATASET_SMALL_READ_TEST_HYPERSLAB_DSET_NAME "dataset_small_read_hyperslab_dset"
|
||||
|
||||
#define DATASET_SMALL_READ_TEST_POINT_SELECTION_DSET_SPACE_RANK 3
|
||||
#define DATASET_SMALL_READ_TEST_POINT_SELECTION_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_SMALL_READ_TEST_POINT_SELECTION_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_SMALL_READ_TEST_POINT_SELECTION_NUM_POINTS 10
|
||||
#define DATASET_SMALL_READ_TEST_POINT_SELECTION_GROUP_NAME "dataset_small_read_point_selection_test"
|
||||
#define DATASET_SMALL_READ_TEST_POINT_SELECTION_DSET_NAME "dataset_small_read_point_selection_dset"
|
||||
|
||||
#define DATASET_IO_POINT_GROUP_NAME "dataset_io_point_selection_test"
|
||||
#define DATASET_IO_POINT_DSET_NAME_NOCHUNK "dataset_io_point_selection_dset_nochunk"
|
||||
#define DATASET_IO_POINT_DSET_NAME_CHUNK "dataset_io_point_selection_dset_chunk"
|
||||
|
||||
#ifndef NO_LARGE_TESTS
|
||||
#define DATASET_LARGE_READ_TEST_ALL_DSET_SPACE_RANK 3
|
||||
#define DATASET_LARGE_READ_TEST_ALL_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_LARGE_READ_TEST_ALL_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_LARGE_READ_TEST_ALL_GROUP_NAME "dataset_large_read_all_test"
|
||||
#define DATASET_LARGE_READ_TEST_ALL_DSET_NAME "dataset_large_read_all_dset"
|
||||
|
||||
#define DATASET_LARGE_READ_TEST_HYPERSLAB_DSET_SPACE_RANK 3
|
||||
#define DATASET_LARGE_READ_TEST_HYPERSLAB_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_LARGE_READ_TEST_HYPERSLAB_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_LARGE_READ_TEST_HYPERSLAB_GROUP_NAME "dataset_large_read_hyperslab_test"
|
||||
#define DATASET_LARGE_READ_TEST_HYPERSLAB_DSET_NAME "dataset_large_read_hyperslab_dset"
|
||||
|
||||
#define DATASET_LARGE_READ_TEST_POINT_SELECTION_DSET_SPACE_RANK 1
|
||||
#define DATASET_LARGE_READ_TEST_POINT_SELECTION_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_LARGE_READ_TEST_POINT_SELECTION_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_LARGE_READ_TEST_POINT_SELECTION_GROUP_NAME "dataset_large_read_point_selection_test"
|
||||
#define DATASET_LARGE_READ_TEST_POINT_SELECTION_DSET_NAME "dataset_large_read_point_selection_dset"
|
||||
#endif
|
||||
|
||||
#define DATASET_READ_INVALID_PARAMS_TEST_DSET_SPACE_RANK 3
|
||||
#define DATASET_READ_INVALID_PARAMS_TEST_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_READ_INVALID_PARAMS_TEST_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_READ_INVALID_PARAMS_TEST_GROUP_NAME "dataset_read_invalid_params_test"
|
||||
#define DATASET_READ_INVALID_PARAMS_TEST_DSET_NAME "dataset_read_invalid_params_dset"
|
||||
|
||||
#define DATASET_SMALL_WRITE_TEST_ALL_DSET_SPACE_RANK 3
|
||||
#define DATASET_SMALL_WRITE_TEST_ALL_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_SMALL_WRITE_TEST_ALL_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_SMALL_WRITE_TEST_ALL_GROUP_NAME "dataset_small_write_all_test"
|
||||
#define DATASET_SMALL_WRITE_TEST_ALL_DSET_NAME "dataset_small_write_all_dset"
|
||||
|
||||
#define DATASET_SMALL_WRITE_TEST_HYPERSLAB_DSET_SPACE_RANK 3
|
||||
#define DATASET_SMALL_WRITE_TEST_HYPERSLAB_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_SMALL_WRITE_TEST_HYPERSLAB_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_SMALL_WRITE_TEST_HYPERSLAB_GROUP_NAME "dataset_small_write_hyperslab_test"
|
||||
#define DATASET_SMALL_WRITE_TEST_HYPERSLAB_DSET_NAME "dataset_small_write_hyperslab_dset"
|
||||
|
||||
#define DATASET_SMALL_WRITE_TEST_POINT_SELECTION_DSET_SPACE_RANK 3
|
||||
#define DATASET_SMALL_WRITE_TEST_POINT_SELECTION_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_SMALL_WRITE_TEST_POINT_SELECTION_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_SMALL_WRITE_TEST_POINT_SELECTION_NUM_POINTS 10
|
||||
#define DATASET_SMALL_WRITE_TEST_POINT_SELECTION_GROUP_NAME "dataset_small_write_point_selection_test"
|
||||
#define DATASET_SMALL_WRITE_TEST_POINT_SELECTION_DSET_NAME "dataset_small_write_point_selection_dset"
|
||||
|
||||
#ifndef NO_LARGE_TESTS
|
||||
#define DATASET_LARGE_WRITE_TEST_ALL_DSET_SPACE_RANK 3
|
||||
#define DATASET_LARGE_WRITE_TEST_ALL_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_LARGE_WRITE_TEST_ALL_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_LARGE_WRITE_TEST_ALL_GROUP_NAME "dataset_large_write_all_test"
|
||||
#define DATASET_LARGE_WRITE_TEST_ALL_DSET_NAME "dataset_large_write_all_dset"
|
||||
|
||||
#define DATASET_LARGE_WRITE_TEST_HYPERSLAB_DSET_SPACE_RANK 3
|
||||
#define DATASET_LARGE_WRITE_TEST_HYPERSLAB_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_LARGE_WRITE_TEST_HYPERSLAB_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_LARGE_WRITE_TEST_HYPERSLAB_GROUP_NAME "dataset_large_write_hyperslab_test"
|
||||
#define DATASET_LARGE_WRITE_TEST_HYPERSLAB_DSET_NAME "dataset_large_write_hyperslab_dset"
|
||||
|
||||
#define DATASET_LARGE_WRITE_TEST_POINT_SELECTION_DSET_SPACE_RANK 3
|
||||
#define DATASET_LARGE_WRITE_TEST_POINT_SELECTION_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_LARGE_WRITE_TEST_POINT_SELECTION_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_LARGE_WRITE_TEST_POINT_SELECTION_GROUP_NAME "dataset_large_write_point_selection_test"
|
||||
#define DATASET_LARGE_WRITE_TEST_POINT_SELECTION_DSET_NAME "dataset_large_write_point_selection_dset"
|
||||
#endif
|
||||
|
||||
#define DATASET_DATA_VERIFY_WRITE_TEST_DSET_SPACE_RANK 3
|
||||
#define DATASET_DATA_VERIFY_WRITE_TEST_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_DATA_VERIFY_WRITE_TEST_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_DATA_VERIFY_WRITE_TEST_NUM_POINTS 10
|
||||
#define DATASET_DATA_VERIFY_WRITE_TEST_GROUP_NAME "dataset_data_write_verification_test"
|
||||
#define DATASET_DATA_VERIFY_WRITE_TEST_DSET_NAME "dataset_data_write_verification_dset"
|
||||
|
||||
#define DATASET_WRITE_INVALID_PARAMS_TEST_DSET_SPACE_RANK 3
|
||||
#define DATASET_WRITE_INVALID_PARAMS_TEST_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_WRITE_INVALID_PARAMS_TEST_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_WRITE_INVALID_PARAMS_TEST_GROUP_NAME "dataset_write_invalid_params_test"
|
||||
#define DATASET_WRITE_INVALID_PARAMS_TEST_DSET_NAME "dataset_write_invalid_params_dset"
|
||||
|
||||
#define DATASET_DATA_BUILTIN_CONVERSION_TEST_DSET_SPACE_RANK 3
|
||||
#define DATASET_DATA_BUILTIN_CONVERSION_TEST_MEM_DTYPESIZE sizeof(int)
|
||||
#define DATASET_DATA_BUILTIN_CONVERSION_TEST_MEM_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_DATA_BUILTIN_CONVERSION_TEST_NUM_POINTS 10
|
||||
#define DATASET_DATA_BUILTIN_CONVERSION_TEST_GROUP_NAME "dataset_builtin_conversion_verification_test"
|
||||
#define DATASET_DATA_BUILTIN_CONVERSION_TEST_DSET_NAME "dataset_builtin_conversion_verification_dset"
|
||||
|
||||
#define DATASET_COMPOUND_PARTIAL_IO_DSET_DIMS 10
|
||||
#define DATASET_DATA_COMPOUND_PARTIAL_IO_TEST_GROUP_NAME "dataset_compound_partial_io_test"
|
||||
#define DATASET_DATA_COMPOUND_PARTIAL_IO_TEST_DSET_NAME "dataset_compound_partial_io_test"
|
||||
|
||||
#define DATASET_SET_EXTENT_CHUNKED_UNLIMITED_TEST_SPACE_RANK 2
|
||||
#define DATASET_SET_EXTENT_CHUNKED_UNLIMITED_TEST_NUM_PASSES 3
|
||||
#define DATASET_SET_EXTENT_CHUNKED_UNLIMITED_TEST_GROUP_NAME "set_extent_chunked_unlimited_test"
|
||||
#define DATASET_SET_EXTENT_CHUNKED_UNLIMITED_TEST_DSET_NAME "set_extent_chunked_unlimited_test_dset"
|
||||
|
||||
#define DATASET_SET_EXTENT_CHUNKED_FIXED_TEST_SPACE_RANK 2
|
||||
#define DATASET_SET_EXTENT_CHUNKED_FIXED_TEST_NUM_PASSES 3
|
||||
#define DATASET_SET_EXTENT_CHUNKED_FIXED_TEST_GROUP_NAME "set_extent_chunked_fixed_test"
|
||||
#define DATASET_SET_EXTENT_CHUNKED_FIXED_TEST_DSET_NAME "set_extent_chunked_fixed_test_dset"
|
||||
#define DATASET_SET_EXTENT_CHUNKED_FIXED_TEST_DSET_NAME2 "set_extent_chunked_fixed_test_dset2"
|
||||
|
||||
#define DATASET_SET_EXTENT_DATA_TEST_SPACE_RANK 2
|
||||
#define DATASET_SET_EXTENT_DATA_TEST_GROUP_NAME "set_extent_chunked_data_test"
|
||||
#define DATASET_SET_EXTENT_DATA_TEST_DSET_NAME "set_extent_chunked_data_test_dset"
|
||||
#define DATASET_SET_EXTENT_DATA_TEST_SPACE_DIM 8
|
||||
|
||||
#define DATASET_SET_EXTENT_DOUBLE_HANDLES_TEST_SPACE_RANK 2
|
||||
#define DATASET_SET_EXTENT_DOUBLE_HANDLES_TEST_GROUP_NAME "set_extent_chunked_double_handles_test"
|
||||
#define DATASET_SET_EXTENT_DOUBLE_HANDLES_TEST_DSET_NAME "set_extent_chunked_double_handles_test_dset"
|
||||
#define DATASET_SET_EXTENT_DOUBLE_HANDLES_TEST_SPACE_DIM 8
|
||||
|
||||
#define DATASET_SET_EXTENT_INVALID_PARAMS_TEST_SPACE_RANK 2
|
||||
#define DATASET_SET_EXTENT_INVALID_PARAMS_TEST_GROUP_NAME "set_extent_invalid_params_test"
|
||||
#define DATASET_SET_EXTENT_INVALID_PARAMS_TEST_DSET_NAME "set_extent_invalid_params_test_dset"
|
||||
#define DATASET_SET_EXTENT_INVALID_LAYOUT_TEST_COMPACT_DSET_NAME "set_extent_invalid_layout_test_compact_dset"
|
||||
#define DATASET_SET_EXTENT_INVALID_LAYOUT_TEST_CONTIGUOUS_DSET_NAME \
|
||||
"set_extent_invalid_layout_test_contiguous_dset"
|
||||
|
||||
#define DATASET_SINGLE_CHUNK_TEST_SPACE_RANK 2
|
||||
#define DATASET_SINGLE_CHUNK_TEST_GROUP_NAME "single_chunk_dataset_test"
|
||||
#define DATASET_SINGLE_CHUNK_TEST_DSET_NAME "single_chunk_dataset"
|
||||
|
||||
#define DATASET_SINGLE_CHUNK_WRITE_TEST_DSET_SPACE_RANK 2
|
||||
#define DATASET_SINGLE_CHUNK_WRITE_TEST_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_SINGLE_CHUNK_WRITE_TEST_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_SINGLE_CHUNK_WRITE_TEST_GROUP_NAME "single_chunk_dataset_write_test"
|
||||
#define DATASET_SINGLE_CHUNK_WRITE_TEST_DSET_NAME "single_chunk_dataset"
|
||||
|
||||
#define DATASET_MULTI_CHUNK_TEST_SPACE_RANK 2
|
||||
#define DATASET_MULTI_CHUNK_TEST_GROUP_NAME "multi_chunk_dataset_test"
|
||||
#define DATASET_MULTI_CHUNK_TEST_DSET_NAME "multi_chunk_dataset"
|
||||
|
||||
#define DATASET_MULTI_CHUNK_WRITE_SAME_SPACE_READ_TEST_DSET_SPACE_RANK 2
|
||||
#define DATASET_MULTI_CHUNK_WRITE_SAME_SPACE_READ_TEST_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_MULTI_CHUNK_WRITE_SAME_SPACE_READ_TEST_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_MULTI_CHUNK_WRITE_SAME_SPACE_READ_TEST_GROUP_NAME \
|
||||
"multi_chunk_dataset_write_same_space_read_test"
|
||||
#define DATASET_MULTI_CHUNK_WRITE_SAME_SPACE_READ_TEST_DSET_NAME "multi_chunk_dataset"
|
||||
|
||||
#define DATASET_MULTI_CHUNK_WRITE_DIFF_SPACE_READ_TEST_DSET_SPACE_RANK 2
|
||||
#define DATASET_MULTI_CHUNK_WRITE_DIFF_SPACE_READ_TEST_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_MULTI_CHUNK_WRITE_DIFF_SPACE_READ_TEST_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_MULTI_CHUNK_WRITE_DIFF_SPACE_READ_TEST_GROUP_NAME \
|
||||
"multi_chunk_dataset_write_diff_space_read_test"
|
||||
#define DATASET_MULTI_CHUNK_WRITE_DIFF_SPACE_READ_TEST_DSET_NAME "multi_chunk_dataset"
|
||||
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_SAME_SPACE_READ_TEST_DSET_SPACE_RANK 2
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_SAME_SPACE_READ_TEST_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_SAME_SPACE_READ_TEST_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_SAME_SPACE_READ_TEST_GROUP_NAME \
|
||||
"multi_chunk_dataset_same_space_overwrite_test"
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_SAME_SPACE_READ_TEST_DSET_NAME "multi_chunk_dataset"
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_SAME_SPACE_READ_TEST_NITERS 10
|
||||
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_DIFF_SPACE_READ_TEST_DSET_SPACE_RANK 2
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_DIFF_SPACE_READ_TEST_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_DIFF_SPACE_READ_TEST_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_DIFF_SPACE_READ_TEST_GROUP_NAME \
|
||||
"multi_chunk_dataset_diff_space_overwrite_test"
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_DIFF_SPACE_READ_TEST_DSET_NAME "multi_chunk_dataset"
|
||||
#define DATASET_MULTI_CHUNK_OVERWRITE_DIFF_SPACE_READ_TEST_NITERS 10
|
||||
|
||||
#define DATASET_PARTIAL_CHUNK_READ_ALL_SEL_TEST_DSET_SPACE_RANK 2
|
||||
#define DATASET_PARTIAL_CHUNK_READ_ALL_SEL_TEST_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_PARTIAL_CHUNK_READ_ALL_SEL_TEST_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_PARTIAL_CHUNK_READ_ALL_SEL_TEST_DSET_CTYPE int
|
||||
#define DATASET_PARTIAL_CHUNK_READ_ALL_SEL_TEST_GROUP_NAME "read_partial_chunk_all_sel_test"
|
||||
#define DATASET_PARTIAL_CHUNK_READ_ALL_SEL_TEST_DSET_NAME "read_partial_chunk_all_sel_dset"
|
||||
|
||||
#define DATASET_PARTIAL_CHUNK_READ_HYPER_SEL_TEST_DSET_SPACE_RANK 2
|
||||
#define DATASET_PARTIAL_CHUNK_READ_HYPER_SEL_TEST_DSET_DTYPESIZE sizeof(int)
|
||||
#define DATASET_PARTIAL_CHUNK_READ_HYPER_SEL_TEST_DSET_DTYPE H5T_NATIVE_INT
|
||||
#define DATASET_PARTIAL_CHUNK_READ_HYPER_SEL_TEST_DSET_CTYPE int
|
||||
#define DATASET_PARTIAL_CHUNK_READ_HYPER_SEL_TEST_GROUP_NAME "read_partial_chunk_hyper_sel_test"
|
||||
#define DATASET_PARTIAL_CHUNK_READ_HYPER_SEL_TEST_DSET_NAME "read_partial_chunk_hyper_sel_dset"
|
||||
|
||||
#define DATASET_GET_VLEN_BUF_SIZE_DSET_SPACE_RANK 1
|
||||
#define DATASET_GET_VLEN_BUF_SIZE_DSET_SPACE_DIM 4
|
||||
#define DATASET_GET_VLEN_BUF_SIZE_GROUP_NAME "get_vlen_buffer_size_group"
|
||||
#define DATASET_GET_VLEN_BUF_SIZE_DSET_NAME "get_vlen_buffer_size_dset"
|
||||
#endif
|
2693
test/API/H5_api_datatype_test.c
Normal file
2693
test/API/H5_api_datatype_test.c
Normal file
File diff suppressed because it is too large
Load Diff
79
test/API/H5_api_datatype_test.h
Normal file
79
test/API/H5_api_datatype_test.h
Normal file
@ -0,0 +1,79 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_DATATYPE_TEST_H
|
||||
#define H5_API_DATATYPE_TEST_H
|
||||
|
||||
#include "H5_api_test.h"
|
||||
|
||||
int H5_api_datatype_test(void);
|
||||
|
||||
/*************************************************
|
||||
* *
|
||||
* API Datatype test defines *
|
||||
* *
|
||||
*************************************************/
|
||||
|
||||
#define DATATYPE_CREATE_TEST_DATASET_DIMS 2
|
||||
#define DATATYPE_CREATE_TEST_GROUP_NAME "committed_datatype_creation_test"
|
||||
#define DATATYPE_CREATE_TEST_TYPE_NAME "test_type"
|
||||
|
||||
#define DATATYPE_CREATE_INVALID_PARAMS_TEST_SPACE_RANK 2
|
||||
#define DATATYPE_CREATE_INVALID_PARAMS_TEST_GROUP_NAME "committed_datatype_creation_invalid_params_test"
|
||||
#define DATATYPE_CREATE_INVALID_PARAMS_TEST_TYPE_NAME "committed_datatype_creation_invalid_params_datatype"
|
||||
|
||||
#define DATATYPE_CREATE_ANONYMOUS_GROUP_NAME "anonymous_type_creation_test"
|
||||
#define DATATYPE_CREATE_ANONYMOUS_TYPE_NAME "anon_type"
|
||||
|
||||
#define DATATYPE_CREATE_ANONYMOUS_INVALID_PARAMS_GROUP_NAME "anonymous_type_creation_invalid_params_test"
|
||||
|
||||
#define DATATYPE_CREATE_EMPTY_TYPES_TEST_CMPD_TYPE_NAME "compound_type"
|
||||
#define DATATYPE_CREATE_EMPTY_TYPES_TEST_ENUM_TYPE_NAME "enum_type"
|
||||
#define DATATYPE_CREATE_EMPTY_TYPES_TEST_GROUP_NAME "committed_datatype_empty_types_test"
|
||||
|
||||
#define RECOMMIT_COMMITTED_TYPE_TEST_GROUP_NAME "recommit_committed_type_test"
|
||||
|
||||
#define DATATYPE_OPEN_TEST_GROUP_NAME "datatype_open_test"
|
||||
#define DATATYPE_OPEN_TEST_TYPE_NAME "open_test_datatype"
|
||||
|
||||
#define DATATYPE_OPEN_INVALID_PARAMS_TEST_GROUP_NAME "datatype_open_invalid_params_test"
|
||||
#define DATATYPE_OPEN_INVALID_PARAMS_TEST_TYPE_NAME "open_invalid_params_test_datatype"
|
||||
|
||||
#define DATATYPE_REOPEN_TEST_SPACE_RANK 2
|
||||
#define DATATYPE_REOPEN_TEST_GROUP_NAME "datatype_reopen_test"
|
||||
|
||||
#define DATASET_CREATE_WITH_DATATYPE_TEST_DATASET_DIMS 2
|
||||
#define DATASET_CREATE_WITH_DATATYPE_TEST_GROUP_NAME "dataset_create_with_committed_type_test"
|
||||
#define DATASET_CREATE_WITH_DATATYPE_TEST_TYPE_NAME "committed_type_test_dtype1"
|
||||
#define DATASET_CREATE_WITH_DATATYPE_TEST_DSET_NAME "committed_type_test_dset"
|
||||
|
||||
#define ATTRIBUTE_CREATE_WITH_DATATYPE_TEST_SPACE_RANK 2
|
||||
#define ATTRIBUTE_CREATE_WITH_DATATYPE_TEST_GROUP_NAME "attribute_create_with_committed_type_test"
|
||||
#define ATTRIBUTE_CREATE_WITH_DATATYPE_TEST_DTYPE_NAME "committed_type_test_dtype2"
|
||||
#define ATTRIBUTE_CREATE_WITH_DATATYPE_TEST_ATTR_NAME "committed_type_test_attr"
|
||||
|
||||
#define DATATYPE_DELETE_TEST_GROUP_NAME "datatype_deletion_test"
|
||||
#define DATATYPE_DELETE_TEST_DTYPE_NAME "delete_test_dtype"
|
||||
|
||||
#define DATATYPE_RESURRECT_TEST_GROUP_NAME "datatype_resurrection_test"
|
||||
#define DATATYPE_RESURRECT_TEST_DTYPE_NAME "delete_test_dtype"
|
||||
#define DATATYPE_RESURRECT_TEST_DTYPE_NAME2 "resurrected_dtype"
|
||||
|
||||
#define DATATYPE_PROPERTY_LIST_TEST_SUBGROUP_NAME "datatype_property_list_test_group"
|
||||
#define DATATYPE_PROPERTY_LIST_TEST_DATATYPE_NAME1 "property_list_test_datatype1"
|
||||
#define DATATYPE_PROPERTY_LIST_TEST_DATATYPE_NAME2 "property_list_test_datatype2"
|
||||
|
||||
#define PREDEFINED_TYPE_COMMIT_TEST_GROUP_NAME "predefined_type_commit_test"
|
||||
|
||||
#define MODIFY_COMMITTED_TYPE_TEST_GROUP_NAME "modify_committed_type_test"
|
||||
|
||||
#endif
|
2564
test/API/H5_api_file_test.c
Normal file
2564
test/API/H5_api_file_test.c
Normal file
File diff suppressed because it is too large
Load Diff
85
test/API/H5_api_file_test.h
Normal file
85
test/API/H5_api_file_test.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_FILE_TEST_H
|
||||
#define H5_API_FILE_TEST_H
|
||||
|
||||
#include "H5_api_test.h"
|
||||
|
||||
int H5_api_file_test(void);
|
||||
|
||||
/*********************************************
|
||||
* *
|
||||
* API File test defines *
|
||||
* *
|
||||
*********************************************/
|
||||
|
||||
#define FILE_CREATE_TEST_FILENAME "test_file.h5"
|
||||
|
||||
#define FILE_CREATE_INVALID_PARAMS_FILE_NAME "invalid_params_file.h5"
|
||||
|
||||
#define FILE_CREATE_EXCL_FILE_NAME "excl_flag_file.h5"
|
||||
|
||||
#define NONEXISTENT_FILENAME "nonexistent_file.h5"
|
||||
|
||||
#define OVERLAPPING_FILENAME "overlapping_file.h5"
|
||||
#define OVERLAPPING_OPEN_TEST_GRP_NAME "group"
|
||||
#define OVERLAPPING_OPEN_TEST_DSET_NAME "dataset"
|
||||
|
||||
#define FILE_PERMISSION_TEST_FILENAME "file_permission.h5"
|
||||
#define FILE_PERMISSION_TEST_GRP_NAME "group"
|
||||
#define FILE_PERMISSION_TEST_DSET_NAME "Dataset"
|
||||
#define FILE_PERMISSION_TEST_DSET2_NAME "Dataset2"
|
||||
#define FILE_PERMISSION_TEST_ATTR_NAME "attribute"
|
||||
#define FILE_PERMISSION_TEST_NAMED_DTYPE "named_dtype"
|
||||
|
||||
#define FILE_FLUSH_TEST_FILENAME "flush_file.h5"
|
||||
|
||||
#define FILE_PROPERTY_LIST_TEST_FCPL_PROP_VAL 65536
|
||||
#define FILE_PROPERTY_LIST_TEST_FNAME1 "property_list_test_file1.h5"
|
||||
#define FILE_PROPERTY_LIST_TEST_FNAME2 "property_list_test_file2.h5"
|
||||
|
||||
#define FILE_INTENT_TEST_FILENAME "intent_test_file.h5"
|
||||
|
||||
#define GET_OBJ_COUNT_TEST_FILENAME1 "file_obj_count1.h5"
|
||||
#define GET_OBJ_COUNT_TEST_FILENAME2 "file_obj_count2.h5"
|
||||
#define GET_OBJ_COUNT_TEST_GRP_NAME "/group"
|
||||
#define GET_OBJ_COUNT_TEST_DSET_NAME "Dataset"
|
||||
#define GET_OBJ_COUNT_TEST_ATTR_NAME "Attribute"
|
||||
#define GET_OBJ_COUNT_TEST_NAMED_DTYPE "named_dtype"
|
||||
|
||||
#define FILE_MOUNT_TEST_FILENAME "file_mount.h5"
|
||||
#define FILE_MOUNT_TEST_GRP_NAME "group"
|
||||
|
||||
#define GET_FILE_NAME_TEST_FNAME "file_name_retrieval.h5"
|
||||
#define GET_FILE_NAME_TEST_GRP_NAME "group"
|
||||
#define GET_FILE_NAME_TEST_DSET_NAME "dataset"
|
||||
#define GET_FILE_NAME_TEST_ATTR_NAME "attribute"
|
||||
#define GET_FILE_NAME_TEST_NAMED_DTYPE "datatype"
|
||||
|
||||
#define FILESPACE_INFO_FILENAME "filespace_info.h5"
|
||||
#define FSP_SIZE512 (hsize_t)512
|
||||
|
||||
#define FILE_GET_ID_TEST_FILENAME "test_file_id.h5"
|
||||
|
||||
#define FILE_CLOSE_DEGREE_FILENAME "test_close_degree.h5"
|
||||
|
||||
#define GET_FREE_SECTIONS_FILENAME "test_free_sections.h5"
|
||||
|
||||
#define FILE_SIZE_FILENAME "file_size.h5"
|
||||
#define KB 1024U
|
||||
|
||||
#define FILE_INFO_FILENAME "file_info.h5"
|
||||
|
||||
#define DOUBLE_GROUP_OPEN_FILENAME "double_group_open.h5"
|
||||
|
||||
#endif
|
2394
test/API/H5_api_group_test.c
Normal file
2394
test/API/H5_api_group_test.c
Normal file
File diff suppressed because it is too large
Load Diff
65
test/API/H5_api_group_test.h
Normal file
65
test/API/H5_api_group_test.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_GROUP_TEST_H
|
||||
#define H5_API_GROUP_TEST_H
|
||||
|
||||
#include "H5_api_test.h"
|
||||
|
||||
int H5_api_group_test(void);
|
||||
|
||||
/**********************************************
|
||||
* *
|
||||
* API Group test defines *
|
||||
* *
|
||||
**********************************************/
|
||||
|
||||
#define GROUP_CREATE_UNDER_ROOT_GNAME "/group_under_root"
|
||||
|
||||
#define GROUP_CREATE_UNDER_GROUP_REL_GNAME "child_group"
|
||||
#define GROUP_CREATE_UNDER_GROUP_ABS_GNAME "child_group/grandchild_group"
|
||||
|
||||
#define GROUP_CREATE_INVALID_PARAMS_GROUP_NAME "/invalid_params_group"
|
||||
|
||||
#define GROUP_CREATE_ANONYMOUS_GROUP_NAME "anon_group"
|
||||
|
||||
#define GROUP_CREATE_INTMD_REL_INTMD_NAME "rel_intmd"
|
||||
#define GROUP_CREATE_INTMD_REL_END_NAME "rel_end"
|
||||
#define GROUP_CREATE_INTMD_ABS_INTMD_NAME "abs_intmd"
|
||||
#define GROUP_CREATE_INTMD_ABS_END_NAME "abs_end"
|
||||
#define GROUP_CREATE_INTMD_MULT_INTMD1_NAME "mult_intmd1"
|
||||
#define GROUP_CREATE_INTMD_MULT_INTMD2_NAME "mult_intmd2"
|
||||
#define GROUP_CREATE_INTMD_MULT_END_NAME "mult_end"
|
||||
|
||||
#define OPEN_NONEXISTENT_GROUP_TEST_GNAME "/nonexistent_group"
|
||||
|
||||
#define GROUP_PROPERTY_LIST_TEST_GROUP_NAME1 "property_list_test_group1"
|
||||
#define GROUP_PROPERTY_LIST_TEST_GROUP_NAME2 "property_list_test_group2"
|
||||
#define GROUP_PROPERTY_LIST_TEST_DUMMY_VAL H5P_CRT_ORDER_TRACKED
|
||||
|
||||
#define GROUP_GET_INFO_TEST_GROUP_NAME "group_info_test"
|
||||
#define GROUP_GET_INFO_TEST_GROUP_NUMB 16
|
||||
|
||||
#define GROUP_FLUSH_GNAME "group_flush_test"
|
||||
|
||||
#define GROUP_REFRESH_GNAME "group_refresh_test"
|
||||
|
||||
#define NAME_BUF_SIZE 64
|
||||
#define GROUP_NUMB 16
|
||||
|
||||
#define MANY_GROUP_CREATIONS_GNAME "home_for_many_groups"
|
||||
#define GROUP_NUMB_MANY 100u
|
||||
|
||||
#define DEEP_GROUP_CREATIONS_GNAME "home_for_deep_groups"
|
||||
#define GROUP_DEPTH 100u
|
||||
|
||||
#endif
|
27072
test/API/H5_api_link_test.c
Normal file
27072
test/API/H5_api_link_test.c
Normal file
File diff suppressed because it is too large
Load Diff
437
test/API/H5_api_link_test.h
Normal file
437
test/API/H5_api_link_test.h
Normal file
@ -0,0 +1,437 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_LINK_TEST_H
|
||||
#define H5_API_LINK_TEST_H
|
||||
|
||||
#include "H5_api_test.h"
|
||||
|
||||
int H5_api_link_test(void);
|
||||
|
||||
/*********************************************
|
||||
* *
|
||||
* API Link test defines *
|
||||
* *
|
||||
*********************************************/
|
||||
|
||||
#define HARD_LINK_TEST_GROUP_NAME "hard_link_creation_test"
|
||||
#define HARD_LINK_TEST_LINK_NAME "hard_link"
|
||||
|
||||
#define HARD_LINK_TEST_GROUP_LONG_NAME "hard_link_long_name"
|
||||
#define MAX_NAME_LEN ((64 * 1024) + 1024)
|
||||
|
||||
#define HARD_LINK_TEST_GROUP_MANY_NAME "hard_link_many_name"
|
||||
#define HARD_LINK_TEST_GROUP_MANY_FINAL_NAME "hard_link_final"
|
||||
#define HARD_LINK_TEST_GROUP_MANY_NAME_BUF_SIZE 1024
|
||||
|
||||
#define H5L_SAME_LOC_TEST_GROUP_NAME "h5l_same_loc_test_group"
|
||||
#define H5L_SAME_LOC_TEST_LINK_NAME1 "h5l_same_loc_test_link1"
|
||||
#define H5L_SAME_LOC_TEST_LINK_NAME2 "h5l_same_loc_test_link2"
|
||||
|
||||
#define HARD_LINK_INVALID_PARAMS_TEST_GROUP_NAME "hard_link_creation_invalid_params_test"
|
||||
#define HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME "hard_link"
|
||||
|
||||
#define SOFT_LINK_EXISTING_RELATIVE_TEST_SUBGROUP_NAME "soft_link_to_existing_relative_path_test"
|
||||
#define SOFT_LINK_EXISTING_RELATIVE_TEST_OBJECT_NAME "group"
|
||||
#define SOFT_LINK_EXISTING_RELATIVE_TEST_LINK_NAME "soft_link_to_existing_relative_path"
|
||||
|
||||
#define SOFT_LINK_EXISTING_ABSOLUTE_TEST_SUBGROUP_NAME "soft_link_to_existing_absolute_path_test"
|
||||
#define SOFT_LINK_EXISTING_ABSOLUTE_TEST_LINK_NAME "soft_link_to_existing_absolute_path"
|
||||
|
||||
#define SOFT_LINK_DANGLING_RELATIVE_TEST_SUBGROUP_NAME "soft_link_dangling_relative_path_test"
|
||||
#define SOFT_LINK_DANGLING_RELATIVE_TEST_OBJECT_NAME "group"
|
||||
#define SOFT_LINK_DANGLING_RELATIVE_TEST_LINK_NAME "soft_link_dangling_relative_path"
|
||||
|
||||
#define SOFT_LINK_DANGLING_ABSOLUTE_TEST_SUBGROUP_NAME "soft_link_dangling_absolute_path_test"
|
||||
#define SOFT_LINK_DANGLING_ABSOLUTE_TEST_OBJECT_NAME "group"
|
||||
#define SOFT_LINK_DANGLING_ABSOLUTE_TEST_LINK_NAME "soft_link_dangling_absolute_path"
|
||||
|
||||
#define SOFT_LINK_TEST_GROUP_LONG_NAME "soft_link_long_name"
|
||||
#define SOFT_LINK_TEST_LONG_OBJECT_NAME "soft_link_object_name"
|
||||
|
||||
#define SOFT_LINK_TEST_GROUP_MANY_NAME "soft_link_many_name"
|
||||
#define SOFT_LINK_TEST_GROUP_MANY_FINAL_NAME "soft_link_final"
|
||||
#define SOFT_LINK_TEST_GROUP_MANY_NAME_BUF_SIZE 1024
|
||||
|
||||
#define SOFT_LINK_INVALID_PARAMS_TEST_GROUP_NAME "soft_link_creation_invalid_params_test"
|
||||
#define SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME "soft_link_to_root"
|
||||
|
||||
#define EXTERNAL_LINK_TEST_SUBGROUP_NAME "external_link_test"
|
||||
#define EXTERNAL_LINK_TEST_FILE_NAME "ext_link_file.h5"
|
||||
#define EXTERNAL_LINK_TEST_LINK_NAME "ext_link"
|
||||
|
||||
#define EXTERNAL_LINK_TEST_DANGLING_SUBGROUP_NAME "external_link_dangling_test"
|
||||
#define EXTERNAL_LINK_TEST_DANGLING_LINK_NAME "dangling_ext_link"
|
||||
#define EXTERNAL_LINK_TEST_DANGLING_OBJECT_NAME "external_group"
|
||||
|
||||
#define EXTERNAL_LINK_TEST_MULTI_NAME "external_link_multi_test"
|
||||
#define EXTERNAL_LINK_TEST_MULTI_NAME_BUF_SIZE 1024
|
||||
#define EXTERNAL_LINK_TEST_FILE_NAME2 "ext_link_file_2.h5"
|
||||
#define EXTERNAL_LINK_TEST_FILE_NAME3 "ext_link_file_3.h5"
|
||||
#define EXTERNAL_LINK_TEST_FILE_NAME4 "ext_link_file_4.h5"
|
||||
|
||||
#define EXTERNAL_LINK_TEST_PING_PONG_NAME1 "ext_link_file_ping_pong_1.h5"
|
||||
#define EXTERNAL_LINK_TEST_PING_PONG_NAME2 "ext_link_file_ping_pong_2.h5"
|
||||
#define EXTERNAL_LINK_TEST_PING_PONG_NAME_BUF_SIZE 1024
|
||||
|
||||
#define EXTERNAL_LINK_INVALID_PARAMS_TEST_GROUP_NAME "external_link_creation_invalid_params_test"
|
||||
#define EXTERNAL_LINK_INVALID_PARAMS_TEST_FILE_NAME "ext_link_invalid_params_file.h5"
|
||||
#define EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME "external_link"
|
||||
|
||||
#define UD_LINK_TEST_UDATA_MAX_SIZE 256
|
||||
#define UD_LINK_TEST_GROUP_NAME "ud_link_creation_test"
|
||||
#define UD_LINK_TEST_LINK_NAME "ud_link"
|
||||
|
||||
#define UD_LINK_INVALID_PARAMS_TEST_UDATA_MAX_SIZE 256
|
||||
#define UD_LINK_INVALID_PARAMS_TEST_GROUP_NAME "ud_link_creation_invalid_params_test"
|
||||
#define UD_LINK_INVALID_PARAMS_TEST_LINK_NAME "ud_link"
|
||||
|
||||
#define LINK_DELETE_TEST_NESTED_GRP_NAME "nested_grp"
|
||||
#define LINK_DELETE_TEST_HARD_LINK_NAME "hard_link"
|
||||
#define LINK_DELETE_TEST_NESTED_HARD_LINK_NAME \
|
||||
LINK_DELETE_TEST_NESTED_GRP_NAME "/" LINK_DELETE_TEST_HARD_LINK_NAME
|
||||
#define LINK_DELETE_TEST_HARD_LINK_NAME2 LINK_DELETE_TEST_HARD_LINK_NAME "2"
|
||||
#define LINK_DELETE_TEST_HARD_LINK_NAME3 LINK_DELETE_TEST_HARD_LINK_NAME "3"
|
||||
#define LINK_DELETE_TEST_SOFT_LINK_NAME "soft_link"
|
||||
#define LINK_DELETE_TEST_SOFT_LINK_NAME2 LINK_DELETE_TEST_SOFT_LINK_NAME "2"
|
||||
#define LINK_DELETE_TEST_SOFT_LINK_NAME3 LINK_DELETE_TEST_SOFT_LINK_NAME "3"
|
||||
#define LINK_DELETE_TEST_EXTERNAL_LINK_NAME "external_link"
|
||||
#define LINK_DELETE_TEST_EXTERNAL_LINK_NAME2 LINK_DELETE_TEST_EXTERNAL_LINK_NAME "2"
|
||||
#define LINK_DELETE_TEST_EXTERNAL_LINK_NAME3 LINK_DELETE_TEST_EXTERNAL_LINK_NAME "3"
|
||||
#define LINK_DELETE_TEST_SUBGROUP_NAME "link_delete_test"
|
||||
#define LINK_DELETE_TEST_SUBGROUP1_NAME "H5Ldelete_hard_link"
|
||||
#define LINK_DELETE_TEST_NESTED_SUBGROUP_NAME1 "H5Ldelete_nested_hard_link"
|
||||
#define LINK_DELETE_TEST_SUBGROUP2_NAME "H5Ldelete_soft_link"
|
||||
#define LINK_DELETE_TEST_SUBGROUP3_NAME "H5Ldelete_external_link"
|
||||
#define LINK_DELETE_TEST_SUBGROUP4_NAME "H5Ldelete_ud_link"
|
||||
#define LINK_DELETE_TEST_SUBGROUP5_NAME "H5Ldelete_by_idx_hard_link_crt_order_increasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP6_NAME "H5Ldelete_by_idx_hard_link_crt_order_decreasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP7_NAME "H5Ldelete_by_idx_hard_link_name_order_increasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP8_NAME "H5Ldelete_by_idx_hard_link_name_order_decreasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP9_NAME "H5Ldelete_by_idx_soft_link_crt_order_increasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP10_NAME "H5Ldelete_by_idx_soft_link_crt_order_decreasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP11_NAME "H5Ldelete_by_idx_soft_link_name_order_increasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP12_NAME "H5Ldelete_by_idx_soft_link_name_order_decreasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP13_NAME "H5Ldelete_by_idx_external_link_crt_order_increasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP14_NAME "H5Ldelete_by_idx_external_link_crt_order_decreasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP15_NAME "H5Ldelete_by_idx_external_link_name_order_increasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP16_NAME "H5Ldelete_by_idx_external_link_name_order_decreasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP17_NAME "H5Ldelete_by_idx_ud_link_crt_order_increasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP18_NAME "H5Ldelete_by_idx_ud_link_crt_order_decreasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP19_NAME "H5Ldelete_by_idx_ud_link_name_order_increasing"
|
||||
#define LINK_DELETE_TEST_SUBGROUP20_NAME "H5Ldelete_by_idx_ud_link_name_order_decreasing"
|
||||
|
||||
#define LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_SUBGROUP_NAME "H5Ldelete_reset_grp_max_crt_order_test"
|
||||
#define LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_SUBGROUP1_NAME "H5Ldelete_bottom_up"
|
||||
#define LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_SUBGROUP2_NAME "H5Ldelete_top_down"
|
||||
#define LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS 5
|
||||
#define LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_BUF_SIZE 1024
|
||||
|
||||
#define LINK_DELETE_INVALID_PARAMS_TEST_HARD_LINK_NAME "hard_link"
|
||||
#define LINK_DELETE_INVALID_PARAMS_TEST_GROUP_NAME "link_deletion_invalid_params_test"
|
||||
|
||||
#define COPY_LINK_TEST_LINK_VAL_BUF_SIZE 1024
|
||||
#define COPY_LINK_TEST_EXTERNAL_LINK_NAME "external_link"
|
||||
#define COPY_LINK_TEST_EXTERNAL_LINK_NAME2 COPY_LINK_TEST_EXTERNAL_LINK_NAME "2"
|
||||
#define COPY_LINK_TEST_EXTERNAL_LINK_NAME3 COPY_LINK_TEST_EXTERNAL_LINK_NAME "3"
|
||||
#define COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME "external_link_copy"
|
||||
#define COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME2 COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME "2"
|
||||
#define COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME "external_link_same_loc"
|
||||
#define COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME2 COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME "2"
|
||||
#define COPY_LINK_TEST_HARD_LINK_NAME "hard_link"
|
||||
#define COPY_LINK_TEST_HARD_LINK_NAME2 COPY_LINK_TEST_HARD_LINK_NAME "2"
|
||||
#define COPY_LINK_TEST_HARD_LINK_NAME3 COPY_LINK_TEST_HARD_LINK_NAME "3"
|
||||
#define COPY_LINK_TEST_HARD_LINK_COPY_NAME "hard_link_copy"
|
||||
#define COPY_LINK_TEST_HARD_LINK_COPY_NAME2 COPY_LINK_TEST_HARD_LINK_COPY_NAME "2"
|
||||
#define COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME "hard_link_same_loc"
|
||||
#define COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME2 COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME "2"
|
||||
#define COPY_LINK_TEST_SOFT_LINK_TARGET_PATH "/" LINK_TEST_GROUP_NAME "/" COPY_LINK_TEST_SUBGROUP_NAME
|
||||
#define COPY_LINK_TEST_SOFT_LINK_NAME "soft_link"
|
||||
#define COPY_LINK_TEST_SOFT_LINK_NAME2 COPY_LINK_TEST_SOFT_LINK_NAME "2"
|
||||
#define COPY_LINK_TEST_SOFT_LINK_NAME3 COPY_LINK_TEST_SOFT_LINK_NAME "3"
|
||||
#define COPY_LINK_TEST_SOFT_LINK_COPY_NAME "soft_link_copy"
|
||||
#define COPY_LINK_TEST_SOFT_LINK_COPY_NAME2 COPY_LINK_TEST_SOFT_LINK_COPY_NAME "2"
|
||||
#define COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME "soft_link_same_loc"
|
||||
#define COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME2 COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME "2"
|
||||
#define COPY_LINK_TEST_SRC_GROUP_NAME "src_group"
|
||||
#define COPY_LINK_TEST_DST_GROUP_NAME "dst_group"
|
||||
#define COPY_LINK_TEST_SUBGROUP_NAME "link_copy_test"
|
||||
|
||||
#define COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_COPY_NAME "hard_link_copy"
|
||||
#define COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME "hard_link"
|
||||
#define COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NEW_NAME "hard_link_new"
|
||||
#define COPY_LINK_INVALID_PARAMS_TEST_SRC_GROUP_NAME "src_group"
|
||||
#define COPY_LINK_INVALID_PARAMS_TEST_DST_GROUP_NAME "dst_group"
|
||||
#define COPY_LINK_INVALID_PARAMS_TEST_SUBGROUP_NAME "link_copy_invalid_params_test"
|
||||
|
||||
#define MOVE_LINK_TEST_LINK_VAL_BUF_SIZE 1024
|
||||
#define MOVE_LINK_TEST_EXTERN_LINK_NAME "extern_link"
|
||||
#define MOVE_LINK_TEST_EXTERN_LINK_NAME2 MOVE_LINK_TEST_EXTERN_LINK_NAME "2"
|
||||
#define MOVE_LINK_TEST_EXTERN_LINK_NAME3 MOVE_LINK_TEST_EXTERN_LINK_NAME "3"
|
||||
#define MOVE_LINK_TEST_EXTERN_LINK_NAME4 MOVE_LINK_TEST_EXTERN_LINK_NAME "4"
|
||||
#define MOVE_LINK_TEST_EXTERN_LINK_NEW_NAME "extern_link_renamed"
|
||||
#define MOVE_LINK_TEST_EXTERN_LINK_SAME_LOC_NAME "extern_link_same_loc"
|
||||
#define MOVE_LINK_TEST_HARD_LINK_NAME "hard_link"
|
||||
#define MOVE_LINK_TEST_HARD_LINK_NAME2 MOVE_LINK_TEST_HARD_LINK_NAME "2"
|
||||
#define MOVE_LINK_TEST_HARD_LINK_NAME3 MOVE_LINK_TEST_HARD_LINK_NAME "3"
|
||||
#define MOVE_LINK_TEST_HARD_LINK_NAME4 MOVE_LINK_TEST_HARD_LINK_NAME "4"
|
||||
#define MOVE_LINK_TEST_HARD_LINK_NEW_NAME "hard_link_renamed"
|
||||
#define MOVE_LINK_TEST_HARD_LINK_SAME_LOC_NAME "hard_link_same_loc"
|
||||
#define MOVE_LINK_TEST_SOFT_LINK_TARGET_PATH "/" LINK_TEST_GROUP_NAME "/" MOVE_LINK_TEST_SUBGROUP_NAME
|
||||
#define MOVE_LINK_TEST_SOFT_LINK_NAME "soft_link"
|
||||
#define MOVE_LINK_TEST_SOFT_LINK_NAME2 MOVE_LINK_TEST_SOFT_LINK_NAME "2"
|
||||
#define MOVE_LINK_TEST_SOFT_LINK_NAME3 MOVE_LINK_TEST_SOFT_LINK_NAME "3"
|
||||
#define MOVE_LINK_TEST_SOFT_LINK_NAME4 MOVE_LINK_TEST_SOFT_LINK_NAME "4"
|
||||
#define MOVE_LINK_TEST_SOFT_LINK_NEW_NAME "soft_link_renamed"
|
||||
#define MOVE_LINK_TEST_SOFT_LINK_SAME_LOC_NAME "soft_link_same_loc"
|
||||
#define MOVE_LINK_TEST_SRC_GROUP_NAME "src_group"
|
||||
#define MOVE_LINK_TEST_DST_GROUP_NAME "dst_group"
|
||||
#define MOVE_LINK_TEST_SUBGROUP_NAME "link_move_test"
|
||||
|
||||
#define MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_SUBGROUP_NAME "link_move_into_group_with_links_test"
|
||||
#define MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_SRC_GRP_NAME "source_group"
|
||||
#define MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_DST_GRP_NAME "dest_group"
|
||||
#define MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_NUM_LINKS 5
|
||||
#define MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_BUF_SIZE 1024
|
||||
|
||||
#define MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_SUBGROUP_NAME "H5Lmove_reset_grp_max_crt_order_test"
|
||||
#define MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_SRC_GRP_NAME "source_group"
|
||||
#define MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_DST_GRP_NAME "dest_group"
|
||||
#define MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS 5
|
||||
#define MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_BUF_SIZE 1024
|
||||
|
||||
#define MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME "hard_link"
|
||||
#define MOVE_LINK_INVALID_PARAMS_TEST_SRC_GROUP_NAME "src_grp"
|
||||
#define MOVE_LINK_INVALID_PARAMS_TEST_DST_GROUP_NAME "dst_grp"
|
||||
#define MOVE_LINK_INVALID_PARAMS_TEST_SUBGROUP_NAME "link_move_invalid_params_test"
|
||||
|
||||
#define GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE 1024
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP_NAME "get_link_val_test"
|
||||
#define GET_LINK_VAL_TEST_SOFT_LINK_NAME "soft_link"
|
||||
#define GET_LINK_VAL_TEST_SOFT_LINK_NAME2 GET_LINK_VAL_TEST_SOFT_LINK_NAME "2"
|
||||
#define GET_LINK_VAL_TEST_SOFT_LINK_NAME3 GET_LINK_VAL_TEST_SOFT_LINK_NAME "3"
|
||||
#define GET_LINK_VAL_TEST_EXT_LINK_NAME "ext_link"
|
||||
#define GET_LINK_VAL_TEST_EXT_LINK_NAME2 GET_LINK_VAL_TEST_EXT_LINK_NAME "2"
|
||||
#define GET_LINK_VAL_TEST_EXT_LINK_NAME3 GET_LINK_VAL_TEST_EXT_LINK_NAME "3"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP1_NAME "H5Lget_val_soft_link"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP2_NAME "H5Lget_val_external_link"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP3_NAME "H5Lget_val_ud_link"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP4_NAME "H5Lget_val_by_idx_soft_link_crt_order_increasing"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP5_NAME "H5Lget_val_by_idx_soft_link_crt_order_decreasing"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP6_NAME "H5Lget_val_by_idx_soft_link_name_order_increasing"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP7_NAME "H5Lget_val_by_idx_soft_link_name_order_decreasing"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP8_NAME "H5Lget_val_by_idx_external_link_crt_order_increasing"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP9_NAME "H5Lget_val_by_idx_external_link_crt_order_decreasing"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP10_NAME "H5Lget_val_by_idx_external_link_name_order_increasing"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP11_NAME "H5Lget_val_by_idx_external_link_name_order_decreasing"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP12_NAME "H5Lget_val_by_idx_ud_link_crt_order_increasing"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP13_NAME "H5Lget_val_by_idx_ud_link_crt_order_decreasing"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP14_NAME "H5Lget_val_by_idx_ud_link_name_order_increasing"
|
||||
#define GET_LINK_VAL_TEST_SUBGROUP15_NAME "H5Lget_val_by_idx_ud_link_name_order_decreasing"
|
||||
|
||||
#define GET_LINK_VAL_INVALID_PARAMS_TEST_SOFT_LINK_NAME "soft_link"
|
||||
#define GET_LINK_VAL_INVALID_PARAMS_TEST_GROUP_NAME "get_link_val_invalid_params_test"
|
||||
|
||||
#define GET_LINK_INFO_TEST_HARD_LINK_NAME "hard_link"
|
||||
#define GET_LINK_INFO_TEST_HARD_LINK_NAME2 GET_LINK_INFO_TEST_HARD_LINK_NAME "2"
|
||||
#define GET_LINK_INFO_TEST_HARD_LINK_NAME3 GET_LINK_INFO_TEST_HARD_LINK_NAME "3"
|
||||
#define GET_LINK_INFO_TEST_SOFT_LINK_NAME "soft_link"
|
||||
#define GET_LINK_INFO_TEST_SOFT_LINK_NAME2 GET_LINK_INFO_TEST_SOFT_LINK_NAME "2"
|
||||
#define GET_LINK_INFO_TEST_SOFT_LINK_NAME3 GET_LINK_INFO_TEST_SOFT_LINK_NAME "3"
|
||||
#define GET_LINK_INFO_TEST_EXT_LINK_NAME "ext_link"
|
||||
#define GET_LINK_INFO_TEST_EXT_LINK_NAME2 GET_LINK_INFO_TEST_EXT_LINK_NAME "2"
|
||||
#define GET_LINK_INFO_TEST_EXT_LINK_NAME3 GET_LINK_INFO_TEST_EXT_LINK_NAME "3"
|
||||
#define GET_LINK_INFO_TEST_GROUP_NAME "get_link_info_test"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP1_NAME "H5Lget_info_hard_link"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP2_NAME "H5Lget_info_soft_link"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP3_NAME "H5Lget_info_external_link"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP4_NAME "H5Lget_info_ud_link"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP5_NAME "H5Lget_info_by_idx_hard_link_crt_order_increasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP6_NAME "H5Lget_info_by_idx_hard_link_crt_order_decreasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP7_NAME "H5Lget_info_by_idx_hard_link_name_order_increasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP8_NAME "H5Lget_info_by_idx_hard_link_name_order_decreasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP9_NAME "H5Lget_info_by_idx_soft_link_crt_order_increasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP10_NAME "H5Lget_info_by_idx_soft_link_crt_order_decreasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP11_NAME "H5Lget_info_by_idx_soft_link_name_order_increasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP12_NAME "H5Lget_info_by_idx_soft_link_name_order_decreasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP13_NAME "H5Lget_info_by_idx_external_link_crt_order_increasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP14_NAME "H5Lget_info_by_idx_external_link_crt_order_decreasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP15_NAME "H5Lget_info_by_idx_external_link_name_order_increasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP16_NAME "H5Lget_info_by_idx_external_link_name_order_decreasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP17_NAME "H5Lget_info_by_idx_ud_link_crt_order_increasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP18_NAME "H5Lget_info_by_idx_ud_link_crt_order_decreasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP19_NAME "H5Lget_info_by_idx_ud_link_name_order_increasing"
|
||||
#define GET_LINK_INFO_TEST_SUBGROUP20_NAME "H5Lget_info_by_idx_ud_link_name_order_decreasing"
|
||||
|
||||
#define GET_LINK_INFO_INVALID_PARAMS_TEST_HARD_LINK_NAME "hard_link"
|
||||
#define GET_LINK_INFO_INVALID_PARAMS_TEST_GROUP_NAME "get_link_info_invalid_params_test"
|
||||
|
||||
#define GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME "get_external_link_name_crt_order_increasing"
|
||||
#define GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME2 "get_external_link_name_crt_order_decreasing"
|
||||
#define GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME3 "get_external_link_name_alpha_order_increasing"
|
||||
#define GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME4 "get_external_link_name_alpha_order_decreasing"
|
||||
#define GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME "external_link"
|
||||
#define GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2 GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME "2"
|
||||
#define GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3 GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME "3"
|
||||
#define GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME "get_hard_link_name_crt_order_increasing"
|
||||
#define GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME2 "get_hard_link_name_crt_order_decreasing"
|
||||
#define GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME3 "get_hard_link_name_alpha_order_increasing"
|
||||
#define GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME4 "get_hard_link_name_alpha_order_decreasing"
|
||||
#define GET_LINK_NAME_TEST_HARD_LINK_NAME "hard_link"
|
||||
#define GET_LINK_NAME_TEST_HARD_LINK_NAME2 GET_LINK_NAME_TEST_HARD_LINK_NAME "2"
|
||||
#define GET_LINK_NAME_TEST_HARD_LINK_NAME3 GET_LINK_NAME_TEST_HARD_LINK_NAME "3"
|
||||
#define GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME "get_soft_link_name_crt_order_increasing"
|
||||
#define GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME2 "get_soft_link_name_crt_order_decreasing"
|
||||
#define GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME3 "get_soft_link_name_alpha_order_increasing"
|
||||
#define GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME4 "get_soft_link_name_alpha_order_decreasing"
|
||||
#define GET_LINK_NAME_TEST_SOFT_LINK_NAME "soft_link"
|
||||
#define GET_LINK_NAME_TEST_SOFT_LINK_NAME2 GET_LINK_NAME_TEST_SOFT_LINK_NAME "2"
|
||||
#define GET_LINK_NAME_TEST_SOFT_LINK_NAME3 GET_LINK_NAME_TEST_SOFT_LINK_NAME "3"
|
||||
#define GET_LINK_NAME_TEST_GROUP_NAME "get_link_name_test"
|
||||
#define GET_LINK_NAME_TEST_BUF_SIZE 256
|
||||
|
||||
#define GET_LINK_NAME_INVALID_PARAMS_TEST_HARD_LINK_NAME "test_link1"
|
||||
#define GET_LINK_NAME_INVALID_PARAMS_TEST_GROUP_NAME "get_link_name_invalid_params_test"
|
||||
|
||||
#define LINK_ITER_HARD_LINKS_TEST_DSET_SPACE_RANK 2
|
||||
#define LINK_ITER_HARD_LINKS_TEST_SUBGROUP_NAME "link_iter_hard_links_test"
|
||||
#define LINK_ITER_HARD_LINKS_TEST_LINK_NAME "hard_link"
|
||||
#define LINK_ITER_HARD_LINKS_TEST_NUM_LINKS 10
|
||||
#define LINK_ITER_HARD_LINKS_TEST_BUF_SIZE 64
|
||||
|
||||
#define LINK_ITER_SOFT_LINKS_TEST_SUBGROUP_NAME "link_iter_soft_links_test"
|
||||
#define LINK_ITER_SOFT_LINKS_TEST_LINK_NAME "soft_link"
|
||||
#define LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS 10
|
||||
#define LINK_ITER_SOFT_LINKS_TEST_BUF_SIZE 64
|
||||
|
||||
#define LINK_ITER_EXT_LINKS_TEST_SUBGROUP_NAME "link_iter_ext_links_test"
|
||||
#define LINK_ITER_EXT_LINKS_TEST_LINK_NAME "external_link"
|
||||
#define LINK_ITER_EXT_LINKS_TEST_NUM_LINKS 10
|
||||
#define LINK_ITER_EXT_LINKS_TEST_BUF_SIZE 64
|
||||
|
||||
#define LINK_ITER_MIXED_LINKS_TEST_DSET_SPACE_RANK 2
|
||||
#define LINK_ITER_MIXED_LINKS_TEST_HARD_LINK_NAME "hard_link1"
|
||||
#define LINK_ITER_MIXED_LINKS_TEST_SOFT_LINK_NAME "soft_link1"
|
||||
#define LINK_ITER_MIXED_LINKS_TEST_EXT_LINK_NAME "ext_link1"
|
||||
#define LINK_ITER_MIXED_LINKS_TEST_SUBGROUP_NAME "link_iter_mixed_links_test"
|
||||
#define LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS 3
|
||||
|
||||
#define LINK_ITER_INVALID_PARAMS_TEST_DSET_SPACE_RANK 2
|
||||
#define LINK_ITER_INVALID_PARAMS_TEST_HARD_LINK_NAME "hard_link1"
|
||||
#define LINK_ITER_INVALID_PARAMS_TEST_SOFT_LINK_NAME "soft_link1"
|
||||
#define LINK_ITER_INVALID_PARAMS_TEST_EXT_LINK_NAME "ext_link1"
|
||||
#define LINK_ITER_INVALID_PARAMS_TEST_SUBGROUP_NAME "link_iter_invalid_params_test"
|
||||
|
||||
#define LINK_ITER_0_LINKS_TEST_SUBGROUP_NAME "link_iter_0_links_test"
|
||||
|
||||
#define LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST \
|
||||
((LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP * \
|
||||
LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS) + \
|
||||
LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS)
|
||||
#define LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP 10
|
||||
#define LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_DSET_SPACE_RANK 2
|
||||
#define LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS 5
|
||||
#define LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "subgroup"
|
||||
#define LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME "link_visit_hard_links_no_cycle_test"
|
||||
#define LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_LINK_NAME "hard_link"
|
||||
#define LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_BUF_SIZE 256
|
||||
|
||||
#define LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST \
|
||||
((LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP * \
|
||||
LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS) + \
|
||||
LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS)
|
||||
#define LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP 10
|
||||
#define LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS 5
|
||||
#define LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "subgroup"
|
||||
#define LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME "link_visit_soft_links_no_cycle_test"
|
||||
#define LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_LINK_NAME "soft_link"
|
||||
#define LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE 256
|
||||
|
||||
#define LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST \
|
||||
((LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP * \
|
||||
LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS) + \
|
||||
LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS)
|
||||
#define LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP 10
|
||||
#define LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS 5
|
||||
#define LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "subgroup"
|
||||
#define LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME "link_visit_ext_links_no_cycle_test"
|
||||
#define LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_LINK_NAME "external_link"
|
||||
#define LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_BUF_SIZE 256
|
||||
|
||||
#define LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_SPACE_RANK 2
|
||||
#define LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME "dset"
|
||||
#define LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME2 "dset2"
|
||||
#define LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME "link_visit_mixed_links_no_cycle_test"
|
||||
#define LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2 "link_visit_subgroup1"
|
||||
#define LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3 "link_visit_subgroup2"
|
||||
#define LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME1 "hard_link1"
|
||||
#define LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME2 "soft_link1"
|
||||
#define LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME3 "ext_link1"
|
||||
#define LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME4 "hard_link2"
|
||||
#define LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS 8
|
||||
|
||||
#define LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST \
|
||||
((LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP * \
|
||||
LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_SUBGROUPS) + \
|
||||
LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_SUBGROUPS)
|
||||
#define LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP 10
|
||||
#define LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_SUBGROUPS 5
|
||||
#define LINK_VISIT_HARD_LINKS_CYCLE_TEST_NESTED_GRP_NAME "subgroup"
|
||||
#define LINK_VISIT_HARD_LINKS_CYCLE_TEST_SUBGROUP_NAME "link_visit_hard_links_cycle_test"
|
||||
#define LINK_VISIT_HARD_LINKS_CYCLE_TEST_LINK_NAME "hard_link"
|
||||
#define LINK_VISIT_HARD_LINKS_CYCLE_TEST_BUF_SIZE 256
|
||||
|
||||
#define LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST \
|
||||
((LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP * \
|
||||
LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_SUBGROUPS) + \
|
||||
LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_SUBGROUPS)
|
||||
#define LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP 10
|
||||
#define LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_SUBGROUPS 5
|
||||
#define LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NESTED_GRP_NAME "subgroup"
|
||||
#define LINK_VISIT_SOFT_LINKS_CYCLE_TEST_SUBGROUP_NAME "link_visit_soft_links_cycle_test"
|
||||
#define LINK_VISIT_SOFT_LINKS_CYCLE_TEST_LINK_NAME "soft_link"
|
||||
#define LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE 256
|
||||
|
||||
#define LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST \
|
||||
((LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP * LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_SUBGROUPS) + \
|
||||
LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_SUBGROUPS)
|
||||
#define LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP 10
|
||||
#define LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_SUBGROUPS 5
|
||||
#define LINK_VISIT_EXT_LINKS_CYCLE_TEST_NESTED_GRP_NAME "subgroup"
|
||||
#define LINK_VISIT_EXT_LINKS_CYCLE_TEST_SUBGROUP_NAME "link_visit_ext_links_cycle_test"
|
||||
#define LINK_VISIT_EXT_LINKS_CYCLE_TEST_LINK_NAME "external_link"
|
||||
#define LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE 256
|
||||
|
||||
#define LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME "link_visit_mixed_links_cycle_test"
|
||||
#define LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2 "link_visit_subgroup1"
|
||||
#define LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3 "link_visit_subgroup2"
|
||||
#define LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME1 "hard_link1"
|
||||
#define LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME2 "soft_link1"
|
||||
#define LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME3 "ext_link1"
|
||||
#define LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME4 "hard_link2"
|
||||
#define LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS 6
|
||||
|
||||
#define LINK_VISIT_INVALID_PARAMS_TEST_DSET_SPACE_RANK 2
|
||||
#define LINK_VISIT_INVALID_PARAMS_TEST_DSET_NAME "dset"
|
||||
#define LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME "link_visit_invalid_params_test"
|
||||
#define LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME2 "link_visit_subgroup1"
|
||||
#define LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME3 "link_visit_subgroup2"
|
||||
#define LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME1 "hard_link1"
|
||||
#define LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME2 "soft_link1"
|
||||
#define LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME3 "ext_link1"
|
||||
#define LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME4 "hard_link2"
|
||||
|
||||
#define LINK_VISIT_0_LINKS_TEST_SUBGROUP_NAME "link_visit_0_links_test"
|
||||
#define LINK_VISIT_0_LINKS_TEST_SUBGROUP_NAME2 "link_visit_0_links_test_subgroup1"
|
||||
#define LINK_VISIT_0_LINKS_TEST_SUBGROUP_NAME3 "link_visit_0_links_test_subgroup2"
|
||||
|
||||
#endif
|
1060
test/API/H5_api_misc_test.c
Normal file
1060
test/API/H5_api_misc_test.c
Normal file
File diff suppressed because it is too large
Load Diff
52
test/API/H5_api_misc_test.h
Normal file
52
test/API/H5_api_misc_test.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_MISC_TEST_H
|
||||
#define H5_API_MISC_TEST_H
|
||||
|
||||
#include "H5_api_test.h"
|
||||
|
||||
int H5_api_misc_test(void);
|
||||
|
||||
/******************************************************
|
||||
* *
|
||||
* API Miscellaneous test defines *
|
||||
* *
|
||||
******************************************************/
|
||||
|
||||
#define OPEN_LINK_WITHOUT_SLASH_DSET_SPACE_RANK 2
|
||||
#define OPEN_LINK_WITHOUT_SLASH_DSET_NAME "link_without_slash_test_dset"
|
||||
|
||||
#define OBJECT_CREATE_BY_ABSOLUTE_PATH_TEST_CONTAINER_GROUP_NAME "absolute_path_test_container_group"
|
||||
#define OBJECT_CREATE_BY_ABSOLUTE_PATH_TEST_SUBGROUP_NAME "absolute_path_test_subgroup"
|
||||
#define OBJECT_CREATE_BY_ABSOLUTE_PATH_TEST_DTYPE_NAME "absolute_path_test_dtype"
|
||||
#define OBJECT_CREATE_BY_ABSOLUTE_PATH_TEST_DSET_NAME "absolute_path_test_dset"
|
||||
#define OBJECT_CREATE_BY_ABSOLUTE_PATH_TEST_DSET_SPACE_RANK 3
|
||||
|
||||
#define ABSOLUTE_VS_RELATIVE_PATH_TEST_CONTAINER_GROUP_NAME "absolute_vs_relative_test_container_group"
|
||||
#define ABSOLUTE_VS_RELATIVE_PATH_TEST_DSET1_NAME "absolute_vs_relative_test_dset1"
|
||||
#define ABSOLUTE_VS_RELATIVE_PATH_TEST_DSET2_NAME "absolute_vs_relative_test_dset2"
|
||||
#define ABSOLUTE_VS_RELATIVE_PATH_TEST_DSET3_NAME "absolute_vs_relative_test_dset3"
|
||||
#define ABSOLUTE_VS_RELATIVE_PATH_TEST_DSET4_NAME "absolute_vs_relative_test_dset4"
|
||||
#define ABSOLUTE_VS_RELATIVE_PATH_TEST_DSET5_NAME "absolute_vs_relative_test_dset5"
|
||||
#define ABSOLUTE_VS_RELATIVE_PATH_TEST_DSET6_NAME "absolute_vs_relative_test_dset6"
|
||||
#define ABSOLUTE_VS_RELATIVE_PATH_TEST_DSET_SPACE_RANK 3
|
||||
|
||||
#define DOT_AS_OBJECT_NAME_TEST_SUBGROUP_NAME "dot_as_object_name_test"
|
||||
|
||||
#define COMPOUND_WITH_SYMBOLS_IN_MEMBER_NAMES_TEST_SUBGROUP_NAME \
|
||||
"compound_type_with_symbols_in_member_names_test"
|
||||
#define COMPOUND_WITH_SYMBOLS_IN_MEMBER_NAMES_TEST_NUM_SUBTYPES 9
|
||||
#define COMPOUND_WITH_SYMBOLS_IN_MEMBER_NAMES_TEST_DSET_RANK 2
|
||||
#define COMPOUND_WITH_SYMBOLS_IN_MEMBER_NAMES_TEST_DSET_NAME "dset"
|
||||
|
||||
#endif
|
7172
test/API/H5_api_object_test.c
Normal file
7172
test/API/H5_api_object_test.c
Normal file
File diff suppressed because it is too large
Load Diff
191
test/API/H5_api_object_test.h
Normal file
191
test/API/H5_api_object_test.h
Normal file
@ -0,0 +1,191 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_OBJECT_TEST_H
|
||||
#define H5_API_OBJECT_TEST_H
|
||||
|
||||
#include "H5_api_test.h"
|
||||
|
||||
int H5_api_object_test(void);
|
||||
|
||||
/***********************************************
|
||||
* *
|
||||
* API Object test defines *
|
||||
* *
|
||||
***********************************************/
|
||||
|
||||
#define OBJECT_OPEN_TEST_SPACE_RANK 2
|
||||
#define OBJECT_OPEN_TEST_GROUP_NAME "object_open_test"
|
||||
#define OBJECT_OPEN_TEST_GRP_NAME "object_open_test_group"
|
||||
#define OBJECT_OPEN_TEST_DSET_NAME "object_open_test_dset"
|
||||
#define OBJECT_OPEN_TEST_TYPE_NAME "object_open_test_type"
|
||||
|
||||
#define OBJECT_OPEN_INVALID_PARAMS_TEST_GROUP_NAME "object_open_invalid_params_test"
|
||||
#define OBJECT_OPEN_INVALID_PARAMS_TEST_GRP_NAME "object_open_invalid_params_test_group"
|
||||
|
||||
#define OBJECT_CLOSE_INVALID_TEST_GROUP_NAME "object_close_invalid_params_test"
|
||||
#define OBJECT_CLOSE_INVALID_TEST_ATTRIBUTE_NAME "object_close_invalid_test_attribute"
|
||||
#define OBJECT_CLOSE_INVALID_TEST_SPACE_RANK 2
|
||||
|
||||
#define OBJECT_EXISTS_TEST_DSET_SPACE_RANK 2
|
||||
#define OBJECT_EXISTS_TEST_SUBGROUP_NAME "object_exists_test"
|
||||
#define OBJECT_EXISTS_TEST_DANGLING_LINK_NAME "object_exists_test_dangling_soft_link"
|
||||
#define OBJECT_EXISTS_TEST_SOFT_LINK_NAME "object_exists_test_soft_link"
|
||||
#define OBJECT_EXISTS_TEST_GRP_NAME "object_exists_test_group"
|
||||
#define OBJECT_EXISTS_TEST_TYPE_NAME "object_exists_test_type"
|
||||
#define OBJECT_EXISTS_TEST_DSET_NAME "object_exists_test_dset"
|
||||
|
||||
#define OBJECT_EXISTS_INVALID_PARAMS_TEST_SUBGROUP_NAME "object_exists_invalid_params_test"
|
||||
#define OBJECT_EXISTS_INVALID_PARAMS_TEST_GRP_NAME "object_exists_invalid_params_test_group"
|
||||
|
||||
#define OBJECT_COPY_BASIC_TEST_DEEP_NESTED_GROUP_NAME "deep_nested_group"
|
||||
#define OBJECT_COPY_BASIC_TEST_NUM_NESTED_OBJS 3
|
||||
#define OBJECT_COPY_BASIC_TEST_NEW_GROUP_NAME "copied_group"
|
||||
#define OBJECT_COPY_BASIC_TEST_NEW_DSET_NAME "copied_dset"
|
||||
#define OBJECT_COPY_BASIC_TEST_NEW_DTYPE_NAME "copied_dtype"
|
||||
#define OBJECT_COPY_BASIC_TEST_SUBGROUP_NAME "object_copy_basic_test"
|
||||
#define OBJECT_COPY_BASIC_TEST_GROUP_NAME "group_to_copy"
|
||||
#define OBJECT_COPY_BASIC_TEST_DSET_NAME "dset_to_copy"
|
||||
#define OBJECT_COPY_BASIC_TEST_DTYPE_NAME "dtype_to_copy"
|
||||
#define OBJECT_COPY_BASIC_TEST_SPACE_RANK 2
|
||||
#define OBJECT_COPY_BASIC_TEST_NUM_ATTRS 3
|
||||
#define OBJECT_COPY_BASIC_TEST_BUF_SIZE 256
|
||||
|
||||
#define OBJECT_COPY_ALREADY_EXISTING_TEST_SUBGROUP_NAME "object_copy_existing_objects_test"
|
||||
#define OBJECT_COPY_ALREADY_EXISTING_TEST_GROUP_NAME "group_to_copy"
|
||||
#define OBJECT_COPY_ALREADY_EXISTING_TEST_DSET_NAME "dset_to_copy"
|
||||
#define OBJECT_COPY_ALREADY_EXISTING_TEST_DTYPE_NAME "dtype_to_copy"
|
||||
#define OBJECT_COPY_ALREADY_EXISTING_TEST_SPACE_RANK 2
|
||||
|
||||
#define OBJECT_COPY_SHALLOW_TEST_DEEP_NESTED_GROUP_NAME "deep_nested_group"
|
||||
#define OBJECT_COPY_SHALLOW_TEST_NUM_NESTED_OBJS 3
|
||||
#define OBJECT_COPY_SHALLOW_TEST_SUBGROUP_NAME "object_copy_shallow_group_copy_test"
|
||||
#define OBJECT_COPY_SHALLOW_TEST_NEW_GROUP_NAME "copied_group"
|
||||
#define OBJECT_COPY_SHALLOW_TEST_GROUP_NAME "group_to_copy"
|
||||
#define OBJECT_COPY_SHALLOW_TEST_BUF_SIZE 256
|
||||
|
||||
#define OBJECT_COPY_NO_ATTRS_TEST_SUBGROUP_NAME "object_copy_no_attributes_test"
|
||||
#define OBJECT_COPY_NO_ATTRS_TEST_NEW_GROUP_NAME "copied_group"
|
||||
#define OBJECT_COPY_NO_ATTRS_TEST_NEW_DSET_NAME "copied_dset"
|
||||
#define OBJECT_COPY_NO_ATTRS_TEST_NEW_DTYPE_NAME "copied_dtype"
|
||||
#define OBJECT_COPY_NO_ATTRS_TEST_GROUP_NAME "group_to_copy"
|
||||
#define OBJECT_COPY_NO_ATTRS_TEST_DSET_NAME "dset_to_copy"
|
||||
#define OBJECT_COPY_NO_ATTRS_TEST_DTYPE_NAME "dtype_to_copy"
|
||||
#define OBJECT_COPY_NO_ATTRS_TEST_SPACE_RANK 2
|
||||
#define OBJECT_COPY_NO_ATTRS_TEST_NUM_ATTRS 3
|
||||
#define OBJECT_COPY_NO_ATTRS_TEST_BUF_SIZE 256
|
||||
|
||||
#define OBJECT_COPY_SOFT_LINK_TEST_DEEP_NESTED_GROUP_NAME "deep_nested_group"
|
||||
#define OBJECT_COPY_SOFT_LINK_TEST_DANGLING_LINK_NAME "dangling_link"
|
||||
#define OBJECT_COPY_SOFT_LINK_TEST_NUM_NESTED_OBJS 3
|
||||
#define OBJECT_COPY_SOFT_LINK_TEST_SUBGROUP_NAME "object_copy_soft_link_test"
|
||||
#define OBJECT_COPY_SOFT_LINK_TEST_SOFT_LINK_NAME "soft_link_to_group_to_copy"
|
||||
#define OBJECT_COPY_SOFT_LINK_TEST_NEW_GROUP_NAME "copied_group"
|
||||
#define OBJECT_COPY_SOFT_LINK_TEST_GROUP_NAME "group_to_copy"
|
||||
#define OBJECT_COPY_SOFT_LINK_TEST_SPACE_RANK 2
|
||||
#define OBJECT_COPY_SOFT_LINK_TEST_NUM_ATTRS 3
|
||||
#define OBJECT_COPY_SOFT_LINK_TEST_BUF_SIZE 256
|
||||
|
||||
#define OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_EXPAND_DANGLING_GROUP_NAME "expanded_dangling_soft_links_group"
|
||||
#define OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NON_EXPAND_GROUP_NAME "non_expanded_soft_links_group"
|
||||
#define OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_EXPAND_GROUP_NAME "expanded_soft_links_group"
|
||||
#define OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NUM_NESTED_OBJS 3
|
||||
#define OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_SUBGROUP_NAME "object_copy_group_with_soft_links_test"
|
||||
#define OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_GROUP_NAME "group_to_copy"
|
||||
#define OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE 256
|
||||
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_DEEP_NESTED_GROUP_NAME "deep_nested_group"
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_NUM_NESTED_OBJS 3
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_SUBGROUP_NAME "object_copy_between_files_test"
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_NEW_GROUP_NAME "copied_group"
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DSET_NAME "copied_dset"
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DTYPE_NAME "copied_dtype"
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_FILE_NAME "object_copy_test_file.h5"
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_GROUP_NAME "group_to_copy"
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_DSET_NAME "dset_to_copy"
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_DTYPE_NAME "dtype_to_copy"
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_SPACE_RANK 2
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_NUM_ATTRS 3
|
||||
#define OBJECT_COPY_BETWEEN_FILES_TEST_BUF_SIZE 256
|
||||
|
||||
#define OBJECT_COPY_INVALID_PARAMS_TEST_SUBGROUP_NAME "object_copy_invalid_params_test"
|
||||
#define OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME "object_copy_invalid_params_group"
|
||||
#define OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME2 "object_copy_invalid_params_group_copy"
|
||||
|
||||
#define OBJECT_VISIT_TEST_NUM_OBJS_VISITED 4
|
||||
#define OBJECT_VISIT_TEST_SUBGROUP_NAME "object_visit_test"
|
||||
#define OBJECT_VISIT_TEST_SPACE_RANK 2
|
||||
#define OBJECT_VISIT_TEST_GROUP_NAME "object_visit_test_group"
|
||||
#define OBJECT_VISIT_TEST_DSET_NAME "object_visit_test_dset"
|
||||
#define OBJECT_VISIT_TEST_TYPE_NAME "object_visit_test_type"
|
||||
|
||||
#define OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED 1
|
||||
#define OBJECT_VISIT_SOFT_LINK_TEST_SUBGROUP_NAME "object_visit_soft_link"
|
||||
#define OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME1 "links_group"
|
||||
#define OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME2 "objects_group"
|
||||
#define OBJECT_VISIT_SOFT_LINK_TEST_LINK_NAME1 "soft_link1"
|
||||
#define OBJECT_VISIT_SOFT_LINK_TEST_LINK_NAME2 "soft_link2"
|
||||
#define OBJECT_VISIT_SOFT_LINK_TEST_LINK_NAME3 "soft_link3"
|
||||
#define OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME1 "group1"
|
||||
#define OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME2 "group2"
|
||||
#define OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME3 "group3"
|
||||
|
||||
#define OBJECT_VISIT_DANGLING_LINK_TEST_SUBGROUP_NAME "object_visit_dangling_link_test"
|
||||
#define OBJECT_VISIT_DANGLING_LINK_TEST_LINK_NAME1 "dangling_link1"
|
||||
#define OBJECT_VISIT_DANGLING_LINK_TEST_LINK_NAME2 "dangling_link2"
|
||||
#define OBJECT_VISIT_DANGLING_LINK_TEST_LINK_NAME3 "dangling_link3"
|
||||
|
||||
#define OBJECT_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME "object_visit_invalid_params_test"
|
||||
#define OBJECT_VISIT_INVALID_PARAMS_TEST_GROUP_NAME "object_visit_invalid_params_group"
|
||||
|
||||
#define OBJECT_CLOSE_TEST_SPACE_RANK 2
|
||||
#define OBJECT_CLOSE_TEST_GROUP_NAME "object_close_test"
|
||||
#define OBJECT_CLOSE_TEST_GRP_NAME "object_close_test_group"
|
||||
#define OBJECT_CLOSE_TEST_DSET_NAME "object_close_test_dset"
|
||||
#define OBJECT_CLOSE_TEST_TYPE_NAME "object_close_test_type"
|
||||
|
||||
#define OBJECT_LINK_TEST_GROUP_NAME "object_link_test_group"
|
||||
#define OBJECT_LINK_TEST_GROUP_NAME2 "object_link_test_group_link"
|
||||
#define OBJECT_LINK_TEST_DSET_NAME "object_link_test_dataset"
|
||||
#define OBJECT_LINK_TEST_DTYPE_NAME "object_link_test_datatype"
|
||||
#define OBJECT_LINK_TEST_SPACE_RANK 2
|
||||
|
||||
#define OBJECT_LINK_INVALID_PARAMS_TEST_GROUP_NAME "object_link_invalid_params_test_group"
|
||||
|
||||
#define OBJ_REF_GET_TYPE_TEST_SUBGROUP_NAME "obj_ref_get_obj_type_test"
|
||||
#define OBJ_REF_GET_TYPE_TEST_DSET_NAME "ref_dset"
|
||||
#define OBJ_REF_GET_TYPE_TEST_TYPE_NAME "ref_dtype"
|
||||
#define OBJ_REF_GET_TYPE_TEST_SPACE_RANK 2
|
||||
|
||||
#define OBJ_REF_DATASET_WRITE_TEST_SUBGROUP_NAME "obj_ref_write_test"
|
||||
#define OBJ_REF_DATASET_WRITE_TEST_REF_DSET_NAME "ref_dset"
|
||||
#define OBJ_REF_DATASET_WRITE_TEST_REF_TYPE_NAME "ref_dtype"
|
||||
#define OBJ_REF_DATASET_WRITE_TEST_SPACE_RANK 1
|
||||
#define OBJ_REF_DATASET_WRITE_TEST_DSET_NAME "obj_ref_dset"
|
||||
|
||||
#define OBJ_REF_DATASET_READ_TEST_SUBGROUP_NAME "obj_ref_read_test"
|
||||
#define OBJ_REF_DATASET_READ_TEST_REF_DSET_NAME "ref_dset"
|
||||
#define OBJ_REF_DATASET_READ_TEST_REF_TYPE_NAME "ref_dtype"
|
||||
#define OBJ_REF_DATASET_READ_TEST_SPACE_RANK 1
|
||||
#define OBJ_REF_DATASET_READ_TEST_DSET_NAME "obj_ref_dset"
|
||||
|
||||
#define OBJ_REF_DATASET_EMPTY_WRITE_TEST_SUBGROUP_NAME "obj_ref_empty_write_test"
|
||||
#define OBJ_REF_DATASET_EMPTY_WRITE_TEST_SPACE_RANK 1
|
||||
#define OBJ_REF_DATASET_EMPTY_WRITE_TEST_DSET_NAME "obj_ref_dset"
|
||||
|
||||
#define OBJECT_REF_COUNT_TEST_SUBGROUP_NAME "ref_count_test"
|
||||
#define OBJECT_REF_COUNT_TEST_GRP_NAME "ref_count_test_group"
|
||||
#define OBJECT_REF_COUNT_TEST_DSET_NAME "ref_count_dset"
|
||||
#define OBJECT_REF_COUNT_TEST_TYPE_NAME "ref_count_dtype"
|
||||
#define OBJECT_REF_COUNT_TEST_DSET_SPACE_RANK 2
|
||||
|
||||
#endif
|
227
test/API/H5_api_test.c
Normal file
227
test/API/H5_api_test.c
Normal file
@ -0,0 +1,227 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*
|
||||
* A test suite which only makes public HDF5 API calls and which is meant
|
||||
* to test the native VOL connector or a specified HDF5 VOL connector (or
|
||||
* set of connectors stacked with each other). This test suite must assume
|
||||
* that a VOL connector could only implement the File interface. Therefore,
|
||||
* the suite should check that a particular piece of functionality is supported
|
||||
* by the VOL connector before actually testing it. If the functionality is
|
||||
* not supported, the test should simply be skipped, perhaps with a note as
|
||||
* to why the test was skipped, if possible.
|
||||
*
|
||||
* If the VOL connector being used supports the creation of groups, this
|
||||
* test suite will attempt to organize the output of these various tests
|
||||
* into groups based on their respective HDF5 interface.
|
||||
*/
|
||||
|
||||
#include "H5_api_test.h"
|
||||
|
||||
#include "H5_api_attribute_test.h"
|
||||
#include "H5_api_dataset_test.h"
|
||||
#include "H5_api_datatype_test.h"
|
||||
#include "H5_api_file_test.h"
|
||||
#include "H5_api_group_test.h"
|
||||
#include "H5_api_link_test.h"
|
||||
#include "H5_api_misc_test.h"
|
||||
#include "H5_api_object_test.h"
|
||||
#include "H5_api_test_util.h"
|
||||
#ifdef H5_API_TEST_HAVE_ASYNC
|
||||
#include "H5_api_async_test.h"
|
||||
#endif
|
||||
|
||||
char H5_api_test_filename[H5_API_TEST_FILENAME_MAX_LENGTH];
|
||||
|
||||
const char *test_path_prefix;
|
||||
|
||||
/* X-macro to define the following for each test:
|
||||
* - enum type
|
||||
* - name
|
||||
* - test function
|
||||
* - enabled by default
|
||||
*/
|
||||
#ifdef H5_API_TEST_HAVE_ASYNC
|
||||
#define H5_API_TESTS \
|
||||
X(H5_API_TEST_NULL, "", NULL, 0) \
|
||||
X(H5_API_TEST_FILE, "file", H5_api_file_test, 1) \
|
||||
X(H5_API_TEST_GROUP, "group", H5_api_group_test, 1) \
|
||||
X(H5_API_TEST_DATASET, "dataset", H5_api_dataset_test, 1) \
|
||||
X(H5_API_TEST_DATATYPE, "datatype", H5_api_datatype_test, 1) \
|
||||
X(H5_API_TEST_ATTRIBUTE, "attribute", H5_api_attribute_test, 1) \
|
||||
X(H5_API_TEST_LINK, "link", H5_api_link_test, 1) \
|
||||
X(H5_API_TEST_OBJECT, "object", H5_api_object_test, 1) \
|
||||
X(H5_API_TEST_MISC, "misc", H5_api_misc_test, 1) \
|
||||
X(H5_API_TEST_ASYNC, "async", H5_api_async_test, 1) \
|
||||
X(H5_API_TEST_MAX, "", NULL, 0)
|
||||
#else
|
||||
#define H5_API_TESTS \
|
||||
X(H5_API_TEST_NULL, "", NULL, 0) \
|
||||
X(H5_API_TEST_FILE, "file", H5_api_file_test, 1) \
|
||||
X(H5_API_TEST_GROUP, "group", H5_api_group_test, 1) \
|
||||
X(H5_API_TEST_DATASET, "dataset", H5_api_dataset_test, 1) \
|
||||
X(H5_API_TEST_DATATYPE, "datatype", H5_api_datatype_test, 1) \
|
||||
X(H5_API_TEST_ATTRIBUTE, "attribute", H5_api_attribute_test, 1) \
|
||||
X(H5_API_TEST_LINK, "link", H5_api_link_test, 1) \
|
||||
X(H5_API_TEST_OBJECT, "object", H5_api_object_test, 1) \
|
||||
X(H5_API_TEST_MISC, "misc", H5_api_misc_test, 1) \
|
||||
X(H5_API_TEST_MAX, "", NULL, 0)
|
||||
#endif
|
||||
|
||||
#define X(a, b, c, d) a,
|
||||
enum H5_api_test_type { H5_API_TESTS };
|
||||
#undef X
|
||||
#define X(a, b, c, d) b,
|
||||
static const char *const H5_api_test_name[] = {H5_API_TESTS};
|
||||
#undef X
|
||||
#define X(a, b, c, d) c,
|
||||
static int (*H5_api_test_func[])(void) = {H5_API_TESTS};
|
||||
#undef X
|
||||
#define X(a, b, c, d) d,
|
||||
static int H5_api_test_enabled[] = {H5_API_TESTS};
|
||||
#undef X
|
||||
|
||||
static enum H5_api_test_type
|
||||
H5_api_test_name_to_type(const char *test_name)
|
||||
{
|
||||
enum H5_api_test_type i = 0;
|
||||
|
||||
while (strcmp(H5_api_test_name[i], test_name) && i != H5_API_TEST_MAX)
|
||||
i++;
|
||||
|
||||
return ((i == H5_API_TEST_MAX) ? H5_API_TEST_NULL : i);
|
||||
}
|
||||
|
||||
static void
|
||||
H5_api_test_run(void)
|
||||
{
|
||||
enum H5_api_test_type i;
|
||||
|
||||
for (i = H5_API_TEST_FILE; i < H5_API_TEST_MAX; i++)
|
||||
if (H5_api_test_enabled[i])
|
||||
(void)H5_api_test_func[i]();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *vol_connector_name;
|
||||
unsigned seed;
|
||||
hid_t fapl_id = H5I_INVALID_HID;
|
||||
hbool_t err_occurred = FALSE;
|
||||
|
||||
/* Simple argument checking, TODO can improve that later */
|
||||
if (argc > 1) {
|
||||
enum H5_api_test_type i = H5_api_test_name_to_type(argv[1]);
|
||||
if (i != H5_API_TEST_NULL) {
|
||||
/* Run only specific API test */
|
||||
memset(H5_api_test_enabled, 0, sizeof(H5_api_test_enabled));
|
||||
H5_api_test_enabled[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* If HDF5 was built with parallel enabled, go ahead and call MPI_Init before
|
||||
* running these tests. Even though these are meant to be serial tests, they will
|
||||
* likely be run using mpirun (or similar) and we cannot necessarily expect HDF5 or
|
||||
* an HDF5 VOL connector to call MPI_Init.
|
||||
*/
|
||||
MPI_Init(&argc, &argv);
|
||||
#endif
|
||||
|
||||
/* h5_reset(); */
|
||||
|
||||
n_tests_run_g = 0;
|
||||
n_tests_passed_g = 0;
|
||||
n_tests_failed_g = 0;
|
||||
n_tests_skipped_g = 0;
|
||||
|
||||
seed = (unsigned)HDtime(NULL);
|
||||
srand(seed);
|
||||
|
||||
if (NULL == (test_path_prefix = HDgetenv(HDF5_API_TEST_PATH_PREFIX)))
|
||||
test_path_prefix = "";
|
||||
|
||||
HDsnprintf(H5_api_test_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
|
||||
TEST_FILE_NAME);
|
||||
|
||||
if (NULL == (vol_connector_name = HDgetenv(HDF5_VOL_CONNECTOR))) {
|
||||
HDprintf("No VOL connector selected; using native VOL connector\n");
|
||||
vol_connector_name = "native";
|
||||
}
|
||||
|
||||
HDprintf("Running API tests with VOL connector '%s'\n\n", vol_connector_name);
|
||||
HDprintf("Test parameters:\n");
|
||||
HDprintf(" - Test file name: '%s'\n", H5_api_test_filename);
|
||||
HDprintf(" - Test seed: %u\n", seed);
|
||||
HDprintf("\n\n");
|
||||
|
||||
/* Retrieve the VOL cap flags - work around an HDF5
|
||||
* library issue by creating a FAPL
|
||||
*/
|
||||
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) {
|
||||
HDfprintf(stderr, "Unable to create FAPL\n");
|
||||
err_occurred = TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
vol_cap_flags_g = H5VL_CAP_FLAG_NONE;
|
||||
if (H5Pget_vol_cap_flags(fapl_id, &vol_cap_flags_g) < 0) {
|
||||
HDfprintf(stderr, "Unable to retrieve VOL connector capability flags\n");
|
||||
err_occurred = TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the file that will be used for all of the tests,
|
||||
* except for those which test file creation.
|
||||
*/
|
||||
if (create_test_container(H5_api_test_filename, vol_cap_flags_g) < 0) {
|
||||
HDfprintf(stderr, "Unable to create testing container file '%s'\n", H5_api_test_filename);
|
||||
err_occurred = TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Run all the tests that are enabled */
|
||||
H5_api_test_run();
|
||||
|
||||
HDprintf("Cleaning up testing files\n");
|
||||
H5Fdelete(H5_api_test_filename, fapl_id);
|
||||
|
||||
if (n_tests_run_g > 0) {
|
||||
HDprintf("%zu/%zu (%.2f%%) API tests passed with VOL connector '%s'\n", n_tests_passed_g,
|
||||
n_tests_run_g, ((double)n_tests_passed_g / (double)n_tests_run_g * 100.0),
|
||||
vol_connector_name);
|
||||
HDprintf("%zu/%zu (%.2f%%) API tests did not pass with VOL connector '%s'\n", n_tests_failed_g,
|
||||
n_tests_run_g, ((double)n_tests_failed_g / (double)n_tests_run_g * 100.0),
|
||||
vol_connector_name);
|
||||
HDprintf("%zu/%zu (%.2f%%) API tests were skipped with VOL connector '%s'\n", n_tests_skipped_g,
|
||||
n_tests_run_g, ((double)n_tests_skipped_g / (double)n_tests_run_g * 100.0),
|
||||
vol_connector_name);
|
||||
}
|
||||
|
||||
done:
|
||||
if (fapl_id >= 0 && H5Pclose(fapl_id) < 0) {
|
||||
HDfprintf(stderr, "Unable to close FAPL\n");
|
||||
err_occurred = TRUE;
|
||||
}
|
||||
|
||||
H5close();
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
MPI_Finalize();
|
||||
#endif
|
||||
|
||||
HDexit(((err_occurred || n_tests_failed_g > 0) ? EXIT_FAILURE : EXIT_SUCCESS));
|
||||
}
|
73
test/API/H5_api_test.h
Normal file
73
test/API/H5_api_test.h
Normal file
@ -0,0 +1,73 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_TEST_H
|
||||
#define H5_API_TEST_H
|
||||
|
||||
#include <hdf5.h>
|
||||
#include <H5private.h>
|
||||
|
||||
#include "h5test.h"
|
||||
|
||||
#include "H5_api_test_config.h"
|
||||
#include "H5_api_test_util.h"
|
||||
#include "H5_api_tests_disabled.h"
|
||||
|
||||
/* Define H5VL_VERSION if not already defined */
|
||||
#ifndef H5VL_VERSION
|
||||
#define H5VL_VERSION 0
|
||||
#endif
|
||||
|
||||
/* Define macro to wait forever depending on version */
|
||||
#if H5VL_VERSION >= 2
|
||||
#define H5_API_TEST_WAIT_FOREVER H5ES_WAIT_FOREVER
|
||||
#else
|
||||
#define H5_API_TEST_WAIT_FOREVER UINT64_MAX
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* The name of the file that all of the tests will operate on */
|
||||
#define TEST_FILE_NAME "H5_api_test.h5"
|
||||
extern char H5_api_test_filename[];
|
||||
|
||||
extern const char *test_path_prefix;
|
||||
|
||||
/*
|
||||
* Environment variable specifying a prefix string to add to
|
||||
* filenames generated by the API tests
|
||||
*/
|
||||
#define HDF5_API_TEST_PATH_PREFIX "HDF5_API_TEST_PATH_PREFIX"
|
||||
|
||||
/* The names of a set of container groups which hold objects
|
||||
* created by each of the different types of tests.
|
||||
*/
|
||||
#define GROUP_TEST_GROUP_NAME "group_tests"
|
||||
#define ATTRIBUTE_TEST_GROUP_NAME "attribute_tests"
|
||||
#define DATASET_TEST_GROUP_NAME "dataset_tests"
|
||||
#define DATATYPE_TEST_GROUP_NAME "datatype_tests"
|
||||
#define LINK_TEST_GROUP_NAME "link_tests"
|
||||
#define OBJECT_TEST_GROUP_NAME "object_tests"
|
||||
#define MISCELLANEOUS_TEST_GROUP_NAME "miscellaneous_tests"
|
||||
|
||||
#define ARRAY_LENGTH(array) sizeof(array) / sizeof(array[0])
|
||||
|
||||
#define UNUSED(o) (void)(o);
|
||||
|
||||
#define H5_API_TEST_FILENAME_MAX_LENGTH 1024
|
||||
|
||||
/* The maximum size of a dimension in an HDF5 dataspace as allowed
|
||||
* for this testing suite so as not to try to create too large
|
||||
* of a dataspace/datatype. */
|
||||
#define MAX_DIM_SIZE 16
|
||||
|
||||
#endif
|
66
test/API/H5_api_test_config.h.in
Normal file
66
test/API/H5_api_test_config.h.in
Normal file
@ -0,0 +1,66 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_TEST_CONFIG_H
|
||||
#define H5_API_TEST_CONFIG_H
|
||||
|
||||
#include "hdf5.h"
|
||||
|
||||
#cmakedefine H5_API_TEST_HAVE_ASYNC
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
#cmakedefine MPIEXEC_EXECUTABLE "@MPIEXEC_EXECUTABLE@"
|
||||
#cmakedefine MPIEXEC "@MPIEXEC@" /* For compatibility */
|
||||
#ifndef MPIEXEC_EXECUTABLE
|
||||
# define MPIEXEC_EXECUTABLE MPIEXEC
|
||||
#endif
|
||||
#cmakedefine MPIEXEC_NUMPROC_FLAG "@MPIEXEC_NUMPROC_FLAG@"
|
||||
#cmakedefine MPIEXEC_PREFLAGS "@MPIEXEC_PREFLAGS@"
|
||||
#cmakedefine MPIEXEC_POSTFLAGS "@MPIEXEC_POSTFLAGS@"
|
||||
/* Server-specific flags if different */
|
||||
#cmakedefine MPIEXEC_SERVER_PREFLAGS "@MPIEXEC_SERVER_PREFLAGS@"
|
||||
#cmakedefine MPIEXEC_SERVER_POSTFLAGS "@MPIEXEC_SERVER_POSTFLAGS@"
|
||||
#cmakedefine MPIEXEC_MAX_NUMPROCS @MPIEXEC_MAX_NUMPROCS@
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
#cmakedefine DART_TESTING_TIMEOUT @DART_TESTING_TIMEOUT@
|
||||
#ifndef DART_TESTING_TIMEOUT
|
||||
# define DART_TESTING_TIMEOUT 1500
|
||||
#endif
|
||||
|
||||
#cmakedefine H5_API_TEST_ENV_VARS "@H5_API_TEST_ENV_VARS@"
|
||||
|
||||
#cmakedefine H5_API_TEST_INIT_COMMAND "@H5_API_TEST_INIT_COMMAND@"
|
||||
|
||||
#cmakedefine H5_API_TEST_SERVER_START_MSG "@H5_API_TEST_SERVER_START_MSG@"
|
||||
#ifndef H5_API_TEST_SERVER_START_MSG
|
||||
# define H5_API_TEST_SERVER_START_MSG "Waiting"
|
||||
#endif
|
||||
#cmakedefine H5_API_TEST_SERVER_EXIT_COMMAND "@H5_API_TEST_SERVER_EXIT_COMMAND@"
|
||||
|
||||
#cmakedefine H5_API_TEST_CLIENT_HELPER_START_MSG "@H5_API_TEST_CLIENT_HELPER_START_MSG@"
|
||||
#ifndef H5_API_TEST_CLIENT_HELPER_START_MSG
|
||||
# define H5_API_TEST_CLIENT_HELPER_START_MSG "Waiting"
|
||||
#endif
|
||||
#cmakedefine H5_API_TEST_CLIENT_HELPER_EXIT_COMMAND "@H5_API_TEST_CLIENT_HELPER_EXIT_COMMAND@"
|
||||
|
||||
#cmakedefine H5_API_TEST_CLIENT_INIT_TOKEN_REGEX "@H5_API_TEST_CLIENT_INIT_TOKEN_REGEX@"
|
||||
#ifndef H5_API_TEST_CLIENT_INIT_TOKEN_REGEX
|
||||
# define H5_API_TEST_CLIENT_INIT_TOKEN_REGEX "^token"
|
||||
#endif
|
||||
#cmakedefine H5_API_TEST_CLIENT_INIT_TOKEN_VAR "@H5_API_TEST_CLIENT_INIT_TOKEN_VAR@"
|
||||
#ifndef H5_API_TEST_CLIENT_INIT_TOKEN_VAR
|
||||
# define H5_API_TEST_CLIENT_INIT_TOKEN_VAR "TOKEN"
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* H5_API_TEST_CONFIG_H */
|
819
test/API/H5_api_test_util.c
Normal file
819
test/API/H5_api_test_util.c
Normal file
@ -0,0 +1,819 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "H5_api_test.h"
|
||||
#include "H5_api_test_util.h"
|
||||
|
||||
/*
|
||||
* The maximum allowable size of a generated datatype.
|
||||
*
|
||||
* NOTE: HDF5 currently has limits on the maximum size of
|
||||
* a datatype of an object, as this information is stored
|
||||
* in the object header. In order to provide maximum
|
||||
* compatibility between the native VOL connector and others
|
||||
* for this test suite, we limit the size of a datatype here.
|
||||
* This value should be adjusted as future HDF5 development
|
||||
* allows.
|
||||
*/
|
||||
#define GENERATED_DATATYPE_MAX_SIZE 65536
|
||||
|
||||
/*
|
||||
* The maximum size of a datatype for compact objects that
|
||||
* must fit within the size of a native HDF5 object header message.
|
||||
* This is typically used for attributes and compact datasets.
|
||||
*/
|
||||
#define COMPACT_DATATYPE_MAX_SIZE 1024
|
||||
|
||||
/* The maximum level of recursion that the generate_random_datatype()
|
||||
* function should go down to, before being forced to choose a base type
|
||||
* in order to not cause a stack overflow.
|
||||
*/
|
||||
#define TYPE_GEN_RECURSION_MAX_DEPTH 3
|
||||
|
||||
/* The maximum number of members allowed in an HDF5 compound type, as
|
||||
* generated by the generate_random_datatype() function, for ease of
|
||||
* development.
|
||||
*/
|
||||
#define COMPOUND_TYPE_MAX_MEMBERS 4
|
||||
|
||||
/* The maximum number and size of the dimensions of an HDF5 array
|
||||
* datatype, as generated by the generate_random_datatype() function.
|
||||
*/
|
||||
#define ARRAY_TYPE_MAX_DIMS 4
|
||||
|
||||
/* The maximum number of members and the maximum size of those
|
||||
* members' names for an HDF5 enum type, as generated by the
|
||||
* generate_random_datatype() function.
|
||||
*/
|
||||
#define ENUM_TYPE_MAX_MEMBER_NAME_LENGTH 256
|
||||
#define ENUM_TYPE_MAX_MEMBERS 16
|
||||
|
||||
/* The maximum size of an HDF5 string datatype, as created by the
|
||||
* generate_random_datatype() function.
|
||||
*/
|
||||
#define STRING_TYPE_MAX_SIZE 1024
|
||||
|
||||
/*
|
||||
* The maximum dimensionality and dimension size of a dataspace
|
||||
* generated for an attribute or compact dataset.
|
||||
*/
|
||||
#define COMPACT_SPACE_MAX_DIM_SIZE 4
|
||||
#define COMPACT_SPACE_MAX_DIMS 3
|
||||
|
||||
/*
|
||||
* Helper function to generate a random HDF5 datatype in order to thoroughly
|
||||
* test support for datatypes. The parent_class parameter is to support
|
||||
* recursive generation of datatypes. In most cases, this function should be
|
||||
* called with H5T_NO_CLASS for the parent_class parameter.
|
||||
*/
|
||||
/*
|
||||
* XXX: limit size of datatype generated
|
||||
*/
|
||||
hid_t
|
||||
generate_random_datatype(H5T_class_t parent_class, hbool_t is_compact)
|
||||
{
|
||||
static int depth = 0;
|
||||
hsize_t *array_dims = NULL;
|
||||
size_t i;
|
||||
hid_t compound_members[COMPOUND_TYPE_MAX_MEMBERS];
|
||||
hid_t datatype = H5I_INVALID_HID;
|
||||
|
||||
depth++;
|
||||
|
||||
for (i = 0; i < COMPOUND_TYPE_MAX_MEMBERS; i++)
|
||||
compound_members[i] = H5I_INVALID_HID;
|
||||
|
||||
switch (rand() % H5T_NCLASSES) {
|
||||
case_integer:
|
||||
case H5T_INTEGER: {
|
||||
switch (rand() % 16) {
|
||||
case 0:
|
||||
if ((datatype = H5Tcopy(H5T_STD_I8BE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if ((datatype = H5Tcopy(H5T_STD_I8LE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if ((datatype = H5Tcopy(H5T_STD_I16BE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if ((datatype = H5Tcopy(H5T_STD_I16LE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if ((datatype = H5Tcopy(H5T_STD_I32BE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if ((datatype = H5Tcopy(H5T_STD_I32LE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if ((datatype = H5Tcopy(H5T_STD_I64BE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 7:
|
||||
if ((datatype = H5Tcopy(H5T_STD_I64LE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if ((datatype = H5Tcopy(H5T_STD_U8BE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 9:
|
||||
if ((datatype = H5Tcopy(H5T_STD_U8LE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 10:
|
||||
if ((datatype = H5Tcopy(H5T_STD_U16BE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 11:
|
||||
if ((datatype = H5Tcopy(H5T_STD_U16LE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 12:
|
||||
if ((datatype = H5Tcopy(H5T_STD_U32BE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 13:
|
||||
if ((datatype = H5Tcopy(H5T_STD_U32LE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 14:
|
||||
if ((datatype = H5Tcopy(H5T_STD_U64BE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 15:
|
||||
if ((datatype = H5Tcopy(H5T_STD_U64LE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined integer type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
H5_FAILED();
|
||||
HDprintf(" invalid value for predefined integer type; should not happen\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case_float:
|
||||
case H5T_FLOAT: {
|
||||
switch (rand() % 4) {
|
||||
case 0:
|
||||
if ((datatype = H5Tcopy(H5T_IEEE_F32BE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined floating-point type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if ((datatype = H5Tcopy(H5T_IEEE_F32LE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined floating-point type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if ((datatype = H5Tcopy(H5T_IEEE_F64BE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined floating-point type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if ((datatype = H5Tcopy(H5T_IEEE_F64LE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy predefined floating-point type\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
H5_FAILED();
|
||||
HDprintf(" invalid value for floating point type; should not happen\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case_time:
|
||||
case H5T_TIME: {
|
||||
/* Time datatype is unsupported, try again */
|
||||
goto reroll;
|
||||
break;
|
||||
}
|
||||
|
||||
case_string:
|
||||
case H5T_STRING: {
|
||||
/* Note: currently only H5T_CSET_ASCII is supported for the character set and
|
||||
* only H5T_STR_NULLTERM is supported for string padding for variable-length
|
||||
* strings and only H5T_STR_NULLPAD is supported for string padding for
|
||||
* fixed-length strings, but these may change in the future.
|
||||
*/
|
||||
if (0 == (rand() % 2)) {
|
||||
if ((datatype = H5Tcreate(H5T_STRING, (size_t)(rand() % STRING_TYPE_MAX_SIZE) + 1)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't create fixed-length string datatype\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (H5Tset_strpad(datatype, H5T_STR_NULLPAD) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't set H5T_STR_NULLPAD for fixed-length string type\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Currently, all VL datatypes are disabled.
|
||||
*/
|
||||
goto reroll;
|
||||
|
||||
#if 0
|
||||
if ((datatype = H5Tcreate(H5T_STRING, H5T_VARIABLE)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't create variable-length string datatype\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (H5Tset_strpad(datatype, H5T_STR_NULLTERM) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't set H5T_STR_NULLTERM for variable-length string type\n");
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (H5Tset_cset(datatype, H5T_CSET_ASCII) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't set string datatype character set\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case_bitfield:
|
||||
case H5T_BITFIELD: {
|
||||
/* Bitfield datatype is unsupported, try again */
|
||||
goto reroll;
|
||||
break;
|
||||
}
|
||||
|
||||
case_opaque:
|
||||
case H5T_OPAQUE: {
|
||||
/* Opaque datatype is unsupported, try again */
|
||||
goto reroll;
|
||||
break;
|
||||
}
|
||||
|
||||
case_compound:
|
||||
case H5T_COMPOUND: {
|
||||
size_t num_members;
|
||||
size_t next_offset = 0;
|
||||
size_t compound_size = 0;
|
||||
|
||||
/* Currently only allows arrays of integer, float or string. Pick another type if we
|
||||
* are creating an array of something other than these. Also don't allow recursion
|
||||
* to go too deep. Pick another type that doesn't recursively call this function. */
|
||||
if (H5T_ARRAY == parent_class || depth > TYPE_GEN_RECURSION_MAX_DEPTH)
|
||||
goto reroll;
|
||||
|
||||
if ((datatype = H5Tcreate(H5T_COMPOUND, 1)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't create compound datatype\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
num_members = (size_t)(rand() % COMPOUND_TYPE_MAX_MEMBERS + 1);
|
||||
|
||||
for (i = 0; i < num_members; i++) {
|
||||
size_t member_size;
|
||||
char member_name[256];
|
||||
|
||||
HDsnprintf(member_name, 256, "compound_member%zu", i);
|
||||
|
||||
if ((compound_members[i] = generate_random_datatype(H5T_NO_CLASS, is_compact)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't create compound datatype member %zu\n", i);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!(member_size = H5Tget_size(compound_members[i]))) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't get compound member %zu size\n", i);
|
||||
goto done;
|
||||
}
|
||||
|
||||
compound_size += member_size;
|
||||
|
||||
if (H5Tset_size(datatype, compound_size) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't set size for compound datatype\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (H5Tinsert(datatype, member_name, next_offset, compound_members[i]) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't insert compound datatype member %zu\n", i);
|
||||
goto done;
|
||||
}
|
||||
|
||||
next_offset += member_size;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case_reference:
|
||||
case H5T_REFERENCE: {
|
||||
/* Temporarily disable generation of reference datatypes */
|
||||
goto reroll;
|
||||
|
||||
/* Currently only allows arrays of integer, float or string. Pick another type if we
|
||||
* are creating an array of something other than these. */
|
||||
if (H5T_ARRAY == parent_class)
|
||||
goto reroll;
|
||||
|
||||
if (0 == (rand() % 2)) {
|
||||
if ((datatype = H5Tcopy(H5T_STD_REF_OBJ)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy object reference datatype\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Region references are currently unsupported */
|
||||
goto reroll;
|
||||
|
||||
if ((datatype = H5Tcopy(H5T_STD_REF_DSETREG)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't copy region reference datatype\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case_enum:
|
||||
case H5T_ENUM: {
|
||||
/* Currently doesn't currently support ARRAY of ENUM, so try another type
|
||||
* if this happens. */
|
||||
if (H5T_ARRAY == parent_class)
|
||||
goto reroll;
|
||||
|
||||
if ((datatype = H5Tenum_create(H5T_NATIVE_INT)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't create enum datatype\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < (size_t)(rand() % ENUM_TYPE_MAX_MEMBERS + 1); i++) {
|
||||
char name[ENUM_TYPE_MAX_MEMBER_NAME_LENGTH];
|
||||
int value = rand();
|
||||
|
||||
HDsnprintf(name, ENUM_TYPE_MAX_MEMBER_NAME_LENGTH, "enum_val%zu", i);
|
||||
|
||||
if (H5Tenum_insert(datatype, name, &value) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't insert member into enum datatype\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case_vlen:
|
||||
case H5T_VLEN: {
|
||||
/* Variable-length datatypes are unsupported, try again */
|
||||
goto reroll;
|
||||
break;
|
||||
}
|
||||
|
||||
case_array:
|
||||
case H5T_ARRAY: {
|
||||
unsigned ndims;
|
||||
hid_t base_datatype = H5I_INVALID_HID;
|
||||
|
||||
/* Currently doesn't currently support ARRAY of ARRAY, so try another type
|
||||
* if this happens. Also check for too much recursion. */
|
||||
if (H5T_ARRAY == parent_class || depth > TYPE_GEN_RECURSION_MAX_DEPTH)
|
||||
goto reroll;
|
||||
|
||||
ndims = (unsigned)(rand() % ARRAY_TYPE_MAX_DIMS + 1);
|
||||
|
||||
if (NULL == (array_dims = (hsize_t *)HDmalloc(ndims * sizeof(*array_dims))))
|
||||
goto done;
|
||||
|
||||
for (i = 0; i < ndims; i++)
|
||||
array_dims[i] = (hsize_t)(rand() % MAX_DIM_SIZE + 1);
|
||||
|
||||
if ((base_datatype = generate_random_datatype(H5T_ARRAY, is_compact)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't create array base datatype\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((datatype = H5Tarray_create2(base_datatype, ndims, array_dims)) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't create array datatype\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
H5_FAILED();
|
||||
HDprintf(" invalid datatype class\n");
|
||||
break;
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
if (depth > 0)
|
||||
depth--;
|
||||
|
||||
if (datatype < 0) {
|
||||
for (i = 0; i < COMPOUND_TYPE_MAX_MEMBERS; i++) {
|
||||
if (compound_members[i] > 0 && H5Tclose(compound_members[i]) < 0) {
|
||||
H5_FAILED();
|
||||
HDprintf(" couldn't close compound member %zu\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (array_dims) {
|
||||
HDfree(array_dims);
|
||||
array_dims = NULL;
|
||||
}
|
||||
|
||||
if (is_compact && (depth == 0)) {
|
||||
size_t type_size;
|
||||
|
||||
/*
|
||||
* Check to make sure that the generated datatype does
|
||||
* not exceed the maximum compact datatype size if a
|
||||
* compact datatype was requested.
|
||||
*/
|
||||
if (0 == (type_size = H5Tget_size(datatype))) {
|
||||
H5_FAILED();
|
||||
HDprintf(" failed to retrieve datatype's size\n");
|
||||
H5Tclose(datatype);
|
||||
datatype = H5I_INVALID_HID;
|
||||
}
|
||||
else {
|
||||
if (type_size > COMPACT_DATATYPE_MAX_SIZE) {
|
||||
/*
|
||||
* Generate a new datatype.
|
||||
*/
|
||||
H5Tclose(datatype);
|
||||
datatype = H5I_INVALID_HID;
|
||||
goto reroll;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return datatype;
|
||||
|
||||
reroll:
|
||||
if (depth > 0)
|
||||
depth--;
|
||||
|
||||
/*
|
||||
* The datatype generation resulted in a datatype that is currently invalid
|
||||
* for these tests, try again.
|
||||
*/
|
||||
switch (rand() % H5T_NCLASSES) {
|
||||
case H5T_INTEGER:
|
||||
goto case_integer;
|
||||
case H5T_FLOAT:
|
||||
goto case_float;
|
||||
case H5T_TIME:
|
||||
goto case_time;
|
||||
case H5T_STRING:
|
||||
goto case_string;
|
||||
case H5T_BITFIELD:
|
||||
goto case_bitfield;
|
||||
case H5T_OPAQUE:
|
||||
goto case_opaque;
|
||||
case H5T_COMPOUND:
|
||||
goto case_compound;
|
||||
case H5T_REFERENCE:
|
||||
goto case_reference;
|
||||
case H5T_ENUM:
|
||||
goto case_enum;
|
||||
case H5T_VLEN:
|
||||
goto case_vlen;
|
||||
case H5T_ARRAY:
|
||||
goto case_array;
|
||||
default:
|
||||
H5_FAILED();
|
||||
HDprintf(" invalid value for goto\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return H5I_INVALID_HID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to generate a random HDF5 dataspace in order to thoroughly
|
||||
* test support for dataspaces.
|
||||
*/
|
||||
hid_t
|
||||
generate_random_dataspace(int rank, const hsize_t *max_dims, hsize_t *dims_out, hbool_t is_compact)
|
||||
{
|
||||
hsize_t dataspace_dims[H5S_MAX_RANK];
|
||||
size_t i;
|
||||
hid_t dataspace_id = H5I_INVALID_HID;
|
||||
|
||||
if (rank < 0)
|
||||
TEST_ERROR;
|
||||
if (is_compact && (rank > COMPACT_SPACE_MAX_DIMS)) {
|
||||
HDprintf(" current rank of compact dataspace (%lld) exceeds maximum dimensionality (%lld)\n",
|
||||
(long long)rank, (long long)COMPACT_SPACE_MAX_DIMS);
|
||||
TEST_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: if max_dims is specified, make sure that the dimensions generated
|
||||
* are not larger than this.
|
||||
*/
|
||||
for (i = 0; i < (size_t)rank; i++) {
|
||||
if (is_compact)
|
||||
dataspace_dims[i] = (hsize_t)(rand() % COMPACT_SPACE_MAX_DIM_SIZE + 1);
|
||||
else
|
||||
dataspace_dims[i] = (hsize_t)(rand() % MAX_DIM_SIZE + 1);
|
||||
|
||||
if (dims_out)
|
||||
dims_out[i] = dataspace_dims[i];
|
||||
}
|
||||
|
||||
if ((dataspace_id = H5Screate_simple(rank, dataspace_dims, max_dims)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
return dataspace_id;
|
||||
|
||||
error:
|
||||
return H5I_INVALID_HID;
|
||||
}
|
||||
|
||||
int
|
||||
create_test_container(char *filename, uint64_t vol_cap_flags)
|
||||
{
|
||||
hid_t file_id = H5I_INVALID_HID;
|
||||
hid_t group_id = H5I_INVALID_HID;
|
||||
|
||||
if (!(vol_cap_flags & H5VL_CAP_FLAG_FILE_BASIC)) {
|
||||
HDprintf(" VOL connector doesn't support file creation\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
|
||||
HDprintf(" couldn't create testing container file '%s'\n", filename);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (vol_cap_flags & H5VL_CAP_FLAG_GROUP_BASIC) {
|
||||
/* Create container groups for each of the test interfaces
|
||||
* (group, attribute, dataset, etc.).
|
||||
*/
|
||||
if ((group_id = H5Gcreate2(file_id, GROUP_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) >=
|
||||
0) {
|
||||
HDprintf(" created container group for Group tests\n");
|
||||
H5Gclose(group_id);
|
||||
}
|
||||
|
||||
if ((group_id = H5Gcreate2(file_id, ATTRIBUTE_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
|
||||
H5P_DEFAULT)) >= 0) {
|
||||
HDprintf(" created container group for Attribute tests\n");
|
||||
H5Gclose(group_id);
|
||||
}
|
||||
|
||||
if ((group_id =
|
||||
H5Gcreate2(file_id, DATASET_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) >= 0) {
|
||||
HDprintf(" created container group for Dataset tests\n");
|
||||
H5Gclose(group_id);
|
||||
}
|
||||
|
||||
if ((group_id =
|
||||
H5Gcreate2(file_id, DATATYPE_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) >= 0) {
|
||||
HDprintf(" created container group for Datatype tests\n");
|
||||
H5Gclose(group_id);
|
||||
}
|
||||
|
||||
if ((group_id = H5Gcreate2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) >=
|
||||
0) {
|
||||
HDprintf(" created container group for Link tests\n");
|
||||
H5Gclose(group_id);
|
||||
}
|
||||
|
||||
if ((group_id = H5Gcreate2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) >=
|
||||
0) {
|
||||
HDprintf(" created container group for Object tests\n");
|
||||
H5Gclose(group_id);
|
||||
}
|
||||
|
||||
if ((group_id = H5Gcreate2(file_id, MISCELLANEOUS_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
|
||||
H5P_DEFAULT)) >= 0) {
|
||||
HDprintf(" created container group for Miscellaneous tests\n");
|
||||
H5Gclose(group_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (H5Fclose(file_id) < 0) {
|
||||
HDprintf(" failed to close testing container\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY
|
||||
{
|
||||
H5Gclose(group_id);
|
||||
H5Fclose(file_id);
|
||||
}
|
||||
H5E_END_TRY;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a prefix to the given filename. The caller
|
||||
* is responsible for freeing the returned filename
|
||||
* pointer with HDfree().
|
||||
*/
|
||||
herr_t
|
||||
prefix_filename(const char *prefix, const char *filename, char **filename_out)
|
||||
{
|
||||
char *out_buf = NULL;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
if (!prefix) {
|
||||
HDprintf(" invalid file prefix\n");
|
||||
ret_value = FAIL;
|
||||
goto done;
|
||||
}
|
||||
if (!filename || (*filename == '\0')) {
|
||||
HDprintf(" invalid filename\n");
|
||||
ret_value = FAIL;
|
||||
goto done;
|
||||
}
|
||||
if (!filename_out) {
|
||||
HDprintf(" invalid filename_out buffer\n");
|
||||
ret_value = FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (NULL == (out_buf = HDmalloc(H5_API_TEST_FILENAME_MAX_LENGTH))) {
|
||||
HDprintf(" couldn't allocated filename buffer\n");
|
||||
ret_value = FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
HDsnprintf(out_buf, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", prefix, filename);
|
||||
|
||||
*filename_out = out_buf;
|
||||
|
||||
done:
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calls H5Fdelete on the given filename. If a prefix string
|
||||
* is given, adds that prefix string to the filename before
|
||||
* calling H5Fdelete
|
||||
*/
|
||||
herr_t
|
||||
remove_test_file(const char *prefix, const char *filename)
|
||||
{
|
||||
const char *test_file;
|
||||
char *prefixed_filename = NULL;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
if (prefix) {
|
||||
if (prefix_filename(prefix, filename, &prefixed_filename) < 0) {
|
||||
HDprintf(" couldn't prefix filename\n");
|
||||
ret_value = FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
test_file = prefixed_filename;
|
||||
}
|
||||
else
|
||||
test_file = filename;
|
||||
|
||||
if (H5Fdelete(test_file, H5P_DEFAULT) < 0) {
|
||||
HDprintf(" couldn't remove file '%s'\n", test_file);
|
||||
ret_value = FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
HDfree(prefixed_filename);
|
||||
|
||||
return ret_value;
|
||||
}
|
24
test/API/H5_api_test_util.h
Normal file
24
test/API/H5_api_test_util.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_TEST_UTIL_H_
|
||||
#define H5_API_TEST_UTIL_H_
|
||||
|
||||
#include "hdf5.h"
|
||||
|
||||
hid_t generate_random_datatype(H5T_class_t parent_class, hbool_t is_compact);
|
||||
hid_t generate_random_dataspace(int rank, const hsize_t *max_dims, hsize_t *dims_out, hbool_t is_compact);
|
||||
int create_test_container(char *filename, uint64_t vol_cap_flags);
|
||||
herr_t prefix_filename(const char *prefix, const char *filename, char **filename_out);
|
||||
herr_t remove_test_file(const char *prefix, const char *filename);
|
||||
|
||||
#endif /* H5_API_TEST_UTIL_H_ */
|
46
test/API/H5_api_tests_disabled.h
Normal file
46
test/API/H5_api_tests_disabled.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the COPYING file, which can be found at the root of the source code *
|
||||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||||
* If you do not have access to either file, you may request a copy from *
|
||||
* help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef H5_API_TESTS_DISABLED_H
|
||||
#define H5_API_TESTS_DISABLED_H
|
||||
|
||||
#include "H5_api_test_config.h"
|
||||
|
||||
/* Contains #defines to temporarily disable API tests based
|
||||
* on problematic or unsupported functionality */
|
||||
|
||||
#define NO_LARGE_TESTS
|
||||
#define NO_ATTR_FILL_VALUE_SUPPORT
|
||||
#define NO_DECREASING_ALPHA_ITER_ORDER
|
||||
#define NO_USER_DEFINED_LINKS
|
||||
#define NO_EXTERNAL_LINKS
|
||||
#define NO_ITERATION_RESTART
|
||||
#define NO_FILE_MOUNTS
|
||||
#define NO_CLEAR_ON_SHRINK
|
||||
#define NO_DOUBLE_OBJECT_OPENS
|
||||
#define NO_OBJECT_GET_NAME
|
||||
#define WRONG_DATATYPE_OBJ_COUNT
|
||||
#define NO_SHARED_DATATYPES
|
||||
#define NO_INVALID_PROPERTY_LIST_TESTS
|
||||
#define NO_MAX_LINK_CRT_ORDER_RESET
|
||||
#define NO_PREVENT_HARD_LINKS_ACROSS_FILES
|
||||
#define NO_SOFT_LINK_MANY_DANGLING
|
||||
#define NO_ID_PREVENTS_OBJ_DELETE
|
||||
#define NO_WRITE_SAME_ELEMENT_TWICE
|
||||
#define NO_PREVENT_CREATE_SAME_ATTRIBUTE_TWICE
|
||||
#define NO_DELETE_NONEXISTENT_ATTRIBUTE
|
||||
#define NO_TRUNCATE_OPEN_FILE
|
||||
#define NO_CHECK_SELECTION_BOUNDS
|
||||
#define NO_VALIDATE_DATASPACE
|
||||
#define NO_REFERENCE_TO_DELETED
|
||||
|
||||
#endif /* H5_API_TESTS_DISABLED_H */
|
86
test/API/README.md
Normal file
86
test/API/README.md
Normal file
@ -0,0 +1,86 @@
|
||||
# HDF5 API Tests
|
||||
|
||||
This directory contains several test applications that exercise [HDF5](https://github.com/HDFGroup/hdf5)'s
|
||||
public API and serve as regression tests for HDF5 [VOL Connectors](https://portal.hdfgroup.org/display/HDF5/Virtual+Object+Layer).
|
||||
|
||||
## Build Process and options
|
||||
|
||||
These HDF5 API tests are enabled and built by default, but can be disabled if desired.
|
||||
The following build options are available to influence how the API tests get built:
|
||||
|
||||
### CMake
|
||||
|
||||
To set an option, it should be prepended with `-D` when passed to the `cmake` command.
|
||||
For example,
|
||||
|
||||
cmake -DHDF5_TEST_API=OFF ..
|
||||
|
||||
`HDF5_TEST_API` (Default: `ON`) - Determines whether the API tests will be built.
|
||||
|
||||
`HDF5_TEST_API_INSTALL` (Default: `ON`) - Determines whether the API tests should be installed
|
||||
on the system.
|
||||
|
||||
`HDF5_TEST_API_ENABLE_ASYNC` (Default: `OFF`) - Determines whether tests for HDF5's asynchronous
|
||||
I/O capabilities should be enabled. Note that the "native" HDF5 VOL connector doesn't support
|
||||
this functionality, so these tests are directed towards VOL connectors that do.
|
||||
|
||||
`HDF5_TEST_ENABLE_DRIVER` (Default: `OFF`) - Determines whether the API test driver program should
|
||||
be built. This driver program is useful when a VOL connector relies upon a server executable
|
||||
(as well as possible additional executables) in order to function. The driver program can be
|
||||
supplied with a server executable and
|
||||
|
||||
`HDF5_TEST_API_SERVER` (Default: empty string) - If `HDF5_TEST_ENABLE_DRIVER` is set to `ON`, this
|
||||
option should be edited to point to the server executable that the driver program should attempt
|
||||
to launch before running the API tests.
|
||||
|
||||
### Autotools
|
||||
|
||||
Currently unsupported
|
||||
|
||||
### Usage
|
||||
|
||||
These API tests currently only support usage with HDF5 VOL connectors that can be loaded dynamically
|
||||
as a plugin. For information on how to build a VOL connector in this manner, refer to section 2.3 of
|
||||
the [HDF5 VOL Connector Author Guide](https://portal.hdfgroup.org/display/HDF5/HDF5+VOL+Connector+Authors+Guide?preview=/53610813/59903039/vol_connector_author_guide.pdf).
|
||||
|
||||
TODO: section on building VOL connectors alongside HDF5 for use with tests
|
||||
|
||||
These API tests can also be used to test an HDF5 VOL connector that is external to the library.
|
||||
For convenience, the `HDF5_TEST_API_INSTALL` option can be used to install these tests on the
|
||||
system where other HDF5 executables (such as `h5dump`) are installed.
|
||||
|
||||
To run these tests with your VOL connector, set the following two environment variables:
|
||||
|
||||
`HDF5_VOL_CONNECTOR` - This environment variable should be set to the name chosen for the VOL connector
|
||||
to be used. For example, HDF5's DAOS VOL connector uses the name "[daos](https://github.com/HDFGroup/vol-daos/blob/v1.2.0/src/daos_vol.h#L30)" and would therefore set:
|
||||
|
||||
HDF5_VOL_CONNECTOR=daos
|
||||
|
||||
`HDF5_PLUGIN_PATH` - This environment variable should be set to the directory that contains the built
|
||||
library for the VOL connector to be used.
|
||||
|
||||
Once these are set, the HDF5 API tests will attempt to automatically load the specified VOL connector
|
||||
and use it when running tests. If HDF5 is unable to locate or load the VOL connector specified, it
|
||||
will fall back to running the tests with the native HDF5 VOL connector and an error similar to the
|
||||
following will appear in the test output:
|
||||
|
||||
HDF5-DIAG: Error detected in HDF5 (1.13.0) MPI-process 0:
|
||||
#000: /home/user/git/hdf5/src/H5.c line 1010 in H5open(): library initialization failed
|
||||
major: Function entry/exit
|
||||
minor: Unable to initialize object
|
||||
#001: /home/user/git/hdf5/src/H5.c line 277 in H5_init_library(): unable to initialize vol interface
|
||||
major: Function entry/exit
|
||||
minor: Unable to initialize object
|
||||
#002: /home/user/git/hdf5/src/H5VLint.c line 199 in H5VL_init_phase2(): unable to set default VOL connector
|
||||
major: Virtual Object Layer
|
||||
minor: Can't set value
|
||||
#003: /home/user/git/hdf5/src/H5VLint.c line 429 in H5VL__set_def_conn(): can't register connector
|
||||
major: Virtual Object Layer
|
||||
minor: Unable to register new ID
|
||||
#004: /home/user/git/hdf5/src/H5VLint.c line 1321 in H5VL__register_connector_by_name(): unable to load VOL connector
|
||||
major: Virtual Object Layer
|
||||
minor: Unable to initialize object
|
||||
|
||||
### Help and Support
|
||||
|
||||
For help with building or using the HDF5 API tests, please contact the [HDF Help Desk](https://portal.hdfgroup.org/display/support/The+HDF+Help+Desk).
|
17
test/API/driver/CMakeLists.txt
Normal file
17
test/API/driver/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
cmake_minimum_required(VERSION 2.8.12.2 FATAL_ERROR)
|
||||
project(H5_API_TEST_DRIVER CXX)
|
||||
|
||||
include(CheckAsan)
|
||||
include(CheckUbsan)
|
||||
|
||||
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(kwsys)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/kwsys)
|
||||
|
||||
add_executable(h5_api_test_driver h5_api_test_driver.cxx)
|
||||
target_link_libraries(h5_api_test_driver h5_api_test_sys)
|
910
test/API/driver/h5_api_test_driver.cxx
Normal file
910
test/API/driver/h5_api_test_driver.cxx
Normal file
@ -0,0 +1,910 @@
|
||||
#include "h5_api_test_driver.hxx"
|
||||
|
||||
#include "H5_api_test_config.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
# include <unistd.h>
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#include <h5_api_test_sys/RegularExpression.hxx>
|
||||
#include <h5_api_test_sys/SystemTools.hxx>
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using std::cerr;
|
||||
|
||||
// The main function as this class should only be used by this program
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
H5APITestDriver d;
|
||||
return d.Main(argc, argv);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
H5APITestDriver::H5APITestDriver()
|
||||
{
|
||||
this->ClientArgStart = 0;
|
||||
this->ClientArgCount = 0;
|
||||
this->ClientHelperArgStart = 0;
|
||||
this->ClientHelperArgCount = 0;
|
||||
this->ClientInitArgStart = 0;
|
||||
this->ClientInitArgCount = 0;
|
||||
this->ServerArgStart = 0;
|
||||
this->ServerArgCount = 0;
|
||||
this->AllowErrorInOutput = false;
|
||||
// try to make sure that this times out before dart so it can kill all the processes
|
||||
this->TimeOut = DART_TESTING_TIMEOUT - 10.0;
|
||||
this->ServerExitTimeOut = 2; /* 2 seconds timeout for server to exit */
|
||||
this->ClientHelper = false;
|
||||
this->ClientInit = false;
|
||||
this->TestServer = false;
|
||||
this->TestSerial = false;
|
||||
this->IgnoreServerResult = false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
H5APITestDriver::~H5APITestDriver()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
H5APITestDriver::SeparateArguments(const char *str, vector<string> &flags)
|
||||
{
|
||||
string arg = str;
|
||||
string::size_type pos1 = 0;
|
||||
string::size_type pos2 = arg.find_first_of(" ;");
|
||||
if (pos2 == arg.npos) {
|
||||
flags.push_back(str);
|
||||
return;
|
||||
}
|
||||
while (pos2 != arg.npos) {
|
||||
flags.push_back(arg.substr(pos1, pos2 - pos1));
|
||||
pos1 = pos2 + 1;
|
||||
pos2 = arg.find_first_of(" ;", pos1 + 1);
|
||||
}
|
||||
flags.push_back(arg.substr(pos1, pos2 - pos1));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
H5APITestDriver::CollectConfiguredOptions()
|
||||
{
|
||||
if (this->TimeOut < 0)
|
||||
this->TimeOut = 1500;
|
||||
|
||||
#ifdef H5_API_TEST_ENV_VARS
|
||||
this->SeparateArguments(H5_API_TEST_ENV_VARS, this->ClientEnvVars);
|
||||
#endif
|
||||
|
||||
// now find all the mpi information if mpi run is set
|
||||
#ifdef MPIEXEC_EXECUTABLE
|
||||
this->MPIRun = MPIEXEC_EXECUTABLE;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
int maxNumProc = 1;
|
||||
|
||||
# ifdef MPIEXEC_MAX_NUMPROCS
|
||||
if (!this->TestSerial)
|
||||
maxNumProc = MPIEXEC_MAX_NUMPROCS;
|
||||
# endif
|
||||
# ifdef MPIEXEC_NUMPROC_FLAG
|
||||
this->MPINumProcessFlag = MPIEXEC_NUMPROC_FLAG;
|
||||
# endif
|
||||
# ifdef MPIEXEC_PREFLAGS
|
||||
this->SeparateArguments(MPIEXEC_PREFLAGS, this->MPIClientPreFlags);
|
||||
# endif
|
||||
# ifdef MPIEXEC_POSTFLAGS
|
||||
this->SeparateArguments(MPIEXEC_POSTFLAGS, this->MPIClientPostFlags);
|
||||
# endif
|
||||
# ifdef MPIEXEC_SERVER_PREFLAGS
|
||||
this->SeparateArguments(MPIEXEC_SERVER_PREFLAGS, this->MPIServerPreFlags);
|
||||
#else
|
||||
this->MPIServerPreFlags = this->MPIClientPreFlags;
|
||||
# endif
|
||||
# ifdef MPIEXEC_SERVER_POSTFLAGS
|
||||
this->SeparateArguments(MPIEXEC_SERVER_POSTFLAGS, this->MPIServerPostFlags);
|
||||
#else
|
||||
this->MPIServerPostFlags = this->MPIClientPostFlags;
|
||||
# endif
|
||||
std::stringstream ss;
|
||||
ss << maxNumProc;
|
||||
this->MPIServerNumProcessFlag = "1";
|
||||
this->MPIClientNumProcessFlag = ss.str();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// This adds the debug/build configuration crap for the executable on windows.
|
||||
static string
|
||||
FixExecutablePath(const string &path)
|
||||
{
|
||||
#ifdef CMAKE_INTDIR
|
||||
string parent_dir =
|
||||
h5_api_test_sys::SystemTools::GetFilenamePath(path.c_str());
|
||||
|
||||
string filename =
|
||||
h5_api_test_sys::SystemTools::GetFilenameName(path);
|
||||
|
||||
if (!h5_api_test_sys::SystemTools::StringEndsWith(parent_dir.c_str(), CMAKE_INTDIR)) {
|
||||
parent_dir += "/" CMAKE_INTDIR;
|
||||
}
|
||||
return parent_dir + "/" + filename;
|
||||
#endif
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
H5APITestDriver::ProcessCommandLine(int argc, char *argv[])
|
||||
{
|
||||
int *ArgCountP = NULL;
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "--client") == 0) {
|
||||
this->ClientExecutable = ::FixExecutablePath(argv[i + 1]);
|
||||
++i; /* Skip executable */
|
||||
this->ClientArgStart = i + 1;
|
||||
this->ClientArgCount = this->ClientArgStart;
|
||||
ArgCountP = &this->ClientArgCount;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i], "--client-helper") == 0) {
|
||||
std::cerr << "Client Helper" << std::endl;
|
||||
this->ClientHelper = true;
|
||||
this->ClientHelperExecutable = ::FixExecutablePath(argv[i + 1]);
|
||||
++i; /* Skip executable */
|
||||
this->ClientHelperArgStart = i + 1;
|
||||
this->ClientHelperArgCount = this->ClientHelperArgStart;
|
||||
ArgCountP = &this->ClientHelperArgCount;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i], "--client-init") == 0) {
|
||||
std::cerr << "Client Init" << std::endl;
|
||||
this->ClientInit = true;
|
||||
this->ClientInitExecutable = ::FixExecutablePath(argv[i + 1]);
|
||||
++i; /* Skip executable */
|
||||
this->ClientInitArgStart = i + 1;
|
||||
this->ClientInitArgCount = this->ClientInitArgStart;
|
||||
ArgCountP = &this->ClientInitArgCount;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i], "--server") == 0) {
|
||||
std::cerr << "Test Server" << std::endl;
|
||||
this->TestServer = true;
|
||||
this->ServerExecutable = ::FixExecutablePath(argv[i + 1]);
|
||||
++i; /* Skip executable */
|
||||
this->ServerArgStart = i + 1;
|
||||
this->ServerArgCount = this->ServerArgStart;
|
||||
ArgCountP = &this->ServerArgCount;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i], "--timeout") == 0) {
|
||||
this->TimeOut = atoi(argv[i + 1]);
|
||||
std::cerr << "The timeout was set to " << this->TimeOut << std::endl;
|
||||
ArgCountP = NULL;
|
||||
continue;
|
||||
}
|
||||
if (strncmp(argv[i], "--allow-errors", strlen("--allow-errors")) == 0) {
|
||||
this->AllowErrorInOutput = true;
|
||||
std::cerr << "The allow errors in output flag was set to " <<
|
||||
this->AllowErrorInOutput << std::endl;
|
||||
ArgCountP = NULL;
|
||||
continue;
|
||||
}
|
||||
if (strncmp(argv[i], "--allow-server-errors", strlen("--allow-server-errors")) == 0) {
|
||||
this->IgnoreServerResult = true;
|
||||
std::cerr << "The allow server errors in output flag was set to " <<
|
||||
this->IgnoreServerResult << std::endl;
|
||||
ArgCountP = NULL;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i], "--serial") == 0) {
|
||||
this->TestSerial = true;
|
||||
std::cerr << "This is a serial test" << std::endl;
|
||||
ArgCountP = NULL;
|
||||
continue;
|
||||
}
|
||||
if (ArgCountP)
|
||||
(*ArgCountP)++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
H5APITestDriver::CreateCommandLine(vector<const char*> &commandLine,
|
||||
const char *cmd, int isServer, int isHelper, const char *numProc, int argStart,
|
||||
int argCount, char *argv[])
|
||||
{
|
||||
if (!isServer && this->ClientEnvVars.size()) {
|
||||
for (unsigned int i = 0; i < this->ClientEnvVars.size(); ++i)
|
||||
commandLine.push_back(this->ClientEnvVars[i].c_str());
|
||||
#ifdef H5_API_TEST_CLIENT_INIT_TOKEN_VAR
|
||||
if (this->ClientTokenVar.size())
|
||||
commandLine.push_back(this->ClientTokenVar.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!isHelper && this->MPIRun.size()) {
|
||||
commandLine.push_back(this->MPIRun.c_str());
|
||||
commandLine.push_back(this->MPINumProcessFlag.c_str());
|
||||
commandLine.push_back(numProc);
|
||||
|
||||
if (isServer)
|
||||
for (unsigned int i = 0; i < this->MPIServerPreFlags.size(); ++i)
|
||||
commandLine.push_back(this->MPIServerPreFlags[i].c_str());
|
||||
else
|
||||
for (unsigned int i = 0; i < this->MPIClientPreFlags.size(); ++i)
|
||||
commandLine.push_back(this->MPIClientPreFlags[i].c_str());
|
||||
}
|
||||
|
||||
commandLine.push_back(cmd);
|
||||
|
||||
if (isServer)
|
||||
for (unsigned int i = 0; i < this->MPIServerPostFlags.size(); ++i)
|
||||
commandLine.push_back(MPIServerPostFlags[i].c_str());
|
||||
else
|
||||
for (unsigned int i = 0; i < this->MPIClientPostFlags.size(); ++i)
|
||||
commandLine.push_back(MPIClientPostFlags[i].c_str());
|
||||
|
||||
// remaining flags for the test
|
||||
for (int ii = argStart; ii < argCount; ++ii) {
|
||||
commandLine.push_back(argv[ii]);
|
||||
}
|
||||
|
||||
commandLine.push_back(0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
H5APITestDriver::StartServer(h5_api_test_sysProcess *server, const char *name,
|
||||
vector<char> &out, vector<char> &err)
|
||||
{
|
||||
if (!server)
|
||||
return 1;
|
||||
|
||||
cerr << "H5APITestDriver: starting process " << name << "\n";
|
||||
h5_api_test_sysProcess_SetTimeout(server, this->TimeOut);
|
||||
h5_api_test_sysProcess_Execute(server);
|
||||
int foundWaiting = 0;
|
||||
string output;
|
||||
while (!foundWaiting) {
|
||||
int pipe = this->WaitForAndPrintLine(name, server, output, 100.0, out,
|
||||
err, H5_API_TEST_SERVER_START_MSG, &foundWaiting);
|
||||
if (pipe == h5_api_test_sysProcess_Pipe_None
|
||||
|| pipe == h5_api_test_sysProcess_Pipe_Timeout) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundWaiting) {
|
||||
cerr << "H5APITestDriver: " << name << " successfully started.\n";
|
||||
return 1;
|
||||
} else {
|
||||
cerr << "H5APITestDriver: " << name << " never started.\n";
|
||||
h5_api_test_sysProcess_Kill(server);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
H5APITestDriver::StartClientHelper(h5_api_test_sysProcess *client,
|
||||
const char *name, vector<char> &out, vector<char> &err)
|
||||
{
|
||||
if (!client)
|
||||
return 1;
|
||||
|
||||
cerr << "H5APITestDriver: starting process " << name << "\n";
|
||||
h5_api_test_sysProcess_SetTimeout(client, this->TimeOut);
|
||||
h5_api_test_sysProcess_Execute(client);
|
||||
int foundWaiting = 0;
|
||||
string output;
|
||||
while (!foundWaiting) {
|
||||
int pipe = this->WaitForAndPrintLine(name, client, output, 100.0, out,
|
||||
err, H5_API_TEST_CLIENT_HELPER_START_MSG, &foundWaiting);
|
||||
if (pipe == h5_api_test_sysProcess_Pipe_None
|
||||
|| pipe == h5_api_test_sysProcess_Pipe_Timeout) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundWaiting) {
|
||||
cerr << "H5APITestDriver: " << name << " successfully started.\n";
|
||||
return 1;
|
||||
} else {
|
||||
cerr << "H5APITestDriver: " << name << " never started.\n";
|
||||
h5_api_test_sysProcess_Kill(client);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
H5APITestDriver::StartClientInit(h5_api_test_sysProcess *client,
|
||||
const char *name, vector<char> &out, vector<char> &err)
|
||||
{
|
||||
if (!client)
|
||||
return 1;
|
||||
|
||||
cerr << "H5APITestDriver: starting process " << name << "\n";
|
||||
h5_api_test_sysProcess_SetTimeout(client, this->TimeOut);
|
||||
h5_api_test_sysProcess_Execute(client);
|
||||
int foundToken = 0;
|
||||
string output, token;
|
||||
while (!foundToken) {
|
||||
int pipe = this->WaitForAndPrintLine(name, client, output, 100.0, out,
|
||||
err, NULL, NULL);
|
||||
if (pipe == h5_api_test_sysProcess_Pipe_None
|
||||
|| pipe == h5_api_test_sysProcess_Pipe_Timeout) {
|
||||
break;
|
||||
}
|
||||
if (this->OutputStringHasToken(name, H5_API_TEST_CLIENT_INIT_TOKEN_REGEX, output, token)) {
|
||||
foundToken = 1;
|
||||
this->ClientTokenVar = std::string(H5_API_TEST_CLIENT_INIT_TOKEN_VAR)
|
||||
+ std::string("=") + std::string(token);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundToken) {
|
||||
cerr << "H5APITestDriver: " << name << " token: " << token << " was found.\n";
|
||||
return 1;
|
||||
} else {
|
||||
cerr << "H5APITestDriver: " << name << " token was not found.\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
H5APITestDriver::StartClient(h5_api_test_sysProcess *client, const char *name)
|
||||
{
|
||||
if (!client)
|
||||
return 1;
|
||||
|
||||
cerr << "H5APITestDriver: starting process " << name << "\n";
|
||||
h5_api_test_sysProcess_SetTimeout(client, this->TimeOut);
|
||||
h5_api_test_sysProcess_Execute(client);
|
||||
if (h5_api_test_sysProcess_GetState(client)
|
||||
== h5_api_test_sysProcess_State_Executing) {
|
||||
cerr << "H5APITestDriver: " << name << " successfully started.\n";
|
||||
return 1;
|
||||
} else {
|
||||
this->ReportStatus(client, name);
|
||||
h5_api_test_sysProcess_Kill(client);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
H5APITestDriver::Stop(h5_api_test_sysProcess *p, const char *name)
|
||||
{
|
||||
if (p) {
|
||||
cerr << "H5APITestDriver: killing process " << name << "\n";
|
||||
h5_api_test_sysProcess_Kill(p);
|
||||
h5_api_test_sysProcess_WaitForExit(p, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
H5APITestDriver::OutputStringHasError(const char *pname, string &output)
|
||||
{
|
||||
const char* possibleMPIErrors[] = {"error", "Error", "Missing:",
|
||||
"core dumped", "process in local group is dead", "Segmentation fault",
|
||||
"erroneous", "ERROR:", "Error:",
|
||||
"mpirun can *only* be used with MPI programs", "due to signal",
|
||||
"failure", "abnormal termination", "failed", "FAILED", "Failed", 0};
|
||||
|
||||
const char* nonErrors[] = {
|
||||
"Memcheck, a memory error detector", //valgrind
|
||||
0};
|
||||
|
||||
if (this->AllowErrorInOutput)
|
||||
return 0;
|
||||
|
||||
vector<string> lines;
|
||||
vector<string>::iterator it;
|
||||
h5_api_test_sys::SystemTools::Split(output.c_str(), lines);
|
||||
|
||||
int i, j;
|
||||
|
||||
for (it = lines.begin(); it != lines.end(); ++it) {
|
||||
for (i = 0; possibleMPIErrors[i]; ++i) {
|
||||
if (it->find(possibleMPIErrors[i]) != it->npos) {
|
||||
int found = 1;
|
||||
for (j = 0; nonErrors[j]; ++j) {
|
||||
if (it->find(nonErrors[j]) != it->npos) {
|
||||
found = 0;
|
||||
cerr << "Non error \"" << it->c_str()
|
||||
<< "\" suppressed " << std::endl;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
cerr
|
||||
<< "H5APITestDriver: ***** Test will fail, because the string: \""
|
||||
<< possibleMPIErrors[i]
|
||||
<< "\"\nH5APITestDriver: ***** was found in the following output from the "
|
||||
<< pname << ":\n\"" << it->c_str() << "\"\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
H5APITestDriver::OutputStringHasToken(const char *pname, const char *regex,
|
||||
string &output, string &token)
|
||||
{
|
||||
vector<string> lines;
|
||||
vector<string>::iterator it;
|
||||
h5_api_test_sys::SystemTools::Split(output.c_str(), lines);
|
||||
h5_api_test_sys::RegularExpression re(regex);
|
||||
|
||||
for (it = lines.begin(); it != lines.end(); ++it) {
|
||||
if (re.find(*it)) {
|
||||
token = re.match(1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#define H5_API_CLEAN_PROCESSES do { \
|
||||
h5_api_test_sysProcess_Delete(client); \
|
||||
h5_api_test_sysProcess_Delete(client_helper); \
|
||||
h5_api_test_sysProcess_Delete(client_init); \
|
||||
h5_api_test_sysProcess_Delete(server); \
|
||||
} while (0)
|
||||
|
||||
#define H5_API_EXECUTE_CMD(cmd) do { \
|
||||
if (strlen(cmd) > 0) { \
|
||||
std::vector<std::string> commands = \
|
||||
h5_api_test_sys::SystemTools::SplitString(cmd, ';'); \
|
||||
for (unsigned int cc = 0; cc < commands.size(); cc++) { \
|
||||
std::string command = commands[cc]; \
|
||||
if (command.size() > 0) { \
|
||||
std::cout << command.c_str() << std::endl; \
|
||||
system(command.c_str()); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
H5APITestDriver::Main(int argc, char* argv[])
|
||||
{
|
||||
#ifdef H5_API_TEST_INIT_COMMAND
|
||||
// run user-specified commands before initialization.
|
||||
// For example: "killall -9 rsh test;"
|
||||
H5_API_EXECUTE_CMD(H5_API_TEST_INIT_COMMAND);
|
||||
#endif
|
||||
|
||||
if (!this->ProcessCommandLine(argc, argv))
|
||||
return 1;
|
||||
this->CollectConfiguredOptions();
|
||||
|
||||
// mpi code
|
||||
// Allocate process managers.
|
||||
h5_api_test_sysProcess *server = 0;
|
||||
h5_api_test_sysProcess *client = 0;
|
||||
h5_api_test_sysProcess *client_helper = 0;
|
||||
h5_api_test_sysProcess *client_init = 0;
|
||||
|
||||
if (this->TestServer) {
|
||||
server = h5_api_test_sysProcess_New();
|
||||
if (!server) {
|
||||
H5_API_CLEAN_PROCESSES;
|
||||
cerr << "H5APITestDriver: Cannot allocate h5_api_test_sysProcess to "
|
||||
"run the server.\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (this->ClientHelper) {
|
||||
client_helper = h5_api_test_sysProcess_New();
|
||||
if (!client_helper) {
|
||||
H5API_CLEAN_PROCESSES;
|
||||
cerr << "H5APITestDriver: Cannot allocate h5_api_test_sysProcess to "
|
||||
"run the client helper.\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (this->ClientInit) {
|
||||
client_init = h5_api_test_sysProcess_New();
|
||||
if (!client_init) {
|
||||
H5_API_CLEAN_PROCESSES;
|
||||
cerr << "H5APITestDriver: Cannot allocate h5_api_test_sysProcess to "
|
||||
"run the client init.\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
client = h5_api_test_sysProcess_New();
|
||||
if (!client) {
|
||||
H5_API_CLEAN_PROCESSES;
|
||||
cerr << "H5APITestDriver: Cannot allocate h5_api_test_sysProcess to "
|
||||
"run the client.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
vector<char> ClientStdOut;
|
||||
vector<char> ClientStdErr;
|
||||
vector<char> ClientHelperStdOut;
|
||||
vector<char> ClientHelperStdErr;
|
||||
vector<char> ClientInitStdOut;
|
||||
vector<char> ClientInitStdErr;
|
||||
vector<char> ServerStdOut;
|
||||
vector<char> ServerStdErr;
|
||||
|
||||
vector<const char *> serverCommand;
|
||||
if (server) {
|
||||
const char* serverExe = this->ServerExecutable.c_str();
|
||||
|
||||
this->CreateCommandLine(serverCommand, serverExe, 1, 0,
|
||||
this->MPIServerNumProcessFlag.c_str(), this->ServerArgStart,
|
||||
this->ServerArgCount, argv);
|
||||
this->ReportCommand(&serverCommand[0], "server");
|
||||
h5_api_test_sysProcess_SetCommand(server, &serverCommand[0]);
|
||||
h5_api_test_sysProcess_SetWorkingDirectory(server,
|
||||
this->GetDirectory(serverExe).c_str());
|
||||
}
|
||||
|
||||
vector<const char *> clientHelperCommand;
|
||||
if (client_helper) {
|
||||
// Construct the client helper process command line.
|
||||
const char *clientHelperExe = this->ClientHelperExecutable.c_str();
|
||||
this->CreateCommandLine(clientHelperCommand, clientHelperExe, 0, 1,
|
||||
"1", this->ClientHelperArgStart,
|
||||
this->ClientHelperArgCount, argv);
|
||||
this->ReportCommand(&clientHelperCommand[0], "client_helper");
|
||||
h5_api_test_sysProcess_SetCommand(client_helper, &clientHelperCommand[0]);
|
||||
h5_api_test_sysProcess_SetWorkingDirectory(client_helper,
|
||||
this->GetDirectory(clientHelperExe).c_str());
|
||||
}
|
||||
|
||||
vector<const char *> clientInitCommand;
|
||||
if (client_init) {
|
||||
// Construct the client helper process command line.
|
||||
const char *clientInitExe = this->ClientInitExecutable.c_str();
|
||||
this->CreateCommandLine(clientInitCommand, clientInitExe, 0, 1,
|
||||
"1", this->ClientInitArgStart, this->ClientInitArgCount, argv);
|
||||
this->ReportCommand(&clientInitCommand[0], "client_init");
|
||||
h5_api_test_sysProcess_SetCommand(client_init, &clientInitCommand[0]);
|
||||
h5_api_test_sysProcess_SetWorkingDirectory(client_init,
|
||||
this->GetDirectory(clientInitExe).c_str());
|
||||
}
|
||||
|
||||
// Start the server if there is one
|
||||
if (!this->StartServer(server, "server", ServerStdOut, ServerStdErr)) {
|
||||
cerr << "H5APITestDriver: Server never started.\n";
|
||||
H5_API_CLEAN_PROCESSES;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Start the client helper here if there is one
|
||||
if (!this->StartClientHelper(client_helper, "client_helper",
|
||||
ClientHelperStdOut, ClientHelperStdErr)) {
|
||||
cerr << "H5APITestDriver: Client Helper never started.\n";
|
||||
this->Stop(server, "server");
|
||||
#ifdef H5_API_TEST_SERVER_EXIT_COMMAND
|
||||
H5_API_EXECUTE_CMD(H5_API_TEST_SERVER_EXIT_COMMAND);
|
||||
#endif
|
||||
H5_API_CLEAN_PROCESSES;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Start the client init here if there is one
|
||||
if (!this->StartClientInit(client_init, "client_init",
|
||||
ClientInitStdOut, ClientInitStdErr)) {
|
||||
cerr << "H5APITestDriver: Client Init never started.\n";
|
||||
this->Stop(server, "server");
|
||||
#ifdef H5_API_TEST_SERVER_EXIT_COMMAND
|
||||
H5_API_EXECUTE_CMD(H5_API_TEST_SERVER_EXIT_COMMAND);
|
||||
#endif
|
||||
this->Stop(client_helper, "client_helper");
|
||||
#ifdef H5_API_TEST_CLIENT_HELPER_EXIT_COMMAND
|
||||
H5_API_EXECUTE_CMD(H5_API_TEST_CLIENT_HELPER_EXIT_COMMAND);
|
||||
#endif
|
||||
H5_API_CLEAN_PROCESSES;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Construct the client process command line.
|
||||
vector<const char *> clientCommand;
|
||||
const char *clientExe = this->ClientExecutable.c_str();
|
||||
this->CreateCommandLine(clientCommand, clientExe, 0, 0,
|
||||
this->MPIClientNumProcessFlag.c_str(), this->ClientArgStart,
|
||||
this->ClientArgCount, argv);
|
||||
this->ReportCommand(&clientCommand[0], "client");
|
||||
h5_api_test_sysProcess_SetCommand(client, &clientCommand[0]);
|
||||
h5_api_test_sysProcess_SetWorkingDirectory(client,
|
||||
this->GetDirectory(clientExe).c_str());
|
||||
|
||||
// Now run the client
|
||||
if (!this->StartClient(client, "client")) {
|
||||
this->Stop(server, "server");
|
||||
this->Stop(client_helper, "client_helper");
|
||||
this->Stop(client_init, "client_init");
|
||||
H5_API_CLEAN_PROCESSES;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Report the output of the processes.
|
||||
int clientPipe = 1;
|
||||
|
||||
string output;
|
||||
int mpiError = 0;
|
||||
while (clientPipe) {
|
||||
clientPipe = this->WaitForAndPrintLine("client", client, output, 0.1,
|
||||
ClientStdOut, ClientStdErr, NULL, NULL);
|
||||
if (!mpiError && this->OutputStringHasError("client", output)) {
|
||||
mpiError = 1;
|
||||
}
|
||||
// If client has died, we wait for output from the server processes
|
||||
// for this->ServerExitTimeOut, then we'll kill the servers, if needed.
|
||||
double timeout = (clientPipe) ? 0 : this->ServerExitTimeOut;
|
||||
output = "";
|
||||
this->WaitForAndPrintLine("server", server, output, timeout,
|
||||
ServerStdOut, ServerStdErr, NULL, NULL);
|
||||
if (!mpiError && this->OutputStringHasError("server", output)) {
|
||||
mpiError = 1;
|
||||
}
|
||||
output = "";
|
||||
}
|
||||
|
||||
// Wait for the client and server to exit.
|
||||
h5_api_test_sysProcess_WaitForExit(client, 0);
|
||||
|
||||
// Once client is finished, the servers
|
||||
// must finish quickly. If not, it usually is a sign that
|
||||
// the client crashed/exited before it attempted to connect to
|
||||
// the server.
|
||||
if (server) {
|
||||
#ifdef H5_API_TEST_SERVER_EXIT_COMMAND
|
||||
H5_API_EXECUTE_CMD(H5_API_TEST_SERVER_EXIT_COMMAND);
|
||||
#endif
|
||||
h5_api_test_sysProcess_WaitForExit(server, &this->ServerExitTimeOut);
|
||||
}
|
||||
|
||||
if (client_helper) {
|
||||
#ifdef H5_API_TEST_CLIENT_HELPER_EXIT_COMMAND
|
||||
H5_API_EXECUTE_CMD(H5_API_TEST_CLIENT_HELPER_EXIT_COMMAND);
|
||||
#endif
|
||||
h5_api_test_sysProcess_WaitForExit(client_helper, 0);
|
||||
}
|
||||
|
||||
// Get the results.
|
||||
int clientResult = this->ReportStatus(client, "client");
|
||||
int serverResult = 0;
|
||||
if (server) {
|
||||
serverResult = this->ReportStatus(server, "server");
|
||||
h5_api_test_sysProcess_Kill(server);
|
||||
}
|
||||
|
||||
// Free process managers.
|
||||
H5_API_CLEAN_PROCESSES;
|
||||
|
||||
// Report the server return code if it is nonzero. Otherwise report
|
||||
// the client return code.
|
||||
if (serverResult && !this->IgnoreServerResult)
|
||||
return serverResult;
|
||||
|
||||
if (mpiError) {
|
||||
cerr
|
||||
<< "H5VLTestDriver: Error string found in output, H5APITestDriver returning "
|
||||
<< mpiError << "\n";
|
||||
return mpiError;
|
||||
}
|
||||
|
||||
// if server is fine return the client result
|
||||
return clientResult;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
H5APITestDriver::ReportCommand(const char * const *command, const char *name)
|
||||
{
|
||||
cerr << "H5APITestDriver: " << name << " command is:\n";
|
||||
for (const char * const *c = command; *c; ++c)
|
||||
cerr << " \"" << *c << "\"";
|
||||
cerr << "\n";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
H5APITestDriver::ReportStatus(h5_api_test_sysProcess *process, const char *name)
|
||||
{
|
||||
int result = 1;
|
||||
switch (h5_api_test_sysProcess_GetState(process)) {
|
||||
case h5_api_test_sysProcess_State_Starting: {
|
||||
cerr << "H5APITestDriver: Never started " << name << " process.\n";
|
||||
}
|
||||
break;
|
||||
case h5_api_test_sysProcess_State_Error: {
|
||||
cerr << "H5APITestDriver: Error executing " << name << " process: "
|
||||
<< h5_api_test_sysProcess_GetErrorString(process) << "\n";
|
||||
}
|
||||
break;
|
||||
case h5_api_test_sysProcess_State_Exception: {
|
||||
cerr << "H5APITestDriver: " << name
|
||||
<< " process exited with an exception: ";
|
||||
switch (h5_api_test_sysProcess_GetExitException(process)) {
|
||||
case h5_api_test_sysProcess_Exception_None: {
|
||||
cerr << "None";
|
||||
}
|
||||
break;
|
||||
case h5_api_test_sysProcess_Exception_Fault: {
|
||||
cerr << "Segmentation fault";
|
||||
}
|
||||
break;
|
||||
case h5_api_test_sysProcess_Exception_Illegal: {
|
||||
cerr << "Illegal instruction";
|
||||
}
|
||||
break;
|
||||
case h5_api_test_sysProcess_Exception_Interrupt: {
|
||||
cerr << "Interrupted by user";
|
||||
}
|
||||
break;
|
||||
case h5_api_test_sysProcess_Exception_Numerical: {
|
||||
cerr << "Numerical exception";
|
||||
}
|
||||
break;
|
||||
case h5_api_test_sysProcess_Exception_Other: {
|
||||
cerr << "Unknown";
|
||||
}
|
||||
break;
|
||||
}
|
||||
cerr << "\n";
|
||||
}
|
||||
break;
|
||||
case h5_api_test_sysProcess_State_Executing: {
|
||||
cerr << "H5APITestDriver: Never terminated " << name
|
||||
<< " process.\n";
|
||||
}
|
||||
break;
|
||||
case h5_api_test_sysProcess_State_Exited: {
|
||||
result = h5_api_test_sysProcess_GetExitValue(process);
|
||||
cerr << "H5APITestDriver: " << name << " process exited with code "
|
||||
<< result << "\n";
|
||||
}
|
||||
break;
|
||||
case h5_api_test_sysProcess_State_Expired: {
|
||||
cerr << "H5APITestDriver: killed " << name
|
||||
<< " process due to timeout.\n";
|
||||
}
|
||||
break;
|
||||
case h5_api_test_sysProcess_State_Killed: {
|
||||
cerr << "H5APITestDriver: killed " << name << " process.\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
H5APITestDriver::WaitForLine(h5_api_test_sysProcess *process, string &line,
|
||||
double timeout, vector<char> &out, vector<char> &err)
|
||||
{
|
||||
line = "";
|
||||
vector<char>::iterator outiter = out.begin();
|
||||
vector<char>::iterator erriter = err.begin();
|
||||
while (1) {
|
||||
// Check for a newline in stdout.
|
||||
for (; outiter != out.end(); ++outiter) {
|
||||
if ((*outiter == '\r') && ((outiter + 1) == out.end())) {
|
||||
break;
|
||||
} else if (*outiter == '\n' || *outiter == '\0') {
|
||||
int length = outiter - out.begin();
|
||||
if (length > 1 && *(outiter - 1) == '\r')
|
||||
--length;
|
||||
if (length > 0)
|
||||
line.append(&out[0], length);
|
||||
out.erase(out.begin(), outiter + 1);
|
||||
return h5_api_test_sysProcess_Pipe_STDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a newline in stderr.
|
||||
for (; erriter != err.end(); ++erriter) {
|
||||
if ((*erriter == '\r') && ((erriter + 1) == err.end())) {
|
||||
break;
|
||||
} else if (*erriter == '\n' || *erriter == '\0') {
|
||||
int length = erriter - err.begin();
|
||||
if (length > 1 && *(erriter - 1) == '\r')
|
||||
--length;
|
||||
if (length > 0)
|
||||
line.append(&err[0], length);
|
||||
err.erase(err.begin(), erriter + 1);
|
||||
return h5_api_test_sysProcess_Pipe_STDERR;
|
||||
}
|
||||
}
|
||||
|
||||
// No newlines found. Wait for more data from the process.
|
||||
int length;
|
||||
char *data;
|
||||
int pipe = h5_api_test_sysProcess_WaitForData(process, &data, &length,
|
||||
&timeout);
|
||||
if (pipe == h5_api_test_sysProcess_Pipe_Timeout) {
|
||||
// Timeout has been exceeded.
|
||||
return pipe;
|
||||
} else if (pipe == h5_api_test_sysProcess_Pipe_STDOUT) {
|
||||
// Append to the stdout buffer.
|
||||
vector<char>::size_type size = out.size();
|
||||
out.insert(out.end(), data, data + length);
|
||||
outiter = out.begin() + size;
|
||||
} else if (pipe == h5_api_test_sysProcess_Pipe_STDERR) {
|
||||
// Append to the stderr buffer.
|
||||
vector<char>::size_type size = err.size();
|
||||
err.insert(err.end(), data, data + length);
|
||||
erriter = err.begin() + size;
|
||||
} else if (pipe == h5_api_test_sysProcess_Pipe_None) {
|
||||
// Both stdout and stderr pipes have broken. Return leftover data.
|
||||
if (!out.empty()) {
|
||||
line.append(&out[0], outiter - out.begin());
|
||||
out.erase(out.begin(), out.end());
|
||||
return h5_api_test_sysProcess_Pipe_STDOUT;
|
||||
} else if (!err.empty()) {
|
||||
line.append(&err[0], erriter - err.begin());
|
||||
err.erase(err.begin(), err.end());
|
||||
return h5_api_test_sysProcess_Pipe_STDERR;
|
||||
} else {
|
||||
return h5_api_test_sysProcess_Pipe_None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
H5APITestDriver::PrintLine(const char *pname, const char *line)
|
||||
{
|
||||
// if the name changed then the line is output from a different process
|
||||
if (this->CurrentPrintLineName != pname) {
|
||||
cerr << "-------------- " << pname << " output --------------\n";
|
||||
// save the current pname
|
||||
this->CurrentPrintLineName = pname;
|
||||
}
|
||||
cerr << line << "\n";
|
||||
cerr.flush();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
H5APITestDriver::WaitForAndPrintLine(const char *pname,
|
||||
h5_api_test_sysProcess *process, string &line, double timeout,
|
||||
vector<char> &out, vector<char> &err, const char *waitMsg,
|
||||
int *foundWaiting)
|
||||
{
|
||||
int pipe = this->WaitForLine(process, line, timeout, out, err);
|
||||
if (pipe == h5_api_test_sysProcess_Pipe_STDOUT
|
||||
|| pipe == h5_api_test_sysProcess_Pipe_STDERR) {
|
||||
this->PrintLine(pname, line.c_str());
|
||||
if (foundWaiting && (line.find(waitMsg) != line.npos))
|
||||
*foundWaiting = 1;
|
||||
}
|
||||
return pipe;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
string
|
||||
H5APITestDriver::GetDirectory(string location)
|
||||
{
|
||||
return h5_api_test_sys::SystemTools::GetParentDirectory(location.c_str());
|
||||
}
|
93
test/API/driver/h5_api_test_driver.hxx
Normal file
93
test/API/driver/h5_api_test_driver.hxx
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef H5_API_TEST_DRIVER_H
|
||||
#define H5_API_TEST_DRIVER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <h5_api_test_sys/Process.h>
|
||||
|
||||
class H5APITestDriver {
|
||||
public:
|
||||
int Main(int argc, char *argv[]);
|
||||
H5APITestDriver();
|
||||
~H5APITestDriver();
|
||||
|
||||
protected:
|
||||
void SeparateArguments(const char* str, std::vector<std::string> &flags);
|
||||
|
||||
void ReportCommand(const char * const *command, const char *name);
|
||||
int ReportStatus(h5_api_test_sysProcess *process, const char *name);
|
||||
int ProcessCommandLine(int argc, char *argv[]);
|
||||
void CollectConfiguredOptions();
|
||||
void CreateCommandLine(std::vector<const char *> &commandLine,
|
||||
const char *cmd, int isServer, int isHelper, const char *numProc,
|
||||
int argStart = 0, int argCount = 0, char *argv[] = 0);
|
||||
|
||||
int StartServer(h5_api_test_sysProcess *server, const char *name,
|
||||
std::vector<char> &out, std::vector<char> &err);
|
||||
int StartClientHelper(h5_api_test_sysProcess *client, const char *name,
|
||||
std::vector<char> &out, std::vector<char> &err);
|
||||
int StartClientInit(h5_api_test_sysProcess *client, const char *name,
|
||||
std::vector<char> &out, std::vector<char> &err);
|
||||
int StartClient(h5_api_test_sysProcess *client, const char *name);
|
||||
void Stop(h5_api_test_sysProcess *p, const char *name);
|
||||
int OutputStringHasError(const char *pname, std::string &output);
|
||||
int OutputStringHasToken(const char *pname, const char *regex,
|
||||
std::string &output, std::string &token);
|
||||
|
||||
int WaitForLine(h5_api_test_sysProcess *process, std::string &line,
|
||||
double timeout, std::vector<char> &out, std::vector<char> &err);
|
||||
void PrintLine(const char *pname, const char *line);
|
||||
int WaitForAndPrintLine(const char *pname, h5_api_test_sysProcess *process,
|
||||
std::string &line, double timeout, std::vector<char> &out,
|
||||
std::vector<char> &err, const char *waitMsg, int *foundWaiting);
|
||||
|
||||
std::string GetDirectory(std::string location);
|
||||
|
||||
private:
|
||||
std::string ClientExecutable; // fullpath to client executable
|
||||
std::string ClientHelperExecutable; // fullpath to client helper executable
|
||||
std::string ClientInitExecutable; // fullpath to client init executable
|
||||
std::string ServerExecutable; // fullpath to server executable
|
||||
std::string MPIRun; // fullpath to mpirun executable
|
||||
|
||||
// This specify the preflags and post flags that can be set using:
|
||||
// VTK_MPI_PRENUMPROC_FLAGS VTK_MPI_PREFLAGS / VTK_MPI_POSTFLAGS at config time
|
||||
// std::vector<std::string> MPIPreNumProcFlags;
|
||||
std::vector<std::string> ClientEnvVars;
|
||||
std::vector<std::string> MPIClientPreFlags;
|
||||
std::vector<std::string> MPIClientPostFlags;
|
||||
std::vector<std::string> MPIServerPreFlags;
|
||||
std::vector<std::string> MPIServerPostFlags;
|
||||
|
||||
// Specify the number of process flag, this can be set using: VTK_MPI_NUMPROC_FLAG.
|
||||
// This is then split into :
|
||||
// MPIServerNumProcessFlag & MPIRenderServerNumProcessFlag
|
||||
std::string MPINumProcessFlag;
|
||||
std::string MPIServerNumProcessFlag;
|
||||
std::string MPIClientNumProcessFlag;
|
||||
|
||||
std::string ClientTokenVar; // use token to launch client if requested
|
||||
|
||||
std::string CurrentPrintLineName;
|
||||
|
||||
double TimeOut;
|
||||
double ServerExitTimeOut; // time to wait for servers to finish.
|
||||
bool ClientHelper;
|
||||
bool ClientInit;
|
||||
bool TestServer;
|
||||
|
||||
int ClientArgStart;
|
||||
int ClientArgCount;
|
||||
int ClientHelperArgStart;
|
||||
int ClientHelperArgCount;
|
||||
int ClientInitArgStart;
|
||||
int ClientInitArgCount;
|
||||
int ServerArgStart;
|
||||
int ServerArgCount;
|
||||
bool AllowErrorInOutput;
|
||||
bool TestSerial;
|
||||
bool IgnoreServerResult;
|
||||
};
|
||||
|
||||
#endif //H5_API_TEST_DRIVER_H
|
22
test/API/driver/kwsys/.clang-format
Normal file
22
test/API/driver/kwsys/.clang-format
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
# 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
|
||||
...
|
2
test/API/driver/kwsys/.hooks-config
Normal file
2
test/API/driver/kwsys/.hooks-config
Normal file
@ -0,0 +1,2 @@
|
||||
[hooks "chain"]
|
||||
pre-commit = GitSetup/pre-commit
|
225
test/API/driver/kwsys/Base64.c
Normal file
225
test/API/driver/kwsys/Base64.c
Normal file
@ -0,0 +1,225 @@
|
||||
/* 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);
|
||||
}
|
110
test/API/driver/kwsys/Base64.h.in
Normal file
110
test/API/driver/kwsys/Base64.h.in
Normal file
@ -0,0 +1,110 @@
|
||||
/* 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
|
1260
test/API/driver/kwsys/CMakeLists.txt
Normal file
1260
test/API/driver/kwsys/CMakeLists.txt
Normal file
File diff suppressed because it is too large
Load Diff
49
test/API/driver/kwsys/CONTRIBUTING.rst
Normal file
49
test/API/driver/kwsys/CONTRIBUTING.rst
Normal file
@ -0,0 +1,49 @@
|
||||
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
|
9
test/API/driver/kwsys/CTestConfig.cmake
Normal file
9
test/API/driver/kwsys/CTestConfig.cmake
Normal file
@ -0,0 +1,9 @@
|
||||
# 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)
|
14
test/API/driver/kwsys/CTestCustom.cmake.in
Normal file
14
test/API/driver/kwsys/CTestCustom.cmake.in
Normal file
@ -0,0 +1,14 @@
|
||||
# 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
|
||||
)
|
768
test/API/driver/kwsys/CommandLineArguments.cxx
Normal file
768
test/API/driver/kwsys/CommandLineArguments.cxx
Normal file
@ -0,0 +1,768 @@
|
||||
/* 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
|
270
test/API/driver/kwsys/CommandLineArguments.hxx.in
Normal file
270
test/API/driver/kwsys/CommandLineArguments.hxx.in
Normal file
@ -0,0 +1,270 @@
|
||||
/* 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
|
89
test/API/driver/kwsys/Configure.h.in
Normal file
89
test/API/driver/kwsys/Configure.h.in
Normal file
@ -0,0 +1,89 @@
|
||||
/* 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
|
65
test/API/driver/kwsys/Configure.hxx.in
Normal file
65
test/API/driver/kwsys/Configure.hxx.in
Normal file
@ -0,0 +1,65 @@
|
||||
/* 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
|
398
test/API/driver/kwsys/ConsoleBuf.hxx.in
Normal file
398
test/API/driver/kwsys/ConsoleBuf.hxx.in
Normal file
@ -0,0 +1,398 @@
|
||||
/* 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
|
38
test/API/driver/kwsys/Copyright.txt
Normal file
38
test/API/driver/kwsys/Copyright.txt
Normal file
@ -0,0 +1,38 @@
|
||||
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.
|
236
test/API/driver/kwsys/Directory.cxx
Normal file
236
test/API/driver/kwsys/Directory.cxx
Normal file
@ -0,0 +1,236 @@
|
||||
/* 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
|
72
test/API/driver/kwsys/Directory.hxx.in
Normal file
72
test/API/driver/kwsys/Directory.hxx.in
Normal file
@ -0,0 +1,72 @@
|
||||
/* 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
|
495
test/API/driver/kwsys/DynamicLoader.cxx
Normal file
495
test/API/driver/kwsys/DynamicLoader.cxx
Normal file
@ -0,0 +1,495 @@
|
||||
/* 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
|
106
test/API/driver/kwsys/DynamicLoader.hxx.in
Normal file
106
test/API/driver/kwsys/DynamicLoader.hxx.in
Normal file
@ -0,0 +1,106 @@
|
||||
/* 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
|
69
test/API/driver/kwsys/Encoding.h.in
Normal file
69
test/API/driver/kwsys/Encoding.h.in
Normal file
@ -0,0 +1,69 @@
|
||||
/* 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
|
80
test/API/driver/kwsys/Encoding.hxx.in
Normal file
80
test/API/driver/kwsys/Encoding.hxx.in
Normal file
@ -0,0 +1,80 @@
|
||||
/* 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
|
72
test/API/driver/kwsys/EncodingC.c
Normal file
72
test/API/driver/kwsys/EncodingC.c
Normal file
@ -0,0 +1,72 @@
|
||||
/* 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;
|
||||
}
|
288
test/API/driver/kwsys/EncodingCXX.cxx
Normal file
288
test/API/driver/kwsys/EncodingCXX.cxx
Normal file
@ -0,0 +1,288 @@
|
||||
/* 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
|
1
test/API/driver/kwsys/ExtraTest.cmake.in
Normal file
1
test/API/driver/kwsys/ExtraTest.cmake.in
Normal file
@ -0,0 +1 @@
|
||||
MESSAGE("*** This message is generated by message inside a file that is included in DartTestfile.txt ***")
|
55
test/API/driver/kwsys/FStream.cxx
Normal file
55
test/API/driver/kwsys/FStream.cxx
Normal file
@ -0,0 +1,55 @@
|
||||
/* 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
|
278
test/API/driver/kwsys/FStream.hxx.in
Normal file
278
test/API/driver/kwsys/FStream.hxx.in
Normal file
@ -0,0 +1,278 @@
|
||||
/* 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
|
6
test/API/driver/kwsys/GitSetup/.gitattributes
vendored
Normal file
6
test/API/driver/kwsys/GitSetup/.gitattributes
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
.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
|
202
test/API/driver/kwsys/GitSetup/LICENSE
Normal file
202
test/API/driver/kwsys/GitSetup/LICENSE
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
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.
|
5
test/API/driver/kwsys/GitSetup/NOTICE
Normal file
5
test/API/driver/kwsys/GitSetup/NOTICE
Normal file
@ -0,0 +1,5 @@
|
||||
Kitware Local Git Setup Scripts
|
||||
Copyright 2010-2012 Kitware, Inc.
|
||||
|
||||
This product includes software developed at Kitware, Inc.
|
||||
(http://www.kitware.com/).
|
87
test/API/driver/kwsys/GitSetup/README
Normal file
87
test/API/driver/kwsys/GitSetup/README
Normal file
@ -0,0 +1,87 @@
|
||||
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.
|
4
test/API/driver/kwsys/GitSetup/config
Normal file
4
test/API/driver/kwsys/GitSetup/config
Normal file
@ -0,0 +1,4 @@
|
||||
[hooks]
|
||||
url = https://gitlab.kitware.com/utils/gitsetup.git
|
||||
[upstream]
|
||||
url = https://gitlab.kitware.com/utils/kwsys.git
|
32
test/API/driver/kwsys/GitSetup/config.sample
Normal file
32
test/API/driver/kwsys/GitSetup/config.sample
Normal file
@ -0,0 +1,32 @@
|
||||
# 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
|
74
test/API/driver/kwsys/GitSetup/git-gerrit-push
Normal file
74
test/API/driver/kwsys/GitSetup/git-gerrit-push
Normal file
@ -0,0 +1,74 @@
|
||||
#!/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
|
177
test/API/driver/kwsys/GitSetup/git-gitlab-push
Normal file
177
test/API/driver/kwsys/GitSetup/git-gitlab-push
Normal file
@ -0,0 +1,177 @@
|
||||
#!/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
|
26
test/API/driver/kwsys/GitSetup/pre-commit
Normal file
26
test/API/driver/kwsys/GitSetup/pre-commit
Normal file
@ -0,0 +1,26 @@
|
||||
#!/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
|
6
test/API/driver/kwsys/GitSetup/setup-aliases
Normal file
6
test/API/driver/kwsys/GitSetup/setup-aliases
Normal file
@ -0,0 +1,6 @@
|
||||
#!/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
|
147
test/API/driver/kwsys/GitSetup/setup-gerrit
Normal file
147
test/API/driver/kwsys/GitSetup/setup-gerrit
Normal file
@ -0,0 +1,147 @@
|
||||
#!/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
|
140
test/API/driver/kwsys/GitSetup/setup-gitlab
Normal file
140
test/API/driver/kwsys/GitSetup/setup-gitlab
Normal file
@ -0,0 +1,140 @@
|
||||
#!/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
|
64
test/API/driver/kwsys/GitSetup/setup-hooks
Normal file
64
test/API/driver/kwsys/GitSetup/setup-hooks
Normal file
@ -0,0 +1,64 @@
|
||||
#!/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'
|
111
test/API/driver/kwsys/GitSetup/setup-ssh
Normal file
111
test/API/driver/kwsys/GitSetup/setup-ssh
Normal file
@ -0,0 +1,111 @@
|
||||
#!/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
|
82
test/API/driver/kwsys/GitSetup/setup-stage
Normal file
82
test/API/driver/kwsys/GitSetup/setup-stage
Normal file
@ -0,0 +1,82 @@
|
||||
#!/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.'
|
104
test/API/driver/kwsys/GitSetup/setup-upstream
Normal file
104
test/API/driver/kwsys/GitSetup/setup-upstream
Normal file
@ -0,0 +1,104 @@
|
||||
#!/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
|
39
test/API/driver/kwsys/GitSetup/setup-user
Normal file
39
test/API/driver/kwsys/GitSetup/setup-user
Normal file
@ -0,0 +1,39 @@
|
||||
#!/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
|
55
test/API/driver/kwsys/GitSetup/tips
Normal file
55
test/API/driver/kwsys/GitSetup/tips
Normal file
@ -0,0 +1,55 @@
|
||||
#!/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
|
448
test/API/driver/kwsys/Glob.cxx
Normal file
448
test/API/driver/kwsys/Glob.cxx
Normal file
@ -0,0 +1,448 @@
|
||||
/* 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
|
134
test/API/driver/kwsys/Glob.hxx.in
Normal file
134
test/API/driver/kwsys/Glob.hxx.in
Normal file
@ -0,0 +1,134 @@
|
||||
/* 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
|
255
test/API/driver/kwsys/IOStream.cxx
Normal file
255
test/API/driver/kwsys/IOStream.cxx
Normal file
@ -0,0 +1,255 @@
|
||||
/* 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
|
126
test/API/driver/kwsys/IOStream.hxx.in
Normal file
126
test/API/driver/kwsys/IOStream.hxx.in
Normal file
@ -0,0 +1,126 @@
|
||||
/* 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
|
494
test/API/driver/kwsys/MD5.c
Normal file
494
test/API/driver/kwsys/MD5.c
Normal file
@ -0,0 +1,494 @@
|
||||
/* 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];
|
||||
}
|
||||
}
|
97
test/API/driver/kwsys/MD5.h.in
Normal file
97
test/API/driver/kwsys/MD5.h.in
Normal file
@ -0,0 +1,97 @@
|
||||
/* 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
|
544
test/API/driver/kwsys/Process.h.in
Normal file
544
test/API/driver/kwsys/Process.h.in
Normal file
@ -0,0 +1,544 @@
|
||||
/* 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
|
2920
test/API/driver/kwsys/ProcessUNIX.c
Normal file
2920
test/API/driver/kwsys/ProcessUNIX.c
Normal file
File diff suppressed because it is too large
Load Diff
2786
test/API/driver/kwsys/ProcessWin32.c
Normal file
2786
test/API/driver/kwsys/ProcessWin32.c
Normal file
File diff suppressed because it is too large
Load Diff
37
test/API/driver/kwsys/README.rst
Normal file
37
test/API/driver/kwsys/README.rst
Normal file
@ -0,0 +1,37 @@
|
||||
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
|
1218
test/API/driver/kwsys/RegularExpression.cxx
Normal file
1218
test/API/driver/kwsys/RegularExpression.cxx
Normal file
File diff suppressed because it is too large
Load Diff
562
test/API/driver/kwsys/RegularExpression.hxx.in
Normal file
562
test/API/driver/kwsys/RegularExpression.hxx.in
Normal file
@ -0,0 +1,562 @@
|
||||
/* 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
|
20
test/API/driver/kwsys/SetupForDevelopment.sh
Normal file
20
test/API/driver/kwsys/SetupForDevelopment.sh
Normal file
@ -0,0 +1,20 @@
|
||||
#!/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}
|
879
test/API/driver/kwsys/SharedForward.h.in
Normal file
879
test/API/driver/kwsys/SharedForward.h.in
Normal file
@ -0,0 +1,879 @@
|
||||
/* 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
|
100
test/API/driver/kwsys/String.c
Normal file
100
test/API/driver/kwsys/String.c
Normal file
@ -0,0 +1,100 @@
|
||||
/* 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 */
|
57
test/API/driver/kwsys/String.h.in
Normal file
57
test/API/driver/kwsys/String.h.in
Normal file
@ -0,0 +1,57 @@
|
||||
/* 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
|
65
test/API/driver/kwsys/String.hxx.in
Normal file
65
test/API/driver/kwsys/String.hxx.in
Normal file
@ -0,0 +1,65 @@
|
||||
/* 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
|
236
test/API/driver/kwsys/System.c
Normal file
236
test/API/driver/kwsys/System.c
Normal file
@ -0,0 +1,236 @@
|
||||
/* 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);
|
||||
}
|
60
test/API/driver/kwsys/System.h.in
Normal file
60
test/API/driver/kwsys/System.h.in
Normal file
@ -0,0 +1,60 @@
|
||||
/* 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
|
5466
test/API/driver/kwsys/SystemInformation.cxx
Normal file
5466
test/API/driver/kwsys/SystemInformation.cxx
Normal file
File diff suppressed because it is too large
Load Diff
170
test/API/driver/kwsys/SystemInformation.hxx.in
Normal file
170
test/API/driver/kwsys/SystemInformation.hxx.in
Normal file
@ -0,0 +1,170 @@
|
||||
/* 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
|
4703
test/API/driver/kwsys/SystemTools.cxx
Normal file
4703
test/API/driver/kwsys/SystemTools.cxx
Normal file
File diff suppressed because it is too large
Load Diff
981
test/API/driver/kwsys/SystemTools.hxx.in
Normal file
981
test/API/driver/kwsys/SystemTools.hxx.in
Normal file
@ -0,0 +1,981 @@
|
||||
/* 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
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user