summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--config/cmake/HDFCompilerFlags.cmake4
-rw-r--r--config/sanitizer/sanitizers.cmake27
-rw-r--r--fortran/src/H5Pf.c40
-rw-r--r--fortran/src/H5Pff.F9095
-rw-r--r--fortran/src/H5_f.c8
-rw-r--r--fortran/src/H5_ff.F9010
-rw-r--r--fortran/src/H5f90global.F9012
-rw-r--r--fortran/src/H5f90proto.h1
-rw-r--r--fortran/src/hdf5_fortrandll.def.in1
-rw-r--r--fortran/test/tH5P_F03.F9042
-rw-r--r--release_docs/RELEASE.txt15
-rw-r--r--src/H5Aint.c6
-rw-r--r--src/H5Dint.c4
-rw-r--r--src/H5FDs3comms.c4
-rw-r--r--src/H5Fmount.c2
-rw-r--r--src/H5Gint.c2
-rw-r--r--src/H5Gobj.c2
-rw-r--r--src/H5Gtraverse.c2
-rw-r--r--src/H5L.c4
-rw-r--r--src/H5Oint.c101
-rw-r--r--src/H5Oprivate.h2
-rw-r--r--src/H5T.c444
-rw-r--r--src/H5TS.c9
-rw-r--r--src/H5Tcommit.c6
-rw-r--r--src/H5Tcompound.c87
-rw-r--r--src/H5Tnative.c2
-rw-r--r--src/H5Tprivate.h6
-rw-r--r--src/H5Znbit.c4
-rw-r--r--src/H5private.h5
-rw-r--r--src/H5public.h40
-rw-r--r--test/thread_id.c46
32 files changed, 734 insertions, 302 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dbbf55f..129a73a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -394,9 +394,6 @@ HDF_DIR_PATHS(${HDF5_PACKAGE_NAME})
include (${HDF_RESOURCES_EXT_DIR}/HDFLibMacros.cmake)
include (${HDF_RESOURCES_DIR}/HDF5Macros.cmake)
-if (HDF5_ENABLE_SANITIZERS)
- include (${HDF5_SOURCE_DIR}/config/sanitizer/sanitizers.cmake)
-endif ()
#-----------------------------------------------------------------------------
# Targets built within this project are exported at Install time for use
diff --git a/config/cmake/HDFCompilerFlags.cmake b/config/cmake/HDFCompilerFlags.cmake
index ea85736..17b0854 100644
--- a/config/cmake/HDFCompilerFlags.cmake
+++ b/config/cmake/HDFCompilerFlags.cmake
@@ -30,8 +30,10 @@ macro (ADD_H5_FLAGS h5_flag_var infile)
#message (STATUS "h5_flag_var=${${h5_flag_var}}")
endmacro ()
-message (STATUS "Warnings Configuration:")
set (CMAKE_C_FLAGS "${CMAKE_C99_STANDARD_COMPILE_OPTION} ${CMAKE_C_FLAGS}")
+set (CMAKE_C_FLAGS "${CMAKE_C_SANITIZER_FLAGS} ${CMAKE_C_FLAGS}")
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_SANITIZER_FLAGS} ${CMAKE_CXX_FLAGS}")
+message (STATUS "Warnings Configuration: default: ${CMAKE_C_FLAGS} : ${CMAKE_CXX_FLAGS}")
#-----------------------------------------------------------------------------
# Compiler specific flags : Shouldn't there be compiler tests for these
#-----------------------------------------------------------------------------
diff --git a/config/sanitizer/sanitizers.cmake b/config/sanitizer/sanitizers.cmake
index 2625ec3..ecee2de 100644
--- a/config/sanitizer/sanitizers.cmake
+++ b/config/sanitizer/sanitizers.cmake
@@ -28,52 +28,53 @@ function(append value)
endforeach(variable)
endfunction()
-if(USE_SANITIZER AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+message(STATUS "USE_SANITIZER=${USE_SANITIZER}, CMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}")
+if(USE_SANITIZER AND "${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
- append("-fno-omit-frame-pointer" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ append("-fno-omit-frame-pointer" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS)
+ message(STATUS "Building with sanitize, base flags=${CMAKE_C_SANITIZER_FLAGS}")
if(UNIX)
if(uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
- append("-O1" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ append("-O1" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS)
endif()
if(USE_SANITIZER MATCHES "([Aa]ddress);([Uu]ndefined)"
OR USE_SANITIZER MATCHES "([Uu]ndefined);([Aa]ddress)")
message(STATUS "Building with Address, Undefined sanitizers")
- append("-fsanitize=address,undefined" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ append("-fsanitize=address,undefined" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS)
set(MEMCHECK_TYPE AddressSanitizer)
elseif(USE_SANITIZER MATCHES "([Aa]ddress)")
# Optional: -fno-optimize-sibling-calls -fsanitize-address-use-after-scope
message(STATUS "Building with Address sanitizer")
- append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ append("-fsanitize=address" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS)
set(MEMCHECK_TYPE AddressSanitizer)
elseif(USE_SANITIZER MATCHES "([Mm]emory([Ww]ith[Oo]rigins)?)")
# Optional: -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2
- append("-fsanitize=memory" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ append("-fsanitize=memory" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS)
if(USE_SANITIZER MATCHES "([Mm]emory[Ww]ith[Oo]rigins)")
message(STATUS "Building with MemoryWithOrigins sanitizer")
- append("-fsanitize-memory-track-origins" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ append("-fsanitize-memory-track-origins" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS)
else()
message(STATUS "Building with Memory sanitizer")
endif()
set(MEMCHECK_TYPE MemorySanitizer)
elseif(USE_SANITIZER MATCHES "([Uu]ndefined)")
message(STATUS "Building with Undefined sanitizer")
- append("-fsanitize=undefined" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ append("-fsanitize=undefined" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS)
if(EXISTS "${BLACKLIST_FILE}")
- append("-fsanitize-blacklist=${BLACKLIST_FILE}" CMAKE_C_FLAGS
- CMAKE_CXX_FLAGS)
+ append("-fsanitize-blacklist=${BLACKLIST_FILE}" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS)
endif()
set(MEMCHECK_TYPE UndefinedBehaviorSanitizer)
elseif(USE_SANITIZER MATCHES "([Tt]hread)")
message(STATUS "Building with Thread sanitizer")
- append("-fsanitize=thread" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ append("-fsanitize=thread" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS)
set(MEMCHECK_TYPE ThreadSanitizer)
elseif(USE_SANITIZER MATCHES "([Ll]eak)")
message(STATUS "Building with Leak sanitizer")
- append("-fsanitize=leak" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ append("-fsanitize=leak" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS)
set(MEMCHECK_TYPE LeakSanitizer)
else()
message(
@@ -82,7 +83,7 @@ if(USE_SANITIZER AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
elseif(MSVC)
if(USE_SANITIZER MATCHES "([Aa]ddress)")
message(STATUS "Building with Address sanitizer")
- append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ append("-fsanitize=address" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS)
else()
message(
FATAL_ERROR
diff --git a/fortran/src/H5Pf.c b/fortran/src/H5Pf.c
index 2cacc8c..a931903 100644
--- a/fortran/src/H5Pf.c
+++ b/fortran/src/H5Pf.c
@@ -4061,46 +4061,6 @@ h5pget_attr_creation_order_c(hid_t_f *ocpl_id, int_f *crt_order_flags)
ret_value = 0;
return ret_value;
}
-/****if* H5Pf/h5pset_libver_bounds_c
- * NAME
- * h5pset_libver_bounds_c
- * PURPOSE
- * Calls H5Pset_libver_bounds
- *
- * INPUTS
- *
- * fapl_id - File access property list identifier
- * low - The earliest version of the library that will be used for writing objects.
- * high - The latest version of the library that will be used for writing objects.
- * OUTPUTS
- *
- *
- * RETURNS
- * 0 on success, -1 on failure
- * AUTHOR
- * M. Scot Breitenfeld
- * February 18, 2008
- * HISTORY
- *
- * SOURCE
-*/
-int_f
-h5pset_libver_bounds_c(hid_t_f *fapl_id, int_f *low, int_f *high )
-/******/
-{
- int ret_value = -1;
- herr_t ret;
-
- /*
- * Call H5Pset_libver_bounds function.
- */
- ret = H5Pset_libver_bounds( (hid_t)*fapl_id, (H5F_libver_t)*low, (H5F_libver_t)*high );
- if (ret < 0) return ret_value;
-
- ret_value = 0;
- return ret_value;
-}
-
/****if* H5Pf/h5pset_link_creation_order_c
* NAME
* h5pset_link_creation_order_c
diff --git a/fortran/src/H5Pff.F90 b/fortran/src/H5Pff.F90
index 0c0500d..61d30b8 100644
--- a/fortran/src/H5Pff.F90
+++ b/fortran/src/H5Pff.F90
@@ -4754,6 +4754,65 @@ CONTAINS
END SUBROUTINE h5pget_attr_creation_order_f
+!****s* H5P/H5Pget_libver_bounds_f
+! NAME
+! H5Pget_libver_bounds_f
+!
+! PURPOSE
+! Retrieves the lower and upper bounds on the HDF5 library release versions that indirectly
+! determine the object format versions used when creating objects in the file.
+!
+! INPUTS
+!
+! fapl_id - File access property list identifier
+! low - The earliest version of the library that will be used for writing objects.
+! high - The latest version of the library that will be used for writing objects.
+!
+! OUTPUTS
+!
+! hdferr - error code
+! Success: 0
+! Failure: -1
+!
+! AUTHOR
+! M. Scot Breitenfeld
+! February 10, 2020
+!
+! Fortran Interface:
+ SUBROUTINE h5pget_libver_bounds_f(fapl_id, low, high, hdferr)
+ IMPLICIT NONE
+ INTEGER(HID_T), INTENT(IN) :: fapl_id ! File access property list identifier
+ INTEGER, INTENT(OUT) :: low ! The earliest version of the library that will be used for writing objects.
+ INTEGER, INTENT(OUT) :: high ! The latest version of the library that will be used for writing objects.
+ INTEGER, INTENT(OUT) :: hdferr ! Error code: 0 on success and -1 on failure
+!*****
+! Local variables
+ INTEGER(ENUM_T) :: low_c, high_c
+ INTEGER(C_INT) :: hdferr_c
+!
+! MS FORTRAN needs explicit interface for C functions called here.
+!
+ INTERFACE
+ INTEGER(C_INT) FUNCTION h5pget_libver_bounds(fapl_id, low, high) &
+ BIND(C,NAME='H5Pget_libver_bounds')
+ IMPORT :: C_INT, HID_T, ENUM_T
+ IMPLICIT NONE
+ INTEGER(HID_T) , INTENT(IN) , VALUE :: fapl_id
+ INTEGER(ENUM_T), INTENT(OUT) :: low
+ INTEGER(ENUM_T), INTENT(OUT) :: high
+ END FUNCTION h5pget_libver_bounds
+ END INTERFACE
+
+ hdferr_c = H5Pget_libver_bounds(fapl_id, low_c, high_c)
+
+ low = INT(low_c)
+ high = INT(high_c)
+
+ hdferr = 0
+ IF(hdferr_c.LT.0) hdferr = -1
+
+ END SUBROUTINE h5pget_libver_bounds_f
+
!****s* H5P/H5Pset_libver_bounds_f
! NAME
! H5Pset_libver_bounds_f
@@ -4781,32 +4840,30 @@ CONTAINS
SUBROUTINE h5pset_libver_bounds_f(fapl_id, low, high, hdferr)
IMPLICIT NONE
INTEGER(HID_T), INTENT(IN) :: fapl_id ! File access property list identifier
- INTEGER, INTENT(IN) :: low ! The earliest version of the library that will be used for writing objects.
- ! Currently, low must be one of two pre-defined values:
- ! HDF_LIBVER_EARLIEST_F
- ! HDF_LIBVER_LATEST_F
- INTEGER, INTENT(IN) :: high ! The latest version of the library that will be used for writing objects.
- ! Currently, low must set to the pre-defined value:
- ! HDF_LIBVER_LATEST_F
- INTEGER, INTENT(OUT) :: hdferr ! Error code
- ! 0 on success and -1 on failure
-!*****
+ INTEGER, INTENT(IN) :: low ! The earliest version of the library that will be used for writing objects.
+ INTEGER, INTENT(IN) :: high ! The latest version of the library that will be used for writing objects.
+ INTEGER, INTENT(OUT) :: hdferr ! Error code: 0 on success and -1 on failure
+!*****
+! Local variables
+ INTEGER(C_INT) :: hdferr_c
!
! MS FORTRAN needs explicit interface for C functions called here.
!
INTERFACE
- INTEGER FUNCTION h5pset_libver_bounds_c(fapl_id, low, high) &
- BIND(C,NAME='h5pset_libver_bounds_c')
- IMPORT :: HID_T
+ INTEGER(C_INT) FUNCTION h5pset_libver_bounds(fapl_id, low, high) &
+ BIND(C,NAME='H5Pset_libver_bounds')
+ IMPORT :: C_INT, HID_T, ENUM_T
IMPLICIT NONE
- INTEGER(HID_T), INTENT(IN) :: fapl_id
- INTEGER, INTENT(IN) :: low
- INTEGER, INTENT(IN) :: high
-
- END FUNCTION H5pset_libver_bounds_c
+ INTEGER(HID_T), INTENT(IN), VALUE :: fapl_id
+ INTEGER(ENUM_T), INTENT(IN), VALUE :: low
+ INTEGER(ENUM_T), INTENT(IN), VALUE :: high
+ END FUNCTION h5pset_libver_bounds
END INTERFACE
- hdferr = h5pset_libver_bounds_c(fapl_id, low, high)
+ hdferr_c = h5pset_libver_bounds(fapl_id, INT(low, ENUM_T), INT(high, ENUM_T))
+
+ hdferr = 0
+ IF(hdferr_c.LT.0) hdferr = -1
END SUBROUTINE h5pset_libver_bounds_f
diff --git a/fortran/src/H5_f.c b/fortran/src/H5_f.c
index 132da7b..ced5049 100644
--- a/fortran/src/H5_f.c
+++ b/fortran/src/H5_f.c
@@ -441,7 +441,13 @@ h5init_flags_c( int_f *h5d_flags, size_t_f *h5d_size_flags,
h5f_flags[15] = (int_f)H5F_OBJ_ALL;
h5f_flags[16] = (int_f)H5F_LIBVER_EARLIEST;
h5f_flags[17] = (int_f)H5F_LIBVER_LATEST;
- h5f_flags[18] = (int_f)H5F_UNLIMITED;
+ h5f_flags[18] = (int_f)H5F_LIBVER_ERROR;
+ h5f_flags[19] = (int_f)H5F_LIBVER_NBOUNDS;
+ h5f_flags[20] = (int_f)H5F_UNLIMITED;
+ h5f_flags[21] = (int_f)H5F_LIBVER_V18;
+ h5f_flags[22] = (int_f)H5F_LIBVER_V110;
+ h5f_flags[23] = (int_f)H5F_LIBVER_V112;
+ h5f_flags[24] = (int_f)H5F_LIBVER_V114;
/*
* H5FD flags
diff --git a/fortran/src/H5_ff.F90 b/fortran/src/H5_ff.F90
index 443be79..7c7c751 100644
--- a/fortran/src/H5_ff.F90
+++ b/fortran/src/H5_ff.F90
@@ -46,7 +46,7 @@ MODULE H5LIB
!
! H5F flags declaration
!
- INTEGER, PARAMETER :: H5F_FLAGS_LEN = 19
+ INTEGER, PARAMETER :: H5F_FLAGS_LEN = 25
INTEGER, DIMENSION(1:H5F_FLAGS_LEN) :: H5F_flags
!
! H5generic flags declaration
@@ -343,7 +343,13 @@ CONTAINS
H5F_OBJ_ALL_F = H5F_flags(16)
H5F_LIBVER_EARLIEST_F = H5F_flags(17)
H5F_LIBVER_LATEST_F = H5F_flags(18)
- H5F_UNLIMITED_F = H5F_flags(19)
+ H5F_LIBVER_ERROR_F = H5F_flags(19)
+ H5F_LIBVER_NBOUNDS_F = H5F_flags(20)
+ H5F_UNLIMITED_F = H5F_flags(21)
+ H5F_LIBVER_V18_F = H5F_flags(22)
+ H5F_LIBVER_V110_F = H5F_flags(23)
+ H5F_LIBVER_V112_F = H5F_flags(24)
+ H5F_LIBVER_V114_F = H5F_flags(25)
!
! H5generic flags
!
diff --git a/fortran/src/H5f90global.F90 b/fortran/src/H5f90global.F90
index dabc0bb..6b601e9 100644
--- a/fortran/src/H5f90global.F90
+++ b/fortran/src/H5f90global.F90
@@ -237,6 +237,12 @@ MODULE H5GLOBAL
!DEC$ATTRIBUTES DLLEXPORT :: H5F_LIBVER_EARLIEST_F
!DEC$ATTRIBUTES DLLEXPORT :: H5F_LIBVER_LATEST_F
!DEC$ATTRIBUTES DLLEXPORT :: H5F_UNLIMITED_F
+ !DEC$ATTRIBUTES DLLEXPORT :: H5F_LIBVER_ERROR_F
+ !DEC$ATTRIBUTES DLLEXPORT :: H5F_LIBVER_NBOUNDS_F
+ !DEC$ATTRIBUTES DLLEXPORT :: H5F_LIBVER_V18_F
+ !DEC$ATTRIBUTES DLLEXPORT :: H5F_LIBVER_V110_F
+ !DEC$ATTRIBUTES DLLEXPORT :: H5F_LIBVER_V112_F
+ !DEC$ATTRIBUTES DLLEXPORT :: H5F_LIBVER_V114_F
!DEC$endif
INTEGER :: H5F_ACC_RDWR_F
@@ -258,6 +264,12 @@ MODULE H5GLOBAL
INTEGER :: H5F_LIBVER_EARLIEST_F
INTEGER :: H5F_LIBVER_LATEST_F
INTEGER :: H5F_UNLIMITED_F
+ INTEGER :: H5F_LIBVER_ERROR_F
+ INTEGER :: H5F_LIBVER_NBOUNDS_F
+ INTEGER :: H5F_LIBVER_V18_F
+ INTEGER :: H5F_LIBVER_V110_F
+ INTEGER :: H5F_LIBVER_V112_F
+ INTEGER :: H5F_LIBVER_V114_F
!
! H5G flags declaration
!
diff --git a/fortran/src/H5f90proto.h b/fortran/src/H5f90proto.h
index e6f5dd4..fe616d3 100644
--- a/fortran/src/H5f90proto.h
+++ b/fortran/src/H5f90proto.h
@@ -454,7 +454,6 @@ H5_FCDLL int_f h5pset_attr_creation_order_c(hid_t_f *ocpl_id, int_f *crt_order_f
H5_FCDLL int_f h5pset_shared_mesg_nindexes_c(hid_t_f *plist_id, int_f *nindexes );
H5_FCDLL int_f h5pset_shared_mesg_index_c(hid_t_f *fcpl_id, int_f *index_num, int_f *mesg_type_flags, int_f *min_mesg_size);
H5_FCDLL int_f h5pget_attr_creation_order_c(hid_t_f *ocpl_id, int_f *crt_order_flags);
-H5_FCDLL int_f h5pset_libver_bounds_c(hid_t_f *fapl_id, int_f *low, int_f *high);
H5_FCDLL int_f h5pset_link_creation_order_c(hid_t_f *gcpl_id, int_f *crt_order_flags);
H5_FCDLL int_f h5pget_link_phase_change_c(hid_t_f *gcpl_id, int_f *max_compact, int_f *min_dense );
H5_FCDLL int_f h5pget_obj_track_times_c(hid_t_f *plist_id, int_f *flag);
diff --git a/fortran/src/hdf5_fortrandll.def.in b/fortran/src/hdf5_fortrandll.def.in
index c792232..9c69e5a 100644
--- a/fortran/src/hdf5_fortrandll.def.in
+++ b/fortran/src/hdf5_fortrandll.def.in
@@ -288,6 +288,7 @@ H5P_mp_H5PSET_ATTR_CREATION_ORDER_F
H5P_mp_H5PSET_SHARED_MESG_NINDEXES_F
H5P_mp_H5PSET_SHARED_MESG_INDEX_F
H5P_mp_H5PGET_ATTR_CREATION_ORDER_F
+H5P_mp_H5PGET_LIBVER_BOUNDS_F
H5P_mp_H5PSET_LIBVER_BOUNDS_F
H5P_mp_H5PSET_LINK_CREATION_ORDER_F
H5P_mp_H5PGET_LINK_PHASE_CHANGE_F
diff --git a/fortran/test/tH5P_F03.F90 b/fortran/test/tH5P_F03.F90
index b44540b..083c312 100644
--- a/fortran/test/tH5P_F03.F90
+++ b/fortran/test/tH5P_F03.F90
@@ -112,6 +112,7 @@ SUBROUTINE test_create(total_error)
INTEGER :: ifill
REAL :: rfill
REAL(KIND=dp) :: dpfill
+ INTEGER :: low, high
!
! * Create a file.
@@ -205,11 +206,48 @@ SUBROUTINE test_create(total_error)
CALL check("h5fclose_f", error, total_error)
! Open the file and get the dataset fill value from each dataset
- CALL H5Pcreate_f(H5P_FILE_ACCESS_F, fapl, error)
- CALL check("H5Pcreate_f",error, total_error)
+ CALL h5pcreate_f(H5P_FILE_ACCESS_F, fapl, error)
+ CALL check("h5pcreate_f",error, total_error)
+
+ CALL h5pset_libver_bounds_f(fapl, H5F_LIBVER_V18_F, H5F_LIBVER_V18_F, error)
+ CALL check("h5pset_libver_bounds_f",error, total_error)
+ CALL h5pget_libver_bounds_f(fapl, low, high, error)
+ CALL check("h5pget_libver_bounds_f",error, total_error)
+ CALL VERIFY("***ERROR: Returned wrong low libver_bounds", low, H5F_LIBVER_V18_F, total_error)
+ CALL VERIFY("***ERROR: Returned wrong high libver_bounds", high, H5F_LIBVER_V18_F, total_error)
+
+ CALL h5pset_libver_bounds_f(fapl, H5F_LIBVER_V18_F, H5F_LIBVER_V110_F, error)
+ CALL check("h5pset_libver_bounds_f",error, total_error)
+ CALL h5pget_libver_bounds_f(fapl, low, high, error)
+ CALL check("h5pget_libver_bounds_f",error, total_error)
+ CALL VERIFY("***ERROR: Returned wrong low libver_bounds", low, H5F_LIBVER_V18_F, total_error)
+ CALL VERIFY("***ERROR: Returned wrong high libver_bounds", high, H5F_LIBVER_V110_F, total_error)
+
+ CALL h5pset_libver_bounds_f(fapl, H5F_LIBVER_V112_F, H5F_LIBVER_V112_F, error)
+ CALL check("h5pset_libver_bounds_f",error, total_error)
+ CALL h5pget_libver_bounds_f(fapl, low, high, error)
+ CALL check("h5pget_libver_bounds_f",error, total_error)
+ CALL VERIFY("***ERROR: Returned wrong low libver_bounds", low, H5F_LIBVER_V112_F, total_error)
+ CALL VERIFY("***ERROR: Returned wrong high libver_bounds", high, H5F_LIBVER_V112_F, total_error)
+
+ CALL h5pset_libver_bounds_f(fapl, H5F_LIBVER_V114_F, H5F_LIBVER_V114_F, error)
+ CALL check("h5pset_libver_bounds_f",error, total_error)
+ CALL h5pget_libver_bounds_f(fapl, low, high, error)
+ CALL check("h5pget_libver_bounds_f",error, total_error)
+ CALL VERIFY("***ERROR: Returned wrong low libver_bounds", low, H5F_LIBVER_V114_F, total_error)
+ CALL VERIFY("***ERROR: Returned wrong high libver_bounds", high, H5F_LIBVER_V114_F, total_error)
CALL H5Pset_libver_bounds_f(fapl, H5F_LIBVER_LATEST_F, H5F_LIBVER_LATEST_F, error)
CALL check("H5Pset_libver_bounds_f",error, total_error)
+ CALL h5pget_libver_bounds_f(fapl, low, high, error)
+ CALL check("h5pget_libver_bounds_f",error, total_error)
+ CALL VERIFY("***ERROR: Returned wrong low libver_bounds", low, H5F_LIBVER_LATEST_F, total_error)
+ CALL VERIFY("***ERROR: Returned wrong high libver_bounds", high, H5F_LIBVER_LATEST_F, total_error)
+ IF(H5F_LIBVER_LATEST_F.GE.H5F_LIBVER_NBOUNDS_F)THEN
+ WRITE(*,'(A,I0,A,I0,A)') &
+ "***ERROR: H5F_LIBVER_LATEST_F (",H5F_LIBVER_LATEST_F,") .GE. H5F_LIBVER_NBOUNDS_F (",H5F_LIBVER_NBOUNDS_F,")"
+ total_error = total_error + 1
+ ENDIF
CALL h5fopen_f (FILENAME, H5F_ACC_RDONLY_F, file, error, fapl)
CALL check("h5fopen_f", error, total_error)
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 12a703d..a915059 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -78,9 +78,18 @@ New Features
(ADB - 2020/01/15, HDFFV-11001)
- - Added Clang sanitizers to CMake for analyzer support
-
- Added CMake code and files to execute the Clang sanitizers.
+ - Added Clang sanitizers to CMake for analyzer support if compiler is clang.
+
+ Added CMake code and files to execute the Clang sanitizers if
+ HDF5_ENABLE_SANITIZERS is enabled and the USE_SANITIZER option
+ is set to one of the following:
+ Address
+ Memory
+ MemoryWithOrigins
+ Undefined
+ Thread
+ Leak
+ 'Address;Undefined'
(ADB - 2019/12/12, TRILAB-135)
diff --git a/src/H5Aint.c b/src/H5Aint.c
index fc5ea34..1a74abe 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -224,7 +224,7 @@ H5A__create(const H5G_loc_t *loc, const char *attr_name, const H5T_t *type,
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set version of dataspace")
/* Copy the object header information */
- if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy_deep(&(attr->oloc), loc->oloc) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to copy entry")
/* Deep copy of the group hierarchy path */
@@ -390,7 +390,7 @@ H5A__open_common(const H5G_loc_t *loc, H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path")
/* Deep copy of the symbol table entry */
- if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy_deep(&(attr->oloc), loc->oloc) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
/* Deep copy of the group hier. path */
@@ -909,7 +909,7 @@ H5A__get_type(H5A_t *attr)
* reopen the type before returning it to the user. Make the type
* read-only.
*/
- if (NULL == (dt = H5T_copy(attr->shared->dt, H5T_COPY_REOPEN)))
+ if (NULL == (dt = H5T_copy_reopen(attr->shared->dt)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to copy datatype")
/* Mark any datatypes as being in memory now */
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 0d67fd0..1624f7b 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -1534,7 +1534,7 @@ H5D_open(const H5G_loc_t *loc, hid_t dapl_id)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Shallow copy (take ownership) of the object location object */
- if(H5O_loc_copy(&(dataset->oloc), loc->oloc, H5_COPY_SHALLOW) < 0)
+ if(H5O_loc_copy_shallow(&(dataset->oloc), loc->oloc) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, NULL, "can't copy object location")
/* Shallow copy (take ownership) of the group hier. path */
@@ -3881,7 +3881,7 @@ H5D__get_type(const H5D_t *dset)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to patch datatype's file pointer")
/* Copy the dataset's datatype */
- if(NULL == (dt = H5T_copy(dset->shared->type, H5T_COPY_REOPEN)))
+ if(NULL == (dt = H5T_copy_reopen(dset->shared->type)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy datatype")
/* Mark any datatypes as being in memory now */
diff --git a/src/H5FDs3comms.c b/src/H5FDs3comms.c
index f08e9d5..d9d4c88 100644
--- a/src/H5FDs3comms.c
+++ b/src/H5FDs3comms.c
@@ -1202,7 +1202,7 @@ H5FD_s3comms_s3r_open(const char *url,
if ((region != NULL && *region != '\0') ||
(id != NULL && *id != '\0') ||
- (signing_key != NULL && *signing_key != '\0'))
+ (signing_key != NULL))
{
/* if one exists, all three must exist
*/
@@ -1214,7 +1214,7 @@ H5FD_s3comms_s3r_open(const char *url,
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL,
"secret id cannot be null.\n");
}
- if (signing_key == NULL || signing_key[0] == '\0') {
+ if (signing_key == NULL) {
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL,
"signing key cannot be null.\n");
}
diff --git a/src/H5Fmount.c b/src/H5Fmount.c
index 13d95aa..5e6b899 100644
--- a/src/H5Fmount.c
+++ b/src/H5Fmount.c
@@ -766,7 +766,7 @@ H5F_traverse_mount(H5O_loc_t *oloc/*in,out*/)
HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "unable to free object location")
/* Copy the entry for the root group */
- if(H5O_loc_copy(oloc, mnt_oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy_deep(oloc, mnt_oloc) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location")
/* In case the shared root group info points to a different file handle
diff --git a/src/H5Gint.c b/src/H5Gint.c
index e0b8bd7..a3849a6 100644
--- a/src/H5Gint.c
+++ b/src/H5Gint.c
@@ -336,7 +336,7 @@ H5G_open(const H5G_loc_t *loc)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for group")
/* Shallow copy (take ownership) of the group location object */
- if(H5O_loc_copy(&(grp->oloc), loc->oloc, H5_COPY_SHALLOW) < 0)
+ if(H5O_loc_copy_shallow(&(grp->oloc), loc->oloc) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy object location")
if(H5G_name_copy(&(grp->path), loc->path, H5_COPY_SHALLOW) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy path")
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
index 15dbd79..1892182 100644
--- a/src/H5Gobj.c
+++ b/src/H5Gobj.c
@@ -738,7 +738,7 @@ H5G__obj_info(const H5O_loc_t *oloc, H5G_info_t *grp_info)
H5G_loc_reset(&grp_loc);
/* Deep copy (duplicate) of the group location object */
- if(H5O_loc_copy(&grp_oloc, (H5O_loc_t *)oloc, H5_COPY_DEEP) < 0) /* (Casting away const OK - QAK) */
+ if(H5O_loc_copy_deep(&grp_oloc, oloc) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy object location")
/* Open the group */
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c
index 7482e27..0f27880 100644
--- a/src/H5Gtraverse.c
+++ b/src/H5Gtraverse.c
@@ -132,7 +132,7 @@ H5G__traverse_slink_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc, const char H5_ATTR_UNU
} /* end if */
else {
/* Copy new location information for resolved object */
- H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP);
+ H5O_loc_copy_deep(udata->obj_loc->oloc, obj_loc->oloc);
/* Indicate that the object exists */
udata->exists = TRUE;
diff --git a/src/H5L.c b/src/H5L.c
index 0d5bc02..47e29c0 100644
--- a/src/H5L.c
+++ b/src/H5L.c
@@ -1910,7 +1910,7 @@ H5L__link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t H5_ATT
* copy and wipe out grp_loc)
*/
H5G_name_reset(&temp_path);
- if(H5O_loc_copy(&temp_oloc, grp_loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy_deep(&temp_oloc, grp_loc->oloc) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy object location")
temp_loc.oloc = &temp_oloc;
@@ -2695,7 +2695,7 @@ H5L__move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
* copy and wipe out grp_loc)
*/
H5G_name_reset(&temp_path);
- if(H5O_loc_copy(&temp_oloc, grp_loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy_deep(&temp_oloc, grp_loc->oloc) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy object location")
temp_loc.oloc = &temp_oloc;
diff --git a/src/H5Oint.c b/src/H5Oint.c
index d5a3a71..04220af 100644
--- a/src/H5Oint.c
+++ b/src/H5Oint.c
@@ -1913,27 +1913,19 @@ H5O_loc_reset(H5O_loc_t *loc)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5O_loc_reset() */
-
+
/*-------------------------------------------------------------------------
* Function: H5O_loc_copy
*
- * Purpose: Copy object location information
+ * Purpose: Copy object location information, according to the depth.
*
* Return: Success: Non-negative
- * Failure: Negative
+ * Failure: Negative
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* Monday, September 19, 2005
*
- * Notes: 'depth' parameter determines how much of the group entry
- * structure we want to copy. The values are:
- * H5_COPY_SHALLOW - Copy all the field values from the source
- * to the destination, but not copying objects pointed to.
- * (Destination "takes ownership" of objects pointed to)
- * H5_COPY_DEEP - Copy all the fields from the source to
- * the destination, deep copying objects pointed to.
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1946,25 +1938,88 @@ H5O_loc_copy(H5O_loc_t *dst, H5O_loc_t *src, H5_copy_depth_t depth)
HDassert(dst);
HDassert(depth == H5_COPY_SHALLOW || depth == H5_COPY_DEEP);
+ /* Invoke correct routine */
+ if(depth == H5_COPY_SHALLOW)
+ H5O_loc_copy_shallow(dst, src);
+ else
+ H5O_loc_copy_deep(dst, src);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_loc_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_loc_copy_shallow
+ *
+ * Purpose: Shallow copy object location information. Copies all the field
+ * values from the source to the destination, but not copying
+ * objects pointed to. (i.e. destination "takes ownership" of
+ * objects pointed to)
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_loc_copy_shallow(H5O_loc_t *dst, H5O_loc_t *src)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Check arguments */
+ HDassert(src);
+ HDassert(dst);
+
/* Copy the top level information */
H5MM_memcpy(dst, src, sizeof(H5O_loc_t));
- /* Deep copy the names */
- if(depth == H5_COPY_DEEP) {
- /* If the original entry was holding open the file, this one should
- * hold it open, too.
- */
- if(src->holding_file)
- H5F_INCR_NOPEN_OBJS(dst->file);
- }
- else if(depth == H5_COPY_SHALLOW) {
- H5O_loc_reset(src);
- }
+ /* Reset the source location, as the destination 'owns' it now */
+ H5O_loc_reset(src);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5O_loc_copy() */
+} /* end H5O_loc_copy_shallow() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_loc_copy_deep
+ *
+ * Purpose: Deep copy object location information. Copies all the fields
+ * from the source to the destination, deep copying objects
+ * pointed to.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_loc_copy_deep(H5O_loc_t *dst, const H5O_loc_t *src)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Check arguments */
+ HDassert(src);
+ HDassert(dst);
+
+ /* Copy the top level information */
+ H5MM_memcpy(dst, src, sizeof(H5O_loc_t));
+
+ /* If the original entry was holding open the file, this one should
+ * hold it open, too.
+ */
+ if(src->holding_file)
+ H5F_INCR_NOPEN_OBJS(dst->file);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_loc_copy_deep() */
+
/*-------------------------------------------------------------------------
* Function: H5O_loc_hold_file
*
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 52a72b2..ceaa96d 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -997,6 +997,8 @@ H5_DLL herr_t H5O_debug(H5F_t *f, haddr_t addr, FILE * stream, int indent,
/* These functions operate on object locations */
H5_DLL herr_t H5O_loc_reset(H5O_loc_t *loc);
H5_DLL herr_t H5O_loc_copy(H5O_loc_t *dst, H5O_loc_t *src, H5_copy_depth_t depth);
+H5_DLL herr_t H5O_loc_copy_shallow(H5O_loc_t *dst, H5O_loc_t *src);
+H5_DLL herr_t H5O_loc_copy_deep(H5O_loc_t *dst, const H5O_loc_t *src);
H5_DLL herr_t H5O_loc_hold_file(H5O_loc_t *loc);
H5_DLL herr_t H5O_loc_free(H5O_loc_t *loc);
H5_DLL H5O_loc_t *H5O_get_loc(hid_t id);
diff --git a/src/H5T.c b/src/H5T.c
index f1c2dbb..5d3c4a1 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -301,6 +301,9 @@
/* Local Typedefs */
/******************/
+/* Typedef for recursive const-correct datatype copying routines */
+typedef H5T_t *(*H5T_copy_func_t)(H5T_t *old_dt);
+
/********************/
/* Local Prototypes */
@@ -313,6 +316,11 @@ static herr_t H5T__set_size(H5T_t *dt, size_t size);
static herr_t H5T__close_cb(H5T_t *dt);
static H5T_path_t *H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_conv_func_t *conv);
static hbool_t H5T__detect_vlen_ref(const H5T_t *dt);
+static H5T_t *H5T__initiate_copy(const H5T_t *old_dt);
+static H5T_t *H5T__copy_transient(H5T_t *old_dt);
+static H5T_t *H5T__copy_all(H5T_t *old_dt);
+static herr_t H5T__complete_copy(H5T_t *new_dt, const H5T_t *old_dt,
+ H5T_shared_t *reopened_fo, hbool_t set_memory_type, H5T_copy_func_t copyfn);
/*****************************/
@@ -3304,132 +3312,152 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T__create() */
-
+
/*-------------------------------------------------------------------------
- * Function: H5T_copy
+ * Function: H5T__initiate_copy
*
- * Purpose: Copies datatype OLD_DT. The resulting data type is not
- * locked and is a transient type.
+ * Purpose: Allocates datatype structures, copies core fields, and initializes
+ * VOL fields.
*
* Return: Success: Pointer to a new copy of the OLD_DT argument.
- *
* Failure: NULL
*
- * Programmer: Robb Matzke
- * Thursday, December 4, 1997
+ * Note: Common code for both H5T_copy and H5T_copy_reopen, as part of
+ * the const-correct datatype copying routines.
+ *
+ * Programmer: David Young
+ * January 18, 2020
*
*-------------------------------------------------------------------------
*/
-H5T_t *
-H5T_copy(H5T_t *old_dt, H5T_copy_t method)
+static H5T_t *
+H5T__initiate_copy(const H5T_t *old_dt)
{
- H5T_t *new_dt = NULL, *tmp = NULL;
- H5T_shared_t *reopened_fo = NULL;
- unsigned i;
- char *s;
- H5T_t *ret_value = NULL; /* Return value */
-
- FUNC_ENTER_NOAPI(NULL)
+ H5T_t *new_dt = NULL; /* Copy of datatype */
+ H5T_t *ret_value = NULL; /* Return value */
- /* check args */
- HDassert(old_dt);
+ FUNC_ENTER_STATIC
/* Allocate space */
if(NULL == (new_dt = H5FL_MALLOC(H5T_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, NULL, "H5T_t memory allocation failed")
if(NULL == (new_dt->shared = H5FL_MALLOC(H5T_shared_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, NULL, "H5T_shared_t memory allocation failed")
- /* Copy shared information (entry information is copied last) */
+ /* Copy shared information */
*(new_dt->shared) = *(old_dt->shared);
- /* No VOL object */
+ /* Reset VOL fields */
new_dt->vol_obj = NULL;
-
- /* No owned VOL object */
new_dt->shared->owned_vol_obj = NULL;
- /* Check what sort of copy we are making */
- switch (method) {
- case H5T_COPY_TRANSIENT:
- /*
- * Return an unlocked transient type.
- */
- new_dt->shared->state = H5T_STATE_TRANSIENT;
- break;
+ /* Set return value */
+ ret_value = new_dt;
- case H5T_COPY_ALL:
- /*
- * Return a transient type (locked or unlocked) or an unopened named
- * type. Immutable transient types are degraded to read-only.
- */
- if(H5T_STATE_OPEN==old_dt->shared->state)
- new_dt->shared->state = H5T_STATE_NAMED;
- else if(H5T_STATE_IMMUTABLE==old_dt->shared->state)
- new_dt->shared->state = H5T_STATE_RDONLY;
- break;
+done:
+ if(ret_value == NULL)
+ if(new_dt) {
+ if(new_dt->shared)
+ new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
+ new_dt = H5FL_FREE(H5T_t, new_dt);
+ } /* end if */
- case H5T_COPY_REOPEN:
- /*
- * Return a transient type (locked or unlocked) or an opened named
- * type. Immutable transient types are degraded to read-only.
- */
- if(old_dt->sh_loc.type == H5O_SHARE_TYPE_COMMITTED) {
- /* Check if the object is already open */
- if(NULL == (reopened_fo = (H5T_shared_t *)H5FO_opened(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr))) {
- /* Clear any errors from H5FO_opened() */
- H5E_clear_stack(NULL);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__initiate_copy() */
- /* Open named datatype again */
- if(H5O_open(&old_dt->oloc) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to reopen named data type")
+
+/*-------------------------------------------------------------------------
+ * Function: H5T__copy_transient
+ *
+ * Purpose: Part of recursive framework for const-correct datatype copying.
+ *
+ * Return: Success: Pointer to a new copy of the OLD_DT argument.
+ * Failure: NULL
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5T_t *
+H5T__copy_transient(H5T_t *old_dt)
+{
+ H5T_t *ret_value = NULL; /* Return value */
- /* Insert opened named datatype into opened object list for the file */
- if(H5FO_insert(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr, new_dt->shared, FALSE)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, NULL, "can't insert datatype into list of open objects")
+ FUNC_ENTER_STATIC
- /* Increment object count for the object in the top file */
- if(H5FO_top_incr(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
+ /* Copy datatype, with correct method */
+ if(NULL == (ret_value = H5T_copy(old_dt, H5T_COPY_TRANSIENT)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't make 'transient' copy of datatype")
- new_dt->shared->fo_count = 1;
- } /* end if */
- else {
- /* The object is already open. Free the H5T_shared_t struct
- * we had been using and use the one that already exists.
- * Not terribly efficient. */
- new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
- new_dt->shared = reopened_fo;
-
- reopened_fo->fo_count++;
-
- /* Check if the object has been opened through the top file yet */
- if(H5FO_top_count(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) == 0) {
- /* Open the object through this top file */
- if(H5O_open(&old_dt->oloc) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open object header")
- } /* end if */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__copy_transient() */
- /* Increment object count for the object in the top file */
- if(H5FO_top_incr(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
- } /* end else */
- new_dt->shared->state = H5T_STATE_OPEN;
- }
- else if(H5T_STATE_IMMUTABLE == old_dt->shared->state) {
- new_dt->shared->state = H5T_STATE_RDONLY;
- }
- break;
- default:
- HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, NULL, "invalid copy method type")
- } /* end switch */
+
+/*-------------------------------------------------------------------------
+ * Function: H5T__copy_all
+ *
+ * Purpose: Part of recursive framework for const-correct datatype copying.
+ *
+ * Return: Success: Pointer to a new copy of the OLD_DT argument.
+ * Failure: NULL
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5T_t *
+H5T__copy_all(H5T_t *old_dt)
+{
+ H5T_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Copy datatype, with correct method */
+ if(NULL == (ret_value = H5T_copy(old_dt, H5T_COPY_ALL)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't make 'all' copy of datatype")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__copy_transient() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T__complete_copy
+ *
+ * Purpose: Completes copying datatype fields, as part of the recursive
+ * const-correct datatype copy routines.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Note: Common code for both H5T_copy and H5T_copy_reopen.
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5T__complete_copy(H5T_t *new_dt, const H5T_t *old_dt, H5T_shared_t *reopened_fo,
+ hbool_t set_memory_type, H5T_copy_func_t copyfn)
+{
+ H5T_t *tmp = NULL; /* Temporary copy of compound field's datatype */
+ char *s; /* Temporary copy of compound field name / enum value name */
+ unsigned i; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
/* Update fields in the new struct, if we aren't sharing an already opened
* committed datatype */
if(!reopened_fo) {
/* Copy parent information */
if(old_dt->shared->parent)
- new_dt->shared->parent = H5T_copy(old_dt->shared->parent, method);
+ if(NULL == (new_dt->shared->parent = (*copyfn)(old_dt->shared->parent)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy datatype's parent type")
switch(new_dt->shared->type) {
case H5T_COMPOUND:
@@ -3443,10 +3471,8 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
*/
/* Only malloc if space has been allocated for members - NAF */
if(new_dt->shared->u.compnd.nalloc > 0) {
- new_dt->shared->u.compnd.memb =
- (H5T_cmemb_t *)H5MM_malloc(new_dt->shared->u.compnd.nalloc * sizeof(H5T_cmemb_t));
- if (NULL == new_dt->shared->u.compnd.memb)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(NULL == (new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc * sizeof(H5T_cmemb_t))))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "memory allocation failed")
H5MM_memcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb,
new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t));
@@ -3456,15 +3482,17 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
unsigned j;
int old_match;
- s = new_dt->shared->u.compnd.memb[i].name;
- new_dt->shared->u.compnd.memb[i].name = H5MM_xstrdup(s);
- tmp = H5T_copy (old_dt->shared->u.compnd.memb[i].type, method);
+ if(NULL == (s = H5MM_xstrdup(new_dt->shared->u.compnd.memb[i].name)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy string for compound field's name")
+ new_dt->shared->u.compnd.memb[i].name = s;
+ if(NULL == (tmp = (*copyfn)(old_dt->shared->u.compnd.memb[i].type)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy compound field's datatype")
new_dt->shared->u.compnd.memb[i].type = tmp;
HDassert(tmp != NULL);
/* Range check against compound member's offset */
- if ((accum_change < 0) && ((ssize_t) new_dt->shared->u.compnd.memb[i].offset < accum_change))
- HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, NULL, "invalid field size in datatype")
+ if((accum_change < 0) && ((ssize_t) new_dt->shared->u.compnd.memb[i].offset < accum_change))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid field size in datatype")
/* Apply the accumulated size change to the offset of the field */
new_dt->shared->u.compnd.memb[i].offset += (size_t) accum_change;
@@ -3479,7 +3507,7 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
/* check if we couldn't find a match */
if(old_match < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "fields in datatype corrupted")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "fields in datatype corrupted")
} /* end if */
else
old_match = (int) i;
@@ -3494,8 +3522,8 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
} /* end for */
/* Range check against datatype size */
- if ((accum_change < 0) && ((ssize_t) new_dt->shared->size < accum_change))
- HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, NULL, "invalid field size in datatype")
+ if((accum_change < 0) && ((ssize_t) new_dt->shared->size < accum_change))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "invalid field size in datatype")
/* Apply the accumulated size change to the size of the compound struct */
new_dt->shared->size += (size_t) accum_change;
@@ -3508,27 +3536,25 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
* of each new member with copied values. That is, H5T_copy() is a
* deep copy.
*/
- new_dt->shared->u.enumer.name =
- (char **)H5MM_malloc(new_dt->shared->u.enumer.nalloc * sizeof(char*));
- new_dt->shared->u.enumer.value =
- (uint8_t *)H5MM_malloc(new_dt->shared->u.enumer.nalloc * new_dt->shared->size);
- if(NULL == new_dt->shared->u.enumer.value)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(NULL == (new_dt->shared->u.enumer.name = H5MM_malloc(new_dt->shared->u.enumer.nalloc * sizeof(char*))))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "enam name array memory allocation failed")
+ if(NULL == (new_dt->shared->u.enumer.value = H5MM_malloc(new_dt->shared->u.enumer.nalloc * new_dt->shared->size)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "enam value array memory allocation failed")
H5MM_memcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value,
new_dt->shared->u.enumer.nmembs * new_dt->shared->size);
for(i = 0; i < new_dt->shared->u.enumer.nmembs; i++) {
- s = old_dt->shared->u.enumer.name[i];
- new_dt->shared->u.enumer.name[i] = H5MM_xstrdup(s);
+ if(NULL == (s = H5MM_xstrdup(old_dt->shared->u.enumer.name[i])))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy string for enum value's name")
+ new_dt->shared->u.enumer.name[i] = s;
} /* end for */
break;
case H5T_VLEN:
case H5T_REFERENCE:
- if(method == H5T_COPY_TRANSIENT || method == H5T_COPY_REOPEN) {
+ if(set_memory_type)
/* H5T_copy converts any type into a memory type */
if(H5T_set_loc(new_dt, NULL, H5T_LOC_MEMORY) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location")
- } /* end if */
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
break;
case H5T_OPAQUE:
@@ -3540,7 +3566,7 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
case H5T_ARRAY:
/* Re-compute the array's size, in case it's base type changed size */
- new_dt->shared->size=new_dt->shared->u.array.nelem*new_dt->shared->parent->shared->size;
+ new_dt->shared->size = new_dt->shared->u.array.nelem * new_dt->shared->parent->shared->size;
break;
case H5T_NO_CLASS:
@@ -3559,15 +3585,15 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
* type and the new type is also named.
*/
if(H5O_loc_reset(&new_dt->oloc) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, NULL, "unable to initialize location")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, FAIL, "unable to initialize location")
if(H5G_name_reset(&new_dt->path) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to reset path")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to reset path")
if(new_dt->shared->state == H5T_STATE_NAMED || new_dt->shared->state == H5T_STATE_OPEN) {
- if(H5O_loc_copy(&(new_dt->oloc), &(old_dt->oloc), H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy object location")
+ if(H5O_loc_copy_deep(&(new_dt->oloc), &(old_dt->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy object location")
if(H5G_name_copy(&(new_dt->path), &(old_dt->path), H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to copy path")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to copy path")
} /* end if */
/* Copy shared location information if the new type is named or if it is
@@ -3576,28 +3602,194 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method)
if((old_dt->sh_loc.type == H5O_SHARE_TYPE_SOHM || old_dt->sh_loc.type == H5O_SHARE_TYPE_HERE) ||
new_dt->shared->state == H5T_STATE_NAMED || new_dt->shared->state == H5T_STATE_OPEN) {
if(H5O_set_shared(&(new_dt->sh_loc), &(old_dt->sh_loc)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy shared information")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "can't copy shared information")
} /* end if */
else
/* Reset shared component info */
H5O_msg_reset_share(H5O_DTYPE_ID, new_dt);
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__complete_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_copy
+ *
+ * Purpose: Copies datatype OLD_DT. The resulting data type is not
+ * locked and is a transient type.
+ *
+ * Return: Success: Pointer to a new copy of the OLD_DT argument.
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_t *
+H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
+{
+ H5T_t *new_dt = NULL; /* New datatype */
+ H5T_copy_func_t copyfn; /* Pointer to correct copy routine */
+ H5T_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ /* check args */
+ HDassert(old_dt);
+
+ /* Allocate and copy core datatype information */
+ if(NULL == (new_dt = H5T__initiate_copy(old_dt)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy core datatype info")
+
+ /* Check what sort of copy we are making */
+ switch (method) {
+ case H5T_COPY_TRANSIENT:
+ /*
+ * Return an unlocked transient type.
+ */
+ new_dt->shared->state = H5T_STATE_TRANSIENT;
+ copyfn = H5T__copy_transient;
+ break;
+
+ case H5T_COPY_ALL:
+ /*
+ * Return a transient type (locked or unlocked) or an unopened named
+ * type. Immutable transient types are degraded to read-only.
+ */
+ if(H5T_STATE_OPEN==old_dt->shared->state)
+ new_dt->shared->state = H5T_STATE_NAMED;
+ else if(H5T_STATE_IMMUTABLE==old_dt->shared->state)
+ new_dt->shared->state = H5T_STATE_RDONLY;
+ copyfn = H5T__copy_all;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, NULL, "invalid copy method type")
+ } /* end switch */
+
+ /* Finish making the copy of the datatype */
+ if(H5T__complete_copy(new_dt, old_dt, NULL, (method == H5T_COPY_TRANSIENT), copyfn) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "can't complete datatype initialization")
+
/* Set return value */
ret_value = new_dt;
done:
- if(ret_value == NULL) {
+ if(ret_value == NULL)
if(new_dt) {
- if(new_dt->shared)
- new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
+ HDassert(new_dt->shared);
+ new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
new_dt = H5FL_FREE(H5T_t, new_dt);
} /* end if */
- } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_copy() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_copy_reopen
+ *
+ * Purpose: Copy a datatype, possibly reopening a named datatype, as part
+ * the const-correct datatype copying routines.
+ *
+ * Return: Success: Pointer to a new copy of the OLD_DT argument.
+ * Failure: NULL
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_t *
+H5T_copy_reopen(H5T_t *old_dt)
+{
+ H5T_t *new_dt = NULL; /* New datatype */
+ H5T_shared_t *reopened_fo = NULL; /* Pointer to reopened existing named datatype */
+ H5T_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ /* check args */
+ HDassert(old_dt);
+
+ /* Allocate and copy core datatype information */
+ if(NULL == (new_dt = H5T__initiate_copy(old_dt)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy core datatype info")
+
+ /*
+ * Return a transient type (locked or unlocked) or an opened named
+ * type. Immutable transient types are degraded to read-only.
+ */
+ if(old_dt->sh_loc.type == H5O_SHARE_TYPE_COMMITTED) {
+ /* Check if the object is already open */
+ if(NULL == (reopened_fo = (H5T_shared_t *)H5FO_opened(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr))) {
+ /* Clear any errors from H5FO_opened() */
+ H5E_clear_stack(NULL);
+
+ /* Open named datatype again */
+ if(H5O_open(&old_dt->oloc) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to reopen named data type")
+
+ /* Insert opened named datatype into opened object list for the file */
+ if(H5FO_insert(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr, new_dt->shared, FALSE)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, NULL, "can't insert datatype into list of open objects")
+
+ /* Increment object count for the object in the top file */
+ if(H5FO_top_incr(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
+
+ new_dt->shared->fo_count = 1;
+ } /* end if */
+ else {
+ /* The object is already open. Free the H5T_shared_t struct
+ * we had been using and use the one that already exists.
+ * Not terribly efficient. */
+ new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
+ new_dt->shared = reopened_fo;
+
+ reopened_fo->fo_count++;
+
+ /* Check if the object has been opened through the top file yet */
+ if(H5FO_top_count(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) == 0) {
+ /* Open the object through this top file */
+ if(H5O_open(&old_dt->oloc) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open object header")
+ } /* end if */
+
+ /* Increment object count for the object in the top file */
+ if(H5FO_top_incr(old_dt->sh_loc.file, old_dt->sh_loc.u.loc.oh_addr) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
+ } /* end else */
+
+ /* Set state for new datatype */
+ new_dt->shared->state = H5T_STATE_OPEN;
+ } /* end if */
+ else
+ /* Downgrade immutable datatypes to read-only */
+ if(H5T_STATE_IMMUTABLE == old_dt->shared->state)
+ new_dt->shared->state = H5T_STATE_RDONLY;
+
+ /* Finish making the copy of the datatype */
+ if(H5T__complete_copy(new_dt, old_dt, reopened_fo, TRUE, H5T_copy_reopen) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "can't complete datatype initialization")
+
+ /* Set return value */
+ ret_value = new_dt;
+
+done:
+ if(ret_value == NULL)
+ if(new_dt) {
+ HDassert(new_dt->shared);
+ new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared);
+ new_dt = H5FL_FREE(H5T_t, new_dt);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_copy_reopen() */
+
/*-------------------------------------------------------------------------
* Function: H5T_lock
*
diff --git a/src/H5TS.c b/src/H5TS.c
index 7a801e2..9503e05 100644
--- a/src/H5TS.c
+++ b/src/H5TS.c
@@ -639,13 +639,4 @@ H5TS_create_thread(void *(*func)(void *), H5TS_attr_t *attr, void *udata)
} /* H5TS_create_thread */
-#else /* H5_HAVE_THREADSAFE */
-
-uint64_t
-H5TS_thread_id(void)
-{
- return 0;
-}
-
#endif /* H5_HAVE_THREADSAFE */
-
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index 1b922d5..7d26af3 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -446,7 +446,7 @@ H5T__commit(H5F_t *file, H5T_t *type, hid_t tcpl_id)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message")
/* Copy the new object header's location into the datatype, taking ownership of it */
- if(H5O_loc_copy(&(type->oloc), &temp_oloc, H5_COPY_SHALLOW) < 0)
+ if(H5O_loc_copy_shallow(&(type->oloc), &temp_oloc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype location")
if(H5G_name_copy(&(type->path), &temp_path, H5_COPY_SHALLOW) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype location")
@@ -943,7 +943,7 @@ H5T_open(const H5G_loc_t *loc)
#endif /* H5_USING_MEMCHECKER */
/* Shallow copy (take ownership) of the object location object */
- if(H5O_loc_copy(&dt->oloc, loc->oloc, H5_COPY_SHALLOW) < 0)
+ if(H5O_loc_copy_shallow(&dt->oloc, loc->oloc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy object location")
/* Shallow copy (take ownership) of the group hier. path */
@@ -1033,7 +1033,7 @@ H5T__open_oid(const H5G_loc_t *loc)
dt->shared->state = H5T_STATE_OPEN;
/* Shallow copy (take ownership) of the object location object */
- if(H5O_loc_copy(&dt->oloc, loc->oloc, H5_COPY_SHALLOW) < 0)
+ if(H5O_loc_copy_shallow(&dt->oloc, loc->oloc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy object location")
/* Shallow copy (take ownership) of the group hier. path */
diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c
index d4f1008..f4a9e04 100644
--- a/src/H5Tcompound.c
+++ b/src/H5Tcompound.c
@@ -51,8 +51,9 @@
/********************/
/* Local Prototypes */
/********************/
-static herr_t H5T_pack(const H5T_t *dt);
-static htri_t H5T_is_packed(const H5T_t *dt);
+static herr_t H5T__pack(const H5T_t *dt);
+static htri_t H5T__is_packed(const H5T_t *dt);
+static H5T_t *H5T__reopen_member_type(const H5T_t *dt, unsigned membno);
/*********************/
@@ -226,7 +227,7 @@ H5Tget_member_type(hid_t type_id, unsigned membno)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid member number")
/* Retrieve the datatype for the member */
- if(NULL == (memb_dt = H5T_get_member_type(dt, membno, H5T_COPY_REOPEN)))
+ if(NULL == (memb_dt = H5T__reopen_member_type(dt, membno)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5I_INVALID_HID, "unable to retrieve member type")
/* Get an ID for the datatype */
@@ -245,8 +246,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5T_get_member_type
*
- * Purpose: Private function for H5Tget_member_type. Returns the data
- * type of the specified member.
+ * Purpose: Returns a copy of the data type of the specified member.
*
* Return: Success: A copy of the member datatype;
* modifying the returned datatype does not
@@ -260,18 +260,19 @@ done:
*-------------------------------------------------------------------------
*/
H5T_t *
-H5T_get_member_type(const H5T_t *dt, unsigned membno, H5T_copy_t method)
+H5T_get_member_type(const H5T_t *dt, unsigned membno)
{
H5T_t *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI(NULL)
+ /* Sanity checks */
HDassert(dt);
HDassert(membno < dt->shared->u.compnd.nmembs);
- /* Copy datatype into an atom */
- if(NULL == (ret_value = H5T_copy(dt->shared->u.compnd.memb[membno].type, method)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy member datatype")
+ /* Copy datatype */
+ if(NULL == (ret_value = H5T_copy(dt->shared->u.compnd.memb[membno].type, H5T_COPY_TRANSIENT)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to copy member datatype")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -279,6 +280,43 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5T__reopen_member_type
+ *
+ * Purpose: Private function for H5Tget_member_type. Returns a re-opened
+ * copy of the data type of the specified member.
+ *
+ * Return: Success: A copy of the member datatype;
+ * modifying the returned datatype does not
+ * modify the member type.
+ *
+ * Failure: NULL
+ *
+ * Programmer: David Young
+ * January 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5T_t *
+H5T__reopen_member_type(const H5T_t *dt, unsigned membno)
+{
+ H5T_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(dt);
+ HDassert(membno < dt->shared->u.compnd.nmembs);
+
+ /* Copy datatype, possibly re-opening it */
+ if(NULL == (ret_value = H5T_copy_reopen(dt->shared->u.compnd.memb[membno].type)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to reopen member datatype")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__reopen_member_type() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5T__get_member_size
*
* Purpose: Returns the size of the specified member.
@@ -387,7 +425,7 @@ H5Tpack(hid_t type_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound datatype")
/* Pack */
- if(H5T_pack(dt) < 0)
+ if(H5T__pack(dt) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack compound datatype")
done:
@@ -493,7 +531,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5T_pack
+ * Function: H5T__pack
*
* Purpose: Recursively packs a compound datatype by removing padding
* bytes. This is done in place (that is, destructively).
@@ -506,17 +544,17 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5T_pack(const H5T_t *dt)
+H5T__pack(const H5T_t *dt)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_STATIC
HDassert(dt);
if(H5T_detect_class(dt, H5T_COMPOUND, FALSE) > 0) {
/* If datatype has been packed, skip packing it and indicate success */
- if(TRUE == H5T_is_packed(dt))
+ if(TRUE == H5T__is_packed(dt))
HGOTO_DONE(SUCCEED)
/* Check for packing unmodifiable datatype */
@@ -524,7 +562,7 @@ H5T_pack(const H5T_t *dt)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is read-only")
if(dt->shared->parent) {
- if (H5T_pack(dt->shared->parent) < 0)
+ if(H5T__pack(dt->shared->parent) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack parent of datatype")
/* Adjust size of datatype appropriately */
@@ -539,7 +577,7 @@ H5T_pack(const H5T_t *dt)
/* Recursively pack the members */
for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
- if(H5T_pack(dt->shared->u.compnd.memb[i].type) < 0)
+ if(H5T__pack(dt->shared->u.compnd.memb[i].type) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to pack part of a compound datatype")
/* Update the member size */
@@ -552,7 +590,7 @@ H5T_pack(const H5T_t *dt)
for(i = 0, offset = 0; i < dt->shared->u.compnd.nmembs; i++) {
dt->shared->u.compnd.memb[i].offset = offset;
offset += dt->shared->u.compnd.memb[i].size;
- }
+ } /* end for */
/* Change total size */
dt->shared->size = MAX(1, offset);
@@ -564,11 +602,11 @@ H5T_pack(const H5T_t *dt)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5T_pack() */
+} /* end H5T__pack() */
/*-------------------------------------------------------------------------
- * Function: H5T_is_packed
+ * Function: H5T__is_packed
*
* Purpose: Checks whether a datatype which is compound (or has compound
* components) is packed.
@@ -583,11 +621,11 @@ done:
*-------------------------------------------------------------------------
*/
static htri_t
-H5T_is_packed(const H5T_t *dt)
+H5T__is_packed(const H5T_t *dt)
{
htri_t ret_value = TRUE; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_STATIC_NOERR
HDassert(dt);
@@ -596,12 +634,11 @@ H5T_is_packed(const H5T_t *dt)
dt = dt->shared->parent;
/* If this is a compound datatype, check if it is packed */
- if(dt->shared->type == H5T_COMPOUND) {
+ if(dt->shared->type == H5T_COMPOUND)
ret_value = (htri_t)(dt->shared->u.compnd.packed);
- } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5T_is_packed() */
+} /* end H5T__is_packed() */
/*-------------------------------------------------------------------------
@@ -638,7 +675,7 @@ H5T__update_packed(const H5T_t *dt)
/* Now check if all members are packed */
for(i = 0; i < dt->shared->u.compnd.nmembs; i++)
- if(!H5T_is_packed(dt->shared->u.compnd.memb[i].type)) {
+ if(!H5T__is_packed(dt->shared->u.compnd.memb[i].type)) {
dt->shared->u.compnd.packed = FALSE;
break;
} /* end if */
diff --git a/src/H5Tnative.c b/src/H5Tnative.c
index 8859102..357bb08 100644
--- a/src/H5Tnative.c
+++ b/src/H5Tnative.c
@@ -272,7 +272,7 @@ H5T__get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_ali
/* Construct child compound type and retrieve a list of their IDs, offsets, total size, and alignment for compound type. */
for(u = 0; u < nmemb; u++) {
- if(NULL == (memb_type = H5T_get_member_type(dtype, u, H5T_COPY_TRANSIENT)))
+ if(NULL == (memb_type = H5T_get_member_type(dtype, u)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member type retrieval failed")
if(NULL == (comp_mname[u] = H5T__get_member_name(dtype, u)))
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index d8e98af..e05bb4e 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -59,7 +59,6 @@ struct H5S_t;
typedef enum H5T_copy_t {
H5T_COPY_TRANSIENT,
H5T_COPY_ALL,
- H5T_COPY_REOPEN
} H5T_copy_t;
/* Location of datatype information */
@@ -109,7 +108,8 @@ H5_DLLVAR H5T_order_t H5T_native_order_g;
/* Private functions */
H5_DLL herr_t H5T_init(void);
-H5_DLL H5T_t *H5T_copy(H5T_t *old_dt, H5T_copy_t method);
+H5_DLL H5T_t *H5T_copy(const H5T_t *old_dt, H5T_copy_t method);
+H5_DLL H5T_t *H5T_copy_reopen(H5T_t *old_dt);
H5_DLL herr_t H5T_lock(H5T_t *dt, hbool_t immutable);
H5_DLL herr_t H5T_close(H5T_t *dt);
H5_DLL herr_t H5T_close_real(H5T_t *dt);
@@ -164,7 +164,7 @@ H5_DLL herr_t H5T_update_shared(H5T_t *type);
/* Field functions (for both compound & enumerated types) */
H5_DLL int H5T_get_nmembers(const H5T_t *dt);
-H5_DLL H5T_t *H5T_get_member_type(const H5T_t *dt, unsigned membno, H5T_copy_t method);
+H5_DLL H5T_t *H5T_get_member_type(const H5T_t *dt, unsigned membno);
H5_DLL size_t H5T_get_member_offset(const H5T_t *dt, unsigned membno);
/* Atomic functions */
diff --git a/src/H5Znbit.c b/src/H5Znbit.c
index fe0041c..2f79725 100644
--- a/src/H5Znbit.c
+++ b/src/H5Znbit.c
@@ -338,7 +338,7 @@ H5Z_calc_parms_compound(const H5T_t *type, size_t *cd_values_actual_nparms)
H5T_class_t dtype_member_class; /* Compound datatype's member datatype's class */
/* Get member datatype */
- if(NULL == (dtype_member = H5T_get_member_type(type, u, H5T_COPY_TRANSIENT)))
+ if(NULL == (dtype_member = H5T_get_member_type(type, u)))
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad member datatype")
/* Get member datatype's class */
@@ -695,7 +695,7 @@ H5Z_set_parms_compound(const H5T_t *type, unsigned *cd_values_index,
/* For each member, set parameters */
for(u = 0; u < nmembers; u++) {
/* Get member datatype */
- if(NULL == (dtype_member = H5T_get_member_type(type, u, H5T_COPY_TRANSIENT)))
+ if(NULL == (dtype_member = H5T_get_member_type(type, u)))
HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "bad member datatype")
/* Get member datatype's class */
diff --git a/src/H5private.h b/src/H5private.h
index a132ed3..3759446 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -1922,12 +1922,11 @@ H5_DLL double H5_trace(const double *calltime, const char *func, const char *typ
/* global library version information string */
extern char H5_lib_vers_info_g[];
+#include "H5TSprivate.h"
+
/* Lock headers */
#ifdef H5_HAVE_THREADSAFE
-/* Include required thread-safety header */
-#include "H5TSprivate.h"
-
/* replacement structure for original global variable */
typedef struct H5_api_struct {
H5TS_mutex_t init_lock; /* API entrance mutex */
diff --git a/src/H5public.h b/src/H5public.h
index 86a1fbb..3312cf4 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -51,7 +51,45 @@
# endif
#endif
#ifdef H5_HAVE_INTTYPES_H
-# include <inttypes.h> /* For uint64_t on some platforms */
+# include <inttypes.h> /* C99/POSIX.1 header for uint64_t, PRIu64 */
+#else /* H5_HAVE_INTTYPES_H */
+/* The following definitions should be suitable for 64-bit Windows, which is
+ * LLP64, and for 32-bit Windows, which is ILP32. Those are the only
+ * platforms where <inttypes.h> is likely to be missing. VS2015 and later
+ * *may* provide these definitions.
+ */
+#ifdef _WIN64
+# define PRIdPTR "lld"
+# define PRIoPTR "llo"
+# define PRIuPTR "llu"
+# define PRIxPTR "llx"
+#else /* _WIN64 */
+# define PRIdPTR "ld"
+# define PRIoPTR "lo"
+# define PRIuPTR "lu"
+# define PRIxPTR "lx"
+#endif /* _WIN64 */
+
+# define PRId8 "d"
+# define PRIo8 "o"
+# define PRIu8 "u"
+# define PRIx8 "x"
+# define PRId16 "d"
+# define PRIo16 "o"
+# define PRIu16 "u"
+# define PRIx16 "x"
+# define PRId32 "d"
+# define PRIo32 "o"
+# define PRIu32 "u"
+# define PRIx32 "x"
+# define PRId64 "lld"
+# define PRIo64 "llo"
+# define PRIu64 "llu"
+# define PRIx64 "llx"
+# define PRIdMAX "lld"
+# define PRIoMAX "llo"
+# define PRIuMAX "llu"
+# define PRIxMAX "llx"
#endif
#ifdef H5_HAVE_STDDEF_H
# include <stddef.h>
diff --git a/test/thread_id.c b/test/thread_id.c
index 9b289fa..af36625 100644
--- a/test/thread_id.c
+++ b/test/thread_id.c
@@ -18,7 +18,6 @@
* 3 No two threads share an ID during their lifetimes.
* 4 A thread's ID is available for reuse as soon as it is joined.
*/
-#include <err.h>
/*
* Include required headers. This file tests internal library functions,
@@ -26,11 +25,42 @@
*/
#include "testhdf5.h"
+static void my_errx(int, const char *, ...) H5_ATTR_FORMAT(printf, 2, 3);
+
+static void
+my_errx(int code, const char *fmt, ...)
+{
+ va_list ap;
+
+ (void)HDfprintf(stderr, "thread_id: ");
+ HDva_start(ap, fmt);
+ (void)HDvfprintf(stderr, fmt, ap);
+ HDva_end(ap);
+ (void)HDfputc('\n', stderr);
+ HDexit(code);
+}
+
#if defined(H5_HAVE_THREADSAFE) && !defined(H5_HAVE_WIN_THREADS)
+static void my_err(int, const char *, ...) H5_ATTR_FORMAT(printf, 2, 3);
+
+static void
+my_err(int code, const char *fmt, ...)
+{
+ va_list ap;
+ int errno_copy = errno;
+
+ (void)HDfprintf(stderr, "thread_id: ");
+ HDva_start(ap, fmt);
+ (void)HDvfprintf(stderr, fmt, ap);
+ HDva_end(ap);
+ (void)HDfprintf(stderr, ": %s\n", HDstrerror(errno_copy));
+ HDexit(code);
+}
+
#define threads_failure(_call, _result) do { \
- errx(EXIT_FAILURE, "%s.%d: " #_call ": %s", __func__, \
- __LINE__, strerror(_result)); \
+ my_errx(EXIT_FAILURE, "%s.%d: " #_call ": %s", __func__, \
+ __LINE__, HDstrerror(_result)); \
} while (false)
#define NTHREADS 5
@@ -52,13 +82,13 @@ atomic_printf(const char *fmt, ...)
va_end(ap);
if (nprinted == -1)
- err(EXIT_FAILURE, "%s.%d: vsnprintf", __func__, __LINE__);
+ my_err(EXIT_FAILURE, "%s.%d: vsnprintf", __func__, __LINE__);
else if (nprinted >= (ssize_t)sizeof(buf))
- errx(EXIT_FAILURE, "%s.%d: vsnprintf overflowed", __func__, __LINE__);
+ my_errx(EXIT_FAILURE, "%s.%d: vsnprintf overflowed", __func__, __LINE__);
nwritten = write(STDOUT_FILENO, buf, (size_t)nprinted);
if (nwritten < nprinted) {
- errx(EXIT_FAILURE, "%s.%d: write error or short write",
+ my_errx(EXIT_FAILURE, "%s.%d: write error or short write",
__func__, __LINE__);
}
}
@@ -114,7 +144,7 @@ main(void)
* mutex, etc.
*/
if (H5open() != SUCCEED)
- errx(EXIT_FAILURE, "%s.%d: H5open failed", __func__, __LINE__);
+ my_errx(EXIT_FAILURE, "%s.%d: H5open failed", __func__, __LINE__);
if ((rc = pthread_mutex_init(&used_lock, NULL)) == -1)
threads_failure(pthread_mutex_init, rc);
@@ -144,7 +174,7 @@ main(void)
for (i = 0; i < NTHREADS; i++) {
if (!used[i]) // access synchronized by thread create/join
- errx(EXIT_FAILURE, "thread ID %d did not run.", i + 1);
+ my_errx(EXIT_FAILURE, "thread ID %d did not run.", i + 1);
}
}
if ((rc = pthread_barrier_destroy(&barrier)) != 0)