Add initial version of HDF5 API tests (#2877)

This commit is contained in:
jhendersonHDF 2023-05-02 14:52:39 -05:00 committed by GitHub
parent 41fd8e66a9
commit f8a1b3ceec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
200 changed files with 212642 additions and 49 deletions

View File

@ -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

View File

@ -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 ()

View File

@ -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

View 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()

View 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
View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

437
test/API/H5_api_link_test.h Normal file
View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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
View 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
View 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

View 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
View 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;
}

View 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_ */

View 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
View 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).

View 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)

View 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());
}

View 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

View 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
...

View File

@ -0,0 +1,2 @@
[hooks "chain"]
pre-commit = GitSetup/pre-commit

View 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);
}

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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)

View 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
)

View 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

View 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

View 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

View 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

View 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

View 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.

View 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

View 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

View 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

View 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

View 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

View 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

View 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;
}

View 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

View File

@ -0,0 +1 @@
MESSAGE("*** This message is generated by message inside a file that is included in DartTestfile.txt ***")

View 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

View 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

View 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

View 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.

View 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/).

View 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.

View File

@ -0,0 +1,4 @@
[hooks]
url = https://gitlab.kitware.com/utils/gitsetup.git
[upstream]
url = https://gitlab.kitware.com/utils/kwsys.git

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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'

View 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

View 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.'

View 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

View 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

View 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

View 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

View 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

View 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

View 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
View 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];
}
}

View 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

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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}

View 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

View 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 */

View 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

View 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

View 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);
}

View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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