diff --git a/.github/workflows/abi-report.yml b/.github/workflows/abi-report.yml index 05391bea329..52355524aff 100644 --- a/.github/workflows/abi-report.yml +++ b/.github/workflows/abi-report.yml @@ -178,4 +178,4 @@ jobs: with: name: abi-reports path: | - ${{ runner.workspace }}/buildabi/${{ inputs.file_base }}.html.abi.reports + ${{ runner.workspace }}/buildabi/${{ inputs.file_base }}.html.abi.reports.tar.gz diff --git a/.github/workflows/autotools.yml b/.github/workflows/autotools.yml index b75e75d639f..5be31f72300 100644 --- a/.github/workflows/autotools.yml +++ b/.github/workflows/autotools.yml @@ -83,4 +83,10 @@ jobs: with: build_mode: "production" + call-release-cmake-julia: + name: "Autotools Julia Workflows" + uses: ./.github/workflows/julia-auto.yml + with: + build_mode: "production" + \ No newline at end of file diff --git a/.github/workflows/cmake-bintest.yml b/.github/workflows/cmake-bintest.yml index 6c1506f9719..870592d8c27 100644 --- a/.github/workflows/cmake-bintest.yml +++ b/.github/workflows/cmake-bintest.yml @@ -129,12 +129,6 @@ jobs: run: | ls -l ${{ github.workspace }}/HDF_Group/HDF5 - - name: Set file base name (Linux) - id: set-file-base - run: | - FILE_NAME_BASE=$(echo "${{ inputs.file_base }}") - echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT - - name: List files for the space (Linux) run: | ls -l ${{ github.workspace }} @@ -187,12 +181,6 @@ jobs: run: | ls -l ${{ github.workspace }}/HDF_Group/HDF5 - - name: Set file base name (MacOS) - id: set-file-base - run: | - FILE_NAME_BASE=$(echo "${{ inputs.file_base }}") - echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT - - name: List files for the space (MacOS) run: | ls ${{ github.workspace }} diff --git a/.github/workflows/cmake-ctest.yml b/.github/workflows/cmake-ctest.yml index fdae778710c..fb698ace033 100644 --- a/.github/workflows/cmake-ctest.yml +++ b/.github/workflows/cmake-ctest.yml @@ -4,6 +4,11 @@ name: hdf5 dev ctest runs on: workflow_call: inputs: + snap_name: + description: 'The name in the source tarballs' + type: string + required: false + default: hdfsrc file_base: description: "The common base name of the source tarballs" required: true @@ -46,11 +51,11 @@ jobs: run: | FILE_NAME_BASE=$(echo "${{ inputs.file_base }}") echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT - if [[ '${{ inputs.use_environ }}' == 'snapshots' ]] + if [[ '${{ inputs.use_environ }}' == 'release' ]] then - SOURCE_NAME_BASE=$(echo "hdfsrc") + SOURCE_NAME_BASE=$(echo "${{ inputs.snap_name }}") else - SOURCE_NAME_BASE=$(echo "$FILE_NAME_BASE") + SOURCE_NAME_BASE=$(echo "hdfsrc") fi echo "SOURCE_BASE=$SOURCE_NAME_BASE" >> $GITHUB_OUTPUT shell: bash @@ -129,11 +134,11 @@ jobs: run: | FILE_NAME_BASE=$(echo "${{ inputs.file_base }}") echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT - if [[ '${{ inputs.use_environ }}' == 'snapshots' ]] + if [[ '${{ inputs.use_environ }}' == 'release' ]] then - SOURCE_NAME_BASE=$(echo "hdfsrc") + SOURCE_NAME_BASE=$(echo "${{ inputs.snap_name }}") else - SOURCE_NAME_BASE=$(echo "$FILE_NAME_BASE") + SOURCE_NAME_BASE=$(echo "hdfsrc") fi echo "SOURCE_BASE=$SOURCE_NAME_BASE" >> $GITHUB_OUTPUT @@ -181,7 +186,7 @@ jobs: cp ${{ runner.workspace }}/hdf5/build/${{ inputs.preset_name }}-GNUC/README.md ${{ runner.workspace }}/builddeb/hdf5 cp ${{ runner.workspace }}/hdf5/build/${{ inputs.preset_name }}-GNUC/*.deb ${{ runner.workspace }}/builddeb/hdf5 cd "${{ runner.workspace }}/builddeb" - tar -zcvf ${{ steps.set-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb hdf5 + tar -zcvf ${{ steps.set-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb.tar.gz hdf5 shell: bash - name: Publish rpm binary (Linux) @@ -194,7 +199,7 @@ jobs: cp ${{ runner.workspace }}/hdf5/build/${{ inputs.preset_name }}-GNUC/README.md ${{ runner.workspace }}/buildrpm/hdf5 cp ${{ runner.workspace }}/hdf5/build/${{ inputs.preset_name }}-GNUC/*.rpm ${{ runner.workspace }}/buildrpm/hdf5 cd "${{ runner.workspace }}/buildrpm" - tar -zcvf ${{ steps.set-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm hdf5 + tar -zcvf ${{ steps.set-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm.tar.gz hdf5 shell: bash - name: List files in the space (Linux) @@ -215,7 +220,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: deb-ubuntu-2204_gcc-binary - path: ${{ runner.workspace }}/builddeb/${{ steps.set-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb + path: ${{ runner.workspace }}/builddeb/${{ steps.set-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb.tar.gz if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn` # Save files created by ctest script @@ -223,7 +228,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: rpm-ubuntu-2204_gcc-binary - path: ${{ runner.workspace }}/buildrpm/${{ steps.set-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm + path: ${{ runner.workspace }}/buildrpm/${{ steps.set-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm.tar.gz if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn` # Save doxygen files created by ctest script @@ -253,11 +258,11 @@ jobs: run: | FILE_NAME_BASE=$(echo "${{ inputs.file_base }}") echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT - if [[ '${{ inputs.use_environ }}' == 'snapshots' ]] + if [[ '${{ inputs.use_environ }}' == 'release' ]] then - SOURCE_NAME_BASE=$(echo "hdfsrc") + SOURCE_NAME_BASE=$(echo "${{ inputs.snap_name }}") else - SOURCE_NAME_BASE=$(echo "$FILE_NAME_BASE") + SOURCE_NAME_BASE=$(echo "hdfsrc") fi echo "SOURCE_BASE=$SOURCE_NAME_BASE" >> $GITHUB_OUTPUT @@ -333,11 +338,11 @@ jobs: run: | FILE_NAME_BASE=$(echo "${{ inputs.file_base }}") echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT - if [[ '${{ inputs.use_environ }}' == 'snapshots' ]] + if [[ '${{ inputs.use_environ }}' == 'release' ]] then - SOURCE_NAME_BASE=$(echo "hdfsrc") + SOURCE_NAME_BASE=$(echo "${{ inputs.snap_name }}") else - SOURCE_NAME_BASE=$(echo "$FILE_NAME_BASE") + SOURCE_NAME_BASE=$(echo "hdfsrc") fi echo "SOURCE_BASE=$SOURCE_NAME_BASE" >> $GITHUB_OUTPUT @@ -413,11 +418,11 @@ jobs: run: | FILE_NAME_BASE=$(echo "${{ inputs.file_base }}") echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT - if [[ '${{ inputs.use_environ }}' == 'snapshots' ]] + if [[ '${{ inputs.use_environ }}' == 'release' ]] then - SOURCE_NAME_BASE=$(echo "hdfsrc") + SOURCE_NAME_BASE=$(echo "${{ inputs.snap_name }}") else - SOURCE_NAME_BASE=$(echo "$FILE_NAME_BASE") + SOURCE_NAME_BASE=$(echo "hdfsrc") fi echo "SOURCE_BASE=$SOURCE_NAME_BASE" >> $GITHUB_OUTPUT shell: bash @@ -502,11 +507,11 @@ jobs: run: | FILE_NAME_BASE=$(echo "${{ inputs.file_base }}") echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT - if [[ '${{ inputs.use_environ }}' == 'snapshots' ]] + if [[ '${{ inputs.use_environ }}' == 'release' ]] then - SOURCE_NAME_BASE=$(echo "hdfsrc") + SOURCE_NAME_BASE=$(echo "${{ inputs.snap_name }}") else - SOURCE_NAME_BASE=$(echo "$FILE_NAME_BASE") + SOURCE_NAME_BASE=$(echo "hdfsrc") fi echo "SOURCE_BASE=$SOURCE_NAME_BASE" >> $GITHUB_OUTPUT diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index c0077ce9207..4a52424c2b2 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -85,4 +85,10 @@ jobs: uses: ./.github/workflows/cygwin-cmake.yml with: build_mode: "Release" + + call-release-cmake-julia: + name: "CMake Julia Workflows" + uses: ./.github/workflows/julia-cmake.yml + with: + build_mode: "Release" \ No newline at end of file diff --git a/.github/workflows/cygwin-auto.yml b/.github/workflows/cygwin-auto.yml index 13e08eb8aca..5075fa28bba 100644 --- a/.github/workflows/cygwin-auto.yml +++ b/.github/workflows/cygwin-auto.yml @@ -15,6 +15,7 @@ jobs: cygwin_build_and_test: name: "cygwin ${{ inputs.build_mode }}" runs-on: windows-latest + timeout-minutes: 30 steps: - name: Set git to use LF run: | diff --git a/.github/workflows/cygwin-cmake.yml b/.github/workflows/cygwin-cmake.yml index 73fb5387d97..a04dcbf27d7 100644 --- a/.github/workflows/cygwin-cmake.yml +++ b/.github/workflows/cygwin-cmake.yml @@ -15,6 +15,7 @@ jobs: cygwin_build_and_test: name: "cygwin-${{ inputs.build_mode }}" runs-on: windows-latest + timeout-minutes: 30 steps: - name: Set git to use LF run: | diff --git a/.github/workflows/daily-build.yml b/.github/workflows/daily-build.yml index af4e60e778c..fac360e7884 100644 --- a/.github/workflows/daily-build.yml +++ b/.github/workflows/daily-build.yml @@ -42,10 +42,10 @@ jobs: needs: call-workflow-tarball uses: ./.github/workflows/cmake-ctest.yml with: - file_base: ${{ needs.call-workflow-tarball.outputs.file_base }} preset_name: ci-StdShar + file_base: ${{ needs.call-workflow-tarball.outputs.file_base }} +# use_tag: snapshot use_environ: snapshots - #use_tag: snapshot if: ${{ needs.call-workflow-tarball.outputs.has_changes == 'true' }} call-workflow-abi: diff --git a/.github/workflows/julia-auto.yml b/.github/workflows/julia-auto.yml new file mode 100644 index 00000000000..a7dd2ab15b9 --- /dev/null +++ b/.github/workflows/julia-auto.yml @@ -0,0 +1,79 @@ +name: hdf5 dev autotools julia + +on: + workflow_call: + inputs: + build_mode: + description: "release vs. debug build" + required: true + type: string + +permissions: + contents: read + +jobs: + julia_build_and_test: + name: "julia ${{ inputs.build_mode }}" + runs-on: ubuntu-latest + steps: + - name: Get Sources + uses: actions/checkout@v4.1.1 + + - name: Install Dependencies + shell: bash + run: | + sudo apt-get update + sudo apt-get install autoconf automake libtool libtool-bin libaec-dev + sudo apt-get install doxygen graphviz + sudo apt install -y zlib1g-dev libcurl4-openssl-dev libjpeg-dev wget curl bzip2 + sudo apt install -y m4 flex bison cmake libzip-dev openssl build-essential + + - name: Autotools Configure + shell: bash + run: | + sh ./autogen.sh + mkdir "${{ runner.workspace }}/build" + cd "${{ runner.workspace }}/build" + $GITHUB_WORKSPACE/configure \ + --enable-build-mode=${{ inputs.build_mode }} \ + --disable-fortran \ + --enable-shared \ + --disable-parallel \ + --prefix=/tmp + + - name: Autotools Build + shell: bash + run: | + make -j3 + working-directory: ${{ runner.workspace }}/build + + - name: Install HDF5 + shell: bash + run: | + make install + working-directory: ${{ runner.workspace }}/build + + - name: Install julia + uses: julia-actions/setup-julia@latest + with: + version: '1.6' + arch: 'x64' + + - name: Get julia hdf5 source + uses: actions/checkout@v4.1.1 + with: + repository: JuliaIO/HDF5.jl + path: . + + - name: Generate LocalPreferences + run: | + echo '[HDF5]' >> LocalPreferences.toml + echo 'libhdf5 = "/tmp/lib/libhdf5.so"' >> LocalPreferences.toml + echo 'libhdf5_hl = "/tmp/lib/libhdf5_hl.so"' >> LocalPreferences.toml + + - uses: julia-actions/julia-buildpkg@latest + + - name: Julia Run Tests + uses: julia-actions/julia-runtest@latest + env: + JULIA_DEBUG: Main diff --git a/.github/workflows/julia-cmake.yml b/.github/workflows/julia-cmake.yml new file mode 100644 index 00000000000..fb1de96f197 --- /dev/null +++ b/.github/workflows/julia-cmake.yml @@ -0,0 +1,82 @@ +name: hdf5 dev CMake julia + +on: + workflow_call: + inputs: + build_mode: + description: "release vs. debug build" + required: true + type: string + +permissions: + contents: read + +jobs: + julia_build_and_test: + name: "julia ${{ inputs.build_mode }}" + runs-on: ubuntu-latest + steps: + - name: Get Sources + uses: actions/checkout@v4.1.1 + + - name: Install Dependencies + shell: bash + run: | + sudo apt update + sudo apt-get install ninja-build doxygen graphviz + sudo apt install libssl3 libssl-dev libcurl4 libcurl4-openssl-dev + sudo apt install -y libaec-dev zlib1g-dev wget curl bzip2 flex bison cmake libzip-dev openssl build-essential + + - name: CMake Configure + shell: bash + run: | + mkdir "${{ runner.workspace }}/build" + cd "${{ runner.workspace }}/build" + cmake -C $GITHUB_WORKSPACE/config/cmake/cacheinit.cmake -G Ninja \ + -DCMAKE_BUILD_TYPE=${{ inputs.build_mode }} \ + -DHDF5_ENABLE_SZIP_SUPPORT:BOOL=OFF \ + -DHDF5_ENABLE_PARALLEL:BOOL=OFF \ + -DHDF5_BUILD_CPP_LIB:BOOL=OFF \ + -DLIBAEC_USE_LOCALCONTENT=OFF \ + -DZLIB_USE_LOCALCONTENT=OFF \ + -DHDF5_BUILD_FORTRAN:BOOL=OFF \ + -DHDF5_BUILD_JAVA:BOOL=OFF \ + -DCMAKE_INSTALL_PREFIX=/tmp \ + $GITHUB_WORKSPACE + + - name: CMake Build + shell: bash + run: | + cmake --build . --parallel 3 --config ${{ inputs.build_mode }} + working-directory: ${{ runner.workspace }}/build + + - name: Install HDF5 + shell: bash + run: | + cmake --install . + working-directory: ${{ runner.workspace }}/build + + - name: Install julia + uses: julia-actions/setup-julia@latest + with: + version: '1.6' + arch: 'x64' + + - name: Get julia hdf5 source + uses: actions/checkout@v4.1.1 + with: + repository: JuliaIO/HDF5.jl + path: . + + - name: Generate LocalPreferences + run: | + echo '[HDF5]' >> LocalPreferences.toml + echo 'libhdf5 = "/tmp/lib/libhdf5.so"' >> LocalPreferences.toml + echo 'libhdf5_hl = "/tmp/lib/libhdf5_hl.so"' >> LocalPreferences.toml + + - uses: julia-actions/julia-buildpkg@latest + + - name: Julia Run Tests + uses: julia-actions/julia-runtest@latest + env: + JULIA_DEBUG: Main diff --git a/.github/workflows/main-auto-spc.yml b/.github/workflows/main-auto-spc.yml index 3a7f72d4fbe..b0fc236ee33 100644 --- a/.github/workflows/main-auto-spc.yml +++ b/.github/workflows/main-auto-spc.yml @@ -417,8 +417,10 @@ jobs: sh ./autogen.sh mkdir "${{ runner.workspace }}/build" cd "${{ runner.workspace }}/build" - CFLAGS=-Werror $GITHUB_WORKSPACE/configure \ + CFLAGS=-Werror JAVACFLAGS=-Werror JNIFLAGS=-Werror \ + $GITHUB_WORKSPACE/configure \ --enable-build-mode=debug \ + --enable-warnings-as-errors \ --enable-deprecated-symbols \ --with-default-api-version=v114 \ --enable-shared \ @@ -478,8 +480,10 @@ jobs: sh ./autogen.sh mkdir "${{ runner.workspace }}/build" cd "${{ runner.workspace }}/build" - CFLAGS=-Werror $GITHUB_WORKSPACE/configure \ + CFLAGS=-Werror JAVACFLAGS=-Werror JNIFLAGS=-Werror \ + $GITHUB_WORKSPACE/configure \ --enable-build-mode=production \ + --enable-warnings-as-errors \ --enable-deprecated-symbols \ --with-default-api-version=v114 \ --enable-shared \ diff --git a/.github/workflows/main-cmake.yml b/.github/workflows/main-cmake.yml index 2b02765da9e..a7613dc3a76 100644 --- a/.github/workflows/main-cmake.yml +++ b/.github/workflows/main-cmake.yml @@ -135,10 +135,6 @@ jobs: # CMake gets libaec from fetchcontent - - name: Install Dependencies (Windows) - run: choco install ninja - if: matrix.os == 'windows-latest' - - name: Install Dependencies (macOS) run: brew install ninja if: matrix.os == 'macos-13' diff --git a/.github/workflows/markdown-link-check.yml b/.github/workflows/markdown-link-check.yml new file mode 100644 index 00000000000..00cb686c082 --- /dev/null +++ b/.github/workflows/markdown-link-check.yml @@ -0,0 +1,14 @@ +name: Check Markdown links + +on: + workflow_dispatch: + push: + pull_request: + branches: [ develop ] + +jobs: + markdown-link-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - uses: gaurav-nelson/github-action-markdown-link-check@v1 diff --git a/.github/workflows/mingw-cmake.yml b/.github/workflows/mingw-cmake.yml deleted file mode 100644 index 47613189cd2..00000000000 --- a/.github/workflows/mingw-cmake.yml +++ /dev/null @@ -1,91 +0,0 @@ -name: hdf5 dev CMake MinGW - -on: - workflow_call: - inputs: - build_mode: - description: "release vs. debug build" - required: true - type: string - shared: - description: "shared true/false" - required: true - type: string - netcdf: - description: "netcdf true/false" - required: true - type: string - -permissions: - contents: read - -jobs: - mingw_build_and_test: - name: "mingw-${{ inputs.build_mode }}-NC=${{ inputs.netcdf }}" - if: "!contains(github.event.head_commit.message, 'skip-ci')" - runs-on: ubuntu-latest - steps: - - name: Get Sources - uses: actions/checkout@v4.1.1 - - - name: Install Dependencies - shell: bash - run: | - sudo apt update - sudo apt-get install -y ninja-build libtirpc-dev graphviz - - - name: Install MinGW - uses: egor-tensin/setup-mingw@v2 - with: - platform: x64 - - - name: Install Doxygen - uses: ssciwr/doxygen-install@v1 - with: - version: "1.9.7" - - - name: CMake Configure - shell: bash - run: | - mkdir "${{ runner.workspace }}/build" - cd "${{ runner.workspace }}/build" - cmake -C $GITHUB_WORKSPACE/config/cmake/cacheinit.cmake \ - -G Ninja \ - --log-level=VERBOSE \ - -DCMAKE_BUILD_TYPE=${{ inputs.build_mode }} \ - -DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/config/toolchain/mingw64.cmake \ - -DBUILD_SHARED_LIBS:BOOL=${{ inputs.shared }} \ - -DHDF4_BUILD_EXAMPLES:BOOL=ON \ - -DBUILD_JPEG_WITH_PIC:BOOL=ON \ - -DHDF4_ENABLE_NETCDF:BOOL=${{ inputs.netcdf }} \ - -DHDF4_BUILD_FORTRAN:BOOL=OFF \ - -DHDF4_BUILD_JAVA:BOOL=OFF \ - -DHDF4_BUILD_DOC:BOOL=ON \ - -DJPEG_USE_LOCALCONTENT:BOOL=OFF \ - -DLIBAEC_USE_LOCALCONTENT:BOOL=OFF \ - -DZLIB_USE_LOCALCONTENT:BOOL=OFF \ - -DHDF4_PACK_EXAMPLES:BOOL=ON \ - -DHDF4_PACKAGE_EXTLIBS:BOOL=ON \ - $GITHUB_WORKSPACE - - - name: CMake Build - shell: bash - run: | - cmake --build . --parallel 3 --config ${{ inputs.build_mode }} - working-directory: ${{ runner.workspace }}/build - - - name: CMake Run Tests - shell: bash - run: | - ctest . --parallel 2 -C ${{ inputs.build_mode }} -V - if: false - - - name: CMake Package - shell: bash - run: | - cpack -C ${{ inputs.build_mode }} -V - working-directory: ${{ runner.workspace }}/build - - - name: List files in the space - run: | - ls -l ${{ runner.workspace }}/build diff --git a/.github/workflows/release-files.yml b/.github/workflows/release-files.yml index ec62a2f3d5e..17668d07c98 100644 --- a/.github/workflows/release-files.yml +++ b/.github/workflows/release-files.yml @@ -149,18 +149,18 @@ jobs: - name: Create sha256 sums for files run: | - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}.doxygen.zip > sha256sums.txt - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}.tar.gz >> sha256sums.txt - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}.zip >> sha256sums.txt - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-osx12.tar.gz >> sha256sums.txt - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.tar.gz >> sha256sums.txt - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb >> sha256sums.txt - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm >> sha256sums.txt - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc_s3.tar.gz >> sha256sums.txt - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-win-vs2022_cl.zip >> sha256sums.txt - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_intel.tar.gz >> sha256sums.txt - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-win-vs2022_intel.zip >> sha256sums.txt - sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}.html.abi.reports.tar.gz >> sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}.doxygen.zip > ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}.tar.gz >> ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}.zip >> ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-osx12.tar.gz >> ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.tar.gz >> ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb.tar.gz >> ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm.tar.gz >> ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc_s3.tar.gz >> ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-win-vs2022_cl.zip >> ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_intel.tar.gz >> ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}-win-vs2022_intel.zip >> ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt + sha256sum ${{ steps.get-file-base.outputs.FILE_BASE }}.html.abi.reports.tar.gz >> ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt - name: Store snapshot name run: | @@ -191,14 +191,14 @@ jobs: ${{ steps.get-file-base.outputs.FILE_BASE }}.zip ${{ steps.get-file-base.outputs.FILE_BASE }}-osx12.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.tar.gz - ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb - ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm + ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb.tar.gz + ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc_s3.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}-win-vs2022_cl.zip ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_intel.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}-win-vs2022_intel.zip ${{ steps.get-file-base.outputs.FILE_BASE }}.html.abi.reports.tar.gz - sha256sums.txt + ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn` - name: Release tag @@ -215,14 +215,14 @@ jobs: ${{ steps.get-file-base.outputs.FILE_BASE }}.zip ${{ steps.get-file-base.outputs.FILE_BASE }}-osx12.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.tar.gz - ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb - ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm + ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb.tar.gz + ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc_s3.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}-win-vs2022_cl.zip ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_intel.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}-win-vs2022_intel.zip ${{ steps.get-file-base.outputs.FILE_BASE }}.html.abi.reports.tar.gz - sha256sums.txt + ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn` - name: List files for the space (Linux) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e7c90a46898..aa45a70fe0e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,15 +31,16 @@ jobs: needs: log-the-inputs uses: ./.github/workflows/tarball.yml with: - use_tag: ${{ inputs.use_tag }} + use_tag: ${{ needs.log-the-inputs.outputs.rel_tag }} use_environ: release call-workflow-ctest: needs: call-workflow-tarball uses: ./.github/workflows/cmake-ctest.yml with: - file_base: ${{ needs.call-workflow-tarball.outputs.file_base }} preset_name: ci-StdShar + file_base: ${{ needs.call-workflow-tarball.outputs.file_base }} + snap_name: hdf5-${{ needs.call-workflow-tarball.outputs.source_base }} use_environ: release call-workflow-abi: @@ -58,8 +59,8 @@ jobs: uses: ./.github/workflows/release-files.yml with: file_base: ${{ needs.call-workflow-tarball.outputs.file_base }} - file_branch: ${{ needs.log-the-inputs.outputs.rel_tag }} - file_sha: ${{ needs.log-the-inputs.outputs.rel_tag }} + file_branch: ${{ needs.call-workflow-tarball.outputs.file_branch }} + file_sha: ${{ needs.call-workflow-tarball.outputs.file_sha }} use_tag: ${{ needs.log-the-inputs.outputs.rel_tag }} use_environ: release diff --git a/.github/workflows/remove-files.yml b/.github/workflows/remove-files.yml index 730949eaec9..0b599c65908 100644 --- a/.github/workflows/remove-files.yml +++ b/.github/workflows/remove-files.yml @@ -45,14 +45,15 @@ jobs: token: ${{ github.token }} tag: "${{ inputs.use_tag }}" assets: | + ${{ steps.get-file-base.outputs.FILE_BASE }}.sha256sums.txt ${{ steps.get-file-base.outputs.FILE_BASE }}.html.abi.reports.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}.doxygen.zip ${{ steps.get-file-base.outputs.FILE_BASE }}.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}.zip ${{ steps.get-file-base.outputs.FILE_BASE }}-osx12.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.tar.gz - ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb - ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm + ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.deb.tar.gz + ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc.rpm.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_gcc_s3.tar.gz ${{ steps.get-file-base.outputs.FILE_BASE }}-win-vs2022_cl.zip ${{ steps.get-file-base.outputs.FILE_BASE }}-ubuntu-2204_intel.tar.gz diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index 914f9da6218..c53b4731a54 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -18,6 +18,9 @@ on: has_changes: description: "Whether there were changes the previous day" value: ${{ jobs.check_commits.outputs.has_changes }} + source_base: + description: "The common base name of the source tarballs" + value: ${{ jobs.create_tarball.outputs.source_base }} file_base: description: "The common base name of the source tarballs" value: ${{ jobs.create_tarball.outputs.file_base }} @@ -80,6 +83,7 @@ jobs: if: ${{ ((inputs.use_environ == 'snapshots') && (needs.check_commits.outputs.has_changes == 'true')) || (inputs.use_environ == 'release') }} outputs: file_base: ${{ steps.set-file-base.outputs.FILE_BASE }} + source_base: ${{ steps.version.outputs.SOURCE_TAG }} steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - name: Get Sources @@ -96,20 +100,20 @@ jobs: id: version run: | cd "$GITHUB_WORKSPACE/hdfsrc" - echo "TAG_VERSION=$(bin/h5vers)" >> $GITHUB_OUTPUT + echo "SOURCE_TAG=$(bin/h5vers)" >> $GITHUB_OUTPUT - name: Set file base name id: set-file-base run: | - if [[ '${{ inputs.use_environ }}' == 'snapshots' && '${{ needs.check_commits.outputs.has_changes }}' == 'true' ]] + if [[ '${{ inputs.use_environ }}' == 'snapshots' ]] then FILE_NAME_BASE=$(echo "hdf5-${{ needs.check_commits.outputs.branch_ref }}-${{ needs.check_commits.outputs.branch_sha }}") else if [[ '${{ inputs.use_tag }}' == 'snapshot' ]] then - FILE_NAME_BASE=$(echo "${{ inputs.use_tag }}") + FILE_NAME_BASE=$(echo "snapshot") else - FILE_NAME_BASE=$(echo "hdf5-${{ steps.version.outputs.TAG_VERSION }}") + FILE_NAME_BASE=$(echo "hdf5-${{ steps.version.outputs.SOURCE_TAG }}") fi fi echo "FILE_BASE=$FILE_NAME_BASE" >> $GITHUB_OUTPUT @@ -117,7 +121,7 @@ jobs: - name: Create snapshot file base name id: create-file-base - if: ${{ (inputs.use_environ == 'snapshots') && (needs.check_commits.outputs.has_changes == 'true') }} + if: ${{ (inputs.use_environ == 'snapshots') }} run: | cd "$GITHUB_WORKSPACE/hdfsrc" bin/release -d $GITHUB_WORKSPACE --branch ${{ needs.check_commits.outputs.branch_ref }} --revision gzip zip @@ -125,18 +129,18 @@ jobs: - name: Create release file base name id: create-rel-base - if: ${{ (inputs.use_environ == 'release') && (inputs.use_tag != 'snapshot') }} + if: ${{ (inputs.use_environ == 'release') }} run: | cd "$GITHUB_WORKSPACE/hdfsrc" bin/release -d $GITHUB_WORKSPACE gzip zip shell: bash - - name: Create snapshot file base name - id: create-snap-base - if: ${{ (inputs.use_tag == 'snapshot') && (inputs.use_environ == 'release') }} + - name: Rename release file base name + id: ren-basename + if: ${{ (inputs.use_environ == 'release') && (inputs.use_tag == 'snapshot') }} run: | - cd "$GITHUB_WORKSPACE/hdfsrc" - bin/release -d $GITHUB_WORKSPACE --branch ${{ inputs.use_tag }} gzip zip + mv hdf5-${{ steps.version.outputs.SOURCE_TAG }}.tar.gz ${{ inputs.use_tag }}.tar.gz + mv hdf5-${{ steps.version.outputs.SOURCE_TAG }}.zip ${{ inputs.use_tag }}.zip shell: bash - name: List files in the repository diff --git a/CMakeLists.txt b/CMakeLists.txt index 81a6e96b6fe..879e7307bf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1072,8 +1072,6 @@ set (H5_FC_FUNC_ "H5_FC_FUNC_(name,NAME) name ## _") if (EXISTS "${HDF5_SOURCE_DIR}/fortran" AND IS_DIRECTORY "${HDF5_SOURCE_DIR}/fortran") option (HDF5_BUILD_FORTRAN "Build FORTRAN support" OFF) if (HDF5_BUILD_FORTRAN) - include (${HDF_RESOURCES_DIR}/HDFUseFortran.cmake) - message (VERBOSE "Fortran compiler ID is ${CMAKE_Fortran_COMPILER_ID}") include (${HDF_RESOURCES_DIR}/HDFFortranCompilerFlags.cmake) include (${HDF_RESOURCES_DIR}/HDF5UseFortran.cmake) @@ -1147,16 +1145,6 @@ if (EXISTS "${HDF5_SOURCE_DIR}/c++" AND IS_DIRECTORY "${HDF5_SOURCE_DIR}/c++") endif () endif () -#----------------------------------------------------------------------------- -# Check if Fortran's default real is double precision. If it is and HL is -# being built then configure should fail due to bug HDFFV-889. -#----------------------------------------------------------------------------- -if (HDF5_BUILD_FORTRAN AND HDF5_BUILD_HL_LIB) - if (NOT H5_FORTRAN_DEFAULT_REAL_NOT_DOUBLE) - message (FATAL_ERROR " **** Fortran high-level routines are not supported when the default REAL is DOUBLE PRECISION, use HDF5_BUILD_HL_LIB:BOOL=OFF **** ") - endif () -endif () - #----------------------------------------------------------------------------- # Option to build HDF5 Java Library #----------------------------------------------------------------------------- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index de81b1c8e05..00c884b692c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -122,7 +122,7 @@ Please make sure that you check the items applicable to your pull request: * [ ] If changes were done to Autotools build, were they added to CMake and vice versa? * [ ] Is the pull request applicable to any other branches? If yes, which ones? Please document it in the GitHub issue. * [ ] Is the new code sufficiently documented for future maintenance? - * [ ] Does the new feature require a change to an existing API? See "API Compatibility Macros" document (https://portal.hdfgroup.org/display/HDF5/API+Compatibility+Macros) + * [ ] Does the new feature require a change to an existing API? See "API Compatibility Macros" document (https://docs.hdfgroup.org/hdf5/develop/api-compat-macros.html) * Documentation * [ ] Was the change described in the release_docs/RELEASE.txt file? * [ ] Was the new function documented in the corresponding public header file using [Doxygen](https://hdfgroup.github.io/hdf5/develop/_r_m_t.html)? diff --git a/HDF5Examples/C/H5T/CMakeLists.txt b/HDF5Examples/C/H5T/CMakeLists.txt index e0d76e83fe8..c21a8d03fa1 100644 --- a/HDF5Examples/C/H5T/CMakeLists.txt +++ b/HDF5Examples/C/H5T/CMakeLists.txt @@ -115,7 +115,7 @@ if (HDF5_BUILD_TOOLS) if (NOT ${example_name} STREQUAL "h5ex_t_convert") if (${example_name} STREQUAL "h5ex_t_vlen" OR ${example_name} STREQUAL "h5ex_t_vlenatt") if (HDF5_VERSION_STRING VERSION_GREATER_EQUAL "1.14.3") - if (${H5_LIBVER_DIR} EQUAL 16 AND ${example_name} STREQUAL "h5ex_t_vlenatt") + if ((${EXAMPLE_VARNAME}_USE_16_API OR ${H5_LIBVER_DIR} EQUAL 16) AND ${example_name} STREQUAL "h5ex_t_vlenatt") add_custom_command ( TARGET ${EXAMPLE_VARNAME}_${example_name} POST_BUILD @@ -130,7 +130,7 @@ if (HDF5_BUILD_TOOLS) ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/tfiles/114/${example_name}.ddl ${PROJECT_BINARY_DIR}/${example_name}.ddl ) endif () - elseif (${H5_LIBVER_DIR} EQUAL 16) + elseif (${EXAMPLE_VARNAME}_USE_16_API OR ${H5_LIBVER_DIR} EQUAL 16) add_custom_command ( TARGET ${EXAMPLE_VARNAME}_${example_name} POST_BUILD @@ -180,7 +180,7 @@ if (HDF5_BUILD_TOOLS) ) endif () elseif (HDF5_VERSION_MAJOR VERSION_GREATER_EQUAL "1.12") - if (${H5_LIBVER_DIR} EQUAL 16) + if (${EXAMPLE_VARNAME}_USE_16_API OR ${H5_LIBVER_DIR} EQUAL 16) add_custom_command ( TARGET ${EXAMPLE_VARNAME}_${example_name} POST_BUILD @@ -196,12 +196,21 @@ if (HDF5_BUILD_TOOLS) ) endif () else () - add_custom_command ( - TARGET ${EXAMPLE_VARNAME}_${example_name} - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/tfiles/18/${example_name}.ddl ${PROJECT_BINARY_DIR}/${example_name}.ddl - ) + if (${EXAMPLE_VARNAME}_USE_16_API OR ${H5_LIBVER_DIR} EQUAL 16) + add_custom_command ( + TARGET ${EXAMPLE_VARNAME}_${example_name} + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/tfiles/16/${example_name}.ddl ${PROJECT_BINARY_DIR}/${example_name}.ddl + ) + else () + add_custom_command ( + TARGET ${EXAMPLE_VARNAME}_${example_name} + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/tfiles/18/${example_name}.ddl ${PROJECT_BINARY_DIR}/${example_name}.ddl + ) + endif () endif () else () if (HDF5_VERSION_MAJOR VERSION_EQUAL "1.8") @@ -260,12 +269,21 @@ if (HDF5_BUILD_TOOLS) ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/tfiles/16/${example_name}.ddl ${PROJECT_BINARY_DIR}/${example_name}.ddl ) else () - add_custom_command ( - TARGET ${EXAMPLE_VARNAME}_${example_name} - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/tfiles/18/${example_name}.ddl ${PROJECT_BINARY_DIR}/${example_name}.ddl - ) + if (${EXAMPLE_VARNAME}_USE_16_API) + add_custom_command ( + TARGET ${EXAMPLE_VARNAME}_${example_name} + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/tfiles/16/${example_name}.ddl ${PROJECT_BINARY_DIR}/${example_name}.ddl + ) + else () + add_custom_command ( + TARGET ${EXAMPLE_VARNAME}_${example_name} + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy_if_different ${PROJECT_SOURCE_DIR}/tfiles/18/${example_name}.ddl ${PROJECT_BINARY_DIR}/${example_name}.ddl + ) + endif () endif () endif () endforeach () diff --git a/HDF5Examples/FORTRAN/H5G/h5ex_g_traverse.F90 b/HDF5Examples/FORTRAN/H5G/h5ex_g_traverse.F90 index 169a0044f74..ab401ce9164 100644 --- a/HDF5Examples/FORTRAN/H5G/h5ex_g_traverse.F90 +++ b/HDF5Examples/FORTRAN/H5G/h5ex_g_traverse.F90 @@ -87,6 +87,7 @@ RECURSIVE INTEGER(KIND=C_INT) FUNCTION op_func(loc_id, name, info, operator_data INTEGER :: ret_val_func ret_val_func = 0 + ret_val = 0 name_string(1:10) = " " len = 0 @@ -142,7 +143,7 @@ RECURSIVE INTEGER(KIND=C_INT) FUNCTION op_func(loc_id, name, info, operator_data funptr = C_FUNLOC(op_func) CALL h5literate_by_name_f(loc_id, name_string, H5_INDEX_NAME_F, H5_ITER_NATIVE_F, idx, & funptr, ptr2, ret_val_func, status) - + ret_val = INT(ret_val_func,C_INT) ENDIF WRITE(*,'(A)') space(1:spaces)//"}" RETURN diff --git a/HDF5Examples/README.md b/HDF5Examples/README.md index 9a658365245..2f0090ba02c 100644 --- a/HDF5Examples/README.md +++ b/HDF5Examples/README.md @@ -19,7 +19,7 @@ HELP AND SUPPORT ---------------- Information regarding Help Desk and Support services is available at - https://portal.hdfgroup.org/display/support/The+HDF+Help+Desk + https://hdfgroup.atlassian.net/servicedesk/customer/portals @@ -48,7 +48,7 @@ HDF5 SNAPSHOTS, PREVIOUS RELEASES AND SOURCE CODE -------------------------------------------- Full Documentation and Programming Resources for this HDF5 can be found at - https://portal.hdfgroup.org/display/HDF5 + https://portal.hdfgroup.org/documentation/index.html Periodically development code snapshots are provided at the following URL: @@ -56,7 +56,7 @@ Periodically development code snapshots are provided at the following URL: Source packages for current and previous releases are located at: - https://portal.hdfgroup.org/display/support/Downloads + https://portal.hdfgroup.org/downloads/ Development code is available at our Github location: diff --git a/HDF5Examples/Using_CMake.txt b/HDF5Examples/Using_CMake.txt index df761cb28db..778fa7534b5 100644 --- a/HDF5Examples/Using_CMake.txt +++ b/HDF5Examples/Using_CMake.txt @@ -30,7 +30,7 @@ I. Preconditions 1. We suggest you obtain the latest CMake for windows from the Kitware web site. The HDF5 product requires a minimum CMake version - of 3.12. + of 3.18. 2. You have installed the HDF5 library built with CMake, by executing the HDF Install Utility (the *.msi file in the binary package for @@ -45,7 +45,7 @@ I. Preconditions (Note there are no quote characters used on Windows and all platforms use forward slashes) - 4. Created separate source and build directories. + 4. Create separate source and build directories. (CMake commands are executed in the build directory) @@ -90,11 +90,11 @@ These steps are described in more detail below. * MinGW Makefiles * NMake Makefiles * Unix Makefiles - * Visual Studio 15 - * Visual Studio 15 Win64 - * Visual Studio 17 - * Visual Studio 17 Win64 - * Visual Studio 19 + * Visual Studio 15 2017 + * Visual Studio 15 2017 Win64 + * Visual Studio 16 2019 + * Visual Studio 17 2022 + is: * H5EX_BUILD_TESTING:BOOL=ON diff --git a/HDF5Examples/config/cmake/HDFExampleMacros.cmake b/HDF5Examples/config/cmake/HDFExampleMacros.cmake index 5c425dbbe0c..8173562de88 100644 --- a/HDF5Examples/config/cmake/HDFExampleMacros.cmake +++ b/HDF5Examples/config/cmake/HDFExampleMacros.cmake @@ -45,10 +45,10 @@ macro (BASIC_SETTINGS varname) #----------------------------------------------------------------------------- # Compiler specific flags : Shouldn't there be compiler tests for these #----------------------------------------------------------------------------- - if (CMAKE_COMPILER_IS_GNUCC) + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") set (CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}") endif () - if (CMAKE_CXX_COMPILER_LOADED AND CMAKE_COMPILER_IS_GNUCXX) + if (CMAKE_CXX_COMPILER_LOADED AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_CXX_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_CXX_FLAGS}") endif () @@ -56,10 +56,10 @@ macro (BASIC_SETTINGS varname) # This is in here to help some of the GCC based IDES like Eclipse # and code blocks parse the compiler errors and warnings better. #----------------------------------------------------------------------------- - if (CMAKE_COMPILER_IS_GNUCC) + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0") endif () - if (CMAKE_CXX_COMPILER_LOADED AND CMAKE_COMPILER_IS_GNUCXX) + if (CMAKE_CXX_COMPILER_LOADED AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmessage-length=0") endif () @@ -74,7 +74,7 @@ macro (BASIC_SETTINGS varname) set (HDF_WARNINGS_BLOCKED 1) string (REGEX REPLACE "(^| )([/-])W[0-9]( |$)" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /w") - if (CMAKE_CXX_COMPILER_LOADED AND CMAKE_COMPILER_IS_GNUCXX) + if (CMAKE_CXX_COMPILER_LOADED AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") string (REGEX REPLACE "(^| )([/-])W[0-9]( |$)" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /w") endif () @@ -91,7 +91,7 @@ macro (BASIC_SETTINGS varname) # Most compilers use -w to suppress warnings. if (NOT HDF_WARNINGS_BLOCKED) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") - if (CMAKE_CXX_COMPILER_LOADED AND CMAKE_COMPILER_IS_GNUCXX) + if (CMAKE_CXX_COMPILER_LOADED AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") endif () endif () diff --git a/autogen.sh b/autogen.sh index 142375d6a8b..33a82779465 100755 --- a/autogen.sh +++ b/autogen.sh @@ -11,12 +11,12 @@ # help@hdfgroup.org. # -# A script to reconfigure autotools for HDF5, and to recreate other +# A script to reconfigure the Autotools for HDF5, and to recreate other # generated files specific to HDF5. # # IMPORTANT OS X NOTE # -# If you are using OS X, you will probably not have the autotools +# If you are using OS X, you will probably not have the Autotools # installed, even if you have the Xcode command-line tools. # # The easiest way to fix this is to install everything via Homebrew: @@ -30,31 +30,7 @@ # brew install automake # brew install libtool # -# This only takes a few minutes. Note that libtool and libtoolize will -# be glibtool and glibtoolize so as not to conflict with Apple's non-gnu -# tools. This autogen.sh script handles this for you. -# # END IMPORTANT OS X NOTE -# -# If you want to use a particular version of the autotools, the paths -# to each tool can be overridden using the following environment -# variables: -# -# HDF5_ACLOCAL -# HDF5_AUTOHEADER -# HDF5_AUTOMAKE -# HDF5_AUTOCONF -# HDF5_LIBTOOLIZE -# HDF5_M4 -# -# Note that aclocal will attempt to include libtool's share/aclocal -# directory. -# -# Aside from -h for help, this script takes one potential option: -# -# -v -# -# This emits some extra information, mainly tool versions. echo echo "**************************" @@ -62,76 +38,9 @@ echo "* HDF5 autogen.sh script *" echo "**************************" echo -# Default is not verbose output -verbose=false - -optspec=":hpv-" -while getopts "$optspec" optchar; do - case "${optchar}" in - h) - echo "usage: $0 [OPTIONS]" - echo - echo " -h Print this help message." - echo - echo " -v Show more verbose output." - echo - echo " NOTE: Each tool can be set via an environment variable." - echo " These are documented inside this autogen.sh script." - echo - exit 0 - ;; - v) - echo "Setting verbosity: high" - echo - verbose=true - ;; - *) - if [ "$OPTERR" != 1 ] || case $optspec in :*) ;; *) false; esac; then - echo "ERROR: non-option argument: '-${OPTARG}'" >&2 - echo "Quitting" - exit 1 - fi - ;; - esac -done - -# If paths to autotools are not specified, use whatever the system -# has installed as the default. We use 'command -v ' to -# show exactly what's being used (shellcheck complains that 'which' -# is non-standard and deprecated). -if test -z "${HDF5_AUTOCONF}"; then - HDF5_AUTOCONF="$(command -v autoconf)" -fi -if test -z "${HDF5_AUTOMAKE}"; then - HDF5_AUTOMAKE="$(command -v automake)" -fi -if test -z "${HDF5_AUTOHEADER}"; then - HDF5_AUTOHEADER="$(command -v autoheader)" -fi -if test -z "${HDF5_ACLOCAL}"; then - HDF5_ACLOCAL="$(command -v aclocal)" -fi -if test -z "${HDF5_LIBTOOLIZE}"; then - # check for glibtoolize (likely found on MacOS). If not found - check for libtoolize - HDF5_LIBTOOLIZE="$(command -v glibtoolize)" - if [ ! -f "$HDF5_LIBTOOLIZE" ] ; then - HDF5_LIBTOOLIZE="$(command -v libtoolize)" - fi -fi -if test -z "${HDF5_M4}"; then - HDF5_M4="$(command -v m4)" -fi - - -# Make sure that these versions of the autotools are in the path -AUTOCONF_DIR=$(dirname "${HDF5_AUTOCONF}") -LIBTOOL_DIR=$(dirname "${HDF5_LIBTOOLIZE}") -M4_DIR=$(dirname "${HDF5_M4}") -PATH=${AUTOCONF_DIR}:${LIBTOOL_DIR}:${M4_DIR}:$PATH - # Run scripts that process source. # -# These should be run before the autotools so that failures here block +# These should be run before the Autotools so that failures here block # compilation. # Run trace script @@ -162,73 +71,20 @@ echo "Running overflow macro generation script:" bin/make_overflow src/H5overflow.txt || exit 1 echo -# Run autotools in order -# -# When available, we use the --force option to ensure all files are -# updated. This prevents the autotools from re-running to fix dependencies -# during the 'make' step, which can be a problem if environment variables -# were set on the command line during autogen invocation. - -# Some versions of libtoolize will suggest that we add ACLOCAL_AMFLAGS -# = '-I m4'. This is already done in commence.am, which is included -# in Makefile.am. You can ignore this suggestion. +# Run Autotools -# LIBTOOLIZE -libtoolize_cmd="${HDF5_LIBTOOLIZE} --copy --force" -echo "${libtoolize_cmd}" -if [ "$verbose" = true ] ; then - ${HDF5_LIBTOOLIZE} --version -fi -${libtoolize_cmd} || exit 1 +# The "obsolete" warnings category flags our Java macros as obsolete. +# Since there is no clear way to upgrade them (Java support in the Autotools +# is not great) and they work well enough for now, we suppress those warnings. +echo "Running Autotools" echo echo "NOTE: You can ignore the warning about adding -I m4." echo " We already do this in an included file." echo - -# ACLOCAL -if test -e "${LIBTOOL_DIR}/../share/aclocal" ; then - aclocal_include="-I ${LIBTOOL_DIR}/../share/aclocal" -fi -aclocal_cmd="${HDF5_ACLOCAL} --force -I m4 ${aclocal_include}" -echo "${aclocal_cmd}" -if [ "$verbose" = true ] ; then - ${HDF5_ACLOCAL} --version -fi -${aclocal_cmd} || exit 1 -echo - -# AUTOHEADER -autoheader_cmd="${HDF5_AUTOHEADER} --force" -echo "${autoheader_cmd}" -if [ "$verbose" = true ] ; then - ${HDF5_AUTOHEADER} --version -fi -${autoheader_cmd} || exit 1 -echo - -# AUTOMAKE -automake_cmd="${HDF5_AUTOMAKE} --copy --add-missing --force-missing" -echo "${automake_cmd}" -if [ "$verbose" = true ] ; then - ${HDF5_AUTOMAKE} --version -fi -${automake_cmd} || exit 1 -echo - -# AUTOCONF -# The "obsolete" warnings category flags our Java macros as obsolete. -# Since there is no clear way to upgrade them (Java support in the Autotools -# is not great) and they work well enough for now, we suppress those warnings. -autoconf_cmd="${HDF5_AUTOCONF} --force --warnings=no-obsolete" -echo "${autoconf_cmd}" -if [ "$verbose" = true ] ; then - ${HDF5_AUTOCONF} --version -fi -${autoconf_cmd} || exit 1 +autoreconf -vif --warnings=no-obsolete || exit 1 echo echo "*** SUCCESS ***" echo exit 0 - diff --git a/c++/test/tattr.cpp b/c++/test/tattr.cpp index 2f011d01ac7..5135e0c7fa7 100644 --- a/c++/test/tattr.cpp +++ b/c++/test/tattr.cpp @@ -1406,17 +1406,23 @@ test_attr_dtype_shared(FileAccPropList &fapl) SUBTEST("Shared Datatypes with Attributes"); try { + h5_stat_size_t empty_filesize = 0; // Size of empty file + bool is_default_vfd_compat = false; + // Create a file H5File fid1(FILE_DTYPE, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, fapl); // Close file fid1.close(); - // Get size of file - h5_stat_size_t empty_filesize; // Size of empty file - empty_filesize = h5_get_file_size(FILE_DTYPE.c_str(), H5P_DEFAULT); - if (empty_filesize < 0) - TestErrPrintf("Line %d: file size wrong!\n", __LINE__); + h5_driver_is_default_vfd_compatible(H5P_DEFAULT, &is_default_vfd_compat); + + if (is_default_vfd_compat) { + // Get size of file + empty_filesize = h5_get_file_size(FILE_DTYPE.c_str(), H5P_DEFAULT); + if (empty_filesize < 0) + TestErrPrintf("Line %d: file size wrong!\n", __LINE__); + } // Open the file again fid1.openFile(FILE_DTYPE, H5F_ACC_RDWR); @@ -1533,10 +1539,12 @@ test_attr_dtype_shared(FileAccPropList &fapl) // Close file fid1.close(); - // Check size of file - filesize = h5_get_file_size(FILE_DTYPE.c_str(), H5P_DEFAULT); - verify_val(static_cast(filesize), static_cast(empty_filesize), "Checking file size", - __LINE__, __FILE__); + if (is_default_vfd_compat) { + // Check size of file + filesize = h5_get_file_size(FILE_DTYPE.c_str(), H5P_DEFAULT); + verify_val(static_cast(filesize), static_cast(empty_filesize), "Checking file size", + __LINE__, __FILE__); + } PASSED(); } // end try block diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index ef8500c2559..aea3fd62443 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -905,12 +905,24 @@ if (${HDF_PREFIX}_SIZEOF__FLOAT16) # compile a program that will generate these functions to check for _Float16 # support. If we fail to compile this program, we will simply disable # _Float16 support for the time being. + + # Some compilers, notably AppleClang on MacOS 12, will succeed in the + # configure check below when optimization flags like -O3 are manually + # passed in CMAKE_C_FLAGS. However, the build will then fail when it + # reaches compilation of H5Tconv.c because of the issue mentioned above. + # MacOS 13 appears to have fixed this, but, just to be sure, backup and + # clear CMAKE_C_FLAGS before performing these configure checks. + set (cmake_c_flags_backup "${CMAKE_C_FLAGS}") + set (CMAKE_C_FLAGS "") + H5ConversionTests ( ${HDF_PREFIX}_FLOAT16_CONVERSION_FUNCS_LINK FALSE "Checking if compiler can convert _Float16 type with casts" ) + set (CMAKE_C_FLAGS "${cmake_c_flags_backup}") + if (${${HDF_PREFIX}_FLOAT16_CONVERSION_FUNCS_LINK}) # Finally, MacOS 13 appears to have a bug specifically when converting # long double values to _Float16. Release builds of the dt_arith test @@ -919,12 +931,19 @@ if (${HDF_PREFIX}_SIZEOF__FLOAT16) # simply chopping off all the bytes of the value except for the first 2. # These tests pass on MacOS 14, so let's perform a quick test to check # if the hardware conversion is done correctly. + + # Backup and clear CMAKE_C_FLAGS before performing configure checks + set (cmake_c_flags_backup "${CMAKE_C_FLAGS}") + set (CMAKE_C_FLAGS "") + H5ConversionTests ( ${HDF_PREFIX}_LDOUBLE_TO_FLOAT16_CORRECT TRUE "Checking if correctly converting long double to _Float16 values" ) + set (CMAKE_C_FLAGS "${cmake_c_flags_backup}") + if (NOT ${${HDF_PREFIX}_LDOUBLE_TO_FLOAT16_CORRECT}) message (VERBOSE "Conversions from long double to _Float16 appear to be incorrect. These will be emulated through a soft conversion function.") endif () diff --git a/config/cmake/HDF5Macros.cmake b/config/cmake/HDF5Macros.cmake index 54543e0c715..e17d6bc46b2 100644 --- a/config/cmake/HDF5Macros.cmake +++ b/config/cmake/HDF5Macros.cmake @@ -70,8 +70,17 @@ macro (H5_SET_VFD_LIST) split multi family - splitter - #log - log VFD currently has file space allocation bugs + # Splitter VFD currently can't be tested with the h5_fileaccess() + # approach due to it trying to lock the same W/O file when two + # files are created/opened with the same FAPL that has the VFD + # set on it. When tested with the environment variable and a + # default FAPL, the VFD appends "_wo" to the filename when the + # W/O path isn't specified, which works for all the tests. + #splitter + # Log VFD currently has file space allocation bugs + #log + # Onion VFD not currently tested with VFD tests + #onion ) if (H5_HAVE_DIRECT) @@ -82,16 +91,21 @@ macro (H5_SET_VFD_LIST) # list (APPEND VFD_LIST mpio) endif () if (H5_HAVE_MIRROR_VFD) - list (APPEND VFD_LIST mirror) + # Mirror VFD needs network configuration, etc. and isn't easy to set + # reasonable defaults for that info. + # list (APPEND VFD_LIST mirror) endif () if (H5_HAVE_ROS3_VFD) - list (APPEND VFD_LIST ros3) + # This would require a custom test suite + # list (APPEND VFD_LIST ros3) endif () if (H5_HAVE_LIBHDFS) - list (APPEND VFD_LIST hdfs) + # This would require a custom test suite + # list (APPEND VFD_LIST hdfs) endif () if (H5_HAVE_SUBFILING_VFD) - list (APPEND VFD_LIST subfiling) + # Subfiling has a few VFD test failures to be resolved + # list (APPEND VFD_LIST subfiling) endif () if (H5_HAVE_WINDOWS) list (APPEND VFD_LIST windows) diff --git a/config/cmake/HDF5UseFortran.cmake b/config/cmake/HDF5UseFortran.cmake index 743da3d3560..b4172eace4b 100644 --- a/config/cmake/HDF5UseFortran.cmake +++ b/config/cmake/HDF5UseFortran.cmake @@ -14,27 +14,15 @@ # This file provides functions for HDF5 specific Fortran support. # #------------------------------------------------------------------------------- -enable_language (Fortran) +include (${HDF_RESOURCES_DIR}/HDFUseFortran.cmake) -set (HDF_PREFIX "H5") +include (CheckFortranFunctionExists) # Force lowercase Fortran module file names if (CMAKE_Fortran_COMPILER_ID STREQUAL "Cray") set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ef") endif () -include (CheckFortranFunctionExists) - -include (CheckFortranSourceRuns) -include (CheckFortranSourceCompiles) - -# Read source line beginning at the line matching Input:"START" and ending at the line matching Input:"END" -macro (READ_SOURCE SOURCE_START SOURCE_END RETURN_VAR) - file (READ "${HDF5_SOURCE_DIR}/m4/aclocal_fc.f90" SOURCE_MASTER) - string (REGEX MATCH "${SOURCE_START}[\\\t\\\n\\\r[].+]*${SOURCE_END}" SOURCE_CODE ${SOURCE_MASTER}) - set (RETURN_VAR "${SOURCE_CODE}") -endmacro () - set (RUN_OUTPUT_PATH_DEFAULT ${CMAKE_BINARY_DIR}) # The provided CMake Fortran macros don't provide a general compile/run function # so this one is used. @@ -117,6 +105,16 @@ else () set (${HDF_PREFIX}_FORTRAN_C_BOOL_IS_UNIQUE 0) endif () +# Check if the fortran compiler supports the intrinsic module "ISO_FORTRAN_ENV" (F08) + +READ_SOURCE("PROGRAM PROG_FC_ISO_FORTRAN_ENV" "END PROGRAM PROG_FC_ISO_FORTRAN_ENV" SOURCE_CODE) +check_fortran_source_compiles (${SOURCE_CODE} HAVE_ISO_FORTRAN_ENV SRC_EXT f90) +if (${HAVE_ISO_FORTRAN_ENV}) + set (${HDF_PREFIX}_HAVE_ISO_FORTRAN_ENV 1) +else () + set (${HDF_PREFIX}_HAVE_ISO_FORTRAN_ENV 0) +endif () + ## Set the sizeof function for use later in the fortran tests if (${HDF_PREFIX}_FORTRAN_HAVE_STORAGE_SIZE) set (FC_SIZEOF_A "STORAGE_SIZE(a, c_size_t)/STORAGE_SIZE(c_char_'a',c_size_t)") @@ -142,8 +140,12 @@ endif () #----------------------------------------------------------------------------- # Determine the available KINDs for REALs and INTEGERs #----------------------------------------------------------------------------- +if (${HAVE_ISO_FORTRAN_ENV}) + READ_SOURCE ("PROGRAM FC08_AVAIL_KINDS" "END PROGRAM FC08_AVAIL_KINDS" SOURCE_CODE) +else () + READ_SOURCE ("PROGRAM FC_AVAIL_KINDS" "END PROGRAM FC_AVAIL_KINDS" SOURCE_CODE) +endif () -READ_SOURCE ("PROGRAM FC_AVAIL_KINDS" "END PROGRAM FC_AVAIL_KINDS" SOURCE_CODE) FORTRAN_RUN ("REAL and INTEGER KINDs" "${SOURCE_CODE}" XX @@ -157,6 +159,9 @@ FORTRAN_RUN ("REAL and INTEGER KINDs" # dnl -- LINE 3 -- max decimal precision for reals # dnl -- LINE 4 -- number of valid integer kinds # dnl -- LINE 5 -- number of valid real kinds +# dnl -- LINE 6 -- number of valid logical kinds +# dnl -- LINE 7 -- valid logical kinds (comma separated list) + # # Convert the string to a list of strings by replacing the carriage return with a semicolon string (REGEX REPLACE "[\r\n]+" ";" PROG_OUTPUT "${PROG_OUTPUT}") @@ -192,6 +197,61 @@ message (STATUS "....REAL KINDS FOUND ${PAC_FC_ALL_REAL_KINDS}") message (STATUS "....INTEGER KINDS FOUND ${PAC_FC_ALL_INTEGER_KINDS}") message (STATUS "....MAX DECIMAL PRECISION ${${HDF_PREFIX}_PAC_FC_MAX_REAL_PRECISION}") +if (${HAVE_ISO_FORTRAN_ENV}) + + list (GET PROG_OUTPUT 5 NUM_LKIND) + set (PAC_FORTRAN_NUM_LOGICAL_KINDS "${NUM_LKIND}") + + list (GET PROG_OUTPUT 6 pac_validLogicalKinds) + # If the list is empty then something went wrong. + if (NOT pac_validLogicalKinds) + message (FATAL_ERROR "Failed to find available LOGICAL KINDs for Fortran") + endif () + + set (PAC_FC_ALL_LOGICAL_KINDS "\{${pac_validLogicalKinds}\}") + message (STATUS "....LOGICAL KINDS FOUND ${PAC_FC_ALL_LOGICAL_KINDS}") + +# ******************** +# LOGICAL KIND FOR MPI +# ******************** + if (HDF5_ENABLE_PARALLEL AND BUILD_TESTING) + string (REGEX REPLACE "," ";" VAR "${pac_validLogicalKinds}") + + set(CMAKE_REQUIRED_QUIET TRUE) + set(save_CMAKE_Fortran_FLAGS ${CMAKE_Fortran_FLAGS}) + if (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") + set(CMAKE_Fortran_FLAGS "-warn error") + endif () + + foreach (KIND ${VAR}) + unset(MPI_LOGICAL_KIND CACHE) + set (PROG_SRC + " + PROGRAM main + USE MPI + IMPLICIT NONE + LOGICAL(KIND=${KIND}) :: flag + INTEGER(KIND=MPI_INTEGER_KIND) :: info_ret, mpierror + CHARACTER(LEN=3) :: info_val + CALL mpi_info_get(info_ret,\"foo\", 3_MPI_INTEGER_KIND, info_val, flag, mpierror) + END + " + ) + check_fortran_source_compiles (${PROG_SRC} MPI_LOGICAL_KIND SRC_EXT f90) + + if (MPI_LOGICAL_KIND) + set (${HDF_PREFIX}_MPI_LOGICAL_KIND ${KIND}) + message (STATUS "....FORTRAN LOGICAL KIND for MPI is ${KIND}") + endif () + endforeach () + if (${HDF_PREFIX}_MPI_LOGICAL_KIND STREQUAL "") + message (FATAL_ERROR "Failed to determine LOGICAL KIND for MPI") + endif () + set(CMAKE_REQUIRED_QUIET FALSE) + set(CMAKE_Fortran_FLAGS ${save_CMAKE_Fortran_FLAGS}) + endif() +endif() + #----------------------------------------------------------------------------- # Determine the available KINDs for REALs and INTEGERs #----------------------------------------------------------------------------- @@ -340,7 +400,6 @@ if (NOT PAC_FORTRAN_NATIVE_DOUBLE_KIND) message (FATAL_ERROR "Failed to find KIND of NATIVE DOUBLE for Fortran") endif () - set (${HDF_PREFIX}_FORTRAN_SIZEOF_LONG_DOUBLE ${${HDF_PREFIX}_SIZEOF_LONG_DOUBLE}) # remove the invalid kind from the list diff --git a/config/cmake/HDFCXXCompilerFlags.cmake b/config/cmake/HDFCXXCompilerFlags.cmake index dd120c911cb..5f977f534f6 100644 --- a/config/cmake/HDFCXXCompilerFlags.cmake +++ b/config/cmake/HDFCXXCompilerFlags.cmake @@ -65,7 +65,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC" AND CMAKE_CXX_COMPILER_LOADED) endif () endif () -if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_LOADED) +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_LOADED) set (CMAKE_CXX_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_CXX_FLAGS}") if (${HDF_CFG_NAME} MATCHES "Debug" OR ${HDF_CFG_NAME} MATCHES "Developer") if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) @@ -143,7 +143,7 @@ else () endif() endif() elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_LOADED + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_LOADED AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) # add the general CXX flags for g++ compiler versions 4.8 and above. ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-general") @@ -311,7 +311,7 @@ endif () # This is in here to help some of the GCC based IDES like Eclipse # and code blocks parse the compiler errors and warnings better. #----------------------------------------------------------------------------- -if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_LOADED) +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_LOADED) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmessage-length=0") endif () diff --git a/config/cmake/HDFCompilerFlags.cmake b/config/cmake/HDFCompilerFlags.cmake index 007747a6166..d8a444b84d2 100644 --- a/config/cmake/HDFCompilerFlags.cmake +++ b/config/cmake/HDFCompilerFlags.cmake @@ -96,7 +96,7 @@ if (CMAKE_C_COMPILER_ID STREQUAL "NVHPC" ) set (CMAKE_C_FLAGS_RELWITHDEBINFO "${cmake_c_flags_relwithdebinfo_edited}") endif () -if (CMAKE_COMPILER_IS_GNUCC) +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") set (CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}") if (${HDF_CFG_NAME} MATCHES "Debug" OR ${HDF_CFG_NAME} MATCHES "Developer") if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) @@ -405,7 +405,7 @@ endif () # This is in here to help some of the GCC based IDES like Eclipse # and code blocks parse the compiler errors and warnings better. #----------------------------------------------------------------------------- -if (CMAKE_COMPILER_IS_GNUCC) +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0") endif () diff --git a/config/cmake/HDFUseFortran.cmake b/config/cmake/HDFUseFortran.cmake index 2d53a506124..44d3e7cfd2b 100644 --- a/config/cmake/HDFUseFortran.cmake +++ b/config/cmake/HDFUseFortran.cmake @@ -43,71 +43,26 @@ file (STRINGS ${CMAKE_BINARY_DIR}/FCMangle.h CONTENTS REGEX "H5_FC_GLOBAL_\\(.*, string (REGEX MATCH "H5_FC_GLOBAL_\\(.*,.*\\) +(.*)" RESULT ${CONTENTS}) set (H5_FC_FUNC_ "H5_FC_FUNC_(name,NAME) ${CMAKE_MATCH_1}") -#test code source -set (SIZEOF_CODE - " - PROGRAM main - i = sizeof(x) - END PROGRAM - " -) -set (C_SIZEOF_CODE - " - PROGRAM main - USE ISO_C_BINDING - INTEGER(C_INT) :: a - INTEGER(C_SIZE_T) :: result - result = c_sizeof(a) - END PROGRAM - " -) -set (STORAGE_SIZE_CODE - " - PROGRAM main - INTEGER :: a - INTEGER :: result - result = storage_size(a) - END PROGRAM - " -) -set (CHAR_ALLOC - " - PROGRAM main - CHARACTER(:), ALLOCATABLE :: str - END PROGRAM - " -) -set (ISO_FORTRAN_ENV_CODE - " - PROGRAM main - USE, INTRINSIC :: ISO_FORTRAN_ENV - END PROGRAM - " -) -set (REALISNOTDOUBLE_CODE - " - MODULE type_mod - INTERFACE h5t - MODULE PROCEDURE h5t_real - MODULE PROCEDURE h5t_dble - END INTERFACE - CONTAINS - SUBROUTINE h5t_real(r) - REAL :: r - END SUBROUTINE h5t_real - SUBROUTINE h5t_dble(d) - DOUBLE PRECISION :: d - END SUBROUTINE h5t_dble - END MODULE type_mod - PROGRAM main - USE type_mod - REAL :: r - DOUBLE PRECISION :: d - CALL h5t(r) - CALL h5t(d) - END PROGRAM main - " -) +# Read source line beginning at the line matching Input:"START" and ending at the line matching Input:"END" +macro (READ_SOURCE SOURCE_START SOURCE_END RETURN_VAR) + file (READ "${HDF5_SOURCE_DIR}/m4/aclocal_fc.f90" SOURCE_MASTER) + string (REGEX MATCH "${SOURCE_START}[\\\t\\\n\\\r[].+]*${SOURCE_END}" SOURCE_CODE ${SOURCE_MASTER}) + set (RETURN_VAR "${SOURCE_CODE}") +endmacro () + +if (HDF5_REQUIRED_LIBRARIES) + set (CMAKE_REQUIRED_LIBRARIES "${HDF5_REQUIRED_LIBRARIES}") +endif () + +READ_SOURCE("PROGRAM PROG_FC_SIZEOF" "END PROGRAM PROG_FC_SIZEOF" SOURCE_CODE) +check_fortran_source_compiles (${SOURCE_CODE} ${HDF_PREFIX}_FORTRAN_HAVE_SIZEOF SRC_EXT f90) + +READ_SOURCE("PROGRAM PROG_FC_C_SIZEOF" "END PROGRAM PROG_FC_C_SIZEOF" SOURCE_CODE) +check_fortran_source_compiles (${SOURCE_CODE} ${HDF_PREFIX}_FORTRAN_HAVE_C_SIZEOF SRC_EXT f90) + +READ_SOURCE("PROGRAM PROG_FC_STORAGE_SIZE" "END PROGRAM PROG_FC_STORAGE_SIZE" SOURCE_CODE) +check_fortran_source_compiles (${SOURCE_CODE} ${HDF_PREFIX}_FORTRAN_HAVE_STORAGE_SIZE SRC_EXT f90) + set (ISO_C_BINDING_CODE " PROGRAM main @@ -121,17 +76,7 @@ set (ISO_C_BINDING_CODE END PROGRAM " ) - -if (HDF5_REQUIRED_LIBRARIES) - set (CMAKE_REQUIRED_LIBRARIES "${HDF5_REQUIRED_LIBRARIES}") -endif () -check_fortran_source_compiles (${SIZEOF_CODE} ${HDF_PREFIX}_FORTRAN_HAVE_SIZEOF SRC_EXT f90) -check_fortran_source_compiles (${C_SIZEOF_CODE} ${HDF_PREFIX}_FORTRAN_HAVE_C_SIZEOF SRC_EXT f90) -check_fortran_source_compiles (${STORAGE_SIZE_CODE} ${HDF_PREFIX}_FORTRAN_HAVE_STORAGE_SIZE SRC_EXT f90) -check_fortran_source_compiles (${ISO_FORTRAN_ENV_CODE} ${HDF_PREFIX}_HAVE_ISO_FORTRAN_ENV SRC_EXT f90) -check_fortran_source_compiles (${REALISNOTDOUBLE_CODE} ${HDF_PREFIX}_FORTRAN_DEFAULT_REAL_NOT_DOUBLE SRC_EXT f90) check_fortran_source_compiles (${ISO_C_BINDING_CODE} ${HDF_PREFIX}_FORTRAN_HAVE_ISO_C_BINDING SRC_EXT f90) -check_fortran_source_compiles (${CHAR_ALLOC} ${HDF_PREFIX}_FORTRAN_HAVE_CHAR_ALLOC SRC_EXT f90) #----------------------------------------------------------------------------- # Add debug information (intel Fortran : JB) diff --git a/config/cmake/LIBAEC/CMakeLists.txt b/config/cmake/LIBAEC/CMakeLists.txt index 11f79414e2a..54482163c5e 100644 --- a/config/cmake/LIBAEC/CMakeLists.txt +++ b/config/cmake/LIBAEC/CMakeLists.txt @@ -134,7 +134,7 @@ endif () # This is in here to help some of the GCC based IDES like Eclipse # and code blocks parse the compiler errors and warnings better. #----------------------------------------------------------------------------- -if (CMAKE_COMPILER_IS_GNUCC) +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0") endif () diff --git a/config/cmake/ZLIB/CMakeLists.txt b/config/cmake/ZLIB/CMakeLists.txt index 529f1446a58..7b5d0cf62dd 100644 --- a/config/cmake/ZLIB/CMakeLists.txt +++ b/config/cmake/ZLIB/CMakeLists.txt @@ -128,7 +128,7 @@ endif () #----------------------------------------------------------------------------- # Compiler specific flags : Shouldn't there be compiler tests for these #----------------------------------------------------------------------------- -if (CMAKE_COMPILER_IS_GNUCC) +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") set (CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS} -Wno-strict-prototypes") endif () if (CMAKE_C_COMPILER_ID MATCHES "IntelLLVM" OR CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") @@ -139,7 +139,7 @@ endif () # This is in here to help some of the GCC based IDES like Eclipse # and code blocks parse the compiler errors and warnings better. #----------------------------------------------------------------------------- -if (CMAKE_COMPILER_IS_GNUCC) +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0") endif () @@ -196,7 +196,7 @@ if(NOT MINGW) ) endif() -if(CMAKE_COMPILER_IS_GNUCC) +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") if(ASM686) set(ZLIB_ASMS contrib/asm686/match.S) elseif (AMD64) diff --git a/config/conclude.am b/config/conclude.am index a1fda99ba35..9b73ae77792 100644 --- a/config/conclude.am +++ b/config/conclude.am @@ -155,15 +155,15 @@ $(TEST_PROG_CHKEXE) $(TEST_PROG_PARA_CHKEXE) dummy.chkexe_: if test -n "$(HDF5_VOL_CONNECTOR)"; then \ echo "VOL connector: $(HDF5_VOL_CONNECTOR)" | tee -a $${log}; \ fi; \ - if test -n "$(HDF5_DRIVER)"; then \ - echo "Virtual file driver (VFD): $(HDF5_DRIVER)" | tee -a $${log}; \ + if test -n "$(HDF5_TEST_DRIVER)"; then \ + echo "Virtual file driver (VFD): $(HDF5_TEST_DRIVER)" | tee -a $${log}; \ fi; \ else \ if test -n "$(HDF5_VOL_CONNECTOR)"; then \ echo "VOL connector: $(HDF5_VOL_CONNECTOR)" >> $${log}; \ fi; \ - if test -n "$(HDF5_DRIVER)"; then \ - echo "Virtual file driver (VFD): $(HDF5_DRIVER)" >> $${log}; \ + if test -n "$(HDF5_TEST_DRIVER)"; then \ + echo "Virtual file driver (VFD): $(HDF5_TEST_DRIVER)" >> $${log}; \ fi; \ fi; \ if test -n "$(REALTIMEOUTPUT)"; then \ @@ -276,11 +276,22 @@ build-check-p: $(LIB) $(PROGS) $(chk_TESTS) echo "===Parallel tests in `echo ${PWD} | sed -e s:.*/::` ended `date`===";\ fi -VFD_LIST = sec2 stdio core core_paged split multi family splitter +VFD_LIST = sec2 stdio core core_paged split multi family + +# Splitter VFD currently can't be tested with the h5_fileaccess() +# approach due to it trying to lock the same W/O file when two +# files are created/opened with the same FAPL that has the VFD +# set on it. When tested with the environment variable and a +# default FAPL, the VFD appends "_wo" to the filename when the +# W/O path isn't specified, which works for all the tests. +# VFD_LIST += splitter # log VFD currently has file space allocation bugs # VFD_LIST += log +# Not currently tested with VFD tests +# VFD_LIST += onion + if DIRECT_VFD_CONDITIONAL VFD_LIST += direct endif @@ -302,21 +313,20 @@ if HDFS_VFD_CONDITIONAL # VFD_LIST += hdfs endif if SUBFILING_VFD_CONDITIONAL - # Several VFD tests fail with Subfiling since it - # doesn't currently support collective I/O + # Subfiling has a few VFD test failures to be resolved # VFD_LIST += subfiling endif # Run test with different Virtual File Driver check-vfd: $(LIB) $(PROGS) $(chk_TESTS) - @for vfd in $(VFD_LIST) dummy; do \ - if test $$vfd != dummy; then \ - echo "============================"; \ - echo "Testing Virtual File Driver $$vfd"; \ - echo "============================"; \ - $(MAKE) $(AM_MAKEFLAGS) check-clean || exit 1; \ - HDF5_DRIVER=$$vfd $(MAKE) $(AM_MAKEFLAGS) check || exit 1; \ - fi; \ + @for vfd in $(VFD_LIST) dummy; do \ + if test $$vfd != dummy; then \ + echo "============================"; \ + echo "Testing Virtual File Driver $$vfd"; \ + echo "============================"; \ + $(MAKE) $(AM_MAKEFLAGS) check-clean || exit 1; \ + HDF5_TEST_DRIVER=$$vfd $(MAKE) $(AM_MAKEFLAGS) check || exit 1; \ + fi; \ done # Test with just the native connector, with a single pass-through connector diff --git a/config/gnu-warnings/8 b/config/gnu-warnings/8 index 5e7519dd795..323110950b1 100644 --- a/config/gnu-warnings/8 +++ b/config/gnu-warnings/8 @@ -1,3 +1,2 @@ -Wattribute-alias --Wcast-align=strict -Wshift-overflow=2 diff --git a/config/gnu-warnings/error-8 b/config/gnu-warnings/error-8 index 36c14143228..25839a847b4 100644 --- a/config/gnu-warnings/error-8 +++ b/config/gnu-warnings/error-8 @@ -7,3 +7,14 @@ # that GCC 8 only performs that analysis at -O3, though. # -Werror=maybe-uninitialized +# Ask GCC to warn about cast-align problems, even on platforms where +# it normally wouldn't (because those platforms don't require alignment). +# While this flag doesn't follow the -Werror format like above, it's +# placed here to make sure that it comes after the -Werror=cast-align +# line from error-general in the list of flags. Otherwise, if the +# '--enable-warnings-as-errors' flag isn't passed at configure time, +# the logic in config/gnu-flags that demotes these errors to their +# normal warning form will cause -Wcast-align to come after +# -Wcast-align=strict in the list of flags, causing it to take +# precedence and mask cast-align warnings from GCC on certain platforms. +-Wcast-align=strict diff --git a/config/sanitizer/sanitizers.cmake b/config/sanitizer/sanitizers.cmake index bf2aad27d7c..72f101f4c25 100644 --- a/config/sanitizer/sanitizers.cmake +++ b/config/sanitizer/sanitizers.cmake @@ -57,9 +57,15 @@ if(USE_SANITIZER) if(UNIX) append("-fno-omit-frame-pointer" CMAKE_C_FLAGS) message(STATUS "Building with sanitize, base flags=${CMAKE_C_SANITIZER_FLAGS}") + if (CMAKE_CXX_COMPILER_LOADED) + append("-fno-omit-frame-pointer" CMAKE_CXX_FLAGS) + endif () if(uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") append("-O1" CMAKE_C_FLAGS) + if (CMAKE_CXX_COMPILER_LOADED) + append("-O1" CMAKE_CXX_FLAGS) + endif () endif() if(USE_SANITIZER MATCHES "([Aa]ddress)") @@ -80,11 +86,10 @@ if(USE_SANITIZER) endif() if(USE_SANITIZER MATCHES "([Mm]emory([Ww]ith[Oo]rigins)?)") - # Optional: -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 set(SANITIZER_MEM_FLAG "-fsanitize=memory") if(USE_SANITIZER MATCHES "([Mm]emory[Ww]ith[Oo]rigins)") message(STATUS "Testing with MemoryWithOrigins sanitizer") - append("-fsanitize-memory-track-origins" SANITIZER_MEM_FLAG) + append("-fno-optimize-sibling-calls -fsanitize-memory-track-origins=2" SANITIZER_MEM_FLAG) else() message(STATUS "Testing with Memory sanitizer") endif() @@ -177,6 +182,9 @@ if(USE_SANITIZER) if(SANITIZER_SELECTED_COMPATIBLE) message(STATUS " Building with ${SANITIZER_SELECTED_FLAGS}") append("${SANITIZER_SELECTED_FLAGS}" CMAKE_C_FLAGS) + if (CMAKE_CXX_COMPILER_LOADED) + append("${SANITIZER_SELECTED_FLAGS}" CMAKE_CXX_FLAGS) + endif () else() message(FATAL_ERROR "Unsupported value of USE_SANITIZER: ${USE_SANITIZER}") endif() @@ -184,6 +192,9 @@ if(USE_SANITIZER) if(USE_SANITIZER MATCHES "([Aa]ddress)") message(STATUS "Building with Address sanitizer") append("-fsanitize=address" CMAKE_C_FLAGS) + if (CMAKE_CXX_COMPILER_LOADED) + append("-fsanitize=address" CMAKE_CXX_FLAGS) + endif () if(AFL) append_quoteless(AFL_USE_ASAN=1 CMAKE_C_COMPILER_LAUNCHER) @@ -198,6 +209,9 @@ if(USE_SANITIZER) if(USE_SANITIZER MATCHES "([Aa]ddress)") message(STATUS "Building with Address sanitizer") append("/fsanitize=address" CMAKE_C_FLAGS) + if (CMAKE_CXX_COMPILER_LOADED) + append("/fsanitize=address" CMAKE_CXX_FLAGS) + endif () else() message(FATAL_ERROR "This sanitizer not yet supported in the MSVC environment: ${USE_SANITIZER}") endif() diff --git a/configure.ac b/configure.ac index 86136bb0f1b..6b546dc1f5e 100644 --- a/configure.ac +++ b/configure.ac @@ -198,21 +198,36 @@ saved_user_CPPFLAGS="$CPPFLAGS" ## ## Regex: ## -## -Werror Literal -Werror -## \( Start optional capturing group -## = Literal equals sign -## [^[:space:]-] Non-space characters -## \+ 1 or more of the above -## \) End optional capturing group -## \? 0 or 1 capturing group matches +## -Werror Literal -Werror +## \( Start optional capturing group +## = Literal equals sign +## [^[:space:]] Non-space characters +## \+ 1 or more of the above +## \) End optional capturing group +## \? 0 or 1 capturing group matches ## -WERROR_SED= "sed -e 's/-Werror\(=[^[:space:]]\+\)\?//g'" - -CFLAGS="`echo $CFLAGS | $WERROR_SED`" -CXXFLAGS="`echo $CXXFLAGS | $WERROR_SED`" -FCFLAGS="`echo $FCFLAGS | $WERROR_SED`" -JAVACFLAGS="`echo $JAVACFLAGS | $WERROR_SED`" -CPPFLAGS="`echo $CPPFLAGS | $WERROR_SED`" +## Note that the outer pair of '[]' ends up getting removed +WERROR_SED='s/-Werror\(=[[^[:space:]]]\+\)\?//g' +CFLAGS_SED="`echo $CFLAGS | sed -e $WERROR_SED`" +if test $? -eq 0; then + CFLAGS="$CFLAGS_SED" +fi +CXXFLAGS_SED="`echo $CXXFLAGS | sed -e $WERROR_SED`" +if test $? -eq 0; then + CXXFLAGS="$CXXFLAGS_SED" +fi +FCFLAGS_SED="`echo $FCFLAGS | sed -e $WERROR_SED`" +if test $? -eq 0; then + FCFLAGS="$FCFLAGS_SED" +fi +JAVACFLAGS_SED="`echo $JAVACFLAGS | sed -e $WERROR_SED`" +if test $? -eq 0; then + JAVACFLAGS="$JAVACFLAGS_SED" +fi +CPPFLAGS_SED="`echo $CPPFLAGS | sed -e $WERROR_SED`" +if test $? -eq 0; then + CPPFLAGS="$CPPFLAGS_SED" +fi ## Support F9X variable to define Fortran compiler if FC variable is ## not used. This should be deprecated in the future. @@ -786,6 +801,15 @@ if test "X$HDF_FORTRAN" = "Xyes"; then ## See if the fortran compiler supports the intrinsic function "STORAGE_SIZE" PAC_PROG_FC_STORAGE_SIZE + ## -------------------------------------------------------------------- + ## Checking if the fortran compiler supports ISO_FORTRAN_ENV (Fortran 2008) + HAVE_ISO_FORTRAN_ENV="0" + PAC_PROG_FC_ISO_FORTRAN_ENV + if test "X$CHECK_ISO_FORTRAN_ENV" = "Xyes"; then + HAVE_ISO_FORTRAN_ENV="1" + AC_DEFINE([HAVE_ISO_FORTRAN_ENV], [1], [Define if Fortran supports ISO_FORTRAN_ENV (F08)]) + fi + ## Set the sizeof function for use later in the fortran tests if test "X$HAVE_STORAGE_SIZE_FORTRAN" = "Xyes";then FC_SIZEOF_A="STORAGE_SIZE(a, c_size_t)/STORAGE_SIZE(c_char_'a',c_size_t)" @@ -802,14 +826,17 @@ if test "X$HDF_FORTRAN" = "Xyes"; then fi fi - ## See if the fortran compiler supports the intrinsic module "ISO_FORTRAN_ENV" - PAC_PROG_FC_ISO_FORTRAN_ENV ## Check KIND and size of native integer PAC_FC_NATIVE_INTEGER ## Find all available KINDs - PAC_FC_AVAIL_KINDS - ## Find all sizeofs for available KINDs + if test "X$HAVE_ISO_FORTRAN_ENV" = "X1";then + PAC_FC_AVAIL_KINDS_F08 + else + PAC_FC_AVAIL_KINDS + fi + + ## Find all SIZEOFs for available KINDs PAC_FC_SIZEOF_INT_KINDS PAC_FC_SIZEOF_REAL_KINDS @@ -829,6 +856,7 @@ if test "X$HDF_FORTRAN" = "Xyes"; then AC_SUBST([FORTRAN_HAVE_C_LONG_DOUBLE]) AC_SUBST([FORTRAN_C_LONG_DOUBLE_IS_UNIQUE]) AC_SUBST([FORTRAN_C_BOOL_IS_UNIQUE]) + AC_SUBST([HAVE_ISO_FORTRAN_ENV]) AC_SUBST([H5CONFIG_F_NUM_RKIND]) AC_SUBST([H5CONFIG_F_RKIND]) AC_SUBST([H5CONFIG_F_RKIND_SIZEOF]) @@ -3032,6 +3060,16 @@ if test -n "$PARALLEL"; then [AC_MSG_RESULT([no])] ) AC_LANG_POP(Fortran) + + if test "X$HDF5_TESTS" = "Xyes"; then + AC_SUBST([MPI_LOGICAL_KIND]) + PAC_FIND_MPI_LOGICAL_KIND + if test "X$" = "Xyes"; then + HAVE_ISO_FORTRAN_ENV="1" + AC_DEFINE([HAVE_ISO_FORTRAN_ENV], [1], [Define if Fortran supports ISO_FORTRAN_ENV (F08)]) + fi + fi + fi ## ---------------------------------------------------------------------- diff --git a/doc/getting-started-with-hdf5-development.md b/doc/getting-started-with-hdf5-development.md index b6771dca76e..687a1ea7cca 100644 --- a/doc/getting-started-with-hdf5-development.md +++ b/doc/getting-started-with-hdf5-development.md @@ -726,7 +726,7 @@ are others in `h5test.h` if you want to emit custom text, dump the HDF5 error stack when it would not normally be triggered, etc. Most tests will be set up to run with arbitrary VFDs. To do this, you set the -fapl ID using the `h5_fileaccess()` function, which will check the `HDF5_DRIVER` +fapl ID using the `h5_fileaccess()` function, which will check the `HDF5_TEST_DRIVER` environment variable and set the fapl's VFD accordingly. The `h5_fixname()` call can then be used to get a VFD-appropriate filename for the `H5Fcreate()`, etc. call. diff --git a/doxygen/aliases b/doxygen/aliases index ad868432bee..0f5a4a4ed8f 100644 --- a/doxygen/aliases +++ b/doxygen/aliases @@ -234,14 +234,14 @@ ALIASES += sa_metadata_ops="\sa \li H5Pget_all_coll_metadata_ops() \li H5Pget_co # References ################################################################################ -ALIASES += ref_cons_semantics="Enabling a Strict Consistency Semantics Model in Parallel HDF5" -ALIASES += ref_file_image_ops="HDF5 File Image Operations" +ALIASES += ref_cons_semantics="Enabling a Strict Consistency Semantics Model in Parallel HDF5" +ALIASES += ref_file_image_ops="HDF5 File Image Operations" ALIASES += ref_filter_pipe="Data Flow Pipeline for H5Dread()" -ALIASES += ref_group_impls="Group implementations in HDF5" -ALIASES += ref_h5lib_relver="HDF5 Library Release Version Numbers" +ALIASES += ref_group_impls="Group implementations in HDF5" +ALIASES += ref_h5lib_relver="HDF5 Library Release Version Numbers" ALIASES += ref_mdc_in_hdf5="Metadata Caching in HDF5" ALIASES += ref_mdc_logging="Metadata Cache Logging" -ALIASES += ref_news_112="New Features in HDF5 Release 1.12" +ALIASES += ref_news_112="New Features in HDF5 Release 1.12" ALIASES += ref_h5ocopy="Copying Committed Datatypes with H5Ocopy()" ALIASES += ref_sencode_fmt_change="RFC H5Secnode() / H5Sdecode() Format Change" ALIASES += ref_vlen_strings="\Emph{Creating variable-length string datatypes}" diff --git a/doxygen/dox/ExamplesAPI.dox b/doxygen/dox/ExamplesAPI.dox index 5178b0875a9..b0344e48cb1 100644 --- a/doxygen/dox/ExamplesAPI.dox +++ b/doxygen/dox/ExamplesAPI.dox @@ -394,8 +394,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_arrayatt.h5 -h5ex_t_arrayatt.tst -h5ex_t_arrayatt.ddl +h5ex_t_arrayatt.tst +h5ex_t_arrayatt.ddl Read / Write Array (Dataset) @@ -407,8 +407,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_array.h5 -h5ex_t_array.tst -h5ex_t_array.ddl +h5ex_t_array.tst +h5ex_t_array.ddl Read / Write Bitfield (Attribute) @@ -420,8 +420,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_bitatt.h5 -h5ex_t_bitatt.tst -h5ex_t_bitatt.ddl +h5ex_t_bitatt.tst +h5ex_t_bitatt.ddl Read / Write Bitfield (Dataset) @@ -433,8 +433,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_bit.h5 -h5ex_t_bit.tst -h5ex_t_bit.ddl +h5ex_t_bit.tst +h5ex_t_bit.ddl Read / Write Compound (Attribute) @@ -446,8 +446,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_cmpdatt.h5 -h5ex_t_cmpdatt.tst -h5ex_t_cmpdatt.ddl +h5ex_t_cmpdatt.tst +h5ex_t_cmpdatt.ddl Read / Write Compound (Dataset) @@ -459,8 +459,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_cmpd.h5 -h5ex_t_cmpd.tst -h5ex_t_cmpd.ddl +h5ex_t_cmpd.tst +h5ex_t_cmpd.ddl Commit Named Datatype and Read Back @@ -472,8 +472,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_commit.h5 -h5ex_t_commit.tst -h5ex_t_commit.ddl +h5ex_t_commit.tst +h5ex_t_commit.ddl Convert Between Datatypes in Memory @@ -482,8 +482,8 @@ FORTRAN FORTRAN Java JavaObj MATLAB PyHigh PyLow h5ex_t_convert.h5 -h5ex_t_convert.tst -h5ex_t_convert.ddl +h5ex_t_convert.tst +h5ex_t_convert.ddl Read / Write Complex Compound (Attribute) @@ -492,8 +492,8 @@ FORTRAN FORTRAN Java JavaObj MATLAB PyHigh PyLow h5ex_t_cpxcmpdatt.h5 -h5ex_t_cpxcmpdatt.tst -h5ex_t_cpxcmpdatt.ddl +h5ex_t_cpxcmpdatt.tst +h5ex_t_cpxcmpdatt.ddl Read / Write Complex Compound (Dataset) @@ -502,8 +502,8 @@ FORTRAN FORTRAN Java JavaObj MATLAB PyHigh PyLow h5ex_t_cpxcmpd.h5 -h5ex_t_cpxcmpd.tst -h5ex_t_cpxcmpd.ddl +h5ex_t_cpxcmpd.tst +h5ex_t_cpxcmpd.ddl Read / Write Enumerated (Attribute) @@ -513,8 +513,8 @@ FORTRAN Java JavaObj MATLAB PyHigh PyLow h5ex_t_enumatt.h5 -h5ex_t_enumatt.tst -h5ex_t_enumatt.ddl +h5ex_t_enumatt.tst +h5ex_t_enumatt.ddl Read / Write Enumerated (Dataset) @@ -524,8 +524,8 @@ FORTRAN Java JavaObj MATLAB PyHigh PyLow h5ex_t_enum.h5 -h5ex_t_enum.tst -h5ex_t_enum.ddl +h5ex_t_enum.tst +h5ex_t_enum.ddl Read / Write Floating Point (Attribute) @@ -537,8 +537,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_floatatt.h5 -h5ex_t_floatatt.tst -h5ex_t_floatatt.ddl +h5ex_t_floatatt.tst +h5ex_t_floatatt.ddl Read / Write Floating Point (Dataset) @@ -550,8 +550,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_float.h5 -h5ex_t_float.tst -h5ex_t_float.ddl +h5ex_t_float.tst +h5ex_t_float.ddl Read / Write Integer Datatype (Attribute) @@ -563,8 +563,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_intatt.h5 -h5ex_t_intatt.tst -h5ex_t_intatt.ddl +h5ex_t_intatt.tst +h5ex_t_intatt.ddl Read / Write Integer Datatype (Dataset) @@ -576,8 +576,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_int.h5 -h5ex_t_int.tst -h5ex_t_int.ddl +h5ex_t_int.tst +h5ex_t_int.ddl Read / Write Object References (Attribute) @@ -589,8 +589,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_objrefatt.h5 -h5ex_t_objrefatt.tst -h5ex_t_objrefatt.ddl +h5ex_t_objrefatt.tst +h5ex_t_objrefatt.ddl Read / Write Object References (Dataset) @@ -602,8 +602,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_objref.h5 -h5ex_t_objref.tst -h5ex_t_objref.ddl +h5ex_t_objref.tst +h5ex_t_objref.ddl Read / Write Opaque (Attribute) @@ -615,8 +615,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_opaqueatt.h5 -h5ex_t_opaqueatt.tst -h5ex_t_opaqueatt.ddl +h5ex_t_opaqueatt.tst +h5ex_t_opaqueatt.ddl Read / Write Opaque (Dataset) @@ -628,8 +628,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_opaque.h5 -h5ex_t_opaque.tst -h5ex_t_opaque.ddl +h5ex_t_opaque.tst +h5ex_t_opaque.ddl Read / Write Region References (Attribute) @@ -641,8 +641,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_regrefatt.h5 -h5ex_t_regrefatt.tst -h5ex_t_regrefatt.ddl +h5ex_t_regrefatt.tst +h5ex_t_regrefatt.ddl Read / Write Region References (Dataset) @@ -654,8 +654,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_regref.h5 -h5ex_t_regref.tst -h5ex_t_regref.ddl +h5ex_t_regref.tst +h5ex_t_regref.ddl Read / Write String (Attribute) @@ -667,8 +667,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_stringatt.h5 -h5ex_t_stringatt.tst -h5ex_t_stringatt.ddl +h5ex_t_stringatt.tst +h5ex_t_stringatt.ddl Read / Write String (Dataset) @@ -680,8 +680,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_string.h5 -h5ex_t_string.tst -h5ex_t_string.ddl +h5ex_t_string.tst +h5ex_t_string.ddl Read / Write Variable Length (Attribute) @@ -691,8 +691,8 @@ FORTRAN Java JavaObj MATLAB PyHigh PyLow h5ex_t_vlenatt.h5 -h5ex_t_vlenatt.tst -h5ex_t_vlenatt.ddl +h5ex_t_vlenatt.tst +h5ex_t_vlenatt.ddl Read / Write Variable Length (Dataset) @@ -702,8 +702,8 @@ FORTRAN Java JavaObj MATLAB PyHigh PyLow h5ex_t_vlen.h5 -h5ex_t_vlen.tst -h5ex_t_vlen.ddl +h5ex_t_vlen.tst +h5ex_t_vlen.ddl Read / Write Variable Length String (Attribute) @@ -713,8 +713,8 @@ FORTRAN Java JavaObj MATLAB PyHigh PyLow h5ex_t_vlstringatt.h5 -h5ex_t_vlstringatt.tst -h5ex_t_vlstringatt.ddl +h5ex_t_vlstringatt.tst +h5ex_t_vlstringatt.ddl Read / Write Variable Length String (Dataset) @@ -726,8 +726,8 @@ FORTRAN MATLAB PyHigh PyLow h5ex_t_vlstring.h5 -h5ex_t_vlstring.tst -h5ex_t_vlstring.ddl +h5ex_t_vlstring.tst +h5ex_t_vlstring.ddl diff --git a/doxygen/dox/GettingStarted.dox b/doxygen/dox/GettingStarted.dox index 87f3566361e..feb5f919f9a 100644 --- a/doxygen/dox/GettingStarted.dox +++ b/doxygen/dox/GettingStarted.dox @@ -42,7 +42,7 @@ Parallel HDF5, and the HDF5-1.10 VDS and SWMR new features: diff --git a/doxygen/dox/IntroHDF5.dox b/doxygen/dox/IntroHDF5.dox index afe534be614..33cf4a91ca8 100644 --- a/doxygen/dox/IntroHDF5.dox +++ b/doxygen/dox/IntroHDF5.dox @@ -608,7 +608,7 @@ on the HDF-EOS Tools and Information Center pag \section secHDF5Examples Examples \li \ref LBExamples \li \ref ExAPI -\li Examples in the Source Code +\li Examples in the Source Code \li Other Examples \section secHDF5ExamplesCompile How To Compile diff --git a/doxygen/dox/LearnBasics3.dox b/doxygen/dox/LearnBasics3.dox index 2cf94b0246f..be227c2ba2c 100644 --- a/doxygen/dox/LearnBasics3.dox +++ b/doxygen/dox/LearnBasics3.dox @@ -294,12 +294,12 @@ Specifically look at the \ref ExAPI. There are examples for different languages, where examples of using #H5Literate and #H5Ovisit/#H5Lvisit are included. The h5ex_g_traverse example traverses a file using H5Literate: -\li C: h5ex_g_traverse.c -\li F90: h5ex_g_traverse_F03.f90 +\li C: h5ex_g_traverse.c +\li F90: h5ex_g_traverse_F03.f90 The h5ex_g_visit example traverses a file using H5Ovisit and H5Lvisit: -\li C: h5ex_g_visit.c -\li F90: h5ex_g_visit_F03.f90 +\li C: h5ex_g_visit.c +\li F90: h5ex_g_visit_F03.f90
Navigate back: \ref index "Main" / \ref GettingStarted / \ref LearnBasics diff --git a/doxygen/dox/LearnHDFView.dox b/doxygen/dox/LearnHDFView.dox index 8c617f21477..2916db841e6 100644 --- a/doxygen/dox/LearnHDFView.dox +++ b/doxygen/dox/LearnHDFView.dox @@ -7,7 +7,7 @@ This tutorial enables you to get a feel for HDF5 by using the HDFView browser. I any programming experience. \section sec_learn_hv_install HDFView Installation -\li Download and install HDFView. It can be downloaded from the Download HDFView page. +\li Download and install HDFView. It can be downloaded from the Download HDFView page. \li Obtain the storm1.txt text file, used in the tutorial. \section sec_learn_hv_begin Begin Tutorial diff --git a/doxygen/dox/UsersGuide.dox b/doxygen/dox/UsersGuide.dox index b6113ad15bd..3dd26f1a40a 100644 --- a/doxygen/dox/UsersGuide.dox +++ b/doxygen/dox/UsersGuide.dox @@ -374,7 +374,7 @@ These documents provide additional information for the use and tuning of specifi
-Using the High Level APIs +Using the High Level APIs \ref H5LT \ref H5IM \ref H5TB \ref H5PT \ref H5DS @@ -72,7 +72,7 @@ HDF5-1.10 New Features \li Introduction to the Virtual Dataset - VDS -\li Introduction to Single-Writer/Multiple-Reader (SWMR) +\li Introduction to Single-Writer/Multiple-Reader (SWMR)
-

HDF5 Dynamically Loaded Filters

+

HDF5 Dynamically Loaded Filters

Describes how an HDF5 application can apply a filter that is not registered with the HDF5 Library.

@@ -382,7 +382,7 @@ These documents provide additional information for the use and tuning of specifi
-

HDF5 File Image Operations

+

HDF5 File Image Operations

Describes how to work with HDF5 files in memory. Disk I/O is not required when file images are opened, created, read from, or written to.

@@ -390,7 +390,7 @@ These documents provide additional information for the use and tuning of specifi
-

Modified Region Writes

+

Modified Region Writes

Describes how to set write operations for in-memory files so that only modified regions are written to storage. Available when the Core (Memory) VFD is used.

@@ -438,4 +438,4 @@ Previous Chapter \ref sec_plist HDF5 repo, make changes, and create a pull request !\n -*/ \ No newline at end of file +*/ diff --git a/doxygen/dox/VOLConnGuide.dox b/doxygen/dox/VOLConnGuide.dox index fb662a0ef5a..7a03ab1590d 100644 --- a/doxygen/dox/VOLConnGuide.dox +++ b/doxygen/dox/VOLConnGuide.dox @@ -92,7 +92,7 @@ Public header Files you will need to be familiar with include:
Many VOL connectors are listed on The HDF Group's VOL plugin registration page, located at: -Registered VOL Connectors. +Registered VOL Connectors. Not all of these VOL connectors are supported by The HDF Group and the level of completeness varies, but the connectors found there can serve as examples of working implementations @@ -195,7 +195,7 @@ contact help@hdfgroup.org for help with this. We name you've chosen will appear on the registered VOL connectors page. As noted above, registered VOL connectors will be listed at: -Registered VOL Connectors +Registered VOL Connectors A new \b conn_version field has been added to the class struct for 1.13. This field is currently not used by the library so its use is determined by the connector author. Best practices for this field will be determined diff --git a/doxygen/dox/ViewTools.dox b/doxygen/dox/ViewTools.dox index 951605674be..f4c31c83663 100644 --- a/doxygen/dox/ViewTools.dox +++ b/doxygen/dox/ViewTools.dox @@ -48,7 +48,7 @@ Navigate back: \ref index "Main" / \ref GettingStarted \section secViewToolsCommandObtain Obtain Tools and Files (Optional) Pre-built binaries for Linux and Windows are distributed within the respective HDF5 binary release -packages, which can be obtained from the Download HDF5 page. +packages, which can be obtained from the Download HDF5 page. HDF5 files can be obtained from various places such as \ref HDF5Examples and HDF-EOS and Tools and Information Center. Specifically, the following examples are used in this tutorial topic: diff --git a/fortran/src/CMakeLists.txt b/fortran/src/CMakeLists.txt index b2ac81ea0c6..1b23c94a976 100644 --- a/fortran/src/CMakeLists.txt +++ b/fortran/src/CMakeLists.txt @@ -69,11 +69,21 @@ if (H5_FORTRAN_HAVE_C_SIZEOF) set (CMAKE_H5_FORTRAN_HAVE_C_SIZEOF 1) endif () +set (CMAKE_H5_HAVE_ISO_FORTRAN_ENV 0) +if (H5_HAVE_ISO_FORTRAN_ENV) + set (CMAKE_H5_HAVE_ISO_FORTRAN_ENV 1) +endif () + set (CMAKE_H5_FORTRAN_HAVE_CHAR_ALLOC 0) if (H5_FORTRAN_HAVE_CHAR_ALLOC) set (CMAKE_H5_FORTRAN_HAVE_CHAR_ALLOC 1) endif () +set (CMAKE_H5_MPI_LOGICAL_KIND 0) +if (H5_MPI_LOGICAL_KIND) + set (CMAKE_H5_MPI_LOGICAL_KIND 1) +endif () + configure_file (${HDF5_F90_SRC_SOURCE_DIR}/H5config_f.inc.cmake ${HDF5_F90_BINARY_DIR}/H5config_f.inc @ONLY) configure_file (${HDF5_F90_SRC_SOURCE_DIR}/H5fort_type_defines.h.cmake ${HDF5_F90_BINARY_DIR}/H5fort_type_defines.h @ONLY) diff --git a/fortran/src/H5Eff.F90 b/fortran/src/H5Eff.F90 index 162a7508085..20f45473a3b 100644 --- a/fortran/src/H5Eff.F90 +++ b/fortran/src/H5Eff.F90 @@ -306,19 +306,16 @@ END SUBROUTINE h5eset_auto_f !! \param arg19 C style format control strings !! \param arg20 C style format control strings !! -!! \note \p arg[1-20] expects C-style format strings, similar to the -!! system and C functions printf() and fprintf(). -!! Furthermore, special characters, such as ANSI escapes, -!! will only be interpreted correctly if the Fortran equivalent -!! is used. For example, to print \p msg "TEXT" in red and has -!! a space after the text would be: +!! \note \p arg[1-20] expects C-style format strings, similar to the system and C functions printf() and fprintf(). +!! Furthermore, special characters, such as ANSI escapes, will only be interpreted correctly if the Fortran +!! equivalent is used. For example, to print \p msg "TEXT" in red would be: !!

!! \code -!! (..., "%s TEXT %s"//C_NEW_LINE, hdferr, ..., arg1=ACHAR(27)//"[31m", arg2=ACHAR(27)//"[0m" ) +!! (..., "%s TEXT %s", hdferr, ..., arg1=ACHAR(27)//"[31m"//C_NULL_CHAR, arg2=ACHAR(27)//"[0m"//C_NULL_CHAR ) !! \endcode !!
Using "\n" instead of C_NEW_LINE will not be interpereted correctly, and similarly, -!! using "\x1B" instead of ACHAR(27) -!! +!! using "\x1B" instead of ACHAR(27). Also, all \p arg[1-20] characters strings must be +!! NULL terminated. !! !! See C API: @ref H5Epush2() !! diff --git a/fortran/src/H5Pf.c b/fortran/src/H5Pf.c index 17045a25570..ce62673686c 100644 --- a/fortran/src/H5Pf.c +++ b/fortran/src/H5Pf.c @@ -4606,8 +4606,8 @@ h5pset_fapl_mpio_c(hid_t_f *prp_id, void *comm, void *info) herr_t ret; MPI_Comm c_comm; MPI_Info c_info; - c_comm = MPI_Comm_f2c(*((int *)comm)); - c_info = MPI_Info_f2c(*((int *)info)); + c_comm = MPI_Comm_f2c(*((MPI_Fint *)comm)); + c_info = MPI_Info_f2c(*((MPI_Fint *)info)); /* * Call H5Pset_mpi function. @@ -4677,8 +4677,8 @@ h5pset_mpi_params_c(hid_t_f *prp_id, void *comm, void *info) herr_t ret; MPI_Comm c_comm; MPI_Info c_info; - c_comm = MPI_Comm_f2c(*((int *)comm)); - c_info = MPI_Info_f2c(*((int *)info)); + c_comm = MPI_Comm_f2c(*((MPI_Fint *)comm)); + c_info = MPI_Info_f2c(*((MPI_Fint *)info)); /* * Call H5Pset_mpi_params. diff --git a/fortran/src/H5config_f.inc.cmake b/fortran/src/H5config_f.inc.cmake index 44da2befead..bc9f036e020 100644 --- a/fortran/src/H5config_f.inc.cmake +++ b/fortran/src/H5config_f.inc.cmake @@ -79,8 +79,21 @@ ! Define if Fortran C_BOOL is different from default LOGICAL #define H5_FORTRAN_C_BOOL_IS_UNIQUE @H5_FORTRAN_C_BOOL_IS_UNIQUE@ -! Define if the intrinsic module ISO_FORTRAN_ENV exists -#define H5_HAVE_ISO_FORTRAN_ENV @H5_HAVE_ISO_FORTRAN_ENV@ +! Define MPI Fortran KIND of LOGICAL +#cmakedefine01 CMAKE_H5_MPI_LOGICAL_KIND +#if CMAKE_H5_MPI_LOGICAL_KIND == 0 +#undef H5_MPI_LOGICAL_KIND +#else +#define H5_MPI_LOGICAL_KIND @H5_MPI_LOGICAL_KIND@ +#endif + +! Define if Fortran supports ISO_FORTRAN_ENV (F08) +#cmakedefine01 CMAKE_H5_HAVE_ISO_FORTRAN_ENV +#if CMAKE_H5_HAVE_ISO_FORTRAN_ENV == 0 +#undef H5_HAVE_ISO_FORTRAN_ENV +#else +#define H5_HAVE_ISO_FORTRAN_ENV +#endif ! Define the size of C's double #define H5_SIZEOF_DOUBLE @H5_SIZEOF_DOUBLE@ diff --git a/fortran/src/H5config_f.inc.in b/fortran/src/H5config_f.inc.in index cb2ec185735..7f2d3cad8a9 100644 --- a/fortran/src/H5config_f.inc.in +++ b/fortran/src/H5config_f.inc.in @@ -47,9 +47,12 @@ ! Define if Fortran C_BOOL is different from default LOGICAL #undef FORTRAN_C_BOOL_IS_UNIQUE -! Define if the intrinsic module ISO_FORTRAN_ENV exists +! Define if Fortran supports ISO_FORTRAN_ENV (F08) #undef HAVE_ISO_FORTRAN_ENV +! Define MPI Fortran KIND of LOGICAL +#undef MPI_LOGICAL_KIND + ! Define the size of C's double #undef SIZEOF_DOUBLE diff --git a/fortran/test/tH5E_F03.F90 b/fortran/test/tH5E_F03.F90 index b538e20c530..7060d2ee617 100644 --- a/fortran/test/tH5E_F03.F90 +++ b/fortran/test/tH5E_F03.F90 @@ -298,7 +298,8 @@ SUBROUTINE test_error_stack(total_error) ! push a custom error message onto the stack CALL H5Epush_f(estack_id, file, func, line, & cls_id, major, minor, "%s ERROR TEXT %s %s %s", error, & - arg1=ACHAR(27)//"[31m", arg2=ACHAR(27)//"[0m", arg3=ACHAR(0), arg4=ACHAR(10) ) + arg1=ACHAR(27)//"[31m"//C_NULL_CHAR, arg2=ACHAR(27)//"[0m"//C_NULL_CHAR, & + arg3=ACHAR(0)//C_NULL_CHAR, arg4=ACHAR(10)//C_NULL_CHAR ) CALL check("H5Epush_f", error, total_error) CALL h5eget_num_f(estack_id, count, error) diff --git a/fortran/test/tH5P_F03.F90 b/fortran/test/tH5P_F03.F90 index c962d52821b..64dd1d2891c 100644 --- a/fortran/test/tH5P_F03.F90 +++ b/fortran/test/tH5P_F03.F90 @@ -47,7 +47,7 @@ MODULE test_genprop_cls_cb1_mod CONTAINS - INTEGER FUNCTION test_genprop_cls_cb1_f(list_id, create_data ) bind(C) + INTEGER(KIND=C_INT) FUNCTION test_genprop_cls_cb1_f(list_id, create_data ) bind(C) IMPLICIT NONE diff --git a/fortran/test/tH5T.F90 b/fortran/test/tH5T.F90 index a38cbeadf53..c4f6aa0ece7 100644 --- a/fortran/test/tH5T.F90 +++ b/fortran/test/tH5T.F90 @@ -941,7 +941,7 @@ END SUBROUTINE enumtest !------------------------------------------------------------------------- ! * Function: test_derived_flt ! * -! * Purpose: Tests user-define and query functions of floating-point types. +! * Purpose: Tests user-defined and query functions of floating-point types. ! * test h5tget/set_fields_f. ! * ! * Return: Success: 0 diff --git a/fortran/testpar/mpi_param.F90 b/fortran/testpar/mpi_param.F90 index a57a4c57edd..1d7f8ff70f8 100644 --- a/fortran/testpar/mpi_param.F90 +++ b/fortran/testpar/mpi_param.F90 @@ -27,7 +27,6 @@ SUBROUTINE mpi_param_03(nerrors) INTEGER, INTENT(inout) :: nerrors ! number of errors - INTEGER, PARAMETER :: logical_kind = MPI_INTEGER_KIND INTEGER :: hdferror ! HDF hdferror flag INTEGER(hid_t) :: fapl_id ! file access identifier INTEGER(KIND=MPI_INTEGER_KIND) :: mpi_size, mpi_size_ret ! number of processes in the group of communicator @@ -37,7 +36,11 @@ SUBROUTINE mpi_param_03(nerrors) INTEGER(KIND=MPI_INTEGER_KIND) :: info, info_ret INTEGER(KIND=MPI_INTEGER_KIND) :: comm, comm_ret INTEGER(KIND=MPI_INTEGER_KIND) :: nkeys - LOGICAL(KIND=logical_kind) :: flag +#ifdef H5_MPI_LOGICAL_KIND + LOGICAL(KIND=H5_MPI_LOGICAL_KIND) :: flag +#else + LOGICAL(KIND=MPI_INTEGER_KIND) :: flag +#endif INTEGER :: iconfig CHARACTER(LEN=4) , PARAMETER :: in_key="host" CHARACTER(LEN=10), PARAMETER :: in_value="myhost.org" @@ -172,7 +175,6 @@ END SUBROUTINE mpi_param_03 SUBROUTINE mpi_param_08(nerrors) #ifdef H5_HAVE_MPI_F08 - USE MPI_F08 USE HDF5 USE TH5_MISC @@ -181,7 +183,6 @@ SUBROUTINE mpi_param_08(nerrors) IMPLICIT NONE INTEGER, INTENT(inout) :: nerrors ! number of errors - INTEGER, PARAMETER :: logical_kind = MPI_INTEGER_KIND INTEGER :: hdferror ! HDF hdferror flag INTEGER(hid_t) :: fapl_id ! file access identifier INTEGER(KIND=MPI_INTEGER_KIND) :: mpi_size, mpi_size_ret ! number of processes in the group of communicator @@ -191,7 +192,11 @@ SUBROUTINE mpi_param_08(nerrors) TYPE(MPI_INFO) :: info, info_ret TYPE(MPI_COMM) :: comm, comm_ret INTEGER(KIND=MPI_INTEGER_KIND) :: nkeys - LOGICAL(KIND=logical_kind) :: flag +#ifdef H5_MPI_LOGICAL_KIND + LOGICAL(KIND=H5_MPI_LOGICAL_KIND) :: flag +#else + LOGICAL(KIND=MPI_INTEGER_KIND) :: flag +#endif INTEGER :: iconfig CHARACTER(LEN=4) , PARAMETER :: in_key="host" CHARACTER(LEN=10), PARAMETER :: in_value="myhost.org" diff --git a/fortran/testpar/ptest.F90 b/fortran/testpar/ptest.F90 index 3d7280bbcf8..6e34ffdaaac 100644 --- a/fortran/testpar/ptest.F90 +++ b/fortran/testpar/ptest.F90 @@ -37,6 +37,52 @@ PROGRAM parallel_test CHARACTER(LEN=10), DIMENSION(1:2) :: chr_chunk =(/"contiguous", "chunk "/) INTEGER(KIND=MPI_INTEGER_KIND) :: mpi_int_type + INTERFACE + + SUBROUTINE mpi_param_03(ret_total_error) + IMPLICIT NONE + INTEGER, INTENT(inout) :: ret_total_error + END SUBROUTINE mpi_param_03 + + SUBROUTINE mpi_param_08(ret_total_error) + IMPLICIT NONE + INTEGER, INTENT(inout) :: ret_total_error + END SUBROUTINE mpi_param_08 + + SUBROUTINE hyper(length,do_collective,do_chunk, mpi_size, mpi_rank, nerrors) + USE MPI + IMPLICIT NONE + INTEGER, INTENT(in) :: length + LOGICAL, INTENT(in) :: do_collective + LOGICAL, INTENT(in) :: do_chunk + INTEGER(KIND=MPI_INTEGER_KIND), INTENT(in) :: mpi_size + INTEGER(KIND=MPI_INTEGER_KIND), INTENT(in) :: mpi_rank + INTEGER, INTENT(inout) :: nerrors + END SUBROUTINE hyper + + SUBROUTINE pmultiple_dset_hyper_rw(do_collective, do_chunk, mpi_size, mpi_rank, nerrors) + USE MPI + IMPLICIT NONE + LOGICAL, INTENT(in) :: do_collective + LOGICAL, INTENT(in) :: do_chunk + INTEGER(KIND=MPI_INTEGER_KIND), INTENT(in) :: mpi_size + INTEGER(KIND=MPI_INTEGER_KIND), INTENT(in) :: mpi_rank + INTEGER, INTENT(inout) :: nerrors + END SUBROUTINE pmultiple_dset_hyper_rw + + SUBROUTINE multiple_dset_write(length, do_collective, do_chunk, mpi_size, mpi_rank, nerrors) + USE MPI + IMPLICIT NONE + INTEGER, INTENT(in) :: length + LOGICAL, INTENT(in) :: do_collective + LOGICAL, INTENT(in) :: do_chunk + INTEGER(KIND=MPI_INTEGER_KIND), INTENT(in) :: mpi_size + INTEGER(KIND=MPI_INTEGER_KIND), INTENT(in) :: mpi_rank + INTEGER, INTENT(inout) :: nerrors + END SUBROUTINE multiple_dset_write + + END INTERFACE + ! ! initialize MPI ! diff --git a/fortran/testpar/subfiling.F90 b/fortran/testpar/subfiling.F90 index 876c1ccf822..67f201e0ec7 100644 --- a/fortran/testpar/subfiling.F90 +++ b/fortran/testpar/subfiling.F90 @@ -30,7 +30,6 @@ PROGRAM subfiling_test #ifdef H5_HAVE_SUBFILING_VFD - INTEGER, PARAMETER :: logical_kind = MPI_INTEGER_KIND CHARACTER(LEN=7), PARAMETER :: filename = "subf.h5" INTEGER :: hdferror ! HDF hdferror flag @@ -48,7 +47,11 @@ PROGRAM subfiling_test INTEGER(C_INT64_T) inode TYPE(H5FD_subfiling_config_t) :: vfd_config TYPE(H5FD_ioc_config_t) :: vfd_config_ioc - LOGICAL(KIND=logical_kind) :: flag +#ifdef H5_MPI_LOGICAL_KIND + LOGICAL(KIND=H5_MPI_LOGICAL_KIND) :: flag +#else + LOGICAL(KIND=MPI_INTEGER_KIND) :: flag +#endif INTEGER :: nerrors = 0 @@ -131,7 +134,7 @@ PROGRAM subfiling_test ENDIF CALL mpi_info_get(info_ret,"foo", 3_MPI_INTEGER_KIND, info_val, flag, mpierror) - IF(flag .EQV. .TRUE.)THEN + IF(LOGICAL(flag) .EQV. LOGICAL(.TRUE.))THEN IF(info_val.NE."bar")THEN IF(mpi_rank.EQ.0) & WRITE(*,*) "Failed H5Pset_mpi_params_f and H5Pget_mpi_params_f sequence" diff --git a/hl/src/H5TB.c b/hl/src/H5TB.c index e718605b5a3..82977b3253c 100644 --- a/hl/src/H5TB.c +++ b/hl/src/H5TB.c @@ -2025,7 +2025,7 @@ H5TBinsert_field(hid_t loc_id, const char *dset_name, const char *field_name, hi goto out; /* alloc fill value attribute buffer */ - if (NULL == (tmp_fill_buf = (unsigned char *)malloc(total_size))) + if (NULL == (tmp_fill_buf = (unsigned char *)calloc(1, total_size))) goto out; /* get the fill value attributes */ diff --git a/hl/test/test_table.c b/hl/test/test_table.c index c6614343037..8996fa46480 100644 --- a/hl/test/test_table.c +++ b/hl/test/test_table.c @@ -376,6 +376,8 @@ test_table(hid_t fid, int do_write) field_type[3] = H5T_NATIVE_DOUBLE; field_type[4] = H5T_NATIVE_INT; + memset(wbufd, 0, NRECORDS * sizeof(particle_t)); + /*------------------------------------------------------------------------- * * Functions tested: diff --git a/java/src/jni/h5aImp.c b/java/src/jni/h5aImp.c index 132e0709f5d..54c862eff6c 100644 --- a/java/src/jni/h5aImp.c +++ b/java/src/jni/h5aImp.c @@ -1107,12 +1107,12 @@ Java_hdf_hdf5lib_H5_H5Awrite_1string(JNIEnv *env, jclass clss, jlong attr_id, jl JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, jobjectArray buf) { - jbyte *readBuf = NULL; + void *readBuf = NULL; hsize_t dims[H5S_MAX_RANK]; hid_t sid = H5I_INVALID_HID; size_t typeSize; H5T_class_t type_class; - jsize vl_array_len; + jsize vl_array_len = 0; htri_t vl_data_class; herr_t status = FAIL; htri_t is_variable = 0; @@ -1136,7 +1136,7 @@ Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem if (NULL == (readBuf = calloc((size_t)vl_array_len, typeSize))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Aread: failed to allocate raw VL read buffer"); - if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, (void *)readBuf)) < 0) + if ((status = H5Aread((hid_t)attr_id, (hid_t)mem_type_id, readBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1173,12 +1173,12 @@ Java_hdf_hdf5lib_H5_H5AreadVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5AwriteVL(JNIEnv *env, jclass clss, jlong attr_id, jlong mem_type_id, jobjectArray buf) { - jbyte *writeBuf = NULL; + void *writeBuf = NULL; hsize_t dims[H5S_MAX_RANK]; hid_t sid = H5I_INVALID_HID; size_t typeSize; H5T_class_t type_class; - jsize vl_array_len; + jsize vl_array_len = 0; htri_t vl_data_class; herr_t status = FAIL; htri_t is_variable = 0; diff --git a/java/src/jni/h5dImp.c b/java/src/jni/h5dImp.c index c7e91dc8603..f6318b222d4 100644 --- a/java/src/jni/h5dImp.c +++ b/java/src/jni/h5dImp.c @@ -185,7 +185,7 @@ Java_hdf_hdf5lib_H5_H5Dread(JNIEnv *env, jclass clss, jlong dataset_id, jlong me jbyte *readBuf = NULL; size_t typeSize; H5T_class_t type_class; - jsize vl_array_len; // Only used by vl_data_class types + jsize vl_array_len = 0; // Only used by vl_data_class types htri_t vl_data_class; herr_t status = FAIL; @@ -266,7 +266,7 @@ Java_hdf_hdf5lib_H5_H5Dwrite(JNIEnv *env, jclass clss, jlong dataset_id, jlong m jbyte *writeBuf = NULL; size_t typeSize; H5T_class_t type_class; - jsize vl_array_len; // Only used by vl_data_class types + jsize vl_array_len = 0; // Only used by vl_data_class types htri_t vl_data_class; herr_t status = FAIL; @@ -1134,7 +1134,7 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, jobjectArray buf) { - jbyte *readBuf = NULL; + void *readBuf = NULL; size_t typeSize; H5T_class_t type_class; jsize vl_array_len; @@ -1164,7 +1164,7 @@ Java_hdf_hdf5lib_H5_H5DreadVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5DreadVL: failed to allocate raw VL read buffer"); if ((status = H5Dread((hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, (hid_t)file_space_id, - (hid_t)xfer_plist_id, (void *)readBuf)) < 0) + (hid_t)xfer_plist_id, readBuf)) < 0) H5_LIBRARY_ERROR(ENVONLY); if ((type_class = H5Tget_class((hid_t)mem_type_id)) < 0) H5_LIBRARY_ERROR(ENVONLY); @@ -1194,7 +1194,7 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5DwriteVL(JNIEnv *env, jclass clss, jlong dataset_id, jlong mem_type_id, jlong mem_space_id, jlong file_space_id, jlong xfer_plist_id, jobjectArray buf) { - jbyte *writeBuf = NULL; + void *writeBuf = NULL; size_t typeSize; H5T_class_t type_class; jsize vl_array_len; // Only used by vl_data_class types diff --git a/java/src/jni/h5eImp.c b/java/src/jni/h5eImp.c index 82d7da5980e..d52a4f72cd0 100644 --- a/java/src/jni/h5eImp.c +++ b/java/src/jni/h5eImp.c @@ -455,7 +455,7 @@ Java_hdf_hdf5lib_H5_H5Eget_1msg(JNIEnv *env, jclass clss, jlong msg_id, jintArra H5_LIBRARY_ERROR(ENVONLY); namePtr[buf_size] = '\0'; - theArray[0] = error_msg_type; + theArray[0] = (jint)error_msg_type; if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, namePtr))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); diff --git a/java/src/jni/h5pDCPLImp.c b/java/src/jni/h5pDCPLImp.c index 133b69c40cd..bd44f447bd1 100644 --- a/java/src/jni/h5pDCPLImp.c +++ b/java/src/jni/h5pDCPLImp.c @@ -77,13 +77,11 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Pset_1chunk(JNIEnv *env, jclass clss, jlong plist, jint ndims, jbyteArray dim) { jboolean isCopy; - hsize_t *da = NULL; - hsize_t *lp = NULL; - size_t i; + hsize_t *chunk_dims = NULL; + uint8_t *theArray_p = NULL; size_t rank; jsize arrLen; jbyte *theArray = NULL; - jlong *jlp = NULL; herr_t status = FAIL; UNUSED(clss); @@ -104,22 +102,29 @@ Java_hdf_hdf5lib_H5_H5Pset_1chunk(JNIEnv *env, jclass clss, jlong plist, jint nd PIN_BYTE_ARRAY(ENVONLY, dim, theArray, &isCopy, "H5Pset_chunk: dim array not pinned"); - if (NULL == (da = lp = (hsize_t *)malloc(rank * sizeof(hsize_t)))) + if (NULL == (chunk_dims = malloc(rank * sizeof(hsize_t)))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Pset_chunk: memory allocation failed"); - jlp = (jlong *)theArray; - for (i = 0; i < rank; i++) { - *lp = (hsize_t)*jlp; - lp++; - jlp++; - } /* end if */ + theArray_p = (uint8_t *)theArray; + for (size_t i = 0; i < rank; i++) { + jlong dim_val; - if ((status = H5Pset_chunk((hid_t)plist, (int)ndims, da)) < 0) + memcpy(&dim_val, theArray_p, sizeof(jlong)); + + if (dim_val < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Pset_chunk: chunk dimensions can't be negative"); + + chunk_dims[i] = (hsize_t)dim_val; + + theArray_p += sizeof(jlong); + } + + if ((status = H5Pset_chunk((hid_t)plist, (int)ndims, chunk_dims)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: - if (da) - free(da); + free(chunk_dims); + if (theArray) UNPIN_BYTE_ARRAY(ENVONLY, dim, theArray, JNI_ABORT); diff --git a/java/src/jni/h5pFAPLImp.c b/java/src/jni/h5pFAPLImp.c index e67b167020b..af56336fb55 100644 --- a/java/src/jni/h5pFAPLImp.c +++ b/java/src/jni/h5pFAPLImp.c @@ -1741,15 +1741,15 @@ Java_hdf_hdf5lib_H5_H5Pget_1mdc_1config(JNIEnv *env, jclass clss, jlong plist) args[9].j = (jlong)cacheinfo.max_size; args[10].j = (jlong)cacheinfo.min_size; args[11].j = cacheinfo.epoch_length; - args[12].i = cacheinfo.incr_mode; + args[12].i = (jint)cacheinfo.incr_mode; args[13].d = cacheinfo.lower_hr_threshold; args[14].d = cacheinfo.increment; args[15].z = cacheinfo.apply_max_increment; args[16].j = (jlong)cacheinfo.max_increment; - args[17].i = cacheinfo.flash_incr_mode; + args[17].i = (jint)cacheinfo.flash_incr_mode; args[18].d = cacheinfo.flash_multiple; args[19].d = cacheinfo.flash_threshold; - args[20].i = cacheinfo.decr_mode; + args[20].i = (jint)cacheinfo.decr_mode; args[21].d = cacheinfo.upper_hr_threshold; args[22].d = cacheinfo.decrement; args[23].z = cacheinfo.apply_max_decrement; diff --git a/java/src/jni/h5rImp.c b/java/src/jni/h5rImp.c index 3c356a4484c..f97f803f90e 100644 --- a/java/src/jni/h5rImp.c +++ b/java/src/jni/h5rImp.c @@ -204,6 +204,12 @@ Java_hdf_hdf5lib_H5_H5Rdestroy(JNIEnv *env, jclass clss, jbyteArray ref) if ((status = H5Rdestroy(&loc_ref)) < 0) H5_LIBRARY_ERROR(ENVONLY); + /* Reset buffer to 0 to be safe. H5Rdestroy does this, but + * only on our temporary reference object that we copied + * into for alignment reasons. + */ + memset(refBuf, 0, H5R_REF_BUF_SIZE); + done: if (refBuf) UNPIN_BYTE_ARRAY(ENVONLY, ref, refBuf, (status < 0) ? JNI_ABORT : 0); diff --git a/java/src/jni/h5sImp.c b/java/src/jni/h5sImp.c index d9d7c78a383..55fb268434f 100644 --- a/java/src/jni/h5sImp.c +++ b/java/src/jni/h5sImp.c @@ -221,13 +221,11 @@ Java_hdf_hdf5lib_H5_H5Sselect_1elements(JNIEnv *env, jclass clss, jlong space_id jbyteArray coords) { jboolean isCopy; - hsize_t *lp = NULL; - hsize_t *llp = NULL; - jlong *jlp = NULL; - jbyte *P = NULL; + hsize_t *coords_p = NULL; + uint8_t *pinned_arr_p = NULL; + jbyte *pinned_arr = NULL; jsize size; - int ii; - int nlongs; + size_t nlongs; herr_t status = FAIL; UNUSED(clss); @@ -235,35 +233,40 @@ Java_hdf_hdf5lib_H5_H5Sselect_1elements(JNIEnv *env, jclass clss, jlong space_id if (NULL == coords) H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Sselect_elements: coords is NULL"); - PIN_BYTE_ARRAY(ENVONLY, coords, P, &isCopy, "H5Sselect_elements: coords not pinned"); + PIN_BYTE_ARRAY(ENVONLY, coords, pinned_arr, &isCopy, "H5Sselect_elements: coords not pinned"); if ((size = ENVPTR->GetArrayLength(ENVONLY, coords)) < 0) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sselect_elements: coords array length < 0"); } - nlongs = (int)((size_t)size / sizeof(jlong)); + nlongs = (size_t)size / sizeof(jlong); - if (NULL == (lp = (hsize_t *)malloc((size_t)nlongs * sizeof(hsize_t)))) + if (NULL == (coords_p = malloc(nlongs * sizeof(hsize_t)))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Sselect_elements: failed to allocate coordinate buffer"); - jlp = (jlong *)P; - llp = lp; - for (ii = 0; ii < nlongs; ii++) { - *lp = (hsize_t)*jlp; - lp++; - jlp++; - } /* end for */ + pinned_arr_p = (uint8_t *)pinned_arr; + for (size_t i = 0; i < nlongs; i++) { + jlong coord_elem; + + memcpy(&coord_elem, pinned_arr_p, sizeof(jlong)); + + if (coord_elem < 0) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Sselect_elements: coordinate element can't be negative"); - if ((status = H5Sselect_elements(space_id, (H5S_seloper_t)op, (size_t)num_elemn, (const hsize_t *)llp)) < - 0) + coords_p[i] = (hsize_t)coord_elem; + + pinned_arr_p += sizeof(jlong); + } + + if ((status = H5Sselect_elements(space_id, (H5S_seloper_t)op, (size_t)num_elemn, coords_p)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: - if (llp) - free(llp); - if (P) - UNPIN_BYTE_ARRAY(ENVONLY, coords, P, JNI_ABORT); + free(coords_p); + + if (pinned_arr) + UNPIN_BYTE_ARRAY(ENVONLY, coords, pinned_arr, JNI_ABORT); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Sselect_1elements */ @@ -630,49 +633,49 @@ JNIEXPORT jint JNICALL Java_hdf_hdf5lib_H5_H5Soffset_1simple(JNIEnv *env, jclass clss, jlong space_id, jbyteArray offset) { jboolean isCopy; - hssize_t *sa = NULL; - hssize_t *lp = NULL; + hssize_t *offset_dims = NULL; + uint8_t *pinned_arr_p = NULL; + jbyte *pinned_arr = NULL; size_t rank; - jsize i; - jbyte *P = NULL; - jlong *jlp = NULL; herr_t status = FAIL; UNUSED(clss); if (NULL != offset) { - PIN_BYTE_ARRAY(ENVONLY, offset, P, &isCopy, "H5Soffset_simple: offset not pinned"); + jsize size; + + PIN_BYTE_ARRAY(ENVONLY, offset, pinned_arr, &isCopy, "H5Soffset_simple: offset not pinned"); - if ((i = ENVPTR->GetArrayLength(ENVONLY, offset)) < 0) { + if ((size = ENVPTR->GetArrayLength(ENVONLY, offset)) < 0) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Soffset_simple: offset array length < 0"); } - rank = (size_t)i / sizeof(jlong); + rank = (size_t)size / sizeof(jlong); - if (NULL == (sa = lp = (hssize_t *)malloc((size_t)rank * sizeof(hssize_t)))) + if (NULL == (offset_dims = malloc((size_t)rank * sizeof(hssize_t)))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "H5Soffset_simple: failed to allocate offset buffer"); - jlp = (jlong *)P; - for (i = 0; (size_t)i < rank; i++) { - *lp = (hssize_t)*jlp; - lp++; - jlp++; - } /* end for */ - } - else { - P = NULL; - sa = (hssize_t *)P; + pinned_arr_p = (uint8_t *)pinned_arr; + for (size_t i = 0; i < rank; i++) { + jlong offset_elem; + + memcpy(&offset_elem, pinned_arr_p, sizeof(jlong)); + + offset_dims[i] = (hssize_t)offset_elem; + + pinned_arr_p += sizeof(jlong); + } } - if ((status = H5Soffset_simple(space_id, sa)) < 0) + if ((status = H5Soffset_simple(space_id, offset_dims)) < 0) H5_LIBRARY_ERROR(ENVONLY); done: - if (sa) - free(sa); - if (P) - UNPIN_BYTE_ARRAY(ENVONLY, offset, P, JNI_ABORT); + free(offset_dims); + + if (pinned_arr) + UNPIN_BYTE_ARRAY(ENVONLY, offset, pinned_arr, JNI_ABORT); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Soffset_1simple */ diff --git a/java/src/jni/h5tImp.c b/java/src/jni/h5tImp.c index 155bd3a9a08..309454b16e4 100644 --- a/java/src/jni/h5tImp.c +++ b/java/src/jni/h5tImp.c @@ -447,8 +447,13 @@ Java_hdf_hdf5lib_H5_H5Tget_1fields_1int(JNIEnv *env, jclass clss, jlong type_id, { jboolean isCopy; jsize arrLen; - jint *P = NULL; - herr_t status = FAIL; + size_t spos; + size_t epos; + size_t esize; + size_t mpos; + size_t msize; + jint *pinned_arr = NULL; + herr_t status = FAIL; UNUSED(clss); @@ -462,15 +467,20 @@ Java_hdf_hdf5lib_H5_H5Tget_1fields_1int(JNIEnv *env, jclass clss, jlong type_id, if (arrLen < 5) H5_BAD_ARGUMENT_ERROR(ENVONLY, "H5Tget_fields_int: fields input array < order 5"); - PIN_INT_ARRAY(ENVONLY, fields, P, &isCopy, "H5Tget_fields_int: fields not pinned"); + PIN_INT_ARRAY(ENVONLY, fields, pinned_arr, &isCopy, "H5Tget_fields_int: fields not pinned"); - if ((status = H5Tget_fields((hid_t)type_id, (size_t *)&(P[0]), (size_t *)&(P[1]), (size_t *)&(P[2]), - (size_t *)&(P[3]), (size_t *)&(P[4]))) < 0) + if ((status = H5Tget_fields((hid_t)type_id, &spos, &epos, &esize, &mpos, &msize)) < 0) H5_LIBRARY_ERROR(ENVONLY); + pinned_arr[0] = (jint)spos; + pinned_arr[1] = (jint)epos; + pinned_arr[2] = (jint)esize; + pinned_arr[3] = (jint)mpos; + pinned_arr[4] = (jint)msize; + done: - if (P) - UNPIN_INT_ARRAY(ENVONLY, fields, P, (status < 0) ? JNI_ABORT : 0); + if (pinned_arr) + UNPIN_INT_ARRAY(ENVONLY, fields, pinned_arr, (status < 0) ? JNI_ABORT : 0); return (jint)status; } /* end Java_hdf_hdf5lib_H5_H5Tget_1fields_1int */ diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index 10efb828c54..9c441729a39 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -82,10 +82,10 @@ void translate_atomic_wbuf(JNIEnv *env, jobject in_obj, jlong mem_type_ void *raw_buf); /* Strings for output */ -#define H5_TOOLS_GROUP "GROUP" -#define H5_TOOLS_DATASET "DATASET" -#define H5_TOOLS_DATATYPE "DATATYPE" -#define H5_TOOLS_ATTRIBUTE "ATTRIBUTE" +#define H5_TOOLS_GROUP "GROUP" +#define H5_TOOLS_DATASET "DATASET" +#define H5_TOOLS_DATATYPE "DATATYPE" +#define H5_TOOLS_MAP "MAP" /** frees memory held by array of strings */ void @@ -241,7 +241,7 @@ h5str_convert(JNIEnv *env, char **in_str, hid_t container, hid_t tid, void *out_ } #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE case sizeof(long double): { - long double tmp_ldouble = 0.0; + long double tmp_ldouble = 0.0L; sscanf(token, "%Lg", &tmp_ldouble); memcpy(cptr, &tmp_ldouble, sizeof(long double)); @@ -892,7 +892,7 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i } #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE case sizeof(long double): { - long double tmp_ldouble = 0.0; + long double tmp_ldouble = 0.0L; memcpy(&tmp_ldouble, cptr, sizeof(long double)); @@ -1221,6 +1221,11 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: snprintf failure"); break; + case H5O_TYPE_MAP: + if (snprintf(this_str, size, "%s %s", H5_TOOLS_MAP, obj_tok_str) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, "h5str_sprintf: snprintf failure"); + break; + case H5O_TYPE_UNKNOWN: case H5O_TYPE_NTYPES: default: @@ -1303,6 +1308,12 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i "h5str_sprintf: snprintf failure"); break; + case H5O_TYPE_MAP: + if (snprintf(this_str, this_len, "%s ", H5_TOOLS_MAP) < 0) + H5_JNI_FATAL_ERROR(ENVONLY, + "h5str_sprintf: snprintf failure"); + break; + case H5O_TYPE_UNKNOWN: case H5O_TYPE_NTYPES: default: @@ -4222,6 +4233,9 @@ translate_atomic_rbuf(JNIEnv *env, jlong mem_type_id, H5T_class_t type_class, vo CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); break; } + default: + H5_BAD_ARGUMENT_ERROR(ENVONLY, + "translate_atomic_rbuf: no matching JNI type for integer type"); } break; } /* H5T_INTEGER */ @@ -4246,6 +4260,9 @@ translate_atomic_rbuf(JNIEnv *env, jlong mem_type_id, H5T_class_t type_class, vo CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); break; } + default: + H5_BAD_ARGUMENT_ERROR( + ENVONLY, "translate_atomic_rbuf: no matching JNI type for floating-point type"); } break; } /* H5T_FLOAT */ @@ -4295,6 +4312,9 @@ translate_atomic_rbuf(JNIEnv *env, jlong mem_type_id, H5T_class_t type_class, vo break; } /* H5T_STRING */ + case H5T_TIME: + case H5T_NO_CLASS: + case H5T_NCLASSES: default: H5_UNIMPLEMENTED(ENVONLY, "translate_atomic_rbuf: invalid class type"); break; @@ -4456,6 +4476,9 @@ translate_atomic_wbuf(JNIEnv *env, jobject in_obj, jlong mem_type_id, H5T_class_ memcpy(char_buf, ((char *)&longValue), typeSize); break; } + default: + H5_BAD_ARGUMENT_ERROR(ENVONLY, + "translate_atomic_wbuf: no matching JNI type for integer type"); } break; } /* H5T_INTEGER */ @@ -4472,6 +4495,9 @@ translate_atomic_wbuf(JNIEnv *env, jobject in_obj, jlong mem_type_id, H5T_class_ memcpy(char_buf, ((char *)&doubleValue), typeSize); break; } + default: + H5_BAD_ARGUMENT_ERROR( + ENVONLY, "translate_atomic_wbuf: no matching JNI type for floating-point type"); } break; } /* H5T_FLOAT */ @@ -4510,6 +4536,9 @@ translate_atomic_wbuf(JNIEnv *env, jobject in_obj, jlong mem_type_id, H5T_class_ } break; } /* H5T_STRING */ + case H5T_TIME: + case H5T_NO_CLASS: + case H5T_NCLASSES: default: H5_UNIMPLEMENTED(ENVONLY, "translate_atomic_wbuf: invalid class type"); break; @@ -4729,6 +4758,9 @@ translate_rbuf(JNIEnv *env, jobjectArray ret_buf, jlong mem_type_id, H5T_class_t } break; } + case H5T_TIME: + case H5T_NO_CLASS: + case H5T_NCLASSES: default: H5_UNIMPLEMENTED(ENVONLY, "translate_rbuf: invalid class type"); break; @@ -4888,6 +4920,9 @@ translate_wbuf(JNIEnv *env, jobjectArray in_buf, jlong mem_type_id, H5T_class_t } break; } + case H5T_TIME: + case H5T_NO_CLASS: + case H5T_NCLASSES: default: H5_UNIMPLEMENTED(ENVONLY, "translate_wbuf: invalid class type"); break; diff --git a/java/src/jni/nativeData.c b/java/src/jni/nativeData.c index 17ab6ea8021..d25951ff436 100644 --- a/java/src/jni/nativeData.c +++ b/java/src/jni/nativeData.c @@ -49,13 +49,11 @@ Java_hdf_hdf5lib_HDFNativeData_byteToInt___3B(JNIEnv *env, jclass clss, jbyteArr { jintArray rarray = NULL; jboolean bb; + uint8_t *p = NULL; jbyte *barr = NULL; jint *iarray = NULL; - jint *iap = NULL; - char *bp = NULL; - int blen; - int ii; - int len; + jsize ilen; + jsize blen; UNUSED(clss); @@ -69,20 +67,21 @@ Java_hdf_hdf5lib_HDFNativeData_byteToInt___3B(JNIEnv *env, jclass clss, jbyteArr H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToInt: bdata length < 0"); } - len = blen / (int)sizeof(jint); + ilen = blen / (jsize)sizeof(jint); - if (NULL == (rarray = ENVPTR->NewIntArray(ENVONLY, len))) + if (NULL == (rarray = ENVPTR->NewIntArray(ENVONLY, ilen))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); PIN_INT_ARRAY(ENVONLY, rarray, iarray, &bb, "byteToInt: int array not pinned"); - bp = (char *)barr; - iap = iarray; - for (ii = 0; ii < len; ii++) { - *iap = *(jint *)bp; - iap++; - bp += sizeof(jint); - } /* end for */ + p = (uint8_t *)barr; + for (size_t i = 0; i < (size_t)ilen; i++) { + jint val; + + memcpy(&val, p, sizeof(jint)); + iarray[i] = val; + p += sizeof(jint); + } done: if (iarray) @@ -93,57 +92,6 @@ Java_hdf_hdf5lib_HDFNativeData_byteToInt___3B(JNIEnv *env, jclass clss, jbyteArr return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToInt___3B */ -/* returns float [] */ -JNIEXPORT jfloatArray JNICALL -Java_hdf_hdf5lib_HDFNativeData_byteToFloat___3B(JNIEnv *env, jclass clss, - jbyteArray bdata) /* IN: array of bytes */ -{ - jfloatArray rarray = NULL; - jboolean bb; - jfloat *farray = NULL; - jfloat *iap = NULL; - jbyte *barr = NULL; - char *bp = NULL; - int blen; - int ii; - int len; - - UNUSED(clss); - - if (NULL == bdata) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToFloat: byte array is NULL"); - - PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToFloat: byte array not pinned"); - - if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { - CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToFloat: bdata length < 0"); - } - - len = blen / (int)sizeof(jfloat); - - if (NULL == (rarray = ENVPTR->NewFloatArray(ENVONLY, len))) - CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - - PIN_FLOAT_ARRAY(ENVONLY, rarray, farray, &bb, "byteToFloat: float array not pinned"); - - bp = (char *)barr; - iap = farray; - for (ii = 0; ii < len; ii++) { - *iap = *(jfloat *)bp; - iap++; - bp += sizeof(jfloat); - } /* end for */ - -done: - if (farray) - UNPIN_FLOAT_ARRAY(ENVONLY, rarray, farray, rarray ? 0 : JNI_ABORT); - if (barr) - UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); - - return rarray; -} /* end Java_hdf_hdf5lib_HDFNativeData_byteToFloat___3B */ - /* returns short [] */ JNIEXPORT jshortArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToShort___3B(JNIEnv *env, jclass clss, @@ -151,13 +99,11 @@ Java_hdf_hdf5lib_HDFNativeData_byteToShort___3B(JNIEnv *env, jclass clss, { jshortArray rarray = NULL; jboolean bb; + uint8_t *p = NULL; jshort *sarray = NULL; - jshort *iap = NULL; jbyte *barr = NULL; - char *bp = NULL; - int blen; - int ii; - int len; + jsize slen; + jsize blen; UNUSED(clss); @@ -171,20 +117,21 @@ Java_hdf_hdf5lib_HDFNativeData_byteToShort___3B(JNIEnv *env, jclass clss, H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToShort: bdata length < 0"); } - len = blen / (int)sizeof(jshort); + slen = blen / (jsize)sizeof(jshort); - if (NULL == (rarray = ENVPTR->NewShortArray(ENVONLY, len))) + if (NULL == (rarray = ENVPTR->NewShortArray(ENVONLY, slen))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); PIN_SHORT_ARRAY(ENVONLY, rarray, sarray, &bb, "byteToShort: short array not pinned"); - bp = (char *)barr; - iap = sarray; - for (ii = 0; ii < len; ii++) { - *iap = *(jshort *)bp; - iap++; - bp += sizeof(jshort); - } /* end for */ + p = (uint8_t *)barr; + for (size_t i = 0; i < (size_t)slen; i++) { + jshort val; + + memcpy(&val, p, sizeof(jshort)); + sarray[i] = val; + p += sizeof(jshort); + } done: if (sarray) @@ -202,13 +149,11 @@ Java_hdf_hdf5lib_HDFNativeData_byteToLong___3B(JNIEnv *env, jclass clss, { jlongArray rarray = NULL; jboolean bb; + uint8_t *p = NULL; jlong *larray = NULL; - jlong *iap = NULL; jbyte *barr = NULL; - char *bp = NULL; - int blen; - int ii; - int len; + jsize llen; + jsize blen; UNUSED(clss); @@ -222,20 +167,21 @@ Java_hdf_hdf5lib_HDFNativeData_byteToLong___3B(JNIEnv *env, jclass clss, H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToLong: bdata length < 0"); } - len = blen / (int)sizeof(jlong); + llen = blen / (jsize)sizeof(jlong); - if (NULL == (rarray = ENVPTR->NewLongArray(ENVONLY, len))) + if (NULL == (rarray = ENVPTR->NewLongArray(ENVONLY, llen))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); PIN_LONG_ARRAY(ENVONLY, rarray, larray, &bb, "byteToLong: long array not pinned"); - bp = (char *)barr; - iap = larray; - for (ii = 0; ii < len; ii++) { - *iap = *(jlong *)bp; - iap++; - bp += sizeof(jlong); - } /* end for */ + p = (uint8_t *)barr; + for (size_t i = 0; i < (size_t)llen; i++) { + jlong val; + + memcpy(&val, p, sizeof(jlong)); + larray[i] = val; + p += sizeof(jlong); + } done: if (larray) @@ -246,6 +192,56 @@ Java_hdf_hdf5lib_HDFNativeData_byteToLong___3B(JNIEnv *env, jclass clss, return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToLong___3B */ +/* returns float [] */ +JNIEXPORT jfloatArray JNICALL +Java_hdf_hdf5lib_HDFNativeData_byteToFloat___3B(JNIEnv *env, jclass clss, + jbyteArray bdata) /* IN: array of bytes */ +{ + jfloatArray rarray = NULL; + jboolean bb; + uint8_t *p = NULL; + jfloat *farray = NULL; + jbyte *barr = NULL; + jsize flen; + jsize blen; + + UNUSED(clss); + + if (NULL == bdata) + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToFloat: byte array is NULL"); + + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToFloat: byte array not pinned"); + + if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { + CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToFloat: bdata length < 0"); + } + + flen = blen / (jsize)sizeof(jfloat); + + if (NULL == (rarray = ENVPTR->NewFloatArray(ENVONLY, flen))) + CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); + + PIN_FLOAT_ARRAY(ENVONLY, rarray, farray, &bb, "byteToFloat: float array not pinned"); + + p = (uint8_t *)barr; + for (size_t i = 0; i < (size_t)flen; i++) { + jfloat val; + + memcpy(&val, p, sizeof(jfloat)); + farray[i] = val; + p += sizeof(jfloat); + } + +done: + if (farray) + UNPIN_FLOAT_ARRAY(ENVONLY, rarray, farray, rarray ? 0 : JNI_ABORT); + if (barr) + UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); + + return rarray; +} /* end Java_hdf_hdf5lib_HDFNativeData_byteToFloat___3B */ + /* returns double [] */ JNIEXPORT jdoubleArray JNICALL Java_hdf_hdf5lib_HDFNativeData_byteToDouble___3B(JNIEnv *env, jclass clss, @@ -253,13 +249,11 @@ Java_hdf_hdf5lib_HDFNativeData_byteToDouble___3B(JNIEnv *env, jclass clss, { jdoubleArray rarray = NULL; jboolean bb; + uint8_t *p = NULL; jdouble *darray = NULL; - jdouble *iap = NULL; jbyte *barr = NULL; - char *bp = NULL; - int blen; - int ii; - int len; + jsize dlen; + jsize blen; UNUSED(clss); @@ -273,20 +267,21 @@ Java_hdf_hdf5lib_HDFNativeData_byteToDouble___3B(JNIEnv *env, jclass clss, H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToDouble: bdata length < 0"); } - len = blen / (int)sizeof(jdouble); + dlen = blen / (jsize)sizeof(jdouble); - if (NULL == (rarray = ENVPTR->NewDoubleArray(ENVONLY, len))) + if (NULL == (rarray = ENVPTR->NewDoubleArray(ENVONLY, dlen))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); PIN_DOUBLE_ARRAY(ENVONLY, rarray, darray, &bb, "byteToDouble: double array not pinned"); - bp = (char *)barr; - iap = darray; - for (ii = 0; ii < len; ii++) { - *iap = *(jdouble *)bp; - iap++; - bp += sizeof(jdouble); - } /* end for */ + p = (uint8_t *)barr; + for (size_t i = 0; i < (size_t)dlen; i++) { + jdouble val; + + memcpy(&val, p, sizeof(jdouble)); + darray[i] = val; + p += sizeof(jdouble); + } done: if (darray) @@ -304,12 +299,10 @@ Java_hdf_hdf5lib_HDFNativeData_byteToInt__II_3B(JNIEnv *env, jclass clss, jint s { jintArray rarray = NULL; jboolean bb; + uint8_t *p = NULL; jint *iarray = NULL; - jint *iap = NULL; jbyte *barr = NULL; - char *bp = NULL; - int blen; - int ii; + jsize blen; UNUSED(clss); @@ -323,22 +316,22 @@ Java_hdf_hdf5lib_HDFNativeData_byteToInt__II_3B(JNIEnv *env, jclass clss, jint s H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToInt: bdata length < 0"); } - if ((start < 0) || ((int)(start + (len * (int)sizeof(jint))) > blen)) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToInt: start < 0 or len exceeded buffer length"); - - bp = (char *)barr + start; + if ((start < 0) || (len < 0) || ((int)(start + (len * (int)sizeof(jint))) > blen)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToInt: start < 0, len < 0 or len exceeded buffer length"); if (NULL == (rarray = ENVPTR->NewIntArray(ENVONLY, len))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); PIN_INT_ARRAY(ENVONLY, rarray, iarray, &bb, "byteToInt: int array not pinned"); - iap = iarray; - for (ii = 0; ii < len; ii++) { - *iap = *(jint *)bp; - iap++; - bp += sizeof(jint); - } /* end for */ + p = (uint8_t *)barr + start; + for (size_t i = 0; i < (size_t)len; i++) { + jint val; + + memcpy(&val, p, sizeof(jint)); + iarray[i] = val; + p += sizeof(jint); + } done: if (iarray) @@ -356,12 +349,10 @@ Java_hdf_hdf5lib_HDFNativeData_byteToShort__II_3B(JNIEnv *env, jclass clss, jint { jshortArray rarray = NULL; jboolean bb; + uint8_t *p = NULL; jshort *sarray = NULL; - jshort *iap = NULL; jbyte *barr = NULL; - char *bp = NULL; - int blen; - int ii; + jsize blen; UNUSED(clss); @@ -375,22 +366,22 @@ Java_hdf_hdf5lib_HDFNativeData_byteToShort__II_3B(JNIEnv *env, jclass clss, jint H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToShort: bdata length < 0"); } - if ((start < 0) || ((int)(start + (len * (int)sizeof(jshort))) > blen)) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToShort: start < 0 or len exceeded buffer length"); - - bp = (char *)barr + start; + if ((start < 0) || (len < 0) || ((int)(start + (len * (int)sizeof(jshort))) > blen)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToShort: start < 0, len < 0 or len exceeded buffer length"); if (NULL == (rarray = ENVPTR->NewShortArray(ENVONLY, len))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); PIN_SHORT_ARRAY(ENVONLY, rarray, sarray, &bb, "byteToShort: short array not pinned"); - iap = sarray; - for (ii = 0; ii < len; ii++) { - *iap = *(jshort *)bp; - iap++; - bp += sizeof(jshort); - } /* end for */ + p = (uint8_t *)barr + start; + for (size_t i = 0; i < (size_t)len; i++) { + jshort val; + + memcpy(&val, p, sizeof(jshort)); + sarray[i] = val; + p += sizeof(jshort); + } done: if (sarray) @@ -401,109 +392,105 @@ Java_hdf_hdf5lib_HDFNativeData_byteToShort__II_3B(JNIEnv *env, jclass clss, jint return rarray; } /* end Java_hdf_hdf5lib_HDFNativeData_byteToShort__II_3B */ -/* returns float [] */ -JNIEXPORT jfloatArray JNICALL -Java_hdf_hdf5lib_HDFNativeData_byteToFloat__II_3B(JNIEnv *env, jclass clss, jint start, jint len, - jbyteArray bdata) /* IN: array of bytes */ +/* returns long [] */ +JNIEXPORT jlongArray JNICALL +Java_hdf_hdf5lib_HDFNativeData_byteToLong__II_3B(JNIEnv *env, jclass clss, jint start, jint len, + jbyteArray bdata) /* IN: array of bytes */ { - jfloatArray rarray = NULL; - jboolean bb; - jfloat *farray = NULL; - jfloat *iap = NULL; - jbyte *barr = NULL; - char *bp = NULL; - int blen; - int ii; + jlongArray rarray = NULL; + jboolean bb; + uint8_t *p = NULL; + jlong *larray = NULL; + jbyte *barr = NULL; + jsize blen; UNUSED(clss); if (NULL == bdata) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToFloat: byte array is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToLong: byte array is NULL"); - PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToFloat: byte array not pinned"); + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToLong: byte array not pinned"); if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToFloat: bdata length < 0"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToLong: bdata length < 0"); } - if ((start < 0) || ((int)(start + (len * (int)sizeof(jfloat))) > blen)) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToFloat: start < 0 or len exceeded buffer length"); - - bp = (char *)barr + start; + if ((start < 0) || (len < 0) || ((int)(start + (len * (int)sizeof(jlong))) > blen)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToLong: start < 0, len < 0 or len exceeded buffer length"); - if (NULL == (rarray = ENVPTR->NewFloatArray(ENVONLY, len))) + if (NULL == (rarray = ENVPTR->NewLongArray(ENVONLY, len))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - PIN_FLOAT_ARRAY(ENVONLY, rarray, farray, &bb, "byteToFloat: float array not pinned"); + PIN_LONG_ARRAY(ENVONLY, rarray, larray, &bb, "byteToLong: long array not pinned"); - iap = farray; - for (ii = 0; ii < len; ii++) { - *iap = *(jfloat *)bp; - iap++; - bp += sizeof(jfloat); - } /* end for */ + p = (uint8_t *)barr + start; + for (size_t i = 0; i < (size_t)len; i++) { + jlong val; + + memcpy(&val, p, sizeof(jlong)); + larray[i] = val; + p += sizeof(jlong); + } done: - if (farray) - UNPIN_FLOAT_ARRAY(ENVONLY, rarray, farray, rarray ? 0 : JNI_ABORT); + if (larray) + UNPIN_LONG_ARRAY(ENVONLY, rarray, larray, rarray ? 0 : JNI_ABORT); if (barr) UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); return rarray; -} /* end Java_hdf_hdf5lib_HDFNativeData_byteToFloat__II_3B */ +} /* end Java_hdf_hdf5lib_HDFNativeData_byteToLong__II_3B */ -/* returns long [] */ -JNIEXPORT jlongArray JNICALL -Java_hdf_hdf5lib_HDFNativeData_byteToLong__II_3B(JNIEnv *env, jclass clss, jint start, jint len, - jbyteArray bdata) /* IN: array of bytes */ +/* returns float [] */ +JNIEXPORT jfloatArray JNICALL +Java_hdf_hdf5lib_HDFNativeData_byteToFloat__II_3B(JNIEnv *env, jclass clss, jint start, jint len, + jbyteArray bdata) /* IN: array of bytes */ { - jlongArray rarray = NULL; - jboolean bb; - jlong *larray = NULL; - jlong *iap = NULL; - jbyte *barr = NULL; - char *bp = NULL; - int blen; - int ii; + jfloatArray rarray = NULL; + jboolean bb; + uint8_t *p = NULL; + jfloat *farray = NULL; + jbyte *barr = NULL; + jsize blen; UNUSED(clss); if (NULL == bdata) - H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToLong: byte array is NULL"); + H5_NULL_ARGUMENT_ERROR(ENVONLY, "byteToFloat: byte array is NULL"); - PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToLong: byte array not pinned"); + PIN_BYTE_ARRAY(ENVONLY, bdata, barr, &bb, "byteToFloat: byte array not pinned"); if ((blen = ENVPTR->GetArrayLength(ENVONLY, bdata)) < 0) { CHECK_JNI_EXCEPTION(ENVONLY, JNI_TRUE); - H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToLong: bdata length < 0"); + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToFloat: bdata length < 0"); } - if ((start < 0) || ((int)(start + (len * (int)sizeof(jlong))) > blen)) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToLong: start < 0 or len exceeded buffer length"); - - bp = (char *)barr + start; + if ((start < 0) || (len < 0) || ((int)(start + (len * (int)sizeof(jfloat))) > blen)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToFloat: start < 0, len < 0 or len exceeded buffer length"); - if (NULL == (rarray = ENVPTR->NewLongArray(ENVONLY, len))) + if (NULL == (rarray = ENVPTR->NewFloatArray(ENVONLY, len))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); - PIN_LONG_ARRAY(ENVONLY, rarray, larray, &bb, "byteToLong: long array not pinned"); + PIN_FLOAT_ARRAY(ENVONLY, rarray, farray, &bb, "byteToFloat: float array not pinned"); - iap = larray; - for (ii = 0; ii < len; ii++) { - *iap = *(jlong *)bp; - iap++; - bp += sizeof(jlong); - } /* end for */ + p = (uint8_t *)barr + start; + for (size_t i = 0; i < (size_t)len; i++) { + jfloat val; + + memcpy(&val, p, sizeof(jfloat)); + farray[i] = val; + p += sizeof(jfloat); + } done: - if (larray) - UNPIN_LONG_ARRAY(ENVONLY, rarray, larray, rarray ? 0 : JNI_ABORT); + if (farray) + UNPIN_FLOAT_ARRAY(ENVONLY, rarray, farray, rarray ? 0 : JNI_ABORT); if (barr) UNPIN_BYTE_ARRAY(ENVONLY, bdata, barr, JNI_ABORT); return rarray; -} /* end Java_hdf_hdf5lib_HDFNativeData_byteToLong__II_3B */ +} /* end Java_hdf_hdf5lib_HDFNativeData_byteToFloat__II_3B */ /* returns double [] */ JNIEXPORT jdoubleArray JNICALL @@ -512,12 +499,10 @@ Java_hdf_hdf5lib_HDFNativeData_byteToDouble__II_3B(JNIEnv *env, jclass clss, jin { jdoubleArray rarray = NULL; jboolean bb; + uint8_t *p = NULL; jdouble *darray = NULL; - jdouble *iap = NULL; jbyte *barr = NULL; - char *bp = NULL; - int blen; - int ii; + jsize blen; UNUSED(clss); @@ -531,22 +516,22 @@ Java_hdf_hdf5lib_HDFNativeData_byteToDouble__II_3B(JNIEnv *env, jclass clss, jin H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToDouble: bdata length < 0"); } - if ((start < 0) || ((int)(start + (len * (int)sizeof(jdouble))) > blen)) - H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToDouble: start < 0 or len exceeded buffer length"); - - bp = (char *)barr + start; + if ((start < 0) || (len < 0) || ((int)(start + (len * (int)sizeof(jdouble))) > blen)) + H5_BAD_ARGUMENT_ERROR(ENVONLY, "byteToDouble: start < 0, len < 0 or len exceeded buffer length"); if (NULL == (rarray = ENVPTR->NewDoubleArray(ENVONLY, len))) CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE); PIN_DOUBLE_ARRAY(ENVONLY, rarray, darray, &bb, "byteToDouble: double array not pinned"); - iap = darray; - for (ii = 0; ii < len; ii++) { - *iap = *(jdouble *)bp; - iap++; - bp += sizeof(jdouble); - } /* end for */ + p = (uint8_t *)barr + start; + for (size_t i = 0; i < (size_t)len; i++) { + jdouble val; + + memcpy(&val, p, sizeof(jdouble)); + darray[i] = val; + p += sizeof(jdouble); + } done: if (darray) diff --git a/m4/aclocal_fc.f90 b/m4/aclocal_fc.f90 index 939988f64aa..918fc6769dd 100644 --- a/m4/aclocal_fc.f90 +++ b/m4/aclocal_fc.f90 @@ -21,7 +21,7 @@ ! PROGRAM PROG_FC_ISO_FORTRAN_ENV - USE, INTRINSIC :: ISO_FORTRAN_ENV + USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : logical_kinds END PROGRAM PROG_FC_ISO_FORTRAN_ENV PROGRAM PROG_FC_SIZEOF @@ -182,6 +182,70 @@ PROGRAM FC_AVAIL_KINDS END PROGRAM FC_AVAIL_KINDS !---- END ----- Determine the available KINDs for REALs and INTEGERs +!---- START ----- Determine the available KINDs for REALs, INTEGERs and LOGICALs -- ISO_FORTRAN_ENV (F08) +PROGRAM FC08_AVAIL_KINDS + USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : stdout=>OUTPUT_UNIT, integer_kinds, real_kinds, logical_kinds + IMPLICIT NONE + INTEGER :: ik, jk, k, max_decimal_prec + INTEGER :: num_rkinds, num_ikinds, num_lkinds + + ! Find integer KINDs + + num_ikinds = SIZE(integer_kinds) + + DO k = 1, num_ikinds + WRITE(stdout,'(I0)', ADVANCE='NO') integer_kinds(k) + IF(k.NE.num_ikinds)THEN + WRITE(stdout,'(A)',ADVANCE='NO') ',' + ELSE + WRITE(stdout,'()') + ENDIF + ENDDO + + ! Find real KINDs + + num_rkinds = SIZE(real_kinds) + + max_decimal_prec = 1 + + prec: DO ik = 2, 36 + exp: DO jk = 1, 700 + k = SELECTED_REAL_KIND(ik,jk) + IF(k.LT.0) EXIT exp + max_decimal_prec = ik + ENDDO exp + ENDDO prec + + DO k = 1, num_rkinds + WRITE(stdout,'(I0)', ADVANCE='NO') real_kinds(k) + IF(k.NE.num_rkinds)THEN + WRITE(stdout,'(A)',ADVANCE='NO') ',' + ELSE + WRITE(stdout,'()') + ENDIF + ENDDO + + WRITE(stdout,'(I0)') max_decimal_prec + WRITE(stdout,'(I0)') num_ikinds + WRITE(stdout,'(I0)') num_rkinds + + ! Find logical KINDs + + num_lkinds = SIZE(logical_kinds) + WRITE(stdout,'(I0)') num_lkinds + + DO k = 1, num_lkinds + WRITE(stdout,'(I0)', ADVANCE='NO') logical_kinds(k) + IF(k.NE.num_lkinds)THEN + WRITE(stdout,'(A)',ADVANCE='NO') ',' + ELSE + WRITE(stdout,'()') + ENDIF + ENDDO + +END PROGRAM FC08_AVAIL_KINDS +!---- END ----- Determine the available KINDs for REALs, INTEGERs and LOGICALs -- ISO_FORTRAN_ENV (F08) + PROGRAM FC_MPI_CHECK USE mpi INTEGER :: comm, amode, info, fh, ierror diff --git a/m4/aclocal_fc.m4 b/m4/aclocal_fc.m4 index f8f4fa123b1..cfcfbcf7ca2 100644 --- a/m4/aclocal_fc.m4 +++ b/m4/aclocal_fc.m4 @@ -64,11 +64,11 @@ dnl dnl See if the fortran compiler supports the intrinsic module "ISO_FORTRAN_ENV" AC_DEFUN([PAC_PROG_FC_ISO_FORTRAN_ENV],[ - HAVE_ISO_FORTRAN_ENV="no" - AC_MSG_CHECKING([if Fortran compiler supports intrinsic module ISO_FORTRAN_ENV]) + CHECK_ISO_FORTRAN_ENV="no" + AC_MSG_CHECKING([if Fortran compiler supports intrinsic module ISO_FORTRAN_ENV (F08)]) TEST_SRC="`sed -n '/PROGRAM PROG_FC_ISO_FORTRAN_ENV/,/END PROGRAM PROG_FC_ISO_FORTRAN_ENV/p' $srcdir/m4/aclocal_fc.f90`" AC_LINK_IFELSE([$TEST_SRC],[AC_MSG_RESULT([yes]) - HAVE_ISO_FORTRAN_ENV="yes"], + CHECK_ISO_FORTRAN_ENV="yes"], [AC_MSG_RESULT([no])]) ]) @@ -323,6 +323,104 @@ AC_RUN_IFELSE([$TEST_SRC], AC_LANG_POP([Fortran]) ]) + +dnl -------------------------------------------------------------- +dnl Determine the available KINDs for REALs, INTEGERs and LOGICALS +dnl -------------------------------------------------------------- +dnl +dnl This is a runtime test. +dnl +AC_DEFUN([PAC_FC_AVAIL_KINDS_F08],[ +AC_LANG_PUSH([Fortran]) +TEST_SRC="`sed -n '/PROGRAM FC08_AVAIL_KINDS/,/END PROGRAM FC08_AVAIL_KINDS/p' $srcdir/m4/aclocal_fc.f90`" +AC_RUN_IFELSE([$TEST_SRC], + [ + dnl The output from the above program will be: + dnl -- LINE 1 -- valid integer kinds (comma separated list) + dnl -- LINE 2 -- valid real kinds (comma separated list) + dnl -- LINE 3 -- max decimal precision for reals + dnl -- LINE 4 -- number of valid integer kinds + dnl -- LINE 5 -- number of valid real kinds + dnl -- LINE 6 -- number of valid logical kinds + dnl -- LINE 7 -- valid logical kinds (comma separated list) + + pac_validIntKinds=$(./conftest$EXEEXT 2>&1 | sed -n '1p') + pac_validRealKinds=$(./conftest$EXEEXT 2>&1 | sed -n '2p') + PAC_FC_MAX_REAL_PRECISION=$(./conftest$EXEEXT 2>&1 | sed -n '3p') + AC_DEFINE_UNQUOTED([PAC_FC_MAX_REAL_PRECISION], $PAC_FC_MAX_REAL_PRECISION, [Define Fortran Maximum Real Decimal Precision]) + + PAC_FC_ALL_INTEGER_KINDS="{`echo $pac_validIntKinds`}" + PAC_FC_ALL_REAL_KINDS="{`echo $pac_validRealKinds`}" + + PAC_FORTRAN_NUM_INTEGER_KINDS=$(./conftest$EXEEXT 2>&1 | sed -n '4p') + H5CONFIG_F_NUM_IKIND="INTEGER, PARAMETER :: num_ikinds = `echo $PAC_FORTRAN_NUM_INTEGER_KINDS`" + H5CONFIG_F_IKIND="INTEGER, DIMENSION(1:num_ikinds) :: ikind = (/`echo $pac_validIntKinds`/)" + H5CONFIG_F_NUM_RKIND="INTEGER, PARAMETER :: num_rkinds = $(./conftest$EXEEXT 2>&1 | sed -n '5p')" + H5CONFIG_F_RKIND="INTEGER, DIMENSION(1:num_rkinds) :: rkind = (/`echo $pac_validRealKinds`/)" + + AC_DEFINE_UNQUOTED([H5CONFIG_F_NUM_RKIND], $H5CONFIG_F_NUM_RKIND, [Define number of valid Fortran REAL KINDs]) + AC_DEFINE_UNQUOTED([H5CONFIG_F_NUM_IKIND], $H5CONFIG_F_NUM_IKIND, [Define number of valid Fortran INTEGER KINDs]) + AC_DEFINE_UNQUOTED([H5CONFIG_F_RKIND], $H5CONFIG_F_RKIND, [Define valid Fortran REAL KINDs]) + AC_DEFINE_UNQUOTED([H5CONFIG_F_IKIND], $H5CONFIG_F_IKIND, [Define valid Fortran INTEGER KINDs]) + + PAC_FORTRAN_NUM_LOGICAL_KINDS=$(./conftest$EXEEXT 2>&1 | sed -n '6p') + pac_validLogicalKinds=$(./conftest$EXEEXT 2>&1 | sed -n '7p') + PAC_FC_ALL_LOGICAL_KINDS="{`echo $pac_validLogicalKinds`}" + + AC_MSG_CHECKING([for Number of Fortran INTEGER KINDs]) + AC_MSG_RESULT([$PAC_FORTRAN_NUM_INTEGER_KINDS]) + AC_MSG_CHECKING([for Fortran INTEGER KINDs]) + AC_MSG_RESULT([$PAC_FC_ALL_INTEGER_KINDS]) + AC_MSG_CHECKING([for Fortran REAL KINDs]) + AC_MSG_RESULT([$PAC_FC_ALL_REAL_KINDS]) + AC_MSG_CHECKING([for Fortran REALs maximum decimal precision]) + AC_MSG_RESULT([$PAC_FC_MAX_REAL_PRECISION]) + AC_MSG_CHECKING([for Number of Fortran LOGICAL KINDs]) + AC_MSG_RESULT([$PAC_FORTRAN_NUM_LOGICAL_KINDS]) + AC_MSG_CHECKING([for Fortran LOGICAL KINDs]) + AC_MSG_RESULT([$PAC_FC_ALL_LOGICAL_KINDS]) +],[ + AC_MSG_RESULT([Error]) + AC_MSG_ERROR([Failed to run Fortran program to determine available KINDs]) +],[]) +AC_LANG_POP([Fortran]) +]) + +AC_DEFUN([PAC_FIND_MPI_LOGICAL_KIND],[ +AC_REQUIRE([PAC_FC_AVAIL_KINDS]) +AC_MSG_CHECKING([default Fortran KIND of LOGICAL in MPI]) +AC_LANG_PUSH([Fortran]) +saved_FCFLAGS=$FCFLAGS +check_Intel="`$FC -V 2>&1 |grep '^Intel'`" +if test X != "X$check_Intel"; then + FCFLAGS="-warn error" +else + FCFLAGS="" +fi +for kind in `echo $pac_validLogicalKinds | sed -e 's/,/ /g'`; do + AC_COMPILE_IFELSE([ + PROGRAM main + USE MPI + IMPLICIT NONE + LOGICAL(KIND=$kind) :: flag + INTEGER(KIND=MPI_INTEGER_KIND) :: info_ret, mpierror + CHARACTER(LEN=3) :: info_val + CALL mpi_info_get(info_ret,"foo", 3_MPI_INTEGER_KIND, info_val, flag, mpierror) + END], + [AC_SUBST([PAC_MPI_LOGICAL_KIND]) PAC_MPI_LOGICAL_KIND=$kind], + [] + ) +done +if test "X$PAC_MPI_LOGICAL_KIND" = "X"; then + AC_MSG_ERROR([Failed to find Fortran KIND of LOGICAL in MPI]) +else + AC_DEFINE_UNQUOTED([MPI_LOGICAL_KIND], [$PAC_MPI_LOGICAL_KIND], [Define MPI Fortran KIND of LOGICAL]) + AC_MSG_RESULT([$PAC_MPI_LOGICAL_KIND]) +fi +FCFLAGS=$saved_FCFLAGS +AC_LANG_POP([Fortran]) +]) + AC_DEFUN([PAC_FC_SIZEOF_INT_KINDS],[ AC_REQUIRE([PAC_FC_AVAIL_KINDS]) AC_MSG_CHECKING([sizeof of available INTEGER KINDs]) diff --git a/release_docs/INSTALL_Cygwin.txt b/release_docs/INSTALL_Cygwin.txt index 44516468c07..8f18ef98f72 100644 --- a/release_docs/INSTALL_Cygwin.txt +++ b/release_docs/INSTALL_Cygwin.txt @@ -2,20 +2,21 @@ HDF5 Build and Install Instructions for Cygwin ************************************************************************ -This document is an instruction on how to build, test and install HDF5 library on -Cygwin. See detailed information in hdf5/INSTALL. +This document is an instruction on how to build, test and install HDF5 library +on Cygwin. See detailed information in hdf5/INSTALL. -NOTE: hdf5 can be built with CMake, see the INSTALL_CMake.txt file for more guidance. +NOTE: hdf5 can be built with CMake, see the INSTALL_CMake.txt file for more +guidance. Preconditions: -------------- -1. Installed Cygwin 1.7.25 or higher +1. Cygwin 3.5.1 or higher Installed To install the Cygwin net release, go to http://www.cygwin.com and - click on "setup-x86.exe" (32-bit installation) under the heading + click on "setup-x86_64.exe" under the heading "Current Cygwin DLL version". This will download a GUI - installer called setup-x86.exe which can be run to download a complete + installer called setup-x86_64.exe which can be run to download a complete Cygwin installation via the internet. Then follow the instructions on each screen to install Cygwin. @@ -34,10 +35,10 @@ Preconditions: The following compilers are supported by HDF5 and included in the Cygwin package system: - gcc (4.7.3 and 4.9.2), which includes: - gcc4-core : C compiler - gcc4-g++ : C++ compiler - gcc4-fortran : fortran compiler + gcc, which includes: + gcc-core : C compiler + gcc-g++ : C++ compiler + gcc-fortran : Fortran compiler 2.1.1 Using Compilers Not Supported @@ -59,18 +60,13 @@ Preconditions: 2.2 HDF5 External Library Dependencies - 2.2.1 Zlib + 2.2.1 zlib - zlib-1.2.5 or later is supported and tested on Cygwin. + zlib-1.2.8 or later is supported and tested. 2.2.2 Szip - The HDF5 library has a predefined compression filter that uses - the extended-Rice lossless compression algorithm for chunked - datasets. For more information on Szip compression, license terms, - and obtaining the Szip source code, see: - - https://portal.hdfgroup.org/display/HDF5/Szip+Compression+in+HDF+Products + libaec-1.1.2 or later is supported and tested. 2.3 Additional Utilities @@ -91,8 +87,8 @@ Build, Test and Install HDF5 on Cygwin -------------------------------------- 1. Get HDF5 source code package - Users can download HDF5 source code package from HDF website - (http://hdfgroup.org). + Users can download the HDF5 source code from the official GitHub repository + (https://github.com/HDFGroup/hdf5). 2. Unpacking the distribution @@ -102,32 +98,30 @@ Build, Test and Install HDF5 on Cygwin 2.1 Non-compressed tar archive (*.tar) - $ tar xf hdf5-1.15.x.tar + $ tar xf hdf5-1.15.x.tar 2.2 Gzip'd tar archive (*.tar.gz) - $ gunzip < hdf5-1.15.x.tar.gz | tar xf - + $ gunzip < hdf5-1.15.x.tar.gz | tar xf - 2.3 Bzip'd tar archive (*.tar.bz2) - $ bunzip2 < hdf5-1.15.x.tar.bz2 | tar xf - + $ bunzip2 < hdf5-1.15.x.tar.bz2 | tar xf - 2. Setup Environment In Cygwin, most compilers and setting are automatically detected during - the configure script. However, if you are building Fortran we recommend + the configure script. However, if you are building Fortran, we recommend that you explicitly set the "FC" variable in your environment to use the - gfortran compiler. For example, issue the command: + gfortran compiler. For example, issue the command: - $ export FC=gfortran + $ export FC=gfortran 4. Configuring - Notes: See detailed information in hdf5/release_docs/INSTALL, - part 5. Full installation instructions for source - distributions + Notes: See detailed information in hdf5/release_docs/INSTALL_Auto.txt. - The host configuration file for cygwin i686-pc-cygwin is located + The host configuration file for Cygwin is located in the `config' directory and are based on architecture name, vendor name, and operating system which are displayed near the beginning of the `configure' output. The host config file influences @@ -137,34 +131,34 @@ Build, Test and Install HDF5 on Cygwin To configure HDF5 C Library, using - $ ./configure + $ ./configure To configure HDF5 C/C++ Library, using - $ ./configure --enable-cxx + $ ./configure --enable-cxx To configure HDF5 C/Fortran Library, using - $ ./configure --enable-fortran + $ ./configure --enable-fortran To configure HDF5 C with Szip library, using - $ ./configure --with-szlib="path to szlib" + $ ./configure --with-szlib="path to szlib" - For example, if szip library was installed in the directory + For example, if Szip library was installed in the directory /cygdrive/c/szip, which is parent directory of "include" and "lib", then the following command will configure HDF5 C library - with szip enabled: + with Szip enabled: - $ ./configure --with-szlib=/cygdrive/c/szip + $ ./configure --with-szlib=/cygdrive/c/szip - To configure HDF5 C without Zlib, + To configure HDF5 C without zlib, To disable zlib, using $ ./configure --without-zlib - Two ways to configure HDF5 C with specified Zlib + Two ways to configure HDF5 C with specified zlib Using @@ -174,7 +168,7 @@ Build, Test and Install HDF5 on Cygwin /cygdrive/c/usr, which is the parent directory of directories "include" and "lib", - $ ./configure --with-zlib=/cygdrive/c/usr/include,/cygdrive/c/usr/lib + $ ./configure --with-zlib=/cygdrive/c/usr/include,/cygdrive/c/usr/lib Through the CPPFLAGS and LDFLAGS Variables @@ -188,7 +182,7 @@ Build, Test and Install HDF5 on Cygwin To specify the installation directories, using - $ ./configure --prefix="path for installation" + $ ./configure --prefix="path for installation" By default, HDF5 library, header files, examples, and support programs will be installed in /usr/local/lib, @@ -201,7 +195,7 @@ Build, Test and Install HDF5 on Cygwin All of the above switches can be combined together. For example, if users want to configure HDF5 C/C++/Fortran - library with szip library enabled, with zlib library at + library with Szip library enabled, with zlib library at /cygdrive/c/usr/, and install HDF5 into directory /cygdrive/c/hdf5 using gcc/g++ as C/C++ compiler and gfortran as fortran compiler @@ -237,15 +231,15 @@ Build, Test and Install HDF5 on Cygwin After configuration is done successfully, run the following series of commands to build, test and install HDF5 - $ make > "output file name" - $ make check > "output file name" + $ make > "output file name" + $ make check > "output file name" Before run "make install", check output file for "make check", there should be no failures at all. 6. Make Install - $ make install > "output file name" + $ make install > "output file name" 7. Check installed HDF5 library @@ -255,8 +249,7 @@ Build, Test and Install HDF5 on Cygwin 8. Known Problems - dt_arith tests may fail due to the use of fork. This is a known issue - with cygwin on Windows. + cache_api tests may fail. This is a known issue with Cygwin. "make check" fails when building shared lib files is enabled. The default on Cygwin has been changed to disable shared. It can be enabled with diff --git a/release_docs/NEWSLETTER.txt b/release_docs/NEWSLETTER.txt index 0a7637cf0bf..55b7dcd8203 100644 --- a/release_docs/NEWSLETTER.txt +++ b/release_docs/NEWSLETTER.txt @@ -1,19 +1,20 @@ -Release of HDF5 1.14.4 Library and Tools is now available from the HDF5 Releases page. - -This is a maintenance release with a few changes and updates: ----------------------------------------------------------------------------- - -* Added support for _Float16 16-bit floating-point datatype - - Support for the 16-bit floating-point _Float16 C type has been added to - HDF5. On platforms where this type is available, this can enable more - efficient storage of floating-point data when an application doesn't - need the precision of larger floating-point datatypes. It can also allow - for improved performance when converting between 16-bit floating-point - data and data of another HDF5 datatype. - - (GitHub #4065, #2154) - ----------------------------------------------------------------------------- -Please see the full release notes for detailed information regarding this release, -including a detailed list of changes. \ No newline at end of file +Release of HDF5 1.14.4 Library and Tools is now available from the HDF5 Releases page. + +This is a maintenance release with a few changes and updates: +---------------------------------------------------------------------------- + +* Added support for _Float16 16-bit floating-point datatype + + Support for the 16-bit floating-point _Float16 C type has been added to + HDF5. On platforms where this type is available, this can enable more + efficient storage of floating-point data when an application doesn't + need the precision of larger floating-point datatypes. It can also allow + for improved performance when converting between 16-bit floating-point + data and data of another HDF5 datatype. + + (GitHub #4065, #2154) + +---------------------------------------------------------------------------- +Please see the full release notes for detailed information regarding this release, +including a detailed list of changes. + diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 75e0f925fea..2ff4bd8f017 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -701,6 +701,38 @@ Bug Fixes since HDF5-1.14.0 release an array of compound, variable length, or reference datatypes. Array types now use a background buffer if needed by the parent type. + - Fixed potential buffer read overflows in H5PB_read + + H5PB_read previously did not account for the fact that the size of the + read it's performing could overflow the page buffer pointer, depending + on the calculated offset for the read. This has been fixed by adjusting + the size of the read if it's determined that it would overflow the page. + + - Fixed CVE-2017-17507 + + This CVE was previously declared fixed, but later testing with a static + build of HDF5 showed that it was not fixed. + + When parsing a malformed (fuzzed) compound type containing variable-length + string members, the library could produce a segmentation fault, crashing + the library. + + This was fixed after GitHub PR #4234 + + Fixes GitHub issue #3446 + + - Fixed a cache assert with very large metadata objects + + If the library tries to load a metadata object that is above a + certain size, this would trip an assert in debug builds. This could + happen if you create a very large number of links in an old-style + group that uses local heaps. + + There is no need for this assert. The library's metadata cache + can handle large objects. The assert has been removed. + + Fixes GitHub #3762 + - Fixed an issue with the Subfiling VFD and multiple opens of a file @@ -780,6 +812,27 @@ Bug Fixes since HDF5-1.14.0 release overwriting data with a shorter (top level) variable length sequence, an error could occur. This has been fixed. + - Take user block into account in H5Dchunk_iter() and H5Dget_chunk_info() + + The address reported by the following functions did not correctly + take the user block into account: + + * H5Dchunk_iter() <-- addr passed to callback + * H5Dget_chunk_info() <-- addr parameter + * H5Dget_chunk_info_by_coord() <-- addr parameter + + This means that these functions reported logical HDF5 file addresses, + which would only be equal to the physical addresses when there is no + user block prepended to the HDF5 file. This is unfortunate, as the + primary use of these functions is to get physical addresses in order + to directly access the chunks. + + The listed functions now correctly take the user block into account, + so they will emit physical addresses that can be used to directly + access the chunks. + + Fixes #3003 + - Fixed asserts raised by large values of H5Pset_est_link_info() parameters If large values for est_num_entries and/or est_name_len were passed @@ -1699,6 +1752,11 @@ Platforms Tested Known Problems ============== + When building with the NAG Fortran compiler using the Autotools and libtool + 2.4.2 or earlier, the -shared flag will be missing '-Wl,', which will cause + compilation to fail. This is due to a bug in libtool that was fixed in 2012 + and released in 2.4.4 in 2014. + When HDF5 is compiled with NVHPC versions 23.5 - 23.9 (additional versions may also be applicable) and with -O2 (or higher) and -DNDEBUG, test failures occur in the following tests: @@ -1740,6 +1798,9 @@ Known Problems implemented: (1) derived type argument passed by value (H5VLff.F90), and (2) support for REAL with KIND = 2 in intrinsic SPACING used in testing. + Fortran tests HDF5_1_8.F90 and HDF5_F03.F90 will fail with Cray compilers greater than + version 16.0 due to a compiler bug. The latest version verified as failing was version 17.0. + Several tests currently fail on certain platforms: MPI_TEST-t_bigio fails with spectrum-mpi on ppc64le platforms. diff --git a/src/H5Adense.c b/src/H5Adense.c index 80c3c94f733..48004d2aa70 100644 --- a/src/H5Adense.c +++ b/src/H5Adense.c @@ -1104,12 +1104,12 @@ H5A__dense_iterate(H5F_t *f, hid_t loc_id, const H5O_ainfo_t *ainfo, H5_index_t H5_iter_order_t order, hsize_t skip, hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data) { - H5HF_t *fheap = NULL; /* Fractal heap handle */ - H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ - H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */ - H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ - haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ - herr_t ret_value = FAIL; /* Return value */ + H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + H5A_attr_table_t atable = {0, 0, NULL}; /* Table of attributes */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ + haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ + herr_t ret_value = FAIL; /* Return value */ FUNC_ENTER_PACKAGE @@ -1499,12 +1499,12 @@ herr_t H5A__dense_remove_by_idx(H5F_t *f, const H5O_ainfo_t *ainfo, H5_index_t idx_type, H5_iter_order_t order, hsize_t n) { - H5HF_t *fheap = NULL; /* Fractal heap handle */ - H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ - H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */ - H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ - haddr_t bt2_addr; /* Address of v2 B-tree to use for operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + H5A_attr_table_t atable = {0, 0, NULL}; /* Table of attributes */ + H5B2_t *bt2 = NULL; /* v2 B-tree handle for index */ + haddr_t bt2_addr; /* Address of v2 B-tree to use for operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -1586,7 +1586,7 @@ H5A__dense_remove_by_idx(H5F_t *f, const H5O_ainfo_t *ainfo, H5_index_t idx_type HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "error building table of attributes"); /* Check for skipping too many attributes */ - if (n >= atable.nattrs) + if (n >= atable.num_attrs) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified"); /* Delete appropriate attribute from dense storage */ diff --git a/src/H5Aint.c b/src/H5Aint.c index 5ba02163f87..45df0dfbe3e 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -51,16 +51,9 @@ typedef struct { H5F_t *f; /* Pointer to file that fractal heap is in */ H5A_attr_table_t *atable; /* Pointer to attribute table to build */ - size_t curr_attr; /* Current attribute to operate on */ bool bogus_crt_idx; /* Whether bogus creation index values need to be set */ } H5A_compact_bt_ud_t; -/* Data exchange structure to use when building table of dense attributes for an object */ -typedef struct { - H5A_attr_table_t *atable; /* Pointer to attribute table to build */ - size_t curr_attr; /* Current attribute to operate on */ -} H5A_dense_bt_ud_t; - /* Data exchange structure to use when copying an attribute from _SRC to _DST */ typedef struct { const H5O_ainfo_t *ainfo; /* dense information */ @@ -1455,30 +1448,31 @@ H5A__compact_build_table_cb(H5O_t H5_ATTR_UNUSED *oh, H5O_mesg_t *mesg /*in,out* assert(mesg); /* Re-allocate the table if necessary */ - if (udata->curr_attr == udata->atable->nattrs) { + if (udata->atable->num_attrs == udata->atable->max_attrs) { H5A_t **new_table; /* New table for attributes */ size_t new_table_size; /* Number of attributes in new table */ /* Allocate larger table */ - new_table_size = MAX(1, 2 * udata->atable->nattrs); + new_table_size = MAX(1, 2 * udata->atable->max_attrs); if (NULL == (new_table = (H5A_t **)H5FL_SEQ_REALLOC(H5A_t_ptr, udata->atable->attrs, new_table_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "unable to extend attribute table"); /* Update table information in user data */ - udata->atable->attrs = new_table; - udata->atable->nattrs = new_table_size; + udata->atable->attrs = new_table; + udata->atable->max_attrs = new_table_size; } /* end if */ /* Copy attribute into table */ - if (NULL == (udata->atable->attrs[udata->curr_attr] = H5A__copy(NULL, (const H5A_t *)mesg->native))) + if (NULL == + (udata->atable->attrs[udata->atable->num_attrs] = H5A__copy(NULL, (const H5A_t *)mesg->native))) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute"); /* Assign [somewhat arbitrary] creation order value, if requested */ if (udata->bogus_crt_idx) - ((udata->atable->attrs[udata->curr_attr])->shared)->crt_idx = sequence; + ((udata->atable->attrs[udata->atable->num_attrs])->shared)->crt_idx = sequence; - /* Increment current attribute */ - udata->curr_attr++; + /* Increment attribute count */ + udata->atable->num_attrs++; done: FUNC_LEAVE_NOAPI(ret_value) @@ -1501,9 +1495,10 @@ herr_t H5A__compact_build_table(H5F_t *f, H5O_t *oh, H5_index_t idx_type, H5_iter_order_t order, H5A_attr_table_t *atable) { - H5A_compact_bt_ud_t udata; /* User data for iteration callback */ - H5O_mesg_operator_t op; /* Wrapper for operator */ - herr_t ret_value = SUCCEED; /* Return value */ + H5A_compact_bt_ud_t udata; /* User data for iteration callback */ + H5O_mesg_operator_t op; /* Wrapper for operator */ + bool iter_set_up = false; /* Is everything set up for iteration */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -1513,13 +1508,13 @@ H5A__compact_build_table(H5F_t *f, H5O_t *oh, H5_index_t idx_type, H5_iter_order assert(atable); /* Initialize table */ - atable->attrs = NULL; - atable->nattrs = 0; + atable->attrs = NULL; + atable->num_attrs = 0; + atable->max_attrs = 0; /* Set up user data for iteration */ - udata.f = f; - udata.atable = atable; - udata.curr_attr = 0; + udata.f = f; + udata.atable = atable; udata.bogus_crt_idx = (bool)((oh->version == H5O_VERSION_1 || !(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)) ? true : false); @@ -1527,20 +1522,23 @@ H5A__compact_build_table(H5F_t *f, H5O_t *oh, H5_index_t idx_type, H5_iter_order /* Iterate over existing attributes, checking for attribute with same name */ op.op_type = H5O_MESG_OP_LIB; op.u.lib_op = H5A__compact_build_table_cb; + iter_set_up = true; if (H5O__msg_iterate_real(f, oh, H5O_MSG_ATTR, &op, &udata) < 0) HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error building attribute table"); - /* Correct # of attributes in table */ - atable->nattrs = udata.curr_attr; - /* Don't sort an empty table. */ - if (atable->nattrs > 0) { + if (atable->num_attrs > 0) /* Sort attribute table in correct iteration order */ if (H5A__attr_sort_table(atable, idx_type, order) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSORT, FAIL, "error sorting attribute table"); - } /* end if */ done: + if (ret_value < 0) + /* Clean up partially built table on error */ + if (iter_set_up) + if (atable->attrs && H5A__attr_release_table(atable) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute table"); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5A__compact_build_table() */ @@ -1557,26 +1555,26 @@ H5A__compact_build_table(H5F_t *f, H5O_t *oh, H5_index_t idx_type, H5_iter_order static herr_t H5A__dense_build_table_cb(const H5A_t *attr, void *_udata) { - H5A_dense_bt_ud_t *udata = (H5A_dense_bt_ud_t *)_udata; /* 'User data' passed in */ - herr_t ret_value = H5_ITER_CONT; /* Return value */ + H5A_attr_table_t *atable = (H5A_attr_table_t *)_udata; /* 'User data' passed in */ + herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_PACKAGE /* check arguments */ assert(attr); - assert(udata); - assert(udata->curr_attr < udata->atable->nattrs); + assert(atable); + assert(atable->num_attrs < atable->max_attrs); /* Allocate attribute for entry in the table */ - if (NULL == (udata->atable->attrs[udata->curr_attr] = H5FL_CALLOC(H5A_t))) + if (NULL == (atable->attrs[atable->num_attrs] = H5FL_CALLOC(H5A_t))) HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, H5_ITER_ERROR, "can't allocate attribute"); /* Copy attribute information. Share the attribute object in copying. */ - if (NULL == H5A__copy(udata->atable->attrs[udata->curr_attr], attr)) + if (NULL == H5A__copy(atable->attrs[atable->num_attrs], attr)) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute"); /* Increment number of attributes stored */ - udata->curr_attr++; + atable->num_attrs++; done: FUNC_LEAVE_NOAPI(ret_value) @@ -1622,22 +1620,18 @@ H5A__dense_build_table(H5F_t *f, const H5O_ainfo_t *ainfo, H5_index_t idx_type, if (H5B2_get_nrec(bt2_name, &nrec) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve # of records in index"); - /* Set size of table */ - H5_CHECK_OVERFLOW(nrec, /* From: */ hsize_t, /* To: */ size_t); - atable->nattrs = (size_t)nrec; - /* Allocate space for the table entries */ - if (atable->nattrs > 0) { - H5A_dense_bt_ud_t udata; /* User data for iteration callback */ + if (nrec > 0) { H5A_attr_iter_op_t attr_op; /* Attribute operator */ - /* Allocate the table to store the attributes */ - if ((atable->attrs = (H5A_t **)H5FL_SEQ_CALLOC(H5A_t_ptr, atable->nattrs)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + /* Check for overflow on the downcast */ + H5_CHECK_OVERFLOW(nrec, /* From: */ hsize_t, /* To: */ size_t); - /* Set up user data for iteration */ - udata.atable = atable; - udata.curr_attr = 0; + /* Allocate the table to store the attributes */ + if (NULL == (atable->attrs = (H5A_t **)H5FL_SEQ_CALLOC(H5A_t_ptr, (size_t)nrec))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed"); + atable->num_attrs = 0; + atable->max_attrs = (size_t)nrec; /* Build iterator operator */ attr_op.op_type = H5A_ATTR_OP_LIB; @@ -1645,7 +1639,7 @@ H5A__dense_build_table(H5F_t *f, const H5O_ainfo_t *ainfo, H5_index_t idx_type, /* Iterate over the links in the group, building a table of the link messages */ if (H5A__dense_iterate(f, (hid_t)0, ainfo, H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, NULL, &attr_op, - &udata) < 0) + atable) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table"); /* Sort attribute table in correct iteration order */ @@ -1791,18 +1785,18 @@ H5A__attr_sort_table(H5A_attr_table_t *atable, H5_index_t idx_type, H5_iter_orde /* Pick appropriate comparison routine */ if (idx_type == H5_INDEX_NAME) { if (order == H5_ITER_INC) - qsort(atable->attrs, atable->nattrs, sizeof(H5A_t *), H5A__attr_cmp_name_inc); + qsort(atable->attrs, atable->num_attrs, sizeof(H5A_t *), H5A__attr_cmp_name_inc); else if (order == H5_ITER_DEC) - qsort(atable->attrs, atable->nattrs, sizeof(H5A_t *), H5A__attr_cmp_name_dec); + qsort(atable->attrs, atable->num_attrs, sizeof(H5A_t *), H5A__attr_cmp_name_dec); else assert(order == H5_ITER_NATIVE); } /* end if */ else { assert(idx_type == H5_INDEX_CRT_ORDER); if (order == H5_ITER_INC) - qsort(atable->attrs, atable->nattrs, sizeof(H5A_t *), H5A__attr_cmp_corder_inc); + qsort(atable->attrs, atable->num_attrs, sizeof(H5A_t *), H5A__attr_cmp_corder_inc); else if (order == H5_ITER_DEC) - qsort(atable->attrs, atable->nattrs, sizeof(H5A_t *), H5A__attr_cmp_corder_dec); + qsort(atable->attrs, atable->num_attrs, sizeof(H5A_t *), H5A__attr_cmp_corder_dec); else assert(order == H5_ITER_NATIVE); } /* end else */ @@ -1839,7 +1833,7 @@ H5A__attr_iterate_table(const H5A_attr_table_t *atable, hsize_t skip, hsize_t *l /* Iterate over attribute messages */ H5_CHECKED_ASSIGN(u, size_t, skip, hsize_t); - for (; u < atable->nattrs && !ret_value; u++) { + for (; u < atable->num_attrs && !ret_value; u++) { /* Check which type of callback to make */ switch (attr_op->op_type) { case H5A_ATTR_OP_APP2: { @@ -1906,19 +1900,20 @@ H5A__attr_release_table(H5A_attr_table_t *atable) assert(atable); /* Release attribute info, if any. */ - if (atable->nattrs > 0) { + if (atable->num_attrs > 0) { size_t u; /* Local index variable */ /* Free attribute message information */ - for (u = 0; u < atable->nattrs; u++) + for (u = 0; u < atable->num_attrs; u++) if (atable->attrs[u] && H5A__close(atable->attrs[u]) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute"); + + /* Release array */ + atable->attrs = (H5A_t **)H5FL_SEQ_FREE(H5A_t_ptr, atable->attrs); } /* end if */ else assert(atable->attrs == NULL); - atable->attrs = (H5A_t **)H5FL_SEQ_FREE(H5A_t_ptr, atable->attrs); - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5A__attr_release_table() */ diff --git a/src/H5Apkg.h b/src/H5Apkg.h index 64549c818c0..239d7550c46 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -145,8 +145,9 @@ typedef struct H5A_bt2_ud_ins_t { /* Data structure to hold table of attributes for an object */ typedef struct { - size_t nattrs; /* # of attributes in table */ - H5A_t **attrs; /* Pointer to array of attribute pointers */ + size_t num_attrs; /* Curr. # of attributes in table */ + size_t max_attrs; /* Max. # of attributes in table */ + H5A_t **attrs; /* Pointer to array of attribute pointers */ } H5A_attr_table_t; /*****************************/ diff --git a/src/H5Centry.c b/src/H5Centry.c index c6892e90e3c..6883e897186 100644 --- a/src/H5Centry.c +++ b/src/H5Centry.c @@ -1216,10 +1216,9 @@ H5C__load_entry(H5F_t *f, assert((dirty == false) || (type->id == 5 || type->id == 6)); - entry->cache_ptr = f->shared->cache; - entry->addr = addr; - entry->size = len; - assert(entry->size < H5C_MAX_ENTRY_SIZE); + entry->cache_ptr = f->shared->cache; + entry->addr = addr; + entry->size = len; entry->image_ptr = image; entry->image_up_to_date = !dirty; entry->type = type; diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index e5b690e95c1..310f774e8da 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -250,9 +250,10 @@ typedef struct H5D_chunk_coll_fill_info_t { #endif /* H5_HAVE_PARALLEL */ typedef struct H5D_chunk_iter_ud_t { - H5D_chunk_iter_op_t op; /* User defined callback */ - void *op_data; /* User data for user defined callback */ - H5O_layout_chunk_t *chunk; /* Chunk layout */ + H5D_chunk_iter_op_t op; /* User defined callback */ + void *op_data; /* User data for user defined callback */ + H5O_layout_chunk_t *chunk; /* Chunk layout */ + haddr_t base_addr; /* Base address of the file, taking user block into account */ } H5D_chunk_iter_ud_t; /********************/ @@ -7850,7 +7851,7 @@ H5D__get_num_chunks(const H5D_t *dset, const H5S_t H5_ATTR_UNUSED *space, hsize_ /*------------------------------------------------------------------------- * Function: H5D__get_chunk_info_cb * - * Purpose: Get the chunk info of the queried chunk, given by its index. + * Purpose: Get the chunk info of the queried chunk, given by its index * * Return: Success: H5_ITER_CONT or H5_ITER_STOP * H5_ITER_STOP indicates the queried chunk is found @@ -7901,21 +7902,18 @@ H5D__get_chunk_info_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) * Note: Currently, the domain of the index in this function is of all * the written chunks, regardless the dataspace. * - * Return: Success: SUCCEED - * Failure: FAIL - * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ herr_t H5D__get_chunk_info(const H5D_t *dset, const H5S_t H5_ATTR_UNUSED *space, hsize_t chk_index, hsize_t *offset, unsigned *filter_mask, haddr_t *addr, hsize_t *size) { - H5D_chk_idx_info_t idx_info; /* Chunked index info */ - H5D_chunk_info_iter_ud_t udata; /* User data for callback */ - const H5D_rdcc_t *rdcc = NULL; /* Raw data chunk cache */ - H5D_rdcc_ent_t *ent; /* Cache entry index */ - hsize_t ii = 0; /* Dimension index */ - herr_t ret_value = SUCCEED; /* Return value */ + H5D_chk_idx_info_t idx_info; /* Chunked index info */ + const H5D_rdcc_t *rdcc = NULL; /* Raw data chunk cache */ + H5D_rdcc_ent_t *ent; /* Cache entry index */ + hsize_t ii = 0; /* Dimension index */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_TAG(dset->oloc.addr) @@ -7947,6 +7945,9 @@ H5D__get_chunk_info(const H5D_t *dset, const H5S_t H5_ATTR_UNUSED *space, hsize_ /* If the chunk is written, get its info, otherwise, return without error */ if (H5_addr_defined(idx_info.storage->idx_addr)) { + + H5D_chunk_info_iter_ud_t udata; + /* Initialize before iteration */ udata.chunk_idx = chk_index; udata.curr_idx = 0; @@ -7967,14 +7968,14 @@ H5D__get_chunk_info(const H5D_t *dset, const H5S_t H5_ATTR_UNUSED *space, hsize_ if (filter_mask) *filter_mask = udata.filter_mask; if (addr) - *addr = udata.chunk_addr; + *addr = udata.chunk_addr + H5F_BASE_ADDR(dset->oloc.file); if (size) *size = udata.nbytes; if (offset) for (ii = 0; ii < udata.ndims; ii++) offset[ii] = udata.scaled[ii] * dset->shared->layout.u.chunk.dim[ii]; - } /* end if */ - } /* end if H5_addr_defined */ + } + } done: FUNC_LEAVE_NOAPI_TAG(ret_value) @@ -8039,12 +8040,11 @@ herr_t H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *offset, unsigned *filter_mask, haddr_t *addr, hsize_t *size) { - const H5O_layout_t *layout = NULL; /* Dataset layout */ - const H5D_rdcc_t *rdcc = NULL; /* Raw data chunk cache */ - H5D_rdcc_ent_t *ent; /* Cache entry index */ - H5D_chk_idx_info_t idx_info; /* Chunked index info */ - H5D_chunk_info_iter_ud_t udata; /* User data for callback */ - herr_t ret_value = SUCCEED; /* Return value */ + const H5O_layout_t *layout = NULL; /* Dataset layout */ + const H5D_rdcc_t *rdcc = NULL; /* Raw data chunk cache */ + H5D_rdcc_ent_t *ent; /* Cache entry index */ + H5D_chk_idx_info_t idx_info; /* Chunked index info */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_TAG(dset->oloc.addr) @@ -8080,6 +8080,9 @@ H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *offset, unsigned /* If the dataset is not written, return without errors */ if (H5_addr_defined(idx_info.storage->idx_addr)) { + + H5D_chunk_info_iter_ud_t udata; + /* Calculate the scaled of this chunk */ H5VM_chunk_scaled(dset->shared->ndims, offset, layout->u.chunk.dim, udata.scaled); udata.scaled[dset->shared->ndims] = 0; @@ -8102,11 +8105,11 @@ H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *offset, unsigned if (filter_mask) *filter_mask = udata.filter_mask; if (addr) - *addr = udata.chunk_addr; + *addr = udata.chunk_addr + H5F_BASE_ADDR(dset->oloc.file); if (size) *size = udata.nbytes; - } /* end if */ - } /* end if H5_addr_defined */ + } + } done: FUNC_LEAVE_NOAPI_TAG(ret_value) @@ -8115,33 +8118,32 @@ H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *offset, unsigned /*------------------------------------------------------------------------- * Function: H5D__chunk_iter_cb * - * Purpose: Call the user-defined function with the chunk data. The iterator continues if - * the user-defined function returns H5_ITER_CONT, and stops if H5_ITER_STOP is - * returned. + * Purpose: Call the user-defined function with the chunk data. The + * iterator continues if the user-defined function returns + * H5_ITER_CONT, and stops if H5_ITER_STOP is returned. * * Return: Success: H5_ITER_CONT or H5_ITER_STOP * Failure: Negative (H5_ITER_ERROR) - * *------------------------------------------------------------------------- */ static int H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata) { - const H5D_chunk_iter_ud_t *data = (H5D_chunk_iter_ud_t *)udata; - const H5O_layout_chunk_t *chunk = data->chunk; - int ret_value = H5_ITER_CONT; + const H5D_chunk_iter_ud_t *data = (H5D_chunk_iter_ud_t *)udata; + const H5O_layout_chunk_t *chunk = data->chunk; hsize_t offset[H5O_LAYOUT_NDIMS]; - unsigned ii; /* Match H5O_layout_chunk_t.ndims */ + int ret_value = H5_ITER_CONT; /* Similar to H5D__get_chunk_info */ - for (ii = 0; ii < chunk->ndims; ii++) - offset[ii] = chunk_rec->scaled[ii] * chunk->dim[ii]; + for (unsigned i = 0; i < chunk->ndims; i++) + offset[i] = chunk_rec->scaled[i] * chunk->dim[i]; FUNC_ENTER_PACKAGE_NOERR /* Check for callback failure and pass along return value */ - if ((ret_value = (data->op)(offset, (unsigned)chunk_rec->filter_mask, chunk_rec->chunk_addr, - (hsize_t)chunk_rec->nbytes, data->op_data)) < 0) + if ((ret_value = + (data->op)(offset, (unsigned)chunk_rec->filter_mask, data->base_addr + chunk_rec->chunk_addr, + (hsize_t)chunk_rec->nbytes, data->op_data)) < 0) HERROR(H5E_DATASET, H5E_CANTNEXT, "iteration operator failed"); FUNC_LEAVE_NOAPI(ret_value) @@ -8150,11 +8152,9 @@ H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata) /*------------------------------------------------------------------------- * Function: H5D__chunk_iter * - * Purpose: Iterate over all the chunks in the dataset with given callback. - * - * Return: Success: Non-negative - * Failure: Negative + * Purpose: Iterate over all the chunks in the dataset with given callback * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ herr_t @@ -8196,14 +8196,15 @@ H5D__chunk_iter(H5D_t *dset, H5D_chunk_iter_op_t op, void *op_data) H5D_chunk_iter_ud_t ud; /* Set up info for iteration callback */ - ud.op = op; - ud.op_data = op_data; - ud.chunk = &dset->shared->layout.u.chunk; + ud.op = op; + ud.op_data = op_data; + ud.chunk = &dset->shared->layout.u.chunk; + ud.base_addr = H5F_BASE_ADDR(dset->oloc.file); /* Iterate over the allocated chunks calling the iterator callback */ if ((ret_value = (layout->storage.u.chunk.ops->iterate)(&idx_info, H5D__chunk_iter_cb, &ud)) < 0) HERROR(H5E_DATASET, H5E_CANTNEXT, "chunk iteration failed"); - } /* end if H5_addr_defined */ + } done: FUNC_LEAVE_NOAPI_TAG(ret_value) diff --git a/src/H5Dint.c b/src/H5Dint.c index 8f363ebadbe..3b9d000f523 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -946,6 +946,13 @@ H5D__update_oh_info(H5F_t *file, H5D_t *dset, hid_t dapl_id) if (NULL == (oh = H5O_pin(oloc))) HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header"); + /* Check for creating dataset with unusual datatype */ + if (!(H5O_has_chksum(oh) || (H5F_RFIC_FLAGS(file) & H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS)) && + H5T_is_numeric_with_unusual_unused_bits(type)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, + "creating dataset with unusual datatype, see documentation for " + "H5Pset_relax_file_integrity_checks for details."); + /* Write the dataspace header message */ if (H5S_append(file, oh, dset->shared->space) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update dataspace header message"); diff --git a/src/H5Dio.c b/src/H5Dio.c index 62bb48c2a26..312c7fd854b 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -395,8 +395,12 @@ H5D__read(size_t count, H5D_dset_io_info_t *dset_info) H5AC_tag(dset_info[i].dset->oloc.addr, &prev_tag); /* Invoke correct "high level" I/O routine */ - if ((*dset_info[i].io_ops.multi_read)(&io_info, &dset_info[i]) < 0) + if ((*dset_info[i].io_ops.multi_read)(&io_info, &dset_info[i]) < 0) { + /* Reset metadata tagging */ + H5AC_tag(prev_tag, NULL); + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data"); + } /* Reset metadata tagging */ H5AC_tag(prev_tag, NULL); diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 35d0edfe211..eda38863d89 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -224,7 +224,7 @@ typedef herr_t (*H5D_gather_func_t)(const void *dst_buf, size_t dst_buf_bytes_us * * \param[in] offset Logical position of the chunk's first element in units of dataset elements * \param[in] filter_mask Bitmask indicating the filters used when the chunk was written - * \param[in] addr Chunk address in the file + * \param[in] addr Chunk address in the file, taking the user block (if any) into account * \param[in] size Chunk size in bytes, 0 if the chunk does not exist * \param[in,out] op_data Pointer to any user-defined data associated with * the operation. @@ -669,7 +669,7 @@ H5_DLL herr_t H5Dget_num_chunks(hid_t dset_id, hid_t fspace_id, hsize_t *nchunks * \dset_id * \param[in] offset Logical position of the chunk's first element in units of dataset elements * \param[out] filter_mask Bitmask indicating the filters used when the chunk was written - * \param[out] addr Chunk address in the file + * \param[out] addr Chunk address in the file, taking the user block (if any) into account * \param[out] size Chunk size in bytes, 0 if the chunk does not exist * * \return \herr_t @@ -686,6 +686,9 @@ H5_DLL herr_t H5Dget_num_chunks(hid_t dset_id, hid_t fspace_id, hsize_t *nchunks * equal to the dataset's rank. Each element is the logical * position of the chunk's first element in a dimension. * + * \note Prior to HDF5 1.14.4, the reported address did not take the + * user block into account. + * * \since 1.10.5 * */ @@ -709,6 +712,9 @@ H5_DLL herr_t H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, u * user supplied callback with the details of the chunk and the supplied * context \p op_data. * + * \note Prior to HDF5 1.14.4, the address passed to the callback did not take + * the user block into account. + * * \par Example * For each chunk, print the allocated chunk size (0 for unallocated chunks). * \snippet H5D_examples.c H5Dchunk_iter_cb @@ -731,7 +737,7 @@ H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, hid_t dxpl_id, H5D_chunk_iter_op_t cb * \param[in] chk_idx Index of the chunk * \param[out] offset Logical position of the chunk's first element in units of dataset elements * \param[out] filter_mask Bitmask indicating the filters used when the chunk was written - * \param[out] addr Chunk address in the file + * \param[out] addr Chunk address in the file, taking the user block (if any) into account * \param[out] size Chunk size in bytes, 0 if the chunk does not exist * * \return \herr_t @@ -745,6 +751,9 @@ H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, hid_t dxpl_id, H5D_chunk_iter_op_t cb * address to #HADDR_UNDEF. The value pointed to by filter_mask will * not be modified. \c NULL can be passed in for any \p out parameters. * + * \note Prior to HDF5 1.14.4, the reported address did not take the + * user block into account. + * * \p chk_idx is the chunk index in the selection. The index value * may have a value of 0 up to the number of chunks stored in * the file that has a nonempty intersection with the file diff --git a/src/H5Eint.c b/src/H5Eint.c index a4ba5b2d4b9..70848ecd7c2 100644 --- a/src/H5Eint.c +++ b/src/H5Eint.c @@ -730,13 +730,13 @@ H5E__push_stack(H5E_t *estack, const char *file, const char *func, unsigned line if (estack->nused < H5E_NSLOTS) { /* Increment the IDs to indicate that they are used in this stack */ - if (H5I_inc_ref(cls_id, false) < 0) + if (H5I_inc_ref_noherr(cls_id, false) < 0) HGOTO_DONE(FAIL); estack->slot[estack->nused].cls_id = cls_id; - if (H5I_inc_ref(maj_id, false) < 0) + if (H5I_inc_ref_noherr(maj_id, false) < 0) HGOTO_DONE(FAIL); estack->slot[estack->nused].maj_num = maj_id; - if (H5I_inc_ref(min_id, false) < 0) + if (H5I_inc_ref_noherr(min_id, false) < 0) HGOTO_DONE(FAIL); estack->slot[estack->nused].min_num = min_id; /* The 'func' & 'file' strings are statically allocated (by the compiler) diff --git a/src/H5FDtest.c b/src/H5FDtest.c index 694bae482e5..2a48fb5b8cd 100644 --- a/src/H5FDtest.c +++ b/src/H5FDtest.c @@ -67,14 +67,15 @@ * Purpose: Determines if a VFD supports SWMR. * * The function determines SWMR support by inspecting the - * HDF5_DRIVER environment variable, not by checking the - * VFD feature flags (which do not exist until the driver - * is instantiated). + * HDF5_DRIVER and HDF5_TEST_DRIVER environment variables, not + * by checking the VFD feature flags (which do not exist until + * the driver is instantiated). * * This function is only intended for use in the test code. * * Return: true (1) if the VFD supports SWMR I/O or vfd_name is - * NULL or the empty string (which implies the default VFD). + * NULL or the empty string (which implies the default VFD) or + * compares equal to the default VFD's name. * * false (0) if it does not * @@ -89,7 +90,10 @@ H5FD__supports_swmr_test(const char *vfd_name) FUNC_ENTER_NOAPI_NOINIT_NOERR - if (!vfd_name || !strcmp(vfd_name, "") || !strcmp(vfd_name, "nomatch")) + if (!vfd_name) + vfd_name = getenv("HDF5_TEST_DRIVER"); + + if (!vfd_name || !strcmp(vfd_name, "") || !strcmp(vfd_name, H5_DEFAULT_VFD_NAME)) ret_value = true; else ret_value = !strcmp(vfd_name, "log") || !strcmp(vfd_name, "sec2"); diff --git a/src/H5Fint.c b/src/H5Fint.c index 325947656bf..3f5a1379834 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -438,6 +438,8 @@ H5F_get_access_plist(H5F_t *f, bool app_ref) 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set initial metadata cache resize config."); + if (H5P_set(new_plist, H5F_ACS_RFIC_FLAGS_NAME, &(f->shared->rfic_flags)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set RFIC flags value"); /* Prepare the driver property */ driver_prop.driver_id = f->shared->lf->driver_id; @@ -1230,6 +1232,8 @@ H5F__new(H5F_shared_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5F if (H5P_get(plist, H5F_ACS_META_CACHE_INIT_IMAGE_CONFIG_NAME, &(f->shared->mdc_initCacheImageCfg)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config"); + if (H5P_get(plist, H5F_ACS_RFIC_FLAGS_NAME, &(f->shared->rfic_flags)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get RFIC flags value"); /* Get the VFD values to cache */ f->shared->maxaddr = H5FD_get_maxaddr(lf); diff --git a/src/H5Fmodule.h b/src/H5Fmodule.h index 098e703eac9..f72d4463707 100644 --- a/src/H5Fmodule.h +++ b/src/H5Fmodule.h @@ -235,10 +235,10 @@ * Note that the root group, indicated above by /, was automatically created when the file was created. * * h5dump is described on the - * Tools + * + * Tools * page under - * - * Libraries and Tools Reference. + * Command-line Tools. * The HDF5 DDL grammar is described in the document \ref DDLBNF114. * * \subsection subsec_file_summary File Function Summaries @@ -888,7 +888,7 @@ * * Additional parameters may be added to these functions in the future. * - * @see + * @see * HDF5 File Image Operations * section for information on more advanced usage of the Memory file driver, and * @see diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 60de31ebdfd..7e12ff111d0 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -304,6 +304,7 @@ struct H5F_shared_t { bool use_file_locking; /* Whether or not to use file locking */ bool ignore_disabled_locks; /* Whether or not to ignore disabled file locking */ bool closing; /* File is in the process of being closed */ + uint64_t rfic_flags; /* Relaxed file integrity check (RFIC) flags */ /* Cached VOL connector ID & info */ hid_t vol_id; /* ID of VOL connector for the container */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 682e938120c..d2b1b887a7f 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -101,6 +101,7 @@ typedef struct H5F_t H5F_t; #define H5F_VOL_CLS(F) ((F)->shared->vol_cls) #define H5F_VOL_OBJ(F) ((F)->vol_obj) #define H5F_USE_FILE_LOCKING(F) ((F)->shared->use_file_locking) +#define H5F_RFIC_FLAGS(F) ((F)->shared->rfic_flags) #else /* H5F_MODULE */ #define H5F_LOW_BOUND(F) (H5F_get_low_bound(F)) #define H5F_HIGH_BOUND(F) (H5F_get_high_bound(F)) @@ -165,6 +166,7 @@ typedef struct H5F_t H5F_t; #define H5F_VOL_CLS(F) (H5F_get_vol_cls(F)) #define H5F_VOL_OBJ(F) (H5F_get_vol_obj(F)) #define H5F_USE_FILE_LOCKING(F) (H5F_get_use_file_locking(F)) +#define H5F_RFIC_FLAGS(F) (H5F_get_rfic_flags(F)) #endif /* H5F_MODULE */ /* Macros to encode/decode offset/length's for storing in the file */ @@ -282,6 +284,7 @@ typedef struct H5F_t H5F_t; #define H5F_ACS_MPI_PARAMS_COMM_NAME "mpi_params_comm" /* the MPI communicator */ #define H5F_ACS_MPI_PARAMS_INFO_NAME "mpi_params_info" /* the MPI info struct */ #endif /* H5_HAVE_PARALLEL */ +#define H5F_ACS_RFIC_FLAGS_NAME "rfic_flags" /* Relaxed file integrity check (RFIC) flags */ /* ======================== File Mount properties ====================*/ #define H5F_MNT_SYM_LOCAL_NAME "local" /* Whether absolute symlinks local to file. */ @@ -525,7 +528,8 @@ H5_DLL bool H5F_get_min_dset_ohdr(const H5F_t *f); H5_DLL herr_t H5F_set_min_dset_ohdr(H5F_t *f, bool minimize); H5_DLL const H5VL_class_t *H5F_get_vol_cls(const H5F_t *f); H5_DLL H5VL_object_t *H5F_get_vol_obj(const H5F_t *f); -H5_DLL bool H5F_get_file_locking(const H5F_t *f); +H5_DLL bool H5F_get_use_file_locking(const H5F_t *f); +H5_DLL uint64_t H5F_get_rfic_flags(const H5F_t *f); /* Functions than retrieve values set/cached from the superblock/FCPL */ H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f); diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 45580ac41ec..9dad8852a06 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -242,6 +242,20 @@ typedef struct H5F_retry_info_t { */ typedef herr_t (*H5F_flush_cb_t)(hid_t object_id, void *udata); +/* + * These are the bits that can be passed to the `flags' argument of + * H5Pset_relax_file_integrity_checks(). Use the bit-wise OR operator (|) to + * combine them as needed. + */ +#define H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS \ + (0x0001u) /**< Suppress errors for numeric datatypes with an unusually \ + * high number of unused bits. See documentation for \ + * H5Pset_relax_file_integrity_checks for details. */ +#define H5F_RFIC_ALL \ + (H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS) /**< Suppress all format integrity check errors. See \ + * documentation for H5Pset_relax_file_integrity_checks \ + * for details. */ + /*********************/ /* Public Prototypes */ /*********************/ diff --git a/src/H5Fquery.c b/src/H5Fquery.c index 44a52c8dbfc..89181dad479 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -1356,16 +1356,16 @@ H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info) } /* end H5F_get_cont_info */ /*------------------------------------------------------------------------- - * Function: H5F_get_file_locking + * Function: H5F_get_use_file_locking * - * Purpose: Get the file locking flag for the file + * Purpose: Get the 'use file locking' flag for the file * * Return: true/false * *------------------------------------------------------------------------- */ bool -H5F_get_file_locking(const H5F_t *f) +H5F_get_use_file_locking(const H5F_t *f) { FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -1373,7 +1373,7 @@ H5F_get_file_locking(const H5F_t *f) assert(f->shared); FUNC_LEAVE_NOAPI(f->shared->use_file_locking) -} /* end H5F_get_file_locking */ +} /* end H5F_get_use_file_locking */ /*------------------------------------------------------------------------- * Function: H5F_has_vector_select_io @@ -1401,3 +1401,23 @@ H5F_has_vector_select_io(const H5F_t *f, bool is_write) FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_has_vector_select_io */ + +/*------------------------------------------------------------------------- + * Function: H5F_get_rfic_flags + * + * Purpose: Get the relaxed file integrity checks (RFIC) flags for the file + * + * Return: RFIC flags for a file on success (which can be 0), can't fail + * + *------------------------------------------------------------------------- + */ +uint64_t +H5F_get_rfic_flags(const H5F_t *f) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + assert(f); + assert(f->shared); + + FUNC_LEAVE_NOAPI(f->shared->rfic_flags) +} /* end H5F_get_rfic_flags */ diff --git a/src/H5HG.c b/src/H5HG.c index 7037376118d..3709c705566 100644 --- a/src/H5HG.c +++ b/src/H5HG.c @@ -559,9 +559,13 @@ H5HG_read(H5F_t *f, H5HG_t *hobj, void *object /*out*/, size_t *buf_size) /* Load the heap */ if (NULL == (heap = H5HG__protect(f, hobj->addr, H5AC__READ_ONLY_FLAG))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect global heap"); + if (hobj->idx >= heap->nused) + HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, NULL, "bad heap index, heap object = {%" PRIxHADDR ", %zu}", + hobj->addr, hobj->idx); + if (NULL == heap->obj[hobj->idx].begin) + HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, NULL, "bad heap pointer, heap object = {%" PRIxHADDR ", %zu}", + hobj->addr, hobj->idx); - assert(hobj->idx < heap->nused); - assert(heap->obj[hobj->idx].begin); size = heap->obj[hobj->idx].size; p = heap->obj[hobj->idx].begin + H5HG_SIZEOF_OBJHDR(f); @@ -631,8 +635,12 @@ H5HG_link(H5F_t *f, const H5HG_t *hobj, int adjust) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect global heap"); if (adjust != 0) { - assert(hobj->idx < heap->nused); - assert(heap->obj[hobj->idx].begin); + if (hobj->idx >= heap->nused) + HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "bad heap index, heap object = {%" PRIxHADDR ", %zu}", + hobj->addr, hobj->idx); + if (NULL == heap->obj[hobj->idx].begin) + HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "bad heap pointer, heap object = {%" PRIxHADDR ", %zu}", + hobj->addr, hobj->idx); if ((heap->obj[hobj->idx].nrefs + adjust) < 0) HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, FAIL, "new link count would be out of range"); if ((heap->obj[hobj->idx].nrefs + adjust) > H5HG_MAXLINK) @@ -678,8 +686,13 @@ H5HG_get_obj_size(H5F_t *f, H5HG_t *hobj, size_t *obj_size) if (NULL == (heap = H5HG__protect(f, hobj->addr, H5AC__READ_ONLY_FLAG))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect global heap"); - assert(hobj->idx < heap->nused); - assert(heap->obj[hobj->idx].begin); + /* Sanity check the heap object */ + if (hobj->idx >= heap->nused) + HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "bad heap index, heap object = {%" PRIxHADDR ", %zu}", + hobj->addr, hobj->idx); + if (NULL == heap->obj[hobj->idx].begin) + HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "bad heap pointer, heap object = {%" PRIxHADDR ", %zu}", + hobj->addr, hobj->idx); /* Set object size */ *obj_size = heap->obj[hobj->idx].size; @@ -722,14 +735,22 @@ H5HG_remove(H5F_t *f, H5HG_t *hobj) if (NULL == (heap = H5HG__protect(f, hobj->addr, H5AC__NO_FLAGS_SET))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect global heap"); - assert(hobj->idx < heap->nused); + /* Sanity check the heap object (split around bugfix below) */ + if (hobj->idx >= heap->nused) + HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "bad heap index, heap object = {%" PRIxHADDR ", %zu}", + hobj->addr, hobj->idx); /* When the application selects the same location to rewrite the VL element by using H5Sselect_elements, * it can happen that the entry has been removed by first rewrite. Here we simply skip the removal of * the entry and let the second rewrite happen (see HDFFV-10635). In the future, it'd be nice to handle * this situation in H5T_conv_vlen in H5Tconv.c instead of this level (HDFFV-10648). */ if (heap->obj[hobj->idx].nrefs == 0 && heap->obj[hobj->idx].size == 0 && !heap->obj[hobj->idx].begin) - HGOTO_DONE(ret_value); + HGOTO_DONE(SUCCEED); + + /* Finish sanity checking the heap object */ + if (NULL == heap->obj[hobj->idx].begin) + HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "bad heap pointer, heap object = {%" PRIxHADDR ", %zu}", + hobj->addr, hobj->idx); obj_start = heap->obj[hobj->idx].begin; /* Include object header size */ diff --git a/src/H5Iint.c b/src/H5Iint.c index fe3b90c2454..1df3ae907a8 100644 --- a/src/H5Iint.c +++ b/src/H5Iint.c @@ -1230,6 +1230,27 @@ H5I_dec_app_ref_always_close_async(hid_t id, void **token) FUNC_LEAVE_NOAPI(ret_value) } /* end H5I_dec_app_ref_always_close_async() */ +/*------------------------------------------------------------------------- + * Function: H5I_do_inc_ref + * + * Purpose: Helper function for H5I_inc_ref/H5I_inc_ref_noherr to + * actually increment the reference count for an object. + * + * Return: The new reference count (can't fail) + * + *------------------------------------------------------------------------- + */ +static inline int +H5I_do_inc_ref(H5I_id_info_t *info, bool app_ref) +{ + /* Adjust reference counts */ + ++(info->count); + if (app_ref) + ++(info->app_count); + + return (int)(app_ref ? info->app_count : info->count); +} + /*------------------------------------------------------------------------- * Function: H5I_inc_ref * @@ -1255,18 +1276,59 @@ H5I_inc_ref(hid_t id, bool app_ref) if (NULL == (info = H5I__find_id(id))) HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "can't locate ID"); - /* Adjust reference counts */ - ++(info->count); - if (app_ref) - ++(info->app_count); - /* Set return value */ - ret_value = (int)(app_ref ? info->app_count : info->count); + ret_value = H5I_do_inc_ref(info, app_ref); done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5I_inc_ref() */ +/*------------------------------------------------------------------------- + * Function: H5I_inc_ref_noherr + * + * Purpose: Increment the reference count for an object. Exactly like + * H5I_inc_ref, except that it makes use of HGOTO_DONE on + * failure instead of HGOTO_ERROR. This function is + * specifically meant to be used in the H5E package, where we + * have to avoid calling any function or macro that may call + * HGOTO_ERROR and similar. Otherwise, we can cause a stack + * overflow that looks like (for example): + * + * H5E_printf_stack() + * H5E__push_stack() + * H5I_inc_ref() + * H5I__find_id() (FAIL) + * HGOTO_ERROR() + * H5E_printf_stack() + * ... + * + * Return: Success: The new reference count + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +int +H5I_inc_ref_noherr(hid_t id, bool app_ref) +{ + H5I_id_info_t *info = NULL; /* Pointer to the ID info */ + int ret_value = 0; /* Return value */ + + FUNC_ENTER_NOAPI_NOERR + + /* Sanity check */ + assert(id >= 0); + + /* General lookup of the ID */ + if (NULL == (info = H5I__find_id(id))) + HGOTO_DONE((-1)); + + /* Set return value */ + ret_value = H5I_do_inc_ref(info, app_ref); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I_inc_ref_noherr() */ + /*------------------------------------------------------------------------- * Function: H5I_get_ref * diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h index 75a5787b616..83fdacc686f 100644 --- a/src/H5Iprivate.h +++ b/src/H5Iprivate.h @@ -68,6 +68,7 @@ H5_DLL H5I_type_t H5I_get_type(hid_t id); H5_DLL herr_t H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, bool app_ref); H5_DLL int H5I_get_ref(hid_t id, bool app_ref); H5_DLL int H5I_inc_ref(hid_t id, bool app_ref); +H5_DLL int H5I_inc_ref_noherr(hid_t id, bool app_ref); H5_DLL int H5I_dec_ref(hid_t id); H5_DLL int H5I_dec_app_ref(hid_t id); H5_DLL int H5I_dec_app_ref_async(hid_t id, void **token); diff --git a/src/H5Mpublic.h b/src/H5Mpublic.h index 48625a55382..e108a5c25d7 100644 --- a/src/H5Mpublic.h +++ b/src/H5Mpublic.h @@ -32,33 +32,37 @@ /* Macros defining operation IDs for map VOL callbacks (implemented using the * "optional" VOL callback) */ -#define H5VL_MAP_CREATE 1 -#define H5VL_MAP_OPEN 2 -#define H5VL_MAP_GET_VAL 3 -#define H5VL_MAP_EXISTS 4 -#define H5VL_MAP_PUT 5 -#define H5VL_MAP_GET 6 -#define H5VL_MAP_SPECIFIC 7 -#define H5VL_MAP_OPTIONAL 8 -#define H5VL_MAP_CLOSE 9 +#define H5VL_MAP_CREATE 1 /**< Callback operation ID for map create */ +#define H5VL_MAP_OPEN 2 /**< Callback operation ID for map open */ +#define H5VL_MAP_GET_VAL 3 /**< Callback operation ID for getting an associated value from a map */ +#define H5VL_MAP_EXISTS 4 /**< Callback operation ID for checking if a value exists in a map */ +#define H5VL_MAP_PUT 5 /**< Callback operation ID for putting a key-value pair to a map */ +#define H5VL_MAP_GET 6 /**< Callback operation ID for map get callback */ +#define H5VL_MAP_SPECIFIC 7 /**< Callback operation ID for map specific operation */ +#define H5VL_MAP_OPTIONAL 8 /**< Currently unused */ +#define H5VL_MAP_CLOSE 9 /**< Callback operation ID for terminating access to a map */ /*******************/ /* Public Typedefs */ /*******************/ -/* types for map GET callback */ +/** + * Types for map GET callback + */ typedef enum H5VL_map_get_t { - H5VL_MAP_GET_MAPL, /* map access property list */ - H5VL_MAP_GET_MCPL, /* map creation property list */ - H5VL_MAP_GET_KEY_TYPE, /* key type */ - H5VL_MAP_GET_VAL_TYPE, /* value type */ - H5VL_MAP_GET_COUNT /* key count */ + H5VL_MAP_GET_MAPL, /**< Callback operation ID for getting map access property list */ + H5VL_MAP_GET_MCPL, /**< Callback operation ID for getting map creation property list */ + H5VL_MAP_GET_KEY_TYPE, /**< Callback operation ID for getting the key datatype for a map */ + H5VL_MAP_GET_VAL_TYPE, /**< Callback operation ID for getting the value datatype for a map */ + H5VL_MAP_GET_COUNT /**< Callback operation ID for getting the number of key-value pairs stored in a map */ } H5VL_map_get_t; -/* types for map SPECIFIC callback */ +/** + * Types for map SPECIFIC callback + */ typedef enum H5VL_map_specific_t { - H5VL_MAP_ITER, /* H5Miterate */ - H5VL_MAP_DELETE /* H5Mdelete */ + H5VL_MAP_ITER, /**< Callback operation ID for iterating over all key-value pairs stored in the map */ + H5VL_MAP_DELETE /**< Callback operation ID for deleting a key-value pair stored in the map */ } H5VL_map_specific_t; //! @@ -68,112 +72,116 @@ typedef enum H5VL_map_specific_t { typedef herr_t (*H5M_iterate_t)(hid_t map_id, const void *key, void *op_data); //! -/* Parameters for map operations */ +/** + * Parameters for map operations + */ typedef union H5VL_map_args_t { - /* H5VL_MAP_CREATE */ + + /** H5VL_MAP_CREATE */ struct { - H5VL_loc_params_t loc_params; /* Location parameters for object */ - const char *name; /* Name of new map object */ - hid_t lcpl_id; /* Link creation property list for map */ - hid_t key_type_id; /* Datatype for map keys */ - hid_t val_type_id; /* Datatype for map values */ - hid_t mcpl_id; /* Map creation property list */ - hid_t mapl_id; /* Map access property list */ - void *map; /* Pointer to newly created map object (OUT) */ + H5VL_loc_params_t loc_params; /**< Location parameters for object */ + const char *name; /**< Name of new map object */ + hid_t lcpl_id; /**< Link creation property list for map */ + hid_t key_type_id; /**< Datatype for map keys */ + hid_t val_type_id; /**< Datatype for map values */ + hid_t mcpl_id; /**< Map creation property list */ + hid_t mapl_id; /**< Map access property list */ + void *map; /**< Pointer to newly created map object (OUT) */ } create; - /* H5VL_MAP_OPEN */ + /** H5VL_MAP_OPEN */ struct { - H5VL_loc_params_t loc_params; /* Location parameters for object */ - const char *name; /* Name of new map object */ - hid_t mapl_id; /* Map access property list */ - void *map; /* Pointer to newly created map object (OUT) */ + H5VL_loc_params_t loc_params; /**< Location parameters for object */ + const char *name; /**< Name of new map object */ + hid_t mapl_id; /**< Map access property list */ + void *map; /**< Pointer to newly created map object (OUT) */ } open; - /* H5VL_MAP_GET_VAL */ + /** H5VL_MAP_GET_VAL */ struct { - hid_t key_mem_type_id; /* Memory datatype for key */ - const void *key; /* Pointer to key */ - hid_t value_mem_type_id; /* Memory datatype for value */ - void *value; /* Buffer for value (OUT) */ + hid_t key_mem_type_id; /**< Memory datatype for key */ + const void *key; /**< Pointer to key */ + hid_t value_mem_type_id; /**< Memory datatype for value */ + void *value; /**< Buffer for value (OUT) */ } get_val; - /* H5VL_MAP_EXISTS */ + /** H5VL_MAP_EXISTS */ struct { - hid_t key_mem_type_id; /* Memory datatype for key */ - const void *key; /* Pointer to key */ - hbool_t exists; /* Flag indicating whether key exists in map (OUT) */ + hid_t key_mem_type_id; /**< Memory datatype for key */ + const void *key; /**< Pointer to key */ + hbool_t exists; /**< Flag indicating whether key exists in map (OUT) */ } exists; - /* H5VL_MAP_PUT */ + /** H5VL_MAP_PUT */ struct { - hid_t key_mem_type_id; /* Memory datatype for key */ - const void *key; /* Pointer to key */ - hid_t value_mem_type_id; /* Memory datatype for value */ - const void *value; /* Pointer to value */ + hid_t key_mem_type_id; /**< Memory datatype for key */ + const void *key; /**< Pointer to key */ + hid_t value_mem_type_id; /**< Memory datatype for value */ + const void *value; /**< Pointer to value */ } put; - /* H5VL_MAP_GET */ + /** H5VL_MAP_GET */ struct { - H5VL_map_get_t get_type; /* 'get' operation to perform */ + H5VL_map_get_t get_type; /**< 'get' operation to perform */ - /* Parameters for each operation */ + /** Parameters for each operation */ union { - /* H5VL_MAP_GET_MAPL */ + /** H5VL_MAP_GET_MAPL */ struct { - hid_t mapl_id; /* Map access property list ID (OUT) */ + hid_t mapl_id; /**< Get map access property list ID (OUT) */ } get_mapl; - /* H5VL_MAP_GET_MCPL */ + /** H5VL_MAP_GET_MCPL */ struct { - hid_t mcpl_id; /* Map creation property list ID (OUT) */ + hid_t mcpl_id; /**< Get map creation property list ID (OUT) */ } get_mcpl; - /* H5VL_MAP_GET_KEY_TYPE */ + /** H5VL_MAP_GET_KEY_TYPE */ struct { - hid_t type_id; /* Datatype ID for map's keys (OUT) */ + hid_t type_id; /**< Get datatype ID for map's keys (OUT) */ } get_key_type; - /* H5VL_MAP_GET_VAL_TYPE */ + /** H5VL_MAP_GET_VAL_TYPE */ struct { - hid_t type_id; /* Datatype ID for map's values (OUT) */ + hid_t type_id; /**< Get datatype ID for map's values (OUT) */ } get_val_type; - /* H5VL_MAP_GET_COUNT */ + /** H5VL_MAP_GET_COUNT */ struct { - hsize_t count; /* # of KV pairs in map (OUT) */ + hsize_t count; /**< Get number of key-value pairs in the map (OUT) */ } get_count; } args; } get; - /* H5VL_MAP_SPECIFIC */ + /** H5VL_MAP_SPECIFIC */ struct { - H5VL_map_specific_t specific_type; /* 'specific' operation to perform */ + H5VL_map_specific_t specific_type; + /**< 'specific' operation to perform */ - /* Parameters for each operation */ + /** Parameters for each operation */ union { - /* H5VL_MAP_ITER */ + /* H5VL_MAP_ITER specific operation */ struct { - H5VL_loc_params_t loc_params; /* Location parameters for object */ - hsize_t idx; /* Start/end iteration index (IN/OUT) */ - hid_t key_mem_type_id; /* Memory datatype for key */ - H5M_iterate_t op; /* Iteration callback routine */ - void *op_data; /* Pointer to callback context */ + H5VL_loc_params_t loc_params; /**< Location parameters for object */ + hsize_t idx; /**< Start/end iteration index (IN/OUT) */ + hid_t key_mem_type_id; /**< Memory datatype for key */ + H5M_iterate_t op; /**< Iteration callback routine */ + void *op_data; /**< Pointer to callback context */ } iterate; - /* H5VL_MAP_DELETE */ + /* H5VL_MAP_DELETE specific operation */ struct { - H5VL_loc_params_t loc_params; /* Location parameters for object */ - hid_t key_mem_type_id; /* Memory datatype for key */ - const void *key; /* Pointer to key */ + H5VL_loc_params_t loc_params; /**< Location parameters for object */ + hid_t key_mem_type_id; /**< Memory datatype for key */ + const void *key; /**< Pointer to key */ } del; } args; } specific; - /* H5VL_MAP_OPTIONAL */ + /** H5VL_MAP_OPTIONAL */ /* Unused */ - /* H5VL_MAP_CLOSE */ + /** H5VL_MAP_CLOSE */ /* No args */ } H5VL_map_args_t; diff --git a/src/H5Oainfo.c b/src/H5Oainfo.c index 8b82e39e2a6..8b4340d2392 100644 --- a/src/H5Oainfo.c +++ b/src/H5Oainfo.c @@ -138,19 +138,25 @@ H5O__ainfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS ainfo->max_crt_idx = H5O_MAX_CRT_ORDER_IDX; /* Address of fractal heap to store "dense" attributes */ + H5_GCC_CLANG_DIAG_OFF("type-limits") if (H5_IS_BUFFER_OVERFLOW(p, sizeof_addr, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5_GCC_CLANG_DIAG_ON("type-limits") H5F_addr_decode(f, &p, &(ainfo->fheap_addr)); /* Address of v2 B-tree to index names of attributes (names are always indexed) */ + H5_GCC_CLANG_DIAG_OFF("type-limits") if (H5_IS_BUFFER_OVERFLOW(p, sizeof_addr, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5_GCC_CLANG_DIAG_ON("type-limits") H5F_addr_decode(f, &p, &(ainfo->name_bt2_addr)); /* Address of v2 B-tree to index creation order of links, if there is one */ if (ainfo->index_corder) { + H5_GCC_CLANG_DIAG_OFF("type-limits") if (H5_IS_BUFFER_OVERFLOW(p, sizeof_addr, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5_GCC_CLANG_DIAG_ON("type-limits") H5F_addr_decode(f, &p, &(ainfo->corder_bt2_addr)); } else diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 88c595ea213..4929be56717 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -211,6 +211,13 @@ H5O__attr_create(const H5O_loc_t *loc, H5A_t *attr) if (NULL == (oh = H5O_pin(loc))) HGOTO_ERROR(H5E_ATTR, H5E_CANTPIN, FAIL, "unable to pin object header"); + /* Check for creating attribute with unusual datatype */ + if (!(H5O_has_chksum(oh) || (H5F_RFIC_FLAGS(loc->file) & H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS)) && + H5T_is_numeric_with_unusual_unused_bits(attr->shared->dt)) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, + "creating attribute with unusual datatype, see documentation for " + "H5Pset_relax_file_integrity_checks for details."); + /* Check if this object already has attribute information */ if (oh->version > H5O_VERSION_1) { bool new_ainfo = false; /* Flag to indicate that the attribute information is new */ @@ -1171,10 +1178,10 @@ herr_t H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data) { - H5O_t *oh = NULL; /* Pointer to actual object header */ - H5O_ainfo_t ainfo; /* Attribute information for object */ - H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */ - herr_t ret_value = FAIL; /* Return value */ + H5O_t *oh = NULL; /* Pointer to actual object header */ + H5O_ainfo_t ainfo; /* Attribute information for object */ + H5A_attr_table_t atable = {0, 0, NULL}; /* Table of attributes */ + herr_t ret_value = FAIL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_TAG(loc->addr) @@ -1223,7 +1230,7 @@ H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, H5_index_t idx_type, H oh = NULL; /* Check for skipping too many attributes */ - if (skip > 0 && skip >= atable.nattrs) + if (skip > 0 && skip >= atable.num_attrs) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified"); /* Iterate over attributes in table */ @@ -1293,8 +1300,8 @@ H5O__attr_iterate(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsiz static herr_t H5O__attr_remove_update(const H5O_loc_t *loc, H5O_t *oh, H5O_ainfo_t *ainfo) { - H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */ - herr_t ret_value = SUCCEED; /* Return value */ + H5A_attr_table_t atable = {0, 0, NULL}; /* Table of attributes */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -1530,11 +1537,11 @@ H5O__attr_remove(const H5O_loc_t *loc, const char *name) herr_t H5O__attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, H5_iter_order_t order, hsize_t n) { - H5O_t *oh = NULL; /* Pointer to actual object header */ - H5O_ainfo_t ainfo; /* Attribute information for object */ - htri_t ainfo_exists = false; /* Whether the attribute info exists in the file */ - H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */ - herr_t ret_value = SUCCEED; /* Return value */ + H5O_t *oh = NULL; /* Pointer to actual object header */ + H5O_ainfo_t ainfo; /* Attribute information for object */ + htri_t ainfo_exists = false; /* Whether the attribute info exists in the file */ + H5A_attr_table_t atable = {0, 0, NULL}; /* Table of attributes */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_TAG(loc->addr) @@ -1568,7 +1575,7 @@ H5O__attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, H5_iter_order HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table"); /* Check for skipping too many attributes */ - if (n >= atable.nattrs) + if (n >= atable.num_attrs) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified"); /* Set up user data for callback, to remove the attribute by name */ diff --git a/src/H5Odtype.c b/src/H5Odtype.c index 05652df0fe2..674d8d4ea1c 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -176,6 +176,14 @@ H5O__dtype_decode_helper(unsigned *ioflags /*in,out*/, const uint8_t **pp, H5T_t HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, FAIL, "ran off end of input buffer while decoding"); UINT16DECODE(*pp, dt->shared->u.atomic.offset); UINT16DECODE(*pp, dt->shared->u.atomic.prec); + + /* Sanity checks */ + if (dt->shared->u.atomic.offset >= (dt->shared->size * 8)) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "integer offset out of bounds"); + if (0 == dt->shared->u.atomic.prec) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "precision is zero"); + if (((dt->shared->u.atomic.offset + dt->shared->u.atomic.prec) - 1) >= (dt->shared->size * 8)) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "integer offset+precision out of bounds"); break; case H5T_FLOAT: @@ -212,6 +220,8 @@ H5O__dtype_decode_helper(unsigned *ioflags /*in,out*/, const uint8_t **pp, H5T_t HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown floating-point normalization"); } dt->shared->u.atomic.u.f.sign = (flags >> 8) & 0xff; + if (dt->shared->u.atomic.u.f.sign >= (dt->shared->size * 8)) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "sign bit position out of bounds"); if (H5_IS_KNOWN_BUFFER_OVERFLOW(skip, *pp, 2 + 2, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, FAIL, "ran off end of input buffer while decoding"); @@ -224,6 +234,11 @@ H5O__dtype_decode_helper(unsigned *ioflags /*in,out*/, const uint8_t **pp, H5T_t dt->shared->u.atomic.u.f.esize = *(*pp)++; if (dt->shared->u.atomic.u.f.esize == 0) HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "exponent size can't be zero"); + if (dt->shared->u.atomic.u.f.epos >= (dt->shared->size * 8)) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "exponent starting position out of bounds"); + if (((dt->shared->u.atomic.u.f.epos + dt->shared->u.atomic.u.f.esize) - 1) >= + (dt->shared->size * 8)) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "exponent range out of bounds"); if (H5_IS_KNOWN_BUFFER_OVERFLOW(skip, *pp, 1 + 1, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, FAIL, "ran off end of input buffer while decoding"); @@ -231,10 +246,30 @@ H5O__dtype_decode_helper(unsigned *ioflags /*in,out*/, const uint8_t **pp, H5T_t dt->shared->u.atomic.u.f.msize = *(*pp)++; if (dt->shared->u.atomic.u.f.msize == 0) HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "mantissa size can't be zero"); + if (dt->shared->u.atomic.u.f.mpos >= (dt->shared->size * 8)) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "mantissa starting position out of bounds"); + if (((dt->shared->u.atomic.u.f.mpos + dt->shared->u.atomic.u.f.msize) - 1) >= + (dt->shared->size * 8)) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "mantissa range out of bounds"); if (H5_IS_KNOWN_BUFFER_OVERFLOW(skip, *pp, 4, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, FAIL, "ran off end of input buffer while decoding"); UINT32DECODE(*pp, dt->shared->u.atomic.u.f.ebias); + + /* Sanity check bits don't overlap */ + if (H5_RANGE_OVERLAP(dt->shared->u.atomic.u.f.sign, dt->shared->u.atomic.u.f.sign, + dt->shared->u.atomic.u.f.epos, + ((dt->shared->u.atomic.u.f.epos + dt->shared->u.atomic.u.f.esize) - 1))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "exponent and sign positions overlap"); + if (H5_RANGE_OVERLAP(dt->shared->u.atomic.u.f.sign, dt->shared->u.atomic.u.f.sign, + dt->shared->u.atomic.u.f.mpos, + ((dt->shared->u.atomic.u.f.mpos + dt->shared->u.atomic.u.f.msize) - 1))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "mantissa and sign positions overlap"); + if (H5_RANGE_OVERLAP(dt->shared->u.atomic.u.f.epos, + ((dt->shared->u.atomic.u.f.epos + dt->shared->u.atomic.u.f.esize) - 1), + dt->shared->u.atomic.u.f.mpos, + ((dt->shared->u.atomic.u.f.mpos + dt->shared->u.atomic.u.f.msize) - 1))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "mantissa and exponent positions overlap"); break; case H5T_TIME: @@ -378,9 +413,11 @@ H5O__dtype_decode_helper(unsigned *ioflags /*in,out*/, const uint8_t **pp, H5T_t /* Decode the field offset */ /* (starting with version 3 of the datatype message, use the minimum # of bytes required) */ if (version >= H5O_DTYPE_VERSION_3) { + H5_GCC_CLANG_DIAG_OFF("type-limits") if (H5_IS_KNOWN_BUFFER_OVERFLOW(skip, *pp, offset_nbytes, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, FAIL, "ran off end of input buffer while decoding"); + H5_GCC_CLANG_DIAG_ON("type-limits") UINT32DECODE_VAR(*pp, dt->shared->u.compnd.memb[dt->shared->u.compnd.nmembs].offset, offset_nbytes); } @@ -452,6 +489,13 @@ H5O__dtype_decode_helper(unsigned *ioflags /*in,out*/, const uint8_t **pp, H5T_t } if (temp_type->shared->size == 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "type size can't be zero"); + if ((dt->shared->u.compnd.memb[dt->shared->u.compnd.nmembs].offset + + temp_type->shared->size) > dt->shared->size) { + if (H5T_close_real(temp_type) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "can't release datatype info"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, + "member type extends outside its parent compound type"); + } /* Upgrade the version if we can and it is necessary */ if (can_upgrade && temp_type->shared->version > version) { @@ -770,6 +814,19 @@ H5O__dtype_decode_helper(unsigned *ioflags /*in,out*/, const uint8_t **pp, H5T_t HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown datatype class found"); } + /* Check for numeric type w/unusual # of unused bits */ + if (H5T_is_numeric_with_unusual_unused_bits(dt)) + /* Throw an error if the object header is not checksummed, unless the + * H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS flag is set with + * H5Pset_relax_file_integrity_checks() to suppress it. + */ + if (!(*ioflags & H5O_DECODEIO_RFIC_UNUBNT)) + HGOTO_ERROR( + H5E_DATATYPE, H5E_BADVALUE, FAIL, + "datatype has unusually large # of unused bits (prec = %zu bits, size = %zu bytes), possibly " + "corrupted file. See documentation for H5Pset_relax_file_integrity_checks for details.", + dt->shared->u.atomic.prec, dt->shared->size); + done: /* Cleanup on error */ if (ret_value < 0) @@ -1307,8 +1364,8 @@ H5O__dtype_encode_helper(uint8_t **pp, const H5T_t *dt) function using malloc() and is returned to the caller. --------------------------------------------------------------------------*/ static void * -H5O__dtype_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, - unsigned *ioflags /*in,out*/, size_t p_size, const uint8_t *p) +H5O__dtype_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned *ioflags /*in,out*/, + size_t p_size, const uint8_t *p) { bool skip; H5T_t *dt = NULL; @@ -1331,6 +1388,17 @@ H5O__dtype_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsign */ skip = (p_size == SIZE_MAX ? true : false); + /* Indicate if the object header has a checksum, or if the + * H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS flag is set */ + if (open_oh) { + if (H5O_SIZEOF_CHKSUM_OH(open_oh) > 0 || + (f && (H5F_RFIC_FLAGS(f) & H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS))) + *ioflags |= H5O_DECODEIO_RFIC_UNUBNT; + } + else + /* Decode operations from non-object headers are assumed to be checksummed */ + *ioflags |= H5O_DECODEIO_RFIC_UNUBNT; + /* Perform actual decode of message */ if (H5O__dtype_decode_helper(ioflags, &p, dt, skip, p_end) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode type"); diff --git a/src/H5Oefl.c b/src/H5Oefl.c index ebd92a733ba..57e5e6991df 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -140,6 +140,9 @@ H5O__efl_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED #endif for (size_t u = 0; u < mesg->nused; u++) { + + hsize_t offset = 0; + /* Name */ if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_size(f), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); @@ -156,7 +159,8 @@ H5O__efl_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED /* File offset */ if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_size(f), p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); - H5F_DECODE_LENGTH(f, p, mesg->slot[u].offset); + H5F_DECODE_LENGTH(f, p, offset); /* Decode into an hsize_t to avoid sign warnings */ + mesg->slot[u].offset = (HDoff_t)offset; /* Size */ if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_size(f), p_end)) diff --git a/src/H5Oint.c b/src/H5Oint.c index 537563dbbad..a98e22a1821 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -2919,3 +2919,23 @@ H5O__reset_info2(H5O_info2_t *oinfo) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O__reset_info2() */ + +/*------------------------------------------------------------------------- + * Function: H5O_has_chksum + * + * Purpose: Returns true if object header is checksummed + * + * Return: true/false on success, can't fail + * + *------------------------------------------------------------------------- + */ +bool +H5O_has_chksum(const H5O_t *oh) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Check args */ + assert(oh); + + FUNC_LEAVE_NOAPI(H5O_SIZEOF_CHKSUM_OH(oh) > 0) +} /* end H5O_has_chksum() */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index fc0f59ee60d..d14e0009953 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -392,10 +392,16 @@ H5O__layout_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU case H5D_CHUNK_IDX_SINGLE: /* Single Chunk Index */ if (mesg->u.chunk.flags & H5O_LAYOUT_CHUNK_SINGLE_INDEX_WITH_FILTER) { + uint64_t nbytes = 0; + if (H5_IS_BUFFER_OVERFLOW(p, H5F_sizeof_size(f) + 4, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); - H5F_DECODE_LENGTH(f, p, mesg->storage.u.chunk.u.single.nbytes); + + H5F_DECODE_LENGTH(f, p, nbytes); + H5_CHECKED_ASSIGN(mesg->storage.u.chunk.u.single.nbytes, uint32_t, nbytes, + uint64_t); + UINT32DECODE(p, mesg->storage.u.chunk.u.single.filter_mask); } diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c index 830e4e3113c..6b5dc0b89b5 100644 --- a/src/H5Olinfo.c +++ b/src/H5Olinfo.c @@ -140,6 +140,9 @@ H5O__linfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS if (H5_IS_BUFFER_OVERFLOW(p, 8, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); INT64DECODE(p, linfo->max_corder); + if (linfo->max_corder < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, + "invalid max creation order value for message: %" PRId64, linfo->max_corder); } else linfo->max_corder = 0; @@ -156,8 +159,10 @@ H5O__linfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUS /* Address of v2 B-tree to index creation order of links, if there is one */ if (linfo->index_corder) { + H5_GCC_CLANG_DIAG_OFF("type-limits") if (H5_IS_BUFFER_OVERFLOW(p, addr_size, p_end)) HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); + H5_GCC_CLANG_DIAG_ON("type-limits") H5F_addr_decode(f, &p, &(linfo->corder_bt2_addr)); } else diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 4c719bf340e..8e32f3ae13a 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -150,6 +150,8 @@ /* Input/output flags for decode functions */ #define H5O_DECODEIO_NOCHANGE 0x01u /* IN: do not modify values */ #define H5O_DECODEIO_DIRTY 0x02u /* OUT: message has been changed */ +#define H5O_DECODEIO_RFIC_UNUBNT \ + 0x04u /* IN: Relax file integrity checks for unusual numbers of unused bits in numeric datatypes */ /* Macro to incremend ndecode_dirtied (only if we are debugging) */ #ifndef NDEBUG diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 6f3d39d1e83..968a23caada 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -932,6 +932,7 @@ H5_DLL time_t H5O_get_oh_mtime(const H5O_t *oh); H5_DLL uint8_t H5O_get_oh_version(const H5O_t *oh); H5_DLL herr_t H5O_get_rc_and_type(const H5O_loc_t *oloc, unsigned *rc, H5O_type_t *otype); H5_DLL H5AC_proxy_entry_t *H5O_get_proxy(const H5O_t *oh); +H5_DLL bool H5O_has_chksum(const H5O_t *oh); /* Object header message routines */ H5_DLL herr_t H5O_msg_create(const H5O_loc_t *loc, unsigned type_id, unsigned mesg_flags, diff --git a/src/H5PB.c b/src/H5PB.c index fc09cd56e96..69707d14cba 100644 --- a/src/H5PB.c +++ b/src/H5PB.c @@ -726,7 +726,7 @@ H5PB_read(H5F_shared_t *f_sh, H5FD_mem_t type, haddr_t addr, size_t size, void * if (H5FD_MEM_DRAW == type) { last_page_addr = ((addr + size - 1) / page_buf->page_size) * page_buf->page_size; - /* How many pages does this write span */ + /* How many pages does this read span */ num_touched_pages = (last_page_addr / page_buf->page_size + 1) - (first_page_addr / page_buf->page_size); if (first_page_addr == last_page_addr) { @@ -835,6 +835,10 @@ H5PB_read(H5F_shared_t *f_sh, H5FD_mem_t type, haddr_t addr, size_t size, void * offset = (0 == i ? addr - page_entry->addr : 0); buf_offset = (0 == i ? 0 : size - access_size); + /* Account for reads that would overflow a page */ + if (offset + access_size > page_buf->page_size) + access_size = page_buf->page_size - offset; + /* copy the requested data from the page into the input buffer */ H5MM_memcpy((uint8_t *)buf + buf_offset, (uint8_t *)page_entry->page_buf_ptr + offset, access_size); @@ -905,6 +909,11 @@ H5PB_read(H5F_shared_t *f_sh, H5FD_mem_t type, haddr_t addr, size_t size, void * /* Copy the requested data from the page into the input buffer */ offset = (0 == i ? addr - search_addr : 0); buf_offset = (0 == i ? 0 : size - access_size); + + /* Account for reads that would overflow a page */ + if (offset + access_size > page_buf->page_size) + access_size = page_buf->page_size - offset; + H5MM_memcpy((uint8_t *)buf + buf_offset, (uint8_t *)new_page_buf + offset, access_size); /* Create the new PB entry */ diff --git a/src/H5Pencdec.c b/src/H5Pencdec.c index 4d1d8187591..19d453279ee 100644 --- a/src/H5Pencdec.c +++ b/src/H5Pencdec.c @@ -272,6 +272,41 @@ H5P__encode_double(const void *value, void **_pp, size_t *size) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5P__encode_double() */ +/*------------------------------------------------------------------------- + * Function: H5P__encode_uint64_t + * + * Purpose: Generic encoding callback routine for 'uint64_t' properties. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5P__encode_uint64_t(const void *value, void **_pp, size_t *size) +{ + uint8_t **pp = (uint8_t **)_pp; + + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity checks */ + assert(value); + assert(size); + + if (NULL != *pp) { + /* Encode the size */ + *(*pp)++ = (uint8_t)sizeof(uint64_t); + + /* Encode the value */ + UINT64ENCODE(*pp, *(const unsigned *)value); + } /* end if */ + + /* Set size needed for encoding */ + *size += (1 + sizeof(uint64_t)); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P__encode_uint64_t() */ + /*-------------------------------------------------------------------------- NAME H5P__encode_cb @@ -611,6 +646,42 @@ H5P__decode_double(const void **_pp, void *_value) FUNC_LEAVE_NOAPI(ret_value) } /* end H5P__decode_double() */ +/*------------------------------------------------------------------------- + * Function: H5P__decode_uint64_t + * + * Purpose: Generic decoding callback routine for 'uint64_t' properties. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5P__decode_uint64_t(const void **_pp, void *_value) +{ + uint64_t *value = (uint64_t *)_value; /* Property value to return */ + const uint8_t **pp = (const uint8_t **)_pp; + unsigned enc_size; /* Size of encoded property */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + assert(pp); + assert(*pp); + assert(value); + + /* Decode the size */ + enc_size = *(*pp)++; + if (enc_size != sizeof(uint64_t)) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "uint64_t value can't be decoded"); + + UINT64DECODE(*pp, *value); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__decode_uint64_t() */ + /*------------------------------------------------------------------------- NAME H5P__decode diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 65c21408a3f..80922bd9d1d 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -333,6 +333,11 @@ #endif #define H5F_ACS_IGNORE_DISABLED_FILE_LOCKS_ENC H5P__encode_bool #define H5F_ACS_IGNORE_DISABLED_FILE_LOCKS_DEC H5P__decode_bool +/* Definition for 'rfic' flags */ +#define H5F_ACS_RFIC_FLAGS_SIZE sizeof(uint64_t) +#define H5F_ACS_RFIC_FLAGS_DEF 0 +#define H5F_ACS_RFIC_FLAGS_ENC H5P__encode_uint64_t +#define H5F_ACS_RFIC_FLAGS_DEC H5P__decode_uint64_t /******************/ /* Local Typedefs */ @@ -529,6 +534,7 @@ static const bool H5F_def_use_file_locking_g = H5F_ACS_USE_FILE_LOCKING_DEF; /* Default use file locking flag */ static const bool H5F_def_ignore_disabled_file_locks_g = H5F_ACS_IGNORE_DISABLED_FILE_LOCKS_DEF; /* Default ignore disabled file locks flag */ +static const uint64_t H5F_def_rfic_flags_g = H5F_ACS_RFIC_FLAGS_DEF; /* Default 'rfic' flags */ /*------------------------------------------------------------------------- * Function: H5P__facc_reg_prop @@ -826,6 +832,12 @@ H5P__facc_reg_prop(H5P_genclass_t *pclass) H5F_ACS_IGNORE_DISABLED_FILE_LOCKS_DEC, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); + /* Register the 'rfic' flags. */ + if (H5P__register_real(pclass, H5F_ACS_RFIC_FLAGS_NAME, H5F_ACS_RFIC_FLAGS_SIZE, &H5F_def_rfic_flags_g, + NULL, NULL, NULL, H5F_ACS_RFIC_FLAGS_ENC, H5F_ACS_RFIC_FLAGS_DEC, NULL, NULL, NULL, + NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class"); + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P__facc_reg_prop() */ @@ -6264,3 +6276,75 @@ H5P__facc_vol_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P__facc_vol_close() */ + +/*------------------------------------------------------------------------- + * Function: H5Pset_relax_file_integrity_checks + * + * Purpose: Relax certain file integrity checks that may issue errors + * for valid files that have the potential for incorrect library + * behavior when data is incorrect or corrupted. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_relax_file_integrity_checks(hid_t plist_id, uint64_t flags) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "iUL", plist_id, flags); + + /* Check arguments */ + if (H5P_DEFAULT == plist_id) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't modify default property list"); + if (flags & (uint64_t)~H5F_RFIC_ALL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags"); + + /* Get the property list structure */ + if (NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plist_id is not a file access property list"); + + /* Set value */ + if (H5P_set(plist, H5F_ACS_RFIC_FLAGS_NAME, &flags) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set relaxed file integrity check flags"); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_relax_file_integrity_checks() */ + +/*------------------------------------------------------------------------- + * Function: H5Pget_relax_file_integrity_checks + * + * Purpose: Retrieve relaxed file integrity check flags + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_relax_file_integrity_checks(hid_t plist_id, uint64_t *flags /*out*/) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*UL", plist_id, flags); + + if (H5P_DEFAULT == plist_id) + plist_id = H5P_FILE_ACCESS_DEFAULT; + + /* Get the property list structure */ + if (NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plist_id is not a file access property list"); + + /* Get value */ + if (flags) + if (H5P_get(plist, H5F_ACS_RFIC_FLAGS_NAME, flags) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get relaxed file integrity check flags"); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_relax_file_integrity_checks() */ diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h index e249c7f9b2a..63baced637a 100644 --- a/src/H5Ppkg.h +++ b/src/H5Ppkg.h @@ -175,12 +175,14 @@ H5_DLL herr_t H5P__encode_unsigned(const void *value, void **_pp, size_t *size); H5_DLL herr_t H5P__encode_uint8_t(const void *value, void **_pp, size_t *size); H5_DLL herr_t H5P__encode_bool(const void *value, void **_pp, size_t *size); H5_DLL herr_t H5P__encode_double(const void *value, void **_pp, size_t *size); +H5_DLL herr_t H5P__encode_uint64_t(const void *value, void **_pp, size_t *size); H5_DLL herr_t H5P__decode_hsize_t(const void **_pp, void *value); H5_DLL herr_t H5P__decode_size_t(const void **_pp, void *value); H5_DLL herr_t H5P__decode_unsigned(const void **_pp, void *value); H5_DLL herr_t H5P__decode_uint8_t(const void **_pp, void *value); H5_DLL herr_t H5P__decode_bool(const void **_pp, void *value); H5_DLL herr_t H5P__decode_double(const void **_pp, void *value); +H5_DLL herr_t H5P__decode_uint64_t(const void **_pp, void *value); H5_DLL herr_t H5P__encode_coll_md_read_flag_t(const void *value, void **_pp, size_t *size); H5_DLL herr_t H5P__decode_coll_md_read_flag_t(const void **_pp, void *value); diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index afbf880a912..804e7880280 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -46,56 +46,182 @@ * The library's property list classes */ -#define H5P_ROOT (H5OPEN H5P_CLS_ROOT_ID_g) -#define H5P_OBJECT_CREATE (H5OPEN H5P_CLS_OBJECT_CREATE_ID_g) -#define H5P_FILE_CREATE (H5OPEN H5P_CLS_FILE_CREATE_ID_g) -#define H5P_FILE_ACCESS (H5OPEN H5P_CLS_FILE_ACCESS_ID_g) -#define H5P_DATASET_CREATE (H5OPEN H5P_CLS_DATASET_CREATE_ID_g) -#define H5P_DATASET_ACCESS (H5OPEN H5P_CLS_DATASET_ACCESS_ID_g) -#define H5P_DATASET_XFER (H5OPEN H5P_CLS_DATASET_XFER_ID_g) -#define H5P_FILE_MOUNT (H5OPEN H5P_CLS_FILE_MOUNT_ID_g) -#define H5P_GROUP_CREATE (H5OPEN H5P_CLS_GROUP_CREATE_ID_g) -#define H5P_GROUP_ACCESS (H5OPEN H5P_CLS_GROUP_ACCESS_ID_g) -#define H5P_DATATYPE_CREATE (H5OPEN H5P_CLS_DATATYPE_CREATE_ID_g) -#define H5P_DATATYPE_ACCESS (H5OPEN H5P_CLS_DATATYPE_ACCESS_ID_g) -#define H5P_MAP_CREATE (H5OPEN H5P_CLS_MAP_CREATE_ID_g) -#define H5P_MAP_ACCESS (H5OPEN H5P_CLS_MAP_ACCESS_ID_g) -#define H5P_STRING_CREATE (H5OPEN H5P_CLS_STRING_CREATE_ID_g) +/** + * Property list class root, is not user-accessible + */ +#define H5P_ROOT (H5OPEN H5P_CLS_ROOT_ID_g) +/** + * Object creation property list class, is not user-accessible + */ +#define H5P_OBJECT_CREATE (H5OPEN H5P_CLS_OBJECT_CREATE_ID_g) +/** + * File creation property list class + */ +#define H5P_FILE_CREATE (H5OPEN H5P_CLS_FILE_CREATE_ID_g) +/** + * File access property list class + */ +#define H5P_FILE_ACCESS (H5OPEN H5P_CLS_FILE_ACCESS_ID_g) +/** + * Dataset creation property list class + */ +#define H5P_DATASET_CREATE (H5OPEN H5P_CLS_DATASET_CREATE_ID_g) +/** + * Dataset access property list class + */ +#define H5P_DATASET_ACCESS (H5OPEN H5P_CLS_DATASET_ACCESS_ID_g) +/** + * Dataset transfer property list class + */ +#define H5P_DATASET_XFER (H5OPEN H5P_CLS_DATASET_XFER_ID_g) +/** + * File mount property list class + */ +#define H5P_FILE_MOUNT (H5OPEN H5P_CLS_FILE_MOUNT_ID_g) +/** + * Group creation property list class + */ +#define H5P_GROUP_CREATE (H5OPEN H5P_CLS_GROUP_CREATE_ID_g) +/** + * Group access property list class + */ +#define H5P_GROUP_ACCESS (H5OPEN H5P_CLS_GROUP_ACCESS_ID_g) +/** + * Datatype creation property list class + */ +#define H5P_DATATYPE_CREATE (H5OPEN H5P_CLS_DATATYPE_CREATE_ID_g) +/** + * Datatype access property list class + */ +#define H5P_DATATYPE_ACCESS (H5OPEN H5P_CLS_DATATYPE_ACCESS_ID_g) +/** + * Map creation property list class + */ +#define H5P_MAP_CREATE (H5OPEN H5P_CLS_MAP_CREATE_ID_g) +/** + * Map access property list class + */ +#define H5P_MAP_ACCESS (H5OPEN H5P_CLS_MAP_ACCESS_ID_g) +/** + * String creation property list class, is not user-accessible + */ +#define H5P_STRING_CREATE (H5OPEN H5P_CLS_STRING_CREATE_ID_g) +/** + * Attribute creation property list class + */ #define H5P_ATTRIBUTE_CREATE (H5OPEN H5P_CLS_ATTRIBUTE_CREATE_ID_g) +/** + * Attribute access property list class + */ #define H5P_ATTRIBUTE_ACCESS (H5OPEN H5P_CLS_ATTRIBUTE_ACCESS_ID_g) -#define H5P_OBJECT_COPY (H5OPEN H5P_CLS_OBJECT_COPY_ID_g) -#define H5P_LINK_CREATE (H5OPEN H5P_CLS_LINK_CREATE_ID_g) -#define H5P_LINK_ACCESS (H5OPEN H5P_CLS_LINK_ACCESS_ID_g) -#define H5P_VOL_INITIALIZE (H5OPEN H5P_CLS_VOL_INITIALIZE_ID_g) +/** + * Object copy property list class + */ +#define H5P_OBJECT_COPY (H5OPEN H5P_CLS_OBJECT_COPY_ID_g) +/** + * Link creation property list class + */ +#define H5P_LINK_CREATE (H5OPEN H5P_CLS_LINK_CREATE_ID_g) +/** + * Link access property list class + */ +#define H5P_LINK_ACCESS (H5OPEN H5P_CLS_LINK_ACCESS_ID_g) +/** + * VOL initialization property list class + */ +#define H5P_VOL_INITIALIZE (H5OPEN H5P_CLS_VOL_INITIALIZE_ID_g) +/** + * Reference access property list class + */ #define H5P_REFERENCE_ACCESS (H5OPEN H5P_CLS_REFERENCE_ACCESS_ID_g) /* * The library's default property lists */ -#define H5P_FILE_CREATE_DEFAULT (H5OPEN H5P_LST_FILE_CREATE_ID_g) -#define H5P_FILE_ACCESS_DEFAULT (H5OPEN H5P_LST_FILE_ACCESS_ID_g) -#define H5P_DATASET_CREATE_DEFAULT (H5OPEN H5P_LST_DATASET_CREATE_ID_g) -#define H5P_DATASET_ACCESS_DEFAULT (H5OPEN H5P_LST_DATASET_ACCESS_ID_g) -#define H5P_DATASET_XFER_DEFAULT (H5OPEN H5P_LST_DATASET_XFER_ID_g) -#define H5P_FILE_MOUNT_DEFAULT (H5OPEN H5P_LST_FILE_MOUNT_ID_g) -#define H5P_GROUP_CREATE_DEFAULT (H5OPEN H5P_LST_GROUP_CREATE_ID_g) -#define H5P_GROUP_ACCESS_DEFAULT (H5OPEN H5P_LST_GROUP_ACCESS_ID_g) -#define H5P_DATATYPE_CREATE_DEFAULT (H5OPEN H5P_LST_DATATYPE_CREATE_ID_g) -#define H5P_DATATYPE_ACCESS_DEFAULT (H5OPEN H5P_LST_DATATYPE_ACCESS_ID_g) -#define H5P_MAP_CREATE_DEFAULT (H5OPEN H5P_LST_MAP_CREATE_ID_g) -#define H5P_MAP_ACCESS_DEFAULT (H5OPEN H5P_LST_MAP_ACCESS_ID_g) +/** + * File creation default property list + */ +#define H5P_FILE_CREATE_DEFAULT (H5OPEN H5P_LST_FILE_CREATE_ID_g) +/** + * File access default property list + */ +#define H5P_FILE_ACCESS_DEFAULT (H5OPEN H5P_LST_FILE_ACCESS_ID_g) +/** + * Dataset creation default property list + */ +#define H5P_DATASET_CREATE_DEFAULT (H5OPEN H5P_LST_DATASET_CREATE_ID_g) +/** + * Dataset access default property list + */ +#define H5P_DATASET_ACCESS_DEFAULT (H5OPEN H5P_LST_DATASET_ACCESS_ID_g) +/** + * Dataset transfer default property list + */ +#define H5P_DATASET_XFER_DEFAULT (H5OPEN H5P_LST_DATASET_XFER_ID_g) +/** + * File mount default property list + */ +#define H5P_FILE_MOUNT_DEFAULT (H5OPEN H5P_LST_FILE_MOUNT_ID_g) +/** + * Group creation default property list + */ +#define H5P_GROUP_CREATE_DEFAULT (H5OPEN H5P_LST_GROUP_CREATE_ID_g) +/** + * Group access default property list + */ +#define H5P_GROUP_ACCESS_DEFAULT (H5OPEN H5P_LST_GROUP_ACCESS_ID_g) +/** + * Datytype creation default property list + */ +#define H5P_DATATYPE_CREATE_DEFAULT (H5OPEN H5P_LST_DATATYPE_CREATE_ID_g) +/** + * Datytype access default property list + */ +#define H5P_DATATYPE_ACCESS_DEFAULT (H5OPEN H5P_LST_DATATYPE_ACCESS_ID_g) +/** + * Map creation default property list + */ +#define H5P_MAP_CREATE_DEFAULT (H5OPEN H5P_LST_MAP_CREATE_ID_g) +/** + * Map access default property list + */ +#define H5P_MAP_ACCESS_DEFAULT (H5OPEN H5P_LST_MAP_ACCESS_ID_g) +/** + * Attribute creation default property list + */ #define H5P_ATTRIBUTE_CREATE_DEFAULT (H5OPEN H5P_LST_ATTRIBUTE_CREATE_ID_g) +/** + * Attribute access default property list + */ #define H5P_ATTRIBUTE_ACCESS_DEFAULT (H5OPEN H5P_LST_ATTRIBUTE_ACCESS_ID_g) -#define H5P_OBJECT_COPY_DEFAULT (H5OPEN H5P_LST_OBJECT_COPY_ID_g) -#define H5P_LINK_CREATE_DEFAULT (H5OPEN H5P_LST_LINK_CREATE_ID_g) -#define H5P_LINK_ACCESS_DEFAULT (H5OPEN H5P_LST_LINK_ACCESS_ID_g) -#define H5P_VOL_INITIALIZE_DEFAULT (H5OPEN H5P_LST_VOL_INITIALIZE_ID_g) +/** + * Object copy default property list + */ +#define H5P_OBJECT_COPY_DEFAULT (H5OPEN H5P_LST_OBJECT_COPY_ID_g) +/** + * Link creation default property list + */ +#define H5P_LINK_CREATE_DEFAULT (H5OPEN H5P_LST_LINK_CREATE_ID_g) +/** + * Link access default property list + */ +#define H5P_LINK_ACCESS_DEFAULT (H5OPEN H5P_LST_LINK_ACCESS_ID_g) +/** + * VOL initialization default property list + */ +#define H5P_VOL_INITIALIZE_DEFAULT (H5OPEN H5P_LST_VOL_INITIALIZE_ID_g) +/** + * Reference access default property list + */ #define H5P_REFERENCE_ACCESS_DEFAULT (H5OPEN H5P_LST_REFERENCE_ACCESS_ID_g) - -/* Common creation order flags (for links in groups and attributes on objects) */ +/** + * Attribute creation order is tracked but not necessarily indexed + */ #define H5P_CRT_ORDER_TRACKED 0x0001 +/** + * Attribute creation order is indexed (requires #H5P_CRT_ORDER_TRACKED) + */ #define H5P_CRT_ORDER_INDEXED 0x0002 - /** * Default value of type \ref hid_t for all property list classes */ @@ -3573,7 +3699,7 @@ H5_DLL herr_t H5Pget_fclose_degree(hid_t fapl_id, H5F_close_degree_t *degree); * \see H5LTopen_file_image(), H5Fget_file_image(), H5Pset_file_image(), * H5Pset_file_image_callbacks(), H5Pget_file_image_callbacks(), * \ref H5FD_file_image_callbacks_t, \ref H5FD_file_image_op_t, - * + * * HDF5 File Image Operations. * * @@ -3613,7 +3739,7 @@ H5_DLL herr_t H5Pget_file_image(hid_t fapl_id, void **buf_ptr_ptr, size_t *buf_l * \see H5LTopen_file_image(), H5Fget_file_image(), H5Pset_file_image(), * H5Pset_file_image_callbacks(), H5Pget_file_image_callbacks(), * \ref H5FD_file_image_callbacks_t, \ref H5FD_file_image_op_t, - * + * * HDF5 File Image Operations. * * \since 1.8.9 @@ -4557,7 +4683,7 @@ H5_DLL herr_t H5Pset_fclose_degree(hid_t fapl_id, H5F_close_degree_t degree); * This function is part of the file image * operations feature set. It is highly recommended to study the guide * [HDF5 File Image Operations] - * (https://portal.hdfgroup.org/display/HDF5/HDF5+File+Image+Operations + * (https://portal.hdfgroup.org/documentation/hdf5-docs/advanced_topics/file_image_ops.html * ) before using this feature set. See the “See Also” section below * for links to other elements of HDF5 file image operations. * @@ -4569,9 +4695,9 @@ H5_DLL herr_t H5Pset_fclose_degree(hid_t fapl_id, H5F_close_degree_t degree); * \li H5Pget_file_image_callbacks() * * \li [HDF5 File Image Operations] - * (https://portal.hdfgroup.org/display/HDF5/HDF5+File+Image+Operations) + * (https://portal.hdfgroup.org/documentation/hdf5-docs/advanced_topics/file_image_ops.html) * in [Advanced Topics in HDF5] - * (https://portal.hdfgroup.org/display/HDF5/Advanced+Topics+in+HDF5) + * (https://portal.hdfgroup.org/documentation/hdf5-docs/advanced_topics_list.html) * * \li Within H5Pset_file_image_callbacks(): * \li Callback #H5FD_file_image_callbacks_t @@ -4594,7 +4720,7 @@ H5_DLL herr_t H5Pset_file_image(hid_t fapl_id, void *buf_ptr, size_t buf_len); * **Recommended Reading:** This function is part of the file * image operations feature set. It is highly recommended to study * the guide [HDF5 File Image Operations] - * (https://portal.hdfgroup.org/display/HDF5/HDF5+File+Image+Operations + * (https://portal.hdfgroup.org/documentation/hdf5-docs/advanced_topics/file_image_ops.html * ) before using this feature set. See the “See Also” section below * for links to other elements of HDF5 file image operations. * @@ -5634,6 +5760,79 @@ H5_DLL herr_t H5Pset_mdc_image_config(hid_t plist_id, H5AC_cache_image_config_t H5_DLL herr_t H5Pset_page_buffer_size(hid_t plist_id, size_t buf_size, unsigned min_meta_per, unsigned min_raw_per); +/** + * \ingroup FAPL + * + * \brief Relax file integrity checks that may issue errors for some valid files + * + * \fapl_id{plist_id} + * \param[in] flags Relaxed integrity checks flag. Valid values are: + * \li #H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS + * suppresses integrity checks for detecting + * unusually high values for the number of unused bits in + * numeric datatype classes (H5T_INTEGER, H5T_FLOAT, and + * H5T_BITFIELD). Integrity checks are triggered when + * the precision for a datatype (i.e. the number of bits + * containing actual data) is less than half of the + * datatype's size and the datatype is greater than + * 1 byte in size. For example, a datatype with a + * precision of 15 bits and a size of 4 bytes (i.e. 32 bits) + * will issue an error, but a datatype with 17 bits of + * precision and a size of 4 bytes will not issue an + * error, nor will a datatype with a precision of 1, 2, or + * 3 bits and a size of 1 byte issue an error. + * \li #H5F_RFIC_ALL relaxes all integrity checks above. + * + * \return \herr_t + * + * \details Incorrectly encoded or corrupted metadata in a native HDF5 + * format file can cause incorrect library behavior when the metadata + * has no checksum. Integrity checks within the library detect these + * circumstances and issue errors when incorrect metadata is found. + * Unfortunately, some of the integrity checks for detecting these + * circumstances may incorrectly issue an error for a valid HDF5 file + * that was intentionally created with these configurations. + * Setting the appropriate flag(s) with this routine will relax the + * file integrity checks for these valid files and suppress errors + * when accessing objects with these configurations. + * + * The library will also issue errors when these configurations are + * used to create objects, preventing applications from unintentionally + * creating them. Setting the appropriate flag with this routine will + * also suppress those errors on creation, although using this routine + * and the appropriate flag(s) will still be required when accessing + * files created with these configurations. + * + * A more complete solution that avoids errors on both object creation + * and access is to use the H5Pset_libver_bounds routine with a low + * bound of at least #H5F_LIBVER_V18 when creating objects with these + * configurations. This will cause the library to checksum a file's + * metadata, allowing accidental data corruption to be correctly + * detected and errors correctly issued without ambiguity. + * + * \since 1.14.4 + * + */ +H5_DLL herr_t H5Pset_relax_file_integrity_checks(hid_t plist_id, uint64_t flags); +/** + * \ingroup FAPL + * + * \brief Retrieve relaxed file integrity check flags + * + * \fapl_id{plist_id} + * \param[out] flags Relaxed file integrity check flags + * + * \return \herr_t + * + * \details H5Pget_relax_file_integrity_checks() retrieves the relaxed file + * integrity check value into \p flags for the file access property + * list specified in \p plist_id. + * + * \since 1.14.4 + * + */ +H5_DLL herr_t H5Pget_relax_file_integrity_checks(hid_t plist_id, uint64_t *flags); + /* Dataset creation property list (DCPL) routines */ /** * \ingroup DCPL @@ -6899,7 +7098,7 @@ H5_DLL herr_t H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels * VDS access time. Example code for many source and virtual dataset mappings * is available in the "Examples of Source to Virtual Dataset Mapping" * chapter in the - * + * * RFC: HDF5 Virtual Dataset. * * @@ -6972,7 +7171,7 @@ H5_DLL herr_t H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels * If that source file does not exist, the new \p src_file_name * after stripping will be \Code{A.h5} * - * \see + * \see * Virtual Dataset Overview * * \see_virtual @@ -8823,7 +9022,7 @@ H5_DLL herr_t H5Pset_link_phase_change(hid_t plist_id, unsigned max_compact, uns * must be created and maintained in the original style. This is HDF5's default * behavior. If backward compatibility with pre-1.8.0 libraries is not a concern, * greater efficiencies can be obtained with the new-format compact and indexed - * groups. See Group + * groups. See Group * implementations in HDF5 in the \ref H5G API introduction (at the bottom).\n * H5Pset_local_heap_size_hint() is useful for tuning file size when files * contain original-style groups with either zero members or very large diff --git a/src/H5Rint.c b/src/H5Rint.c index 4606a57d3f7..3df70ba48c3 100644 --- a/src/H5Rint.c +++ b/src/H5Rint.c @@ -956,7 +956,10 @@ H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref) const uint8_t *p = (const uint8_t *)buf; size_t buf_size = 0, decode_size = 0; uint8_t flags; - herr_t ret_value = SUCCEED; + bool decoded_filename = false; /* Whether filename was decoded, for error handling */ + bool decoded_attrname = false; /* Whether attribute name was decoded, for error handling */ + bool decoded_dataspace = false; /* Whether dataspace was decoded, for error handling */ + herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE @@ -990,6 +993,7 @@ H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref) /* Decode file name */ H5R_DECODE(H5R__decode_string, &ref->info.obj.filename, p, buf_size, decode_size, "Cannot decode filename"); + decoded_filename = true; } else ref->info.obj.filename = NULL; @@ -997,22 +1001,28 @@ H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref) switch (ref->type) { case H5R_OBJECT2: break; + case H5R_DATASET_REGION2: /* Decode dataspace */ H5R_DECODE(H5R__decode_region, &ref->info.reg.space, p, buf_size, decode_size, "Cannot decode region"); + decoded_dataspace = true; break; + case H5R_ATTR: /* Decode attribute name */ H5R_DECODE(H5R__decode_string, &ref->info.attr.name, p, buf_size, decode_size, "Cannot decode attribute name"); + decoded_attrname = true; break; + case H5R_OBJECT1: case H5R_DATASET_REGION1: case H5R_BADTYPE: case H5R_MAXTYPE: assert("invalid reference type" && 0); HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)"); + default: assert("unknown reference type" && 0); HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)"); @@ -1031,6 +1041,22 @@ H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref) *nbytes = decode_size; done: + if (ret_value < 0) { + if (decoded_filename) { + H5MM_xfree(ref->info.obj.filename); + ref->info.obj.filename = NULL; + } + if (decoded_attrname) { + H5MM_xfree(ref->info.attr.name); + ref->info.attr.name = NULL; + } + if (decoded_dataspace) { + if (H5S_close(ref->info.reg.space) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, FAIL, "unable to release dataspace"); + ref->info.reg.space = NULL; + } + } + FUNC_LEAVE_NOAPI(ret_value) } /* end H5R__decode() */ @@ -1175,7 +1201,7 @@ H5R__decode_region(const unsigned char *buf, size_t *nbytes, H5S_t **space_ptr) const uint8_t *p_end = p + *nbytes - 1; size_t buf_size = 0; unsigned rank; - H5S_t *space; + H5S_t *space = NULL; herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE @@ -1216,6 +1242,10 @@ H5R__decode_region(const unsigned char *buf, size_t *nbytes, H5S_t **space_ptr) *space_ptr = space; done: + if (ret_value < 0) + if (space && H5S_close(space) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, FAIL, "unable to release dataspace"); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5R__decode_region() */ diff --git a/src/H5S.c b/src/H5S.c index c58176e3243..722eac8b563 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -615,6 +615,10 @@ H5S__extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, bool copy_max) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy shared information"); done: + if (ret_value < 0) + if (dst->size) + dst->size = H5FL_ARR_FREE(hsize_t, dst->size); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S__extent_copy_real() */ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 344351e05be..6b07529df96 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -9178,8 +9178,8 @@ H5S__check_spans_overlap(const H5S_hyper_span_info_t *spans1, const H5S_hyper_sp assert(spans2); /* Use low & high bounds to try to avoid spinning through the span lists */ - if (H5S_RANGE_OVERLAP(spans1->low_bounds[0], spans1->high_bounds[0], spans2->low_bounds[0], - spans2->high_bounds[0])) { + if (H5_RANGE_OVERLAP(spans1->low_bounds[0], spans1->high_bounds[0], spans2->low_bounds[0], + spans2->high_bounds[0])) { H5S_hyper_span_t *span1, *span2; /* Hyperslab spans */ /* Walk over spans, comparing them for overlap */ @@ -9187,7 +9187,7 @@ H5S__check_spans_overlap(const H5S_hyper_span_info_t *spans1, const H5S_hyper_sp span2 = spans2->head; while (span1 && span2) { /* Check current two spans for overlap */ - if (H5S_RANGE_OVERLAP(span1->low, span1->high, span2->low, span2->high)) { + if (H5_RANGE_OVERLAP(span1->low, span1->high, span2->low, span2->high)) { /* Check for spans in lowest dimension already */ if (span1->down) { /* Sanity check */ @@ -9765,8 +9765,8 @@ H5S__hyper_regular_and_single_block(H5S_t *space, const hsize_t start[], const h block_end = (start[u] + block[u]) - 1; /* Check for overlap */ - if (!H5S_RANGE_OVERLAP(space->select.sel_info.hslab->diminfo.opt[u].start, select_end, start[u], - block_end)) { + if (!H5_RANGE_OVERLAP(space->select.sel_info.hslab->diminfo.opt[u].start, select_end, start[u], + block_end)) { overlap = false; break; } /* end if */ @@ -9812,8 +9812,8 @@ H5S__hyper_regular_and_single_block(H5S_t *space, const hsize_t start[], const h block_end = (start[u] + block[u]) - 1; /* Check for overlap */ - if (!H5S_RANGE_OVERLAP(space->select.sel_info.hslab->diminfo.opt[u].start, select_end, start[u], - block_end)) { + if (!H5_RANGE_OVERLAP(space->select.sel_info.hslab->diminfo.opt[u].start, select_end, start[u], + block_end)) { overlap = false; break; } /* end if */ @@ -10446,7 +10446,7 @@ H5S_combine_hyperslab(const H5S_t *old_space, H5S_seloper_t op, const hsize_t st } /* end for */ /* Check bound box of both spaces to see if they overlap */ - if (H5S_RANGE_OVERLAP(old_low_bounds[0], old_high_bounds[0], new_low_bounds[0], new_high_bounds[0])) + if (H5_RANGE_OVERLAP(old_low_bounds[0], old_high_bounds[0], new_low_bounds[0], new_high_bounds[0])) overlapped = true; /* Non-overlapping situations can be handled in special ways */ @@ -11415,8 +11415,8 @@ H5S__hyper_proj_int_iterate(H5S_hyper_span_info_t *ss_span_info, const H5S_hyper /* Check for non-overlapping bounds */ check_intersect = true; for (u = 0; u < (udata->ss_rank - depth); u++) - if (!H5S_RANGE_OVERLAP(ss_span_info->low_bounds[u], ss_span_info->high_bounds[u], - sis_span_info->low_bounds[u], sis_span_info->high_bounds[u])) { + if (!H5_RANGE_OVERLAP(ss_span_info->low_bounds[u], ss_span_info->high_bounds[u], + sis_span_info->low_bounds[u], sis_span_info->high_bounds[u])) { check_intersect = false; break; } /* end if */ @@ -11441,7 +11441,7 @@ H5S__hyper_proj_int_iterate(H5S_hyper_span_info_t *ss_span_info, const H5S_hyper /* Main loop */ do { /* Check if spans overlap */ - if (H5S_RANGE_OVERLAP(ss_low, ss_span->high, sis_low, sis_span->high)) { + if (H5_RANGE_OVERLAP(ss_low, ss_span->high, sis_low, sis_span->high)) { high = MIN(ss_span->high, sis_span->high); if (ss_span->down) { /* Add skipped elements if there's a pre-gap */ diff --git a/src/H5Spkg.h b/src/H5Spkg.h index fddd5e3c5fa..e851f548f94 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -89,15 +89,6 @@ * H5S_UNLIMITED) */ #define H5S_MAX_SIZE ((hsize_t)(hssize_t)(-2)) -/* Macro for checking if two ranges overlap one another */ -/* - * Check for the inverse of whether the ranges are disjoint. If they are - * disjoint, then the low bound of one of the ranges must be greater than the - * high bound of the other. - */ -/* (Assumes that low & high bounds are _inclusive_) */ -#define H5S_RANGE_OVERLAP(L1, H1, L2, H2) (!((L1) > (H2) || (L2) > (H1))) - /* * Dataspace extent information */ diff --git a/src/H5Spoint.c b/src/H5Spoint.c index c95429dcfee..7e66a03a5f6 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -576,8 +576,14 @@ H5S__point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *c for (u = 0; u < num_elem; u++) { unsigned dim; /* Counter for dimensions */ + /* The following allocation relies on the size of an hcoords_t being + * the same as an 'H5S_pnt_node_t *', so fail now if that's not true + */ + HDcompile_assert(sizeof(hcoords_t) >= sizeof(H5S_pnt_node_t *)); + /* Allocate space for the new node */ - if (NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, space->extent.rank))) + /* Note: allocating "rank + 1" to allow for 'next' pointer */ + if (NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, space->extent.rank + 1))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node"); /* Initialize fields in node */ @@ -796,7 +802,7 @@ H5S__copy_pnt_list(const H5S_pnt_list_t *src, unsigned rank) assert(rank > 0); /* Allocate room for the head of the point list */ - if (NULL == (dst = H5FL_MALLOC(H5S_pnt_list_t))) + if (NULL == (dst = H5FL_CALLOC(H5S_pnt_list_t))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate point list node"); curr = src->head; @@ -804,8 +810,14 @@ H5S__copy_pnt_list(const H5S_pnt_list_t *src, unsigned rank) while (curr) { H5S_pnt_node_t *new_node; /* New point information node */ + /* The following allocation relies on the size of an hcoords_t being + * the same as an 'H5S_pnt_node_t *', so fail now if that's not true + */ + HDcompile_assert(sizeof(hcoords_t) >= sizeof(H5S_pnt_node_t *)); + /* Create new point */ - if (NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, rank))) + /* Note: allocating "rank + 1" to allow for 'next' pointer */ + if (NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, rank + 1))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate point node"); new_node->next = NULL; @@ -2275,7 +2287,7 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection"); /* Allocate room for the head of the point list */ - if (NULL == (new_space->select.sel_info.pnt_lst = H5FL_MALLOC(H5S_pnt_list_t))) + if (NULL == (new_space->select.sel_info.pnt_lst = H5FL_CALLOC(H5S_pnt_list_t))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point list node"); /* Check if the new space's rank is < or > base space's rank */ @@ -2294,8 +2306,14 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of base_node = base_space->select.sel_info.pnt_lst->head; prev_node = NULL; while (base_node) { + /* The following allocation relies on the size of an hcoords_t being + * the same as an 'H5S_pnt_node_t *', so fail now if that's not true + */ + HDcompile_assert(sizeof(hcoords_t) >= sizeof(H5S_pnt_node_t *)); + /* Create new point */ - if (NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, new_space->extent.rank))) + /* Note: allocating "rank + 1" to allow for 'next' pointer */ + if (NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, new_space->extent.rank + 1))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node"); new_node->next = NULL; @@ -2336,8 +2354,14 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of base_node = base_space->select.sel_info.pnt_lst->head; prev_node = NULL; while (base_node) { + /* The following allocation relies on the size of an hcoords_t being + * the same as an 'H5S_pnt_node_t *', so fail now if that's not true + */ + HDcompile_assert(sizeof(hcoords_t) >= sizeof(H5S_pnt_node_t *)); + /* Create new point */ - if (NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, new_space->extent.rank))) + /* Note: allocating "rank + 1" to allow for 'next' pointer */ + if (NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, new_space->extent.rank + 1))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node"); new_node->next = NULL; diff --git a/src/H5Sselect.c b/src/H5Sselect.c index d67b8e6f7e0..ef9994ec1b2 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -1945,7 +1945,7 @@ H5S_select_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *en /* Loop over selection bounds and block, checking for overlap */ for (u = 0; u < space->extent.rank; u++) /* If selection bounds & block don't overlap, can leave now */ - if (!H5S_RANGE_OVERLAP(low[u], high[u], start[u], end[u])) + if (!H5_RANGE_OVERLAP(low[u], high[u], start[u], end[u])) HGOTO_DONE(false); } /* end if */ diff --git a/src/H5T.c b/src/H5T.c index b9a387eed9e..ba93eefd1e4 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -41,6 +41,7 @@ #include "H5Pprivate.h" /* Property lists */ #include "H5Tpkg.h" /* Datatypes */ #include "H5VLprivate.h" /* Virtual Object Layer */ +#include "H5VMprivate.h" /* Vectors and arrays */ /****************/ /* Local Macros */ @@ -48,6 +49,12 @@ #define H5T_ENCODE_VERSION 0 +/* + * The default number of slots allocated in the + * datatype conversion path table. + */ +#define H5T_DEF_CONV_TABLE_SLOTS 128 + /* * Type initialization macros * @@ -372,6 +379,10 @@ static herr_t H5T__set_size(H5T_t *dt, size_t size); static herr_t H5T__close_cb(H5T_t *dt, void **request); 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 herr_t H5T__path_find_init_path_table(void); +static herr_t H5T__path_find_init_new_path(H5T_path_t *path, const H5T_t *src, const H5T_t *dst, + H5T_conv_func_t *conv, H5T_conv_ctx_t *conv_ctx); +static herr_t H5T__path_free(H5T_path_t *path, H5T_conv_ctx_t *conv_ctx); static bool H5T_path_match(H5T_path_t *path, H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5VL_object_t *owned_vol_obj, H5T_conv_t func); static bool H5T_path_match_find_type_with_volobj(const H5T_t *datatype, const H5VL_object_t *owned_vol_obj); @@ -1662,52 +1673,16 @@ H5T_top_term_package(void) /* Unregister all conversion functions */ if (H5T_g.path) { - int i, nprint = 0; - - for (i = 0; i < H5T_g.npaths; i++) { - H5T_path_t *path; - - path = H5T_g.path[i]; - assert(path); - if (path->conv.u.app_func) { - H5T__print_stats(path, &nprint /*in,out*/); - path->cdata.command = H5T_CONV_FREE; - if (path->conv.is_app) { - if ((path->conv.u.app_func)(H5I_INVALID_HID, H5I_INVALID_HID, &(path->cdata), 0, 0, 0, - NULL, NULL, H5CX_get_dxpl()) < 0) { -#ifdef H5T_DEBUG - if (H5DEBUG(T)) { - fprintf(H5DEBUG(T), - "H5T: conversion function " - "0x%016zx failed to free private data for " - "%s (ignored)\n", - (size_t)path->conv.u.app_func, path->name); - } /* end if */ -#endif - H5E_clear_stack(NULL); /*ignore the error*/ - } /* end if */ - } /* end if */ - else { - if ((path->conv.u.lib_func)(NULL, NULL, &(path->cdata), NULL, 0, 0, 0, NULL, NULL) < 0) { -#ifdef H5T_DEBUG - if (H5DEBUG(T)) { - fprintf(H5DEBUG(T), - "H5T: conversion function " - "0x%016zx failed to free private data for " - "%s (ignored)\n", - (size_t)path->conv.u.lib_func, path->name); - } /* end if */ -#endif - H5E_clear_stack(NULL); /*ignore the error*/ - } /* end if */ - } /* end else */ - } /* end if */ - - if (path->src) - (void)H5T_close_real(path->src); - if (path->dst) - (void)H5T_close_real(path->dst); - path = H5FL_FREE(H5T_path_t, path); + H5T_conv_ctx_t conv_ctx = {0}; + + conv_ctx.u.free.src_type_id = H5I_INVALID_HID; + conv_ctx.u.free.dst_type_id = H5I_INVALID_HID; + + for (int i = 0; i < H5T_g.npaths; i++) { + H5T_path_t *path = H5T_g.path[i]; + + (void)H5T__path_free(path, &conv_ctx); + H5T_g.path[i] = NULL; } /* end for */ @@ -2655,7 +2630,6 @@ H5T__register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5T_con H5T_t *tmp_dtype = NULL; /*temporary destination datatype */ hid_t tmp_sid = H5I_INVALID_HID; /*temporary datatype ID */ hid_t tmp_did = H5I_INVALID_HID; /*temporary datatype ID */ - int nprint = 0; /*number of paths shut down */ int i; /*counter */ herr_t ret_value = SUCCEED; /*return value */ @@ -2687,7 +2661,7 @@ H5T__register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5T_con } /* end if */ } /* end if */ else { - H5T_conv_ctx_t tmp_ctx = {0}; + H5T_conv_ctx_t conv_ctx = {0}; /* * Get the datatype conversion exception callback structure. @@ -2695,7 +2669,7 @@ H5T__register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5T_con * pushed, since we could have arrived here during library * initialization of the H5T package. */ - if (!conv->is_app && H5CX_pushed() && (H5CX_get_dt_conv_cb(&tmp_ctx.u.init.cb_struct) < 0)) + if (!conv->is_app && H5CX_pushed() && (H5CX_get_dt_conv_cb(&conv_ctx.u.init.cb_struct) < 0)) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); /* Add function to end of soft list */ @@ -2758,8 +2732,8 @@ H5T__register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5T_con continue; } /* end if */ } /* end if */ - else if ((conv->u.lib_func)(old_path->src, old_path->dst, &cdata, &tmp_ctx, 0, 0, 0, NULL, NULL) < - 0) { + else if ((conv->u.lib_func)(old_path->src, old_path->dst, &cdata, &conv_ctx, 0, 0, 0, NULL, + NULL) < 0) { if (H5E_clear_stack(NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, FAIL, "unable to clear current error stack"); continue; @@ -2782,37 +2756,10 @@ H5T__register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5T_con new_path = NULL; /*so we don't free it on error*/ /* Free old path */ - H5T__print_stats(old_path, &nprint); - old_path->cdata.command = H5T_CONV_FREE; - if (old_path->conv.is_app) { - if ((old_path->conv.u.app_func)(tmp_sid, tmp_did, &(old_path->cdata), 0, 0, 0, NULL, NULL, - H5CX_get_dxpl()) < 0) { -#ifdef H5T_DEBUG - if (H5DEBUG(T)) - fprintf(H5DEBUG(T), - "H5T: conversion function 0x%016zx " - "failed to free private data for %s (ignored)\n", - (size_t)old_path->conv.u.app_func, old_path->name); -#endif - } /* end if */ - } /* end if */ - else if ((old_path->conv.u.lib_func)(old_path->src, old_path->dst, &(old_path->cdata), NULL, 0, 0, - 0, NULL, NULL) < 0) { -#ifdef H5T_DEBUG - if (H5DEBUG(T)) - fprintf(H5DEBUG(T), - "H5T: conversion function 0x%016zx " - "failed to free private data for %s (ignored)\n", - (size_t)old_path->conv.u.lib_func, old_path->name); -#endif - } /* end if */ - - if (H5T_close_real(old_path->src) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close datatype"); - if (H5T_close_real(old_path->dst) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close datatype"); - - old_path = H5FL_FREE(H5T_path_t, old_path); + conv_ctx.u.free.src_type_id = tmp_sid; + conv_ctx.u.free.dst_type_id = tmp_did; + if (H5T__path_free(old_path, &conv_ctx) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free datatype conversion path"); /* Release temporary atoms */ if (tmp_sid >= 0) { @@ -2932,12 +2879,15 @@ herr_t H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5VL_object_t *owned_vol_obj, H5T_conv_t func) { - H5T_path_t *path = NULL; /*conversion path */ - H5T_soft_t *soft = NULL; /*soft conversion information */ - int nprint = 0; /*number of paths shut down */ - int i; /*counter */ + H5T_conv_ctx_t conv_ctx = {0}; /* Conversion context object */ + H5T_path_t *path = NULL; /* Conversion path */ + H5T_soft_t *soft = NULL; /* Soft conversion information */ + herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) + + conv_ctx.u.free.src_type_id = H5I_INVALID_HID; + conv_ctx.u.free.dst_type_id = H5I_INVALID_HID; /* * Remove matching entries from the soft list if: @@ -2955,7 +2905,7 @@ H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5VL_o * source or destination types matches the given VOL object. */ if ((H5T_PERS_DONTCARE == pers || H5T_PERS_SOFT == pers) && !owned_vol_obj) { - for (i = H5T_g.nsoft - 1; i >= 0; --i) { + for (int i = H5T_g.nsoft - 1; i >= 0; --i) { soft = H5T_g.soft + i; assert(soft); if (name && *name && strcmp(name, soft->name) != 0) @@ -2969,11 +2919,11 @@ H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5VL_o memmove(H5T_g.soft + i, H5T_g.soft + i + 1, (size_t)(H5T_g.nsoft - (i + 1)) * sizeof(H5T_soft_t)); --H5T_g.nsoft; - } /* end for */ - } /* end if */ + } + } /* Remove matching conversion paths, except no-op path */ - for (i = H5T_g.npaths - 1; i > 0; --i) { + for (int i = H5T_g.npaths - 1; i > 0; --i) { bool nomatch; path = H5T_g.path[i]; @@ -2991,45 +2941,20 @@ H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5VL_o * the list to be recalculated to avoid the removed function. */ path->cdata.recalc = true; - } /* end if */ + } else { /* Remove from table */ memmove(H5T_g.path + i, H5T_g.path + i + 1, (size_t)(H5T_g.npaths - (i + 1)) * sizeof(H5T_path_t *)); --H5T_g.npaths; - /* Shut down path */ - H5T__print_stats(path, &nprint); - path->cdata.command = H5T_CONV_FREE; - if (path->conv.is_app) { - if ((path->conv.u.app_func)(H5I_INVALID_HID, H5I_INVALID_HID, &(path->cdata), 0, 0, 0, NULL, - NULL, H5CX_get_dxpl()) < 0) { -#ifdef H5T_DEBUG - if (H5DEBUG(T)) - fprintf(H5DEBUG(T), - "H5T: conversion function 0x%016zx failed " - "to free private data for %s (ignored)\n", - (size_t)path->conv.u.app_func, path->name); -#endif - } /* end if */ - } /* end if */ - else if ((path->conv.u.lib_func)(NULL, NULL, &(path->cdata), NULL, 0, 0, 0, NULL, NULL) < 0) { -#ifdef H5T_DEBUG - if (H5DEBUG(T)) - fprintf(H5DEBUG(T), - "H5T: conversion function 0x%016zx failed " - "to free private data for %s (ignored)\n", - (size_t)path->conv.u.lib_func, path->name); -#endif - } /* end if */ - (void)H5T_close_real(path->src); - (void)H5T_close_real(path->dst); - path = H5FL_FREE(H5T_path_t, path); - H5E_clear_stack(NULL); /*ignore all shutdown errors*/ - } /* end else */ - } /* end for */ + if (H5T__path_free(path, &conv_ctx) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free datatype conversion path"); + } + } - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_unregister() */ /*------------------------------------------------------------------------- @@ -5056,6 +4981,60 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, bool superset) FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_cmp() */ +/*------------------------------------------------------------------------- + * Function: H5T__bsearch_path_table + * + * Purpose: Performs a binary search on the type conversion path table. + * If `last_cmp` is non-NULL, the value of the last comparison + * is returned through it. If `idx` is non-NULL, the idx into + * the path table where the matching path was found is returned + * through it. If no matching path is found, the value for + * `idx` will be the index into the path table where a path + * entry with source and destination datatypes matching src and + * dst should be inserted. In this case, the caller should be + * sure to increment the index value by 1 if the value of the + * last comparison is > 0. + * + * Return: Success: Pointer to the path in the path table + * Failure: NULL if no matching path is found in the table + * + *------------------------------------------------------------------------- + */ +static void * +H5T__bsearch_path_table(const H5T_t *src, const H5T_t *dst, int *last_cmp, int *idx) +{ + int cmp; + int lt, rt, md; + void *ret_value = NULL; + + FUNC_ENTER_PACKAGE_NOERR + + lt = md = 1; + rt = H5T_g.npaths; + cmp = -1; + + while (cmp && lt < rt) { + md = (lt + rt) / 2; + assert(H5T_g.path[md]); + cmp = H5T_cmp(src, H5T_g.path[md]->src, false); + if (0 == cmp) + cmp = H5T_cmp(dst, H5T_g.path[md]->dst, false); + if (cmp < 0) + rt = md; + else if (cmp > 0) + lt = md + 1; + else + ret_value = H5T_g.path[md]; + } + + if (last_cmp) + *last_cmp = cmp; + if (idx) + *idx = md; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__bsearch_path_table() */ + /*------------------------------------------------------------------------- * Function: H5T_path_find * @@ -5103,16 +5082,20 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst) * Function: H5T__path_find_real * * Purpose: Finds the path which converts type SRC to type DST, creating - * a new path if necessary. If FUNC is non-zero then it is set - * as the hard conversion function for that path regardless of - * whether the path previously existed. Changing the conversion - * function of a path causes statistics to be reset to zero - * after printing them. The NAME is used only when creating a - * new path and is just for debugging. + * a new path if necessary. * - * If SRC and DST are both null pointers then the special no-op - * conversion path is used. This path is always stored as the - * first path in the path table. + * If `conv->u.app_func`/`conv->u.lib_func` is non-NULL then it + * is set as the hard conversion function for that path + * regardless of whether the path previously existed. Changing + * the conversion function of a path causes statistics to be + * reset to zero after printing them. `name` is used only when + * creating a new path and is just for debugging. + * + * If no "force conversion" flags are set for either the source + * or destination datatype and the two datatypes compare equal + * to each other, then the special no-op conversion path is + * used. This path is always stored as the first path in the + * path table. * * Return: Success: Pointer to the path, valid until the path * database is modified. @@ -5125,20 +5108,17 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst) static H5T_path_t * H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_conv_func_t *conv) { - H5T_conv_ctx_t tmp_ctx = {0}; /* temporary conversion context object */ - int lt, rt; /* left and right edges */ - int md; /* middle */ - int cmp; /* comparison result */ - int old_npaths; /* Previous number of paths in table */ - H5T_path_t *table = NULL; /* path existing in the table */ - H5T_path_t *path = NULL; /* new path */ - H5T_t *tmp_stype = NULL; /* temporary source datatype */ - H5T_t *tmp_dtype = NULL; /* temporary destination datatype */ - hid_t src_id = H5I_INVALID_HID; /* source datatype identifier */ - hid_t dst_id = H5I_INVALID_HID; /* destination datatype identifier */ - int i; /* counter */ - int nprint = 0; /* lines of output printed */ - H5T_path_t *ret_value = NULL; /* Return value */ + H5T_conv_ctx_t tmp_ctx = {0}; /* Temporary conversion context object */ + H5T_path_t *matched_path = NULL; /* Path existing in the table */ + H5T_path_t *path = NULL; /* Pointer to current path */ + bool noop_conv = false; /* Whether this is a no-op conversion */ + bool new_path = false; /* Whether we're creating a new path */ + bool new_api_func = false; /* If the caller is an API function specifying a new conversion function */ + bool new_lib_func = false; /* If the caller is a private function specifying a new conversion function */ + int old_npaths; /* Previous number of paths in table */ + int last_cmp = 0; /* Value of last comparison during binary search */ + int path_idx = 0; /* Index into path table for path */ + H5T_path_t *ret_value = NULL; /* Return value */ FUNC_ENTER_PACKAGE @@ -5157,66 +5137,21 @@ H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_co if (H5CX_pushed() && (H5CX_get_dt_conv_cb(&tmp_ctx.u.init.cb_struct) < 0)) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, NULL, "unable to get conversion exception callback"); - /* - * Make sure the first entry in the table is the no-op conversion path. - */ - if (0 == H5T_g.npaths) { - if (NULL == (H5T_g.path = (H5T_path_t **)H5MM_malloc(128 * sizeof(H5T_path_t *)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed for type conversion path table"); - H5T_g.apaths = 128; - if (NULL == (H5T_g.path[0] = H5FL_CALLOC(H5T_path_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed for no-op conversion path"); - snprintf(H5T_g.path[0]->name, sizeof(H5T_g.path[0]->name), "no-op"); - H5T_g.path[0]->conv.is_app = false; - H5T_g.path[0]->conv.u.lib_func = H5T__conv_noop; - H5T_g.path[0]->cdata.command = H5T_CONV_INIT; - if (H5T__conv_noop(NULL, NULL, &(H5T_g.path[0]->cdata), &tmp_ctx, 0, 0, 0, NULL, NULL) < 0) { -#ifdef H5T_DEBUG - if (H5DEBUG(T)) - fprintf(H5DEBUG(T), "H5T: unable to initialize no-op conversion function (ignored)\n"); -#endif - /* Ignore any errors from the conversion function */ - if (H5E_clear_stack(NULL) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, NULL, "unable to clear current error stack"); - } /* end if */ - H5T_g.path[0]->is_noop = true; - H5T_g.npaths = 1; - } /* end if */ + /* Make sure the path table is initialized */ + if ((0 == H5T_g.npaths) && (H5T__path_find_init_path_table() < 0)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to initialize type conversion path table"); - /* Find the conversion path. If source and destination types are equal - * then use entry[0], otherwise do a binary search over the - * remaining entries. - * - * Only allow the no-op conversion to occur if no "force conversion" flags - * are set + /* Find the conversion path. If no "force conversion" flags are + * set and the source and destination types are equal, then use + * the no-op conversion path. Otherwise, do a binary search over + * the remaining entries. */ - if (src->shared->force_conv == false && dst->shared->force_conv == false && - 0 == H5T_cmp(src, dst, true)) { - table = H5T_g.path[0]; - cmp = 0; - md = 0; - } /* end if */ - else { - lt = md = 1; - rt = H5T_g.npaths; - cmp = -1; - - while (cmp && lt < rt) { - md = (lt + rt) / 2; - assert(H5T_g.path[md]); - cmp = H5T_cmp(src, H5T_g.path[md]->src, false); - if (0 == cmp) - cmp = H5T_cmp(dst, H5T_g.path[md]->dst, false); - if (cmp < 0) - rt = md; - else if (cmp > 0) - lt = md + 1; - else - table = H5T_g.path[md]; - } /* end while */ - } /* end else */ + noop_conv = + src->shared->force_conv == false && dst->shared->force_conv == false && 0 == H5T_cmp(src, dst, true); + if (noop_conv) + matched_path = H5T_g.path[0]; + else + matched_path = H5T__bsearch_path_table(src, dst, &last_cmp, &path_idx); /* Keep a record of the number of paths in the table, in case one of the * initialization calls below (hard or soft) causes more entries to be @@ -5224,13 +5159,18 @@ H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_co */ old_npaths = H5T_g.npaths; + /* Set a few convenience variables */ + new_api_func = (matched_path && conv->is_app && conv->u.app_func); + new_lib_func = (matched_path && !conv->is_app && conv->u.lib_func); + /* If we didn't find the path, if the caller is an API function specifying * a new hard conversion function, or if the caller is a private function * specifying a new hard conversion and the path is a soft conversion, then * create a new path and add the new function to the path. */ - if (!table || (table && conv->is_app && conv->u.app_func) || - (table && !table->is_hard && !conv->is_app && conv->u.lib_func)) { + new_path = !matched_path || new_api_func || (new_lib_func && !matched_path->is_hard); + + if (new_path) { if (NULL == (path = H5FL_CALLOC(H5T_path_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for type conversion path"); if (name && *name) { @@ -5245,18 +5185,168 @@ H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_co HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy datatype for conversion path"); } /* end if */ else - path = table; + path = matched_path; + + /* Initialize the path if it's a new path */ + if (new_path && H5T__path_find_init_new_path(path, src, dst, conv, &tmp_ctx) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to initialize new conversion path"); + + /* Fail if the path still doesn't have a conversion function at this point */ + if (!path->conv.u.app_func) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "no appropriate function for conversion path"); + + /* Check if paths were inserted into the table through a recursive call + * and re-compute the correct location for this path if so. - QAK, 1/26/02 + */ + if (old_npaths != H5T_g.npaths) + matched_path = H5T__bsearch_path_table(src, dst, &last_cmp, &path_idx); + + /* Replace an existing table entry or add a new entry */ + if (matched_path && new_path) { + assert(matched_path == H5T_g.path[path_idx]); + + tmp_ctx.u.free.src_type_id = H5I_INVALID_HID; + tmp_ctx.u.free.dst_type_id = H5I_INVALID_HID; + if (H5T__path_free(matched_path, &tmp_ctx) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, NULL, "unable to free datatype conversion path"); + + H5T_g.path[path_idx] = path; + } + else if (new_path) { + /* Make space in the table for the new path if necessary */ + if ((size_t)H5T_g.npaths >= H5T_g.apaths) { + size_t na = MAX(H5T_DEF_CONV_TABLE_SLOTS, 2 * H5T_g.apaths); + H5T_path_t **x; + + if (NULL == (x = H5MM_realloc(H5T_g.path, na * sizeof(H5T_path_t *)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + H5T_g.apaths = na; + H5T_g.path = x; + } + + /* Adjust final location in table for new path if the last comparison + * of paths during binary search was > 0, then shift down all path + * entries in the table starting at that location to make room for + * the new path + */ + assert(last_cmp != 0); + if (last_cmp > 0) + path_idx++; + memmove(H5T_g.path + path_idx + 1, H5T_g.path + path_idx, + (size_t)(H5T_g.npaths - path_idx) * sizeof(H5T_path_t *)); + + H5T_g.npaths++; + H5T_g.path[path_idx] = path; + } + + ret_value = path; + +done: + if (!ret_value && path && new_path) { + if (path->src && (H5T_close_real(path->src) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close datatype"); + if (path->dst && (H5T_close_real(path->dst) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close datatype"); + path = H5FL_FREE(H5T_path_t, path); + } - /* If a hard conversion function is specified and none is defined for the - * path, or the caller is an API function, or the caller is a private function but - * the existing path is a soft function, then add the new conversion to the path - * and initialize its conversion data. + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__path_find_real() */ + +/*------------------------------------------------------------------------- + * Function: H5T__path_find_init_path_table + * + * Purpose: Helper function to allocate and initialize the table holding + * pointers to datatype conversion paths. Sets the no-op + * conversion path as the first entry in the table. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__path_find_init_path_table(void) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + assert(0 == H5T_g.npaths); + + if (NULL == (H5T_g.path = H5MM_malloc(H5T_DEF_CONV_TABLE_SLOTS * sizeof(H5T_path_t *)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion path table"); + H5T_g.apaths = H5T_DEF_CONV_TABLE_SLOTS; + H5T_g.path[0] = NULL; + + /* + * Allocate a path for the no-op conversion function + * and set it as the first entry in the table */ - if (conv->u.app_func && - (!table || (table && conv->is_app) || (table && !table->is_hard && !conv->is_app))) { - assert(path != table); - assert(NULL == path->conv.u.app_func); + if (NULL == (H5T_g.path[0] = H5FL_CALLOC(H5T_path_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for no-op conversion path"); + + /* Initialize the no-op path */ + snprintf(H5T_g.path[0]->name, sizeof(H5T_g.path[0]->name), "no-op"); + H5T_g.path[0]->conv.is_app = false; + H5T_g.path[0]->conv.u.lib_func = H5T__conv_noop; + H5T_g.path[0]->cdata.command = H5T_CONV_INIT; + + if (H5T__conv_noop(NULL, NULL, &(H5T_g.path[0]->cdata), NULL, 0, 0, 0, NULL, NULL) < 0) { +#ifdef H5T_DEBUG + if (H5DEBUG(T)) + fprintf(H5DEBUG(T), "H5T: unable to initialize no-op conversion function (ignored)\n"); +#endif + /* Ignore any errors from the conversion function */ + if (H5E_clear_stack(NULL) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, FAIL, "unable to clear current error stack"); + } /* end if */ + + H5T_g.path[0]->is_noop = true; + H5T_g.npaths = 1; + +done: + if (ret_value < 0) { + if (H5T_g.path) + H5FL_FREE(H5T_path_t, H5T_g.path[0]); + H5MM_free(H5T_g.path); + } + + FUNC_LEAVE_NOAPI(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5T__path_find_init_new_path + * + * Purpose: Helper function to initialize a new conversion path that's + * being added to the path conversion table. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__path_find_init_new_path(H5T_path_t *path, const H5T_t *src, const H5T_t *dst, H5T_conv_func_t *conv, + H5T_conv_ctx_t *conv_ctx) +{ + H5T_t *tmp_stype = NULL; /* temporary source datatype */ + H5T_t *tmp_dtype = NULL; /* temporary destination datatype */ + hid_t src_id = H5I_INVALID_HID; /* source datatype identifier */ + hid_t dst_id = H5I_INVALID_HID; /* destination datatype identifier */ + herr_t status = SUCCEED; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + assert(path); + assert(conv); + assert(conv_ctx); + assert(NULL == path->conv.u.app_func); + /* If a hard conversion function was specified, initialize that + * function and finish setting up the new path. + */ + if (conv->u.app_func) { path->cdata.command = H5T_CONV_INIT; if (conv->is_app) { /* Copy the conversion path's source and destination datatypes and @@ -5264,48 +5354,48 @@ H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_co * conversion function */ if (path->src && (NULL == (tmp_stype = H5T_copy(path->src, H5T_COPY_ALL)))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to copy source datatype"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy source datatype"); if (path->dst && (NULL == (tmp_dtype = H5T_copy(path->dst, H5T_COPY_ALL)))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to copy destination datatype"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy destination datatype"); if (tmp_stype && ((src_id = H5I_register(H5I_DATATYPE, tmp_stype, false)) < 0)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register ID for source datatype"); if (tmp_dtype && ((dst_id = H5I_register(H5I_DATATYPE, tmp_dtype, false)) < 0)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register ID for destination datatype"); - if ((conv->u.app_func)(src_id, dst_id, &(path->cdata), 0, 0, 0, NULL, NULL, H5CX_get_dxpl()) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to initialize conversion function"); - } /* end if */ - else if ((conv->u.lib_func)(path->src, path->dst, &(path->cdata), &tmp_ctx, 0, 0, 0, NULL, NULL) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to initialize conversion function"); + status = (conv->u.app_func)(src_id, dst_id, &(path->cdata), 0, 0, 0, NULL, NULL, H5CX_get_dxpl()); + } + else + status = (conv->u.lib_func)(path->src, path->dst, &(path->cdata), conv_ctx, 0, 0, 0, NULL, NULL); + + if (status < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion function"); if (src_id >= 0) { if (H5I_dec_ref(src_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, NULL, "can't decrement reference on temporary ID"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); src_id = H5I_INVALID_HID; tmp_stype = NULL; } if (dst_id >= 0) { if (H5I_dec_ref(dst_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, NULL, "can't decrement reference on temporary ID"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); dst_id = H5I_INVALID_HID; tmp_dtype = NULL; } path->conv = *conv; path->is_hard = true; - } /* end if */ + } /* - * If the path doesn't have a function by now (because it's a new path - * and the caller didn't supply a hard function) then scan the soft list - * for an applicable function and add it to the path. This can't happen - * for the no-op conversion path. + * Otherwise, scan the soft list for an applicable function + * and add it to the path. */ assert(path->conv.u.app_func || (src && dst)); - for (i = H5T_g.nsoft - 1; i >= 0 && !path->conv.u.app_func; --i) { + for (int i = H5T_g.nsoft - 1; i >= 0 && !path->conv.u.app_func; --i) { bool path_init_error = false; if (src->shared->type != H5T_g.soft[i].src || dst->shared->type != H5T_g.soft[i].dst) @@ -5317,39 +5407,32 @@ H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_co * register an ID for them so we can pass these to the application * conversion function */ - assert(tmp_stype == NULL); - assert(tmp_dtype == NULL); if (NULL == (tmp_stype = H5T_copy(path->src, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to copy source datatype"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy source datatype"); if (NULL == (tmp_dtype = H5T_copy(path->dst, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "unable to copy destination datatype"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy destination datatype"); - assert(src_id == H5I_INVALID_HID); - assert(dst_id == H5I_INVALID_HID); if ((src_id = H5I_register(H5I_DATATYPE, tmp_stype, false)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register ID for source datatype"); if ((dst_id = H5I_register(H5I_DATATYPE, tmp_dtype, false)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register ID for destination datatype"); - if ((H5T_g.soft[i].conv.u.app_func)(src_id, dst_id, &(path->cdata), 0, 0, 0, NULL, NULL, - H5CX_get_dxpl()) < 0) { - memset(&(path->cdata), 0, sizeof(H5T_cdata_t)); - /*ignore the error*/ - if (H5E_clear_stack(NULL) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, NULL, "unable to clear current error stack"); - path_init_error = true; - } /* end if */ - } /* end if */ - else if ((H5T_g.soft[i].conv.u.lib_func)(path->src, path->dst, &(path->cdata), &tmp_ctx, 0, 0, 0, - NULL, NULL) < 0) { + status = (H5T_g.soft[i].conv.u.app_func)(src_id, dst_id, &(path->cdata), 0, 0, 0, NULL, NULL, + H5CX_get_dxpl()); + } + else + status = (H5T_g.soft[i].conv.u.lib_func)(path->src, path->dst, &(path->cdata), conv_ctx, 0, 0, 0, + NULL, NULL); + + if (status < 0) { memset(&(path->cdata), 0, sizeof(H5T_cdata_t)); - /*ignore the error*/ + /* ignore the error */ if (H5E_clear_stack(NULL) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, NULL, "unable to clear current error stack"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, FAIL, "unable to clear current error stack"); path_init_error = true; - } /* end if */ + } /* Finish operation, if no error */ if (!path_init_error) { @@ -5357,133 +5440,105 @@ H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_co path->name[H5T_NAMELEN - 1] = '\0'; path->conv = H5T_g.soft[i].conv; path->is_hard = false; - } /* end else */ + } if (src_id >= 0) { if (H5I_dec_ref(src_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, NULL, "can't decrement reference on temporary ID"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); src_id = H5I_INVALID_HID; tmp_stype = NULL; } if (dst_id >= 0) { if (H5I_dec_ref(dst_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, NULL, "can't decrement reference on temporary ID"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); dst_id = H5I_INVALID_HID; tmp_dtype = NULL; } - } /* end for */ - if (!path->conv.u.app_func) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "no appropriate function for conversion path"); - - /* Check if paths were inserted into the table through a recursive call - * and re-compute the correct location for this path if so. - QAK, 1/26/02 - */ - if (old_npaths != H5T_g.npaths) { - lt = md = 1; - rt = H5T_g.npaths; - cmp = -1; - - while (cmp && lt < rt) { - md = (lt + rt) / 2; - assert(H5T_g.path[md]); - cmp = H5T_cmp(src, H5T_g.path[md]->src, false); - if (0 == cmp) - cmp = H5T_cmp(dst, H5T_g.path[md]->dst, false); - if (cmp < 0) - rt = md; - else if (cmp > 0) - lt = md + 1; - else - table = H5T_g.path[md]; - } /* end while */ - } /* end if */ - - /* Replace an existing table entry or add a new entry */ - if (table && path != table) { - assert(table == H5T_g.path[md]); - H5T__print_stats(table, &nprint /*in,out*/); - table->cdata.command = H5T_CONV_FREE; - if (table->conv.is_app) { - if ((table->conv.u.app_func)(H5I_INVALID_HID, H5I_INVALID_HID, &(table->cdata), 0, 0, 0, NULL, - NULL, H5CX_get_dxpl()) < 0) { -#ifdef H5T_DEBUG - if (H5DEBUG(T)) - fprintf(H5DEBUG(T), "H5T: conversion function 0x%016zx free failed for %s (ignored)\n", - (size_t)path->conv.u.app_func, path->name); -#endif - /*ignore the failure*/ - if (H5E_clear_stack(NULL) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, NULL, "unable to clear current error stack"); - } /* end if */ - } /* end if */ - else if ((table->conv.u.lib_func)(NULL, NULL, &(table->cdata), NULL, 0, 0, 0, NULL, NULL) < 0) { -#ifdef H5T_DEBUG - if (H5DEBUG(T)) - fprintf(H5DEBUG(T), "H5T: conversion function 0x%016zx free failed for %s (ignored)\n", - (size_t)path->conv.u.lib_func, path->name); -#endif - /*ignore the failure*/ - if (H5E_clear_stack(NULL) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRESET, NULL, "unable to clear current error stack"); - } /* end if */ - if (table->src && (H5T_close_real(table->src) < 0)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close datatype"); - if (table->dst && (H5T_close_real(table->dst) < 0)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close datatype"); - table = H5FL_FREE(H5T_path_t, table); - table = path; - H5T_g.path[md] = path; - } /* end if */ - else if (path != table) { - assert(cmp); - if ((size_t)H5T_g.npaths >= H5T_g.apaths) { - size_t na = MAX(128, 2 * H5T_g.apaths); - H5T_path_t **x; - - if (NULL == (x = (H5T_path_t **)H5MM_realloc(H5T_g.path, na * sizeof(H5T_path_t *)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - H5T_g.apaths = na; - H5T_g.path = x; - } /* end if */ - if (cmp > 0) - md++; - memmove(H5T_g.path + md + 1, H5T_g.path + md, (size_t)(H5T_g.npaths - md) * sizeof(H5T_path_t *)); - H5T_g.npaths++; - H5T_g.path[md] = path; - table = path; - } /* end else-if */ - - /* Set return value */ - ret_value = path; + } done: - if (!ret_value && path && path != table) { - if (path->src && (H5T_close_real(path->src) < 0)) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close datatype"); - if (path->dst && (H5T_close_real(path->dst) < 0)) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close datatype"); - path = H5FL_FREE(H5T_path_t, path); - } /* end if */ - if (src_id >= 0) { if (H5I_dec_ref(src_id) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, NULL, "can't decrement reference on temporary ID"); + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); } else if (tmp_stype) { if (H5T_close(tmp_stype) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "can't close temporary datatype"); + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype"); } if (dst_id >= 0) { if (H5I_dec_ref(dst_id) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, NULL, "can't decrement reference on temporary ID"); + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); } else if (tmp_dtype) { if (H5T_close(tmp_dtype) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "can't close temporary datatype"); + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype"); } FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T__path_find_real() */ +} + +/*------------------------------------------------------------------------- + * Function: H5T__path_free + * + * Purpose: Helper function to free a datatype conversion path. This + * function assumes that the 'free' member of the passed in + * 'conv_ctx' has been initialized. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__path_free(H5T_path_t *path, H5T_conv_ctx_t *conv_ctx) +{ + herr_t status = SUCCEED; + int nprint = 0; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + assert(path); + assert(conv_ctx); + + if (path->conv.u.app_func) { + H5T__print_stats(path, &nprint); + + path->cdata.command = H5T_CONV_FREE; + + if (path->conv.is_app) + status = (path->conv.u.app_func)(conv_ctx->u.free.src_type_id, conv_ctx->u.free.dst_type_id, + &(path->cdata), 0, 0, 0, NULL, NULL, H5CX_get_dxpl()); + else + status = + (path->conv.u.lib_func)(path->src, path->dst, &(path->cdata), conv_ctx, 0, 0, 0, NULL, NULL); + + if (status < 0) { + /* Ignore any error from shutting down the path */ + if (H5E_clear_stack(NULL) < 0) + /* Push error, but keep going */ + HDONE_ERROR(H5E_DATATYPE, H5E_CANTRESET, FAIL, "unable to clear current error stack"); + +#ifdef H5T_DEBUG + if (H5DEBUG(T)) { + fprintf(H5DEBUG(T), "H5T: conversion function 0x%016zx free failed for %s (ignored)\n", + path->conv.is_app ? (size_t)path->conv.u.app_func : (size_t)path->conv.u.lib_func, + path->name); + } +#endif + } + } + + if (path->src && (H5T_close_real(path->src) < 0)) + /* Push error, but keep going */ + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close source datatype"); + if (path->dst && (H5T_close_real(path->dst) < 0)) + /* Push error, but keep going */ + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close destination datatype"); + + path = H5FL_FREE(H5T_path_t, path); + + FUNC_LEAVE_NOAPI(ret_value) +} /*------------------------------------------------------------------------- * Function: H5T_path_match @@ -6638,3 +6693,51 @@ H5T__get_path_table_npaths(void) FUNC_LEAVE_NOAPI(ret_value) } + +/*------------------------------------------------------------------------- + * Function: H5T_is_numeric_with_unusual_unused_bits + * + * Purpose: Detect if a datatype is a numeric datatype (int, float, or + * bitfield) with an unusual # of unused bits. This means + * that the precision (i.e. the # of bits used) is less than + * the size of the datatype, at power-of-two boundaries. + * + * Return: true/false on success, can't fail + * + *------------------------------------------------------------------------- + */ +bool +H5T_is_numeric_with_unusual_unused_bits(const H5T_t *dt) +{ + bool ret_value = false; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + assert(dt); + assert(dt->shared); + + /* Is the correct type? */ + if (H5T_INTEGER == dt->shared->type || H5T_FLOAT == dt->shared->type || + H5T_BITFIELD == dt->shared->type) { +#if LDBL_MANT_DIG == 106 + /* This currently won't work for the IBM long double type */ + if (H5T_FLOAT == dt->shared->type && dt->shared->size == 16 && + (dt->shared->u.atomic.prec == 64 || dt->shared->u.atomic.prec == 128)) + HGOTO_DONE(false); +#endif + + /* Has unused bits? */ + if (dt->shared->u.atomic.prec < (dt->shared->size * 8)) { + unsigned surround_bits = + 1U << (1 + H5VM_log2_gen((dt->shared->u.atomic.prec + dt->shared->u.atomic.offset) - 1)); + + /* Unused bits are unusually large? */ + if (dt->shared->size > 1 && ((dt->shared->size * 8) > surround_bits)) + HGOTO_DONE(true); + } + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_is_numeric_with_unusual_unused_bits() */ diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index 5c4b4be9553..00a88984375 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -424,11 +424,13 @@ H5T__commit_anon(H5F_t *file, H5T_t *type, hid_t tcpl_id) herr_t H5T__commit(H5F_t *file, H5T_t *type, hid_t tcpl_id) { - H5O_loc_t temp_oloc; /* Temporary object header location */ - H5G_name_t temp_path; /* Temporary path */ - bool loc_init = false; /* Have temp_oloc and temp_path been initialized? */ - size_t dtype_size; /* Size of the datatype message */ - herr_t ret_value = SUCCEED; /* Return value */ + H5O_t *oh = NULL; /* Pointer to actual object header */ + H5O_loc_t temp_oloc; /* Temporary object header location */ + H5G_name_t temp_path; /* Temporary path */ + bool loc_init = false; /* Have temp_oloc and temp_path been initialized? */ + bool ohdr_created = false; /* Has the object header been created yet? */ + size_t dtype_size; /* Size of the datatype message */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -481,9 +483,23 @@ H5T__commit(H5F_t *file, H5T_t *type, hid_t tcpl_id) */ if (H5O_create(file, dtype_size, (size_t)1, tcpl_id, &temp_oloc) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create datatype object header"); - if (H5O_msg_create(&temp_oloc, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT | H5O_MSG_FLAG_DONTSHARE, - H5O_UPDATE_TIME, type) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message"); + ohdr_created = true; + + /* Pin the object header */ + if (NULL == (oh = H5O_pin(&temp_oloc))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTPIN, FAIL, "unable to pin object header"); + + /* Check for creating committed datatype with unusual datatype */ + if (!(H5O_has_chksum(oh) || (H5F_RFIC_FLAGS(file) & H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS)) && + H5T_is_numeric_with_unusual_unused_bits(type)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "creating committed datatype with unusual datatype, see documentation for " + "H5Pset_relax_file_integrity_checks for details."); + + /* Insert the datatype message */ + if (H5O_msg_append_oh(file, oh, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT | H5O_MSG_FLAG_DONTSHARE, + H5O_UPDATE_TIME, type) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert type header message"); /* Copy the new object header's location into the datatype, taking ownership of it */ if (H5O_loc_copy_shallow(&(type->oloc), &temp_oloc) < 0) @@ -510,23 +526,39 @@ H5T__commit(H5F_t *file, H5T_t *type, hid_t tcpl_id) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype in memory"); done: + if (oh && H5O_unpin(oh) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTUNPIN, FAIL, "unable to unpin object header"); + if (ret_value < 0) { - if (loc_init) { - H5O_loc_free(&temp_oloc); - H5G_name_free(&temp_path); - } /* end if */ - if ((type->shared->state == H5T_STATE_TRANSIENT || type->shared->state == H5T_STATE_RDONLY) && - (type->sh_loc.type == H5O_SHARE_TYPE_COMMITTED)) { - if (H5O_dec_rc_by_loc(&(type->oloc)) < 0) + /* Close & delete the object header on failure */ + if (ohdr_created) { + H5O_loc_t *oloc_ptr; /* Pointer to object header location */ + + /* Point at correct object header location, depending on state when failure occurred */ + if (loc_init) + oloc_ptr = &temp_oloc; + else + oloc_ptr = &(type->oloc); + if (H5O_dec_rc_by_loc(oloc_ptr) < 0) HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object"); - if (H5O_close(&(type->oloc), NULL) < 0) + if (H5O_close(oloc_ptr, NULL) < 0) HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to release object header"); - if (H5O_delete(file, type->sh_loc.u.loc.oh_addr) < 0) + if (H5O_delete(file, oloc_ptr->addr) < 0) HDONE_ERROR(H5E_DATATYPE, H5E_CANTDELETE, FAIL, "unable to delete object header"); + } + + /* Release the location info, if the datatype doesn't own it */ + if (loc_init) { + H5O_loc_free(&temp_oloc); + H5G_name_free(&temp_path); + } + + /* Reset the shared state for the datatype */ + if ((type->shared->state == H5T_STATE_TRANSIENT || type->shared->state == H5T_STATE_RDONLY) && + (type->sh_loc.type == H5O_SHARE_TYPE_COMMITTED)) type->sh_loc.type = H5O_SHARE_TYPE_UNSHARED; - } /* end if */ - } /* end if */ + } FUNC_LEAVE_NOAPI(ret_value) } /* H5T__commit() */ diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 5e9fe80e70b..fe207b0c89d 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -19,18 +19,21 @@ /****************/ #include "H5Tmodule.h" /* This source code file is part of the H5T module */ +#define H5R_FRIEND /* Suppress error about including H5Rpkg */ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5CXprivate.h" /* API Contexts */ -#include "H5Dprivate.h" /* Datasets */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Tpkg.h" /* Datatypes */ +#include "H5private.h" /* Generic Functions */ +#include "H5CXprivate.h" /* API Contexts */ +#include "H5Dprivate.h" /* Datasets */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property lists */ +#include "H5Rpkg.h" /* References */ +#include "H5Tpkg.h" /* Datatypes */ /****************/ /* Local Macros */ @@ -3447,26 +3450,33 @@ H5T__conv_vlen(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T bool write_to_file = false; /* Flag to indicate writing to file */ htri_t parent_is_vlen; /* Flag to indicate parent is vlen datatype */ size_t bg_seq_len = 0; /* The number of elements in the background sequence */ - H5T_t *tsrc_cpy = NULL; /*temporary copy of source base datatype */ - H5T_t *tdst_cpy = NULL; /*temporary copy of destination base datatype */ - hid_t tsrc_id = H5I_INVALID_HID; /*temporary type atom */ - hid_t tdst_id = H5I_INVALID_HID; /*temporary type atom */ - uint8_t *s = NULL; /*source buffer */ - uint8_t *d = NULL; /*destination buffer */ - uint8_t *b = NULL; /*background buffer */ - ssize_t s_stride, d_stride; /*src and dst strides */ - ssize_t b_stride; /*bkg stride */ - size_t safe; /*how many elements are safe to process in each pass */ - size_t src_base_size; /*source base size*/ - size_t dst_base_size; /*destination base size*/ - void *conv_buf = NULL; /*temporary conversion buffer */ - size_t conv_buf_size = 0; /*size of conversion buffer in bytes */ - void *tmp_buf = NULL; /*temporary background buffer */ - size_t tmp_buf_size = 0; /*size of temporary bkg buffer */ - bool nested = false; /*flag of nested VL case */ - bool need_ids = false; /*whether we need IDs for the datatypes */ - size_t elmtno; /*element number counter */ - herr_t ret_value = SUCCEED; /* Return value */ + H5T_t *tsrc_cpy = NULL; /* Temporary copy of source base datatype */ + H5T_t *tdst_cpy = NULL; /* Temporary copy of destination base datatype */ + hid_t tsrc_id = H5I_INVALID_HID; /* Temporary type atom */ + hid_t tdst_id = H5I_INVALID_HID; /* Temporary type atom */ + uint8_t *s = NULL; /* Source buffer */ + uint8_t *d = NULL; /* Destination buffer */ + uint8_t *b = NULL; /* Background buffer */ + ssize_t s_stride = 0; /* Src stride */ + ssize_t d_stride = 0; /* Dst stride */ + ssize_t b_stride; /* Bkg stride */ + size_t safe = 0; /* How many elements are safe to process in each pass */ + size_t src_base_size; /* Source base size*/ + size_t dst_base_size; /* Destination base size*/ + void *conv_buf = NULL; /* Temporary conversion buffer */ + size_t conv_buf_size = 0; /* Size of conversion buffer in bytes */ + void *tmp_buf = NULL; /* Temporary background buffer */ + size_t tmp_buf_size = 0; /* Size of temporary bkg buffer */ + bool nested = false; /* Flag of nested VL case */ + bool need_ids = false; /* Whether we need IDs for the datatypes */ + size_t elmtno = 0; /* Element number counter */ + size_t orig_d_stride = 0; /* Original destination stride (used for error handling) */ + size_t orig_nelmts = nelmts; /* Original # of elements to convert (used for error handling) */ + bool convert_forward = + true; /* Current direction of conversion (forward or backward, used for error handling) */ + bool conversions_made = + false; /* Flag to indicate conversions have been performed, used for error handling */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -3603,6 +3613,10 @@ H5T__conv_vlen(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T if (write_to_file && parent_is_vlen && bkg != NULL) nested = true; + /* Save info for unraveling on errors */ + orig_d_stride = (size_t)d_stride; + convert_forward = !(d_stride > s_stride); + /* The outer loop of the type conversion macro, controlling which */ /* direction the buffer is walked */ while (nelmts > 0) { @@ -3784,6 +3798,9 @@ H5T__conv_vlen(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T } /* end if */ } /* end else */ + /* Indicate that elements have been converted, in case of error */ + conversions_made = true; + /* Advance pointers */ s += s_stride; d += d_stride; @@ -3803,6 +3820,49 @@ H5T__conv_vlen(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T } /* end switch */ done: + /* Release converted elements on error */ + if (ret_value < 0 && conversions_made) { + size_t dest_count; + + /* Set up for first pass to destroy references */ + if (nelmts < orig_nelmts || (convert_forward && elmtno < safe)) { + dest_count = orig_nelmts - nelmts; + + /* Set pointer to correct location, based on direction chosen */ + if (convert_forward) { + d = (uint8_t *)buf; + dest_count += elmtno; /* Include partial iteration in first pass, for forward conversions */ + } + else + d = (uint8_t *)buf + (nelmts * orig_d_stride); + + /* Destroy vlen elements that have already been converted */ + while (dest_count > 0) { + H5T_vlen_reclaim_elmt(d, dst); /* Ignore errors at this point */ + d += orig_d_stride; + dest_count--; + } + } + + /* Do any remaining partial iteration, if converting backwards */ + if (!convert_forward && elmtno < safe) { + dest_count = elmtno; + + /* Set pointer to correct location */ + if (d_stride > 0) + d = (uint8_t *)buf + ((nelmts - safe) * orig_d_stride); + else + d = (uint8_t *)buf + ((nelmts - elmtno) * orig_d_stride); + + /* Destroy references that have already been converted */ + while (dest_count > 0) { + H5T_vlen_reclaim_elmt(d, dst); /* Ignore errors at this point */ + d += orig_d_stride; + dest_count--; + } + } + } + if (tsrc_id >= 0) { if (H5I_dec_ref(tsrc_id) < 0) HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement reference on temporary ID"); @@ -4044,16 +4104,23 @@ H5T__conv_ref(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, const H5T_conv_ctx_t H5_ATTR_UNUSED *conv_ctx, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf, void *bkg) { - uint8_t *s = NULL; /* source buffer */ - uint8_t *d = NULL; /* destination buffer */ - uint8_t *b = NULL; /* background buffer */ - ssize_t s_stride, d_stride; /* src and dst strides */ - ssize_t b_stride; /* bkg stride */ - size_t safe; /* how many elements are safe to process in each pass */ - void *conv_buf = NULL; /* temporary conversion buffer */ - size_t conv_buf_size = 0; /* size of conversion buffer in bytes */ - size_t elmtno; /* element number counter */ - herr_t ret_value = SUCCEED; /* return value */ + uint8_t *s = NULL; /* source buffer */ + uint8_t *d = NULL; /* destination buffer */ + uint8_t *b = NULL; /* background buffer */ + ssize_t s_stride = 0; /* src stride */ + ssize_t d_stride = 0; /* dst stride */ + ssize_t b_stride; /* bkg stride */ + size_t safe = 0; /* how many elements are safe to process in each pass */ + void *conv_buf = NULL; /* temporary conversion buffer */ + size_t conv_buf_size = 0; /* size of conversion buffer in bytes */ + size_t elmtno = 0; /* element number counter */ + size_t orig_d_stride = 0; /* Original destination stride (used for error handling) */ + size_t orig_nelmts = nelmts; /* Original # of elements to convert (used for error handling) */ + bool convert_forward = + true; /* Current direction of conversion (forward or backward, used for error handling) */ + bool conversions_made = + false; /* Flag to indicate conversions have been performed, used for error handling */ + herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_PACKAGE @@ -4114,6 +4181,10 @@ H5T__conv_ref(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, else b_stride = 0; + /* Save info for unraveling on errors */ + orig_d_stride = (size_t)d_stride; + convert_forward = !(d_stride > s_stride); + /* The outer loop of the type conversion macro, controlling which */ /* direction the buffer is walked */ while (nelmts > 0) { @@ -4213,6 +4284,9 @@ H5T__conv_ref(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, } /* end else */ } /* end else */ + /* Indicate that elements have been converted, in case of error */ + conversions_made = true; + /* Advance pointers */ s += s_stride; d += d_stride; @@ -4232,6 +4306,52 @@ H5T__conv_ref(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata, } /* end switch */ done: + /* Release converted elements on error */ + if (ret_value < 0 && conversions_made) { + H5R_ref_priv_t ref_priv; + size_t dest_count; + + /* Set up for first pass to destroy references */ + if (nelmts < orig_nelmts || (convert_forward && elmtno < safe)) { + dest_count = orig_nelmts - nelmts; + + /* Set pointer to correct location, based on direction chosen */ + if (convert_forward) { + d = (uint8_t *)buf; + dest_count += elmtno; /* Include partial iteration in first pass, for forward conversions */ + } + else + d = (uint8_t *)buf + (nelmts * orig_d_stride); + + /* Destroy references that have already been converted */ + while (dest_count > 0) { + memcpy(&ref_priv, d, sizeof(H5R_ref_priv_t)); + H5R__destroy(&ref_priv); /* Ignore errors at this point */ + d += orig_d_stride; + dest_count--; + } + } + + /* Do any remaining partial iteration, if converting backwards */ + if (!convert_forward && elmtno < safe) { + dest_count = elmtno; + + /* Set pointer to correct location */ + if (d_stride > 0) + d = (uint8_t *)buf + ((nelmts - safe) * orig_d_stride); + else + d = (uint8_t *)buf + ((nelmts - elmtno) * orig_d_stride); + + /* Destroy references that have already been converted */ + while (dest_count > 0) { + memcpy(&ref_priv, d, sizeof(H5R_ref_priv_t)); + H5R__destroy(&ref_priv); /* Ignore errors at this point */ + d += orig_d_stride; + dest_count--; + } + } + } + /* Release the conversion buffer (always allocated, except on errors) */ if (conv_buf) conv_buf = H5FL_BLK_FREE(ref_seq, conv_buf); diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 59600f8eea0..8eb7b639cf0 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -158,7 +158,10 @@ struct H5T_stats_t { H5_timevals_t times; /*total time for conversion */ }; -/* Context struct for information used during datatype conversions */ +/* Context struct for information used during datatype conversions. + * Which union member is valid to read from is dictated by the + * accompanying H5T_cdata_t structure's H5T_cmd_t member value. + */ typedef struct H5T_conv_ctx_t { union { /* @@ -187,7 +190,14 @@ typedef struct H5T_conv_ctx_t { bool recursive; } conv; - /* No fields currently defined for H5T_cmd_t H5T_CONV_FREE */ + /* + * Fields only valid during conversion function free process + * (H5T_cmd_t H5T_CONV_FREE) + */ + struct H5T_conv_ctx_free_fields { + hid_t src_type_id; + hid_t dst_type_id; + } free; } u; } H5T_conv_ctx_t; diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 7d8f27615a0..46b2c92fa83 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -139,7 +139,7 @@ H5_DLL herr_t H5T_convert(H5T_path_t *tpath, const H5T_t *src_type, const H5T_t size_t buf_stride, size_t bkg_stride, void *buf, void *bkg); H5_DLL herr_t H5T_reclaim(const H5T_t *type, struct H5S_t *space, void *buf); H5_DLL herr_t H5T_reclaim_cb(void *elem, const H5T_t *dt, unsigned ndim, const hsize_t *point, void *op_data); -H5_DLL herr_t H5T_vlen_reclaim_elmt(void *elem, H5T_t *dt); +H5_DLL herr_t H5T_vlen_reclaim_elmt(void *elem, const H5T_t *dt); H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc); H5_DLL htri_t H5T_is_sensible(const H5T_t *dt); H5_DLL uint32_t H5T_hash(H5F_t *file, const H5T_t *dt); @@ -157,6 +157,7 @@ H5_DLL bool H5T_already_vol_managed(const H5T_t *dt); H5_DLL htri_t H5T_is_vl_storage(const H5T_t *dt); H5_DLL herr_t H5T_invoke_vol_optional(H5T_t *dt, H5VL_optional_args_t *args, hid_t dxpl_id, void **req, H5VL_object_t **vol_obj_ptr); +H5_DLL bool H5T_is_numeric_with_unusual_unused_bits(const H5T_t *dt); /* Reference specific functions */ H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt); diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index 6cf11c77234..971dc3c5d22 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -1053,7 +1053,7 @@ H5T__vlen_reclaim(void *elem, const H5T_t *dt, H5T_vlen_alloc_info_t *alloc_info *------------------------------------------------------------------------- */ herr_t -H5T_vlen_reclaim_elmt(void *elem, H5T_t *dt) +H5T_vlen_reclaim_elmt(void *elem, const H5T_t *dt) { H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */ herr_t ret_value = SUCCEED; /* return value */ diff --git a/src/H5VLint.c b/src/H5VLint.c index feb2debd947..131856db5e6 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -2249,7 +2249,7 @@ H5VL_set_vol_wrapper(const H5VL_object_t *vol_obj) vol_wrap_ctx->obj_wrap_ctx = obj_wrap_ctx; } /* end if */ else - /* Incremeent ref count on existing wrapper context */ + /* Increment ref count on existing wrapper context */ vol_wrap_ctx->rc++; /* Save the wrapper context */ diff --git a/src/H5VLmodule.h b/src/H5VLmodule.h index 19baf344d57..0cca38cf1db 100644 --- a/src/H5VLmodule.h +++ b/src/H5VLmodule.h @@ -83,7 +83,7 @@ * to be much more common than internal implementations. * * A list of VOL connectors can be found here: - * + * * Registered VOL Connectors * * This list is incomplete and only includes the VOL connectors that have been registered with diff --git a/src/H5VLnative_attr.c b/src/H5VLnative_attr.c index 50aca652b2f..bebd127df23 100644 --- a/src/H5VLnative_attr.c +++ b/src/H5VLnative_attr.c @@ -26,6 +26,7 @@ /***********/ #include "H5private.h" /* Generic Functions */ #include "H5Apkg.h" /* Attributes */ +#include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* Files */ #include "H5Gprivate.h" /* Groups */ @@ -195,8 +196,7 @@ H5VL__native_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const cha *------------------------------------------------------------------------- */ herr_t -H5VL__native_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req) +H5VL__native_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t dxpl_id, void H5_ATTR_UNUSED **req) { H5T_t *mem_type; /* Memory datatype */ herr_t ret_value; /* Return value */ @@ -206,6 +206,9 @@ H5VL__native_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t H5_ATTR_UNUS if (NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + /* Set DXPL for operation */ + H5CX_set_dxpl(dxpl_id); + /* Go write the actual data to the attribute */ if ((ret_value = H5A__read((H5A_t *)attr, mem_type, buf)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute"); @@ -224,8 +227,7 @@ H5VL__native_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t H5_ATTR_UNUS *------------------------------------------------------------------------- */ herr_t -H5VL__native_attr_write(void *attr, hid_t dtype_id, const void *buf, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req) +H5VL__native_attr_write(void *attr, hid_t dtype_id, const void *buf, hid_t dxpl_id, void H5_ATTR_UNUSED **req) { H5T_t *mem_type; /* Memory datatype */ herr_t ret_value; /* Return value */ @@ -235,6 +237,9 @@ H5VL__native_attr_write(void *attr, hid_t dtype_id, const void *buf, hid_t H5_AT if (NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + /* Set DXPL for operation */ + H5CX_set_dxpl(dxpl_id); + /* Go write the actual data to the attribute */ if ((ret_value = H5A__write((H5A_t *)attr, mem_type, buf)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute"); diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c index fba1c7d6c2e..048344b763c 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -1210,6 +1210,8 @@ H5Z__filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_valu minbits_mask <<= i * 8; minbits |= minbits_mask; } + if (minbits >= p.size * 8) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "minimum number of bits exceeds size of type"); /* retrieval of minval takes into consideration situation where sizeof * unsigned long long (datatype of minval) may change from compression diff --git a/src/H5encode.h b/src/H5encode.h index 5be75d57f77..690aee104d7 100644 --- a/src/H5encode.h +++ b/src/H5encode.h @@ -212,7 +212,7 @@ n = 0; \ (p) += 8; \ for (_i = 0; _i < sizeof(int64_t); _i++) \ - n = (n << 8) | *(--p); \ + n = (int64_t)(((uint64_t)n << 8) | *(--p)); \ (p) += 8; \ } while (0) @@ -224,7 +224,7 @@ n = 0; \ (p) += 8; \ for (_i = 0; _i < sizeof(uint64_t); _i++) \ - n = (n << 8) | *(--p); \ + n = (uint64_t)(((uint64_t)n << 8) | *(--p)); \ (p) += 8; \ } while (0) diff --git a/src/H5private.h b/src/H5private.h index 8cee9586769..65a99cfc6ed 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -110,7 +110,8 @@ * H5_init_library(); also, make sure that the initializer for default * VFD does *not* call H5_init_library(). */ -#define H5_DEFAULT_VFD H5FD_SEC2 +#define H5_DEFAULT_VFD H5FD_SEC2 +#define H5_DEFAULT_VFD_NAME "sec2" /* Define the default VOL driver */ #define H5_DEFAULT_VOL H5VL_NATIVE @@ -317,6 +318,15 @@ /* limit the middle value to be within a range (inclusive) */ #define RANGE(LO, X, HI) MAX(LO, MIN(X, HI)) +/* Macro for checking if two ranges overlap one another */ +/* + * Check for the inverse of whether the ranges are disjoint. If they are + * disjoint, then the low bound of one of the ranges must be greater than the + * high bound of the other. + */ +/* (Assumes that low & high bounds are _inclusive_) */ +#define H5_RANGE_OVERLAP(L1, H1, L2, H2) (!((L1) > (H2) || (L2) > (H1))) + /* absolute value */ #ifndef ABS #define ABS(a) (((a) >= 0) ? (a) : -(a)) @@ -335,9 +345,28 @@ #define H5_EXP2(n) (1 << (n)) /* Check if a read of size bytes starting at ptr would overflow past - * the last valid byte, pointed to by buffer_end. + * the last valid byte, pointed to by buffer_end. Note that 'size' + * is expected to be of type size_t. Providing values of other + * datatypes may cause warnings due to the comparison against + * PTRDIFF_MAX and comparison of < 0 after conversion to ptrdiff_t. + * For the time being, these can be suppressed with + * H5_GCC_CLANG_DIAG_OFF("type-limits")/H5_GCC_CLANG_DIAG_ON("type-limits") */ -#define H5_IS_BUFFER_OVERFLOW(ptr, size, buffer_end) (((ptr) + (size)-1) > (buffer_end)) +/* clang-format off */ +#define H5_IS_BUFFER_OVERFLOW(ptr, size, buffer_end) \ + ( \ + /* Trivial case */ \ + ((size) != 0) && \ + ( \ + /* Bad precondition */ \ + ((ptr) > (buffer_end)) || \ + /* Account for (likely unintentional) negative 'size' */ \ + (((size_t)(size) <= PTRDIFF_MAX) && ((ptrdiff_t)(size) < 0)) || \ + /* Typical overflow */ \ + ((size_t)(size) > (size_t)((((const uint8_t *)buffer_end) - ((const uint8_t *)ptr)) + 1)) \ + ) \ + ) +/* clang-format on */ /* Variant of H5_IS_BUFFER_OVERFLOW, used with functions such as H5Tdecode() * that don't take a size parameter, where we need to skip the bounds checks. @@ -346,7 +375,7 @@ * the entire library. */ #define H5_IS_KNOWN_BUFFER_OVERFLOW(skip, ptr, size, buffer_end) \ - (skip ? false : ((ptr) + (size)-1) > (buffer_end)) + (skip ? false : H5_IS_BUFFER_OVERFLOW(ptr, size, buffer_end)) /* * HDF Boolean type. @@ -450,8 +479,7 @@ (X) >= (Y)) #define H5_addr_cmp(X,Y) (H5_addr_eq((X), (Y)) ? 0 : \ (H5_addr_lt((X), (Y)) ? -1 : 1)) -#define H5_addr_overlap(O1,L1,O2,L2) (((O1) < (O2) && ((O1) + (L1)) > (O2)) || \ - ((O1) >= (O2) && (O1) < ((O2) + (L2)))) +#define H5_addr_overlap(O1,L1,O2,L2) H5_RANGE_OVERLAP(O1, ((O1)+(L1)-1), O2, ((O2)+(L2)-1)) /* clang-format on */ /* diff --git a/test/API/README.md b/test/API/README.md index 2f5a0650412..aa5884995e1 100644 --- a/test/API/README.md +++ b/test/API/README.md @@ -1,7 +1,7 @@ # HDF5 API Tests This directory contains several test applications that exercise HDF5's -public API and serve as regression tests for HDF5 [VOL Connectors](https://portal.hdfgroup.org/display/HDF5/Virtual+Object+Layer). +public API and serve as regression tests for HDF5 [VOL Connectors](https://docs.hdfgroup.org/hdf5/develop/_h5_v_l__u_g.html). ## Build Process and options diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index a9b935e80a8..687e72830d0 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -163,6 +163,8 @@ set (HDF5_REFERENCE_TEST_FILES test_filters_le.h5 th5s.h5 tlayouto.h5 + tmisc38a.h5 + tmisc38b.h5 tmtimen.h5 tmtimeo.h5 tsizeslheap.h5 diff --git a/test/CMakeVFDTests.cmake b/test/CMakeVFDTests.cmake index f2466ba40cf..a3b40a6107a 100644 --- a/test/CMakeVFDTests.cmake +++ b/test/CMakeVFDTests.cmake @@ -71,6 +71,9 @@ add_custom_target(HDF5_VFDTEST_LIB_files ALL COMMENT "Copying files needed by HD links_env external_env vds_env + mirror_vfd + ros3 + hdfs ) # Skip several tests with subfiling VFD, mostly due diff --git a/test/accum.c b/test/accum.c index 9876998d9b4..cabd4a84c7c 100644 --- a/test/accum.c +++ b/test/accum.c @@ -2049,17 +2049,16 @@ fprintf(stderr, "Random # seed was: %u\n", seed); unsigned test_swmr_write_big(bool newest_format) { - - hid_t fid = H5I_INVALID_HID; /* File ID */ - hid_t fapl = H5I_INVALID_HID; /* File access property list */ - H5F_t *rf = NULL; /* File pointer */ - char filename[1024]; - uint8_t *wbuf2 = NULL, *rbuf = NULL; /* Buffers for reading & writing */ - uint8_t wbuf[1024]; /* Buffer for reading & writing */ - unsigned u; /* Local index variable */ - bool process_success = false; - char *driver = NULL; /* VFD string (from env variable) */ - bool api_ctx_pushed = false; /* Whether API context pushed */ + const char *driver_name = NULL; /* VFD string (from env variable) */ + hid_t fid = H5I_INVALID_HID; /* File ID */ + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + H5F_t *rf = NULL; /* File pointer */ + char filename[1024]; + uint8_t *wbuf2 = NULL, *rbuf = NULL; /* Buffers for reading & writing */ + uint8_t wbuf[1024]; /* Buffer for reading & writing */ + unsigned u; /* Local index variable */ + bool process_success = false; + bool api_ctx_pushed = false; /* Whether API context pushed */ if (newest_format) TESTING("SWMR write of large metadata: with latest format"); @@ -2077,8 +2076,8 @@ test_swmr_write_big(bool newest_format) /* Skip this test if SWMR I/O is not supported for the VFD specified * by the environment variable. */ - driver = getenv(HDF5_DRIVER); - if (!H5FD__supports_swmr_test(driver)) { + driver_name = h5_get_test_driver_name(); + if (!H5FD__supports_swmr_test(driver_name)) { SKIPPED(); puts(" Test skipped due to VFD not supporting SWMR I/O."); return 0; diff --git a/test/accum_swmr_reader.c b/test/accum_swmr_reader.c index 5b3ecd8a7fc..a5b16eba860 100644 --- a/test/accum_swmr_reader.c +++ b/test/accum_swmr_reader.c @@ -40,15 +40,15 @@ static const char *FILENAME[] = {"accum", "accum_swmr_big", NULL}; int main(void) { - hid_t fid = H5I_INVALID_HID; /* File ID */ - hid_t fapl = H5I_INVALID_HID; /* file access property list ID */ - H5F_t *f = NULL; /* File pointer */ - char filename[1024]; - unsigned u; /* Local index variable */ - uint8_t rbuf[1024]; /* Buffer for reading */ - uint8_t buf[1024]; /* Buffer for holding the expected data */ - char *driver = NULL; /* VFD string (from env variable) */ - bool api_ctx_pushed = false; /* Whether API context pushed */ + const char *driver_name = NULL; /* VFD string (from env variable) */ + hid_t fid = H5I_INVALID_HID; /* File ID */ + hid_t fapl = H5I_INVALID_HID; /* file access property list ID */ + H5F_t *f = NULL; /* File pointer */ + char filename[1024]; + unsigned u; /* Local index variable */ + uint8_t rbuf[1024]; /* Buffer for reading */ + uint8_t buf[1024]; /* Buffer for holding the expected data */ + bool api_ctx_pushed = false; /* Whether API context pushed */ /* Testing setup */ h5_reset(); @@ -56,8 +56,8 @@ main(void) /* Skip this test if SWMR I/O is not supported for the VFD specified * by the environment variable. */ - driver = getenv(HDF5_DRIVER); - if (!H5FD__supports_swmr_test(driver)) + driver_name = h5_get_test_driver_name(); + if (!H5FD__supports_swmr_test(driver_name)) return EXIT_SUCCESS; /* Initialize buffers */ diff --git a/test/app_ref.c b/test/app_ref.c index 729862ee39f..1315f03c86b 100644 --- a/test/app_ref.c +++ b/test/app_ref.c @@ -79,7 +79,7 @@ Abrt_Handler(int H5_ATTR_UNUSED sig) int main(void) { - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ hid_t ids[T_NUMCLASSES]; hid_t fapl; /* File Access Property List */ int ninc; @@ -94,14 +94,12 @@ main(void) TESTING("library shutdown with reference count > 1"); /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Don't run this test with the multi/split VFD. A bug in library shutdown * ordering causes problems with the multi VFD when IDs are left dangling. */ - if (!strcmp(env_h5_drvr, "multi") || !strcmp(env_h5_drvr, "split")) { + if (!strcmp(driver_name, "multi") || !strcmp(driver_name, "split")) { puts("\n -- SKIPPED for incompatible VFD --"); return 0; } diff --git a/test/btree2.c b/test/btree2.c index 32700d64bd4..fc7748c7b27 100644 --- a/test/btree2.c +++ b/test/btree2.c @@ -8598,7 +8598,7 @@ gen_l4_btree2(const char *filename, hid_t fapl, const H5B2_create_t *cparam, had *------------------------------------------------------------------------- */ static unsigned -test_remove_lots(const char *env_h5_drvr, hid_t fapl, const H5B2_create_t *cparam) +test_remove_lots(const char *driver_name, hid_t fapl, const H5B2_create_t *cparam) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[1024]; /* Filename to use */ @@ -8656,7 +8656,7 @@ fprintf(stderr, "curr_time = %lu\n", (unsigned long)curr_time); TEST_ERROR; /* Check for VFD which stores data in multiple files */ - single_file_vfd = !h5_driver_uses_multiple_files(env_h5_drvr, H5_EXCLUDE_NON_MULTIPART_DRIVERS); + single_file_vfd = !h5_driver_uses_multiple_files(driver_name, H5_EXCLUDE_NON_MULTIPART_DRIVERS); if (single_file_vfd) { /* Make a copy of the file in memory, in order to speed up deletion testing */ @@ -9916,12 +9916,10 @@ main(void) unsigned nerrors = 0; /* Cumulative error count */ unsigned reopen; /* Whether to reopen B-tree during tests */ int ExpressMode; - const char *envval = NULL; + const char *driver_name; bool api_ctx_pushed = false; /* Whether API context pushed */ - envval = getenv(HDF5_DRIVER); - if (envval == NULL) - envval = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Reset library */ h5_reset(); @@ -9929,7 +9927,7 @@ main(void) ExpressMode = GetTestExpress(); /* For the Direct I/O driver, skip intensive tests due to poor performance */ - if (!strcmp(envval, "direct")) + if (!strcmp(driver_name, "direct")) ExpressMode = 2; if (ExpressMode > 1) @@ -10013,7 +10011,7 @@ main(void) if (ExpressMode > 1) printf("***Express test mode on. test_remove_lots skipped\n"); else - nerrors += test_remove_lots(envval, fapl, &cparam); + nerrors += test_remove_lots(driver_name, fapl, &cparam); /* Test more complex B-tree queries */ nerrors += test_find_neighbor(fapl, &cparam, &tparam); diff --git a/test/cache_image.c b/test/cache_image.c index 60e23984366..d2499631878 100644 --- a/test/cache_image.c +++ b/test/cache_image.c @@ -7752,15 +7752,13 @@ evict_on_close_test(bool H5_ATTR_PARALLEL_UNUSED single_file_vfd) int main(void) { - const char *env_h5_drvr; /* File driver value from environment */ + const char *driver_name; /* File driver value from environment */ bool single_file_vfd; /* Whether VFD used stores data in a single file */ unsigned nerrs = 0; int express_test; /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); H5open(); @@ -7772,7 +7770,7 @@ main(void) printf("=========================================\n"); /* Check for VFD which stores data in multiple files */ - single_file_vfd = !h5_driver_uses_multiple_files(env_h5_drvr, H5_EXCLUDE_NON_MULTIPART_DRIVERS); + single_file_vfd = !h5_driver_uses_multiple_files(driver_name, H5_EXCLUDE_NON_MULTIPART_DRIVERS); nerrs += check_cache_image_ctl_flow_1(single_file_vfd); nerrs += check_cache_image_ctl_flow_2(single_file_vfd); diff --git a/test/chunk_info.c b/test/chunk_info.c index 9533b2aacee..fba429f2b2b 100644 --- a/test/chunk_info.c +++ b/test/chunk_info.c @@ -120,14 +120,15 @@ static const char *FILENAME[] = {"tchunk_info_earliest", void reinit_vars(unsigned *read_flt_msk, haddr_t *addr, hsize_t *size); /* Helper function containing common code that verifies indexing type - and number of chunks */ -static int verify_idx_nchunks(hid_t dset, hid_t dspace, H5D_chunk_index_t exp_idx_type, + * and number of chunks + */ +static herr_t verify_idx_nchunks(hid_t dset, hid_t dspace, H5D_chunk_index_t exp_idx_type, hsize_t exp_num_chunks); -static int verify_get_chunk_info(hid_t dset, hid_t dspace, hsize_t chk_index, hsize_t exp_chk_size, +static herr_t verify_get_chunk_info(hid_t dset, hid_t dspace, hsize_t chk_index, hsize_t exp_chk_size, const hsize_t *exp_offset, unsigned exp_flt_msk); -static int verify_get_chunk_info_by_coord(hid_t dset, hsize_t *offset, hsize_t exp_chk_size, +static herr_t verify_get_chunk_info_by_coord(hid_t dset, hsize_t *offset, hsize_t exp_chk_size, unsigned exp_flt_msk); -static int verify_empty_chunk_info(hid_t dset, hsize_t *offset); +static herr_t verify_empty_chunk_info(hid_t dset, hsize_t *offset); static const char *index_type_str(H5D_chunk_index_t idx_type); /*------------------------------------------------------------------------- @@ -135,10 +136,7 @@ static const char *index_type_str(H5D_chunk_index_t idx_type); * * Purpose: Wipes out variables for the next use, used in various tests. * - * Return: Won't fail - * - * Date: September 2018 - * + * Return: void *------------------------------------------------------------------------- */ void @@ -158,14 +156,10 @@ reinit_vars(unsigned *read_flt_msk, haddr_t *addr, hsize_t *size) * Purpose: Verifies that H5Dget_chunk_info returns correct * values for a chunk. * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Date: August 2019 - * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ -static int +static herr_t verify_get_chunk_info(hid_t dset, hid_t dspace, hsize_t chk_index, hsize_t exp_chk_size, const hsize_t *exp_offset, unsigned exp_flt_msk) { @@ -200,14 +194,10 @@ verify_get_chunk_info(hid_t dset, hid_t dspace, hsize_t chk_index, hsize_t exp_c * Purpose: Verifies that H5Dget_chunk_info_by_coord returns correct * values for a chunk. * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Date: August 2019 - * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ -static int +static herr_t verify_get_chunk_info_by_coord(hid_t dset, hsize_t *offset, hsize_t exp_chk_size, unsigned exp_flt_msk) { uint32_t read_flt_msk = 0; /* Read filter mask */ @@ -237,14 +227,10 @@ verify_get_chunk_info_by_coord(hid_t dset, hsize_t *offset, hsize_t exp_chk_size * Purpose: Verifies that H5Dget_chunk_info_by_coord returns correct * values for an empty chunk. * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Date: August 2018 - * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ -static int +static herr_t verify_empty_chunk_info(hid_t dset, hsize_t *offset) { uint32_t read_flt_msk = 0; /* Read filter mask */ @@ -274,9 +260,6 @@ verify_empty_chunk_info(hid_t dset, hsize_t *offset) * * Return: Success: a valid indexing scheme string * Failure: a note indicating the indexing type is invalid - * - * Date: August 2019 - * *------------------------------------------------------------------------- */ static const char * @@ -297,7 +280,7 @@ index_type_str(H5D_chunk_index_t idx_type) return ("Version 1 B-tree index type (default)"); case H5D_CHUNK_IDX_NTYPES: default: - return ("invalid index type"); + return "invalid index type"; } } /* index_type_str */ @@ -307,14 +290,10 @@ index_type_str(H5D_chunk_index_t idx_type) * Purpose: Reads the chunks within the boundary {start,end} and verify * the values against the populated data. * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Date: August 2019 - * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ -static int +static herr_t verify_selected_chunks(hid_t dset, hid_t plist, const hsize_t *start, const hsize_t *end) { int read_buf[CHUNK_NX][CHUNK_NY]; @@ -328,14 +307,16 @@ verify_selected_chunks(hid_t dset, hid_t plist, const hsize_t *start, const hsiz memset(&read_buf, 0, sizeof(read_buf)); /* Initialize the array of chunk data for all NUM_CHUNKS chunks, this is - the same as the written data and will be used to verify the read data */ + * the same as the written data and will be used to verify the read data + */ for (n = 0; n < NUM_CHUNKS; n++) for (ii = 0; ii < CHUNK_NX; ii++) for (jj = 0; jj < CHUNK_NY; jj++) expected_buf[n][ii][jj] = (int)(ii * jj) + 1; /* Read each chunk within the boundary of {start,end} and verify the - values against the expected data */ + * values against the expected data + */ chk_index = 0; for (ii = start[0]; ii < end[0]; ii++) for (jj = start[1]; jj < end[1]; jj++, chk_index++) { @@ -369,14 +350,10 @@ verify_selected_chunks(hid_t dset, hid_t plist, const hsize_t *start, const hsiz * a subset of chunks. This function opens the dataset then * closes it after writing. * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Date: August 2019 - * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ -static int +static herr_t write_selected_chunks(hid_t dset, hid_t plist, const hsize_t *start, const hsize_t *end, unsigned flt_msk) { int direct_buf[NUM_CHUNKS][CHUNK_NX][CHUNK_NY]; /* Data in chunks */ @@ -392,7 +369,8 @@ write_selected_chunks(hid_t dset, hid_t plist, const hsize_t *start, const hsize direct_buf[n][ii][jj] = (int)(ii * jj) + 1; /* Write NUM_CHUNKS_WRITTEN chunks at the following logical coords: - (0,2) (0,3) (1,2) (1,3) */ + * (0,2) (0,3) (1,2) (1,3) + */ chk_index = 0; for (ii = start[0]; ii < end[0]; ii++) for (jj = start[1]; jj < end[1]; jj++, chk_index++) { @@ -414,14 +392,10 @@ write_selected_chunks(hid_t dset, hid_t plist, const hsize_t *start, const hsize * Purpose: Verifies that chunk indexing scheme and number of chunks of * the dataset match the expected values. * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Date: August 2019 - * + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ -static int +static herr_t verify_idx_nchunks(hid_t dset, hid_t dspace, H5D_chunk_index_t exp_idx_type, hsize_t exp_num_chunks) { H5D_chunk_index_t idx_type; /* Dataset chunk index type */ @@ -461,8 +435,7 @@ verify_idx_nchunks(hid_t dset, hid_t dspace, H5D_chunk_index_t exp_idx_type, hsi * * Purpose: Test getting various chunk information * - * Return: Success: SUCCEED - * Failure: FAIL + * Return: # of errors * * Note: Note that the dataspace argument in these new functions is * currently not used. The functionality involved the dataspace @@ -472,12 +445,9 @@ verify_idx_nchunks(hid_t dset, hid_t dspace, H5D_chunk_index_t exp_idx_type, hsi * This function tests the new API functions added for EED-343: * H5Dget_num_chunks, H5Dget_chunk_info, and * H5Dget_chunk_info_by_coord for high bound up to 1.8. - * - * Date: September 2018 - * *------------------------------------------------------------------------- */ -static herr_t +static int test_get_chunk_info_highest_v18(hid_t fapl) { char filename[FILENAME_BUF_SIZE]; /* File name */ @@ -517,7 +487,8 @@ test_get_chunk_info_highest_v18(hid_t fapl) h5_fixname(FILENAME[H5F_LIBVER_V18], fapl, filename, sizeof filename); /* Set version bounds for creating the file. High bound to V18 to test - chunked dataset that use B-tree v1 structures to index chunks. */ + * chunked dataset that use B-tree v1 structures to index chunks. + */ if (H5Pset_libver_bounds(fapl, H5F_LIBVER_EARLIEST, H5F_LIBVER_V18) < 0) TEST_ERROR; @@ -589,7 +560,8 @@ test_get_chunk_info_highest_v18(hid_t fapl) #endif /* end H5_HAVE_FILTER_DEFLATE */ /* Write only NUM_CHUNKS_WRITTEN chunks at the following logical coords: - (0,2) (0,3) (1,2) (1,3) */ + * (0,2) (0,3) (1,2) (1,3) + */ n = 0; for (ii = START_CHK_X; ii < END_CHK_X; ii++) for (jj = START_CHK_Y; jj < END_CHK_Y; jj++, n++) { @@ -622,7 +594,8 @@ test_get_chunk_info_highest_v18(hid_t fapl) FAIL_PUTS_ERROR("unexpected number of chunks"); /* Get and verify info of the last written chunk again, passing in H5S_ALL - this time */ + * this time + */ offset[0] = 6; offset[1] = 12; if (verify_get_chunk_info(dset, H5S_ALL, NUM_CHUNKS_WRITTEN - 1, chunk_size, offset, flt_msk) == FAIL) @@ -696,7 +669,8 @@ test_get_chunk_info_highest_v18(hid_t fapl) FAIL_PUTS_ERROR(" Attempt to get info of a non-existing chunk."); /* Attempt to get info of a chunk given its coords from an empty dataset, - should succeed with the returned address as HADDR_UNDEF and size as 0 */ + * should succeed with the returned address as HADDR_UNDEF and size as 0 + */ offset[0] = EMPTY_CHK_X; offset[1] = EMPTY_CHK_Y; if (verify_empty_chunk_info(dset, offset) == FAIL) @@ -710,7 +684,8 @@ test_get_chunk_info_highest_v18(hid_t fapl) ************************************************************************/ /* Set space allocation to early so that chunk query functions will - retrieve chunk information even though the dataset is empty */ + * retrieve chunk information even though the dataset is empty + */ if (H5Pset_alloc_time(cparms, H5D_ALLOC_TIME_EARLY) < 0) TEST_ERROR; @@ -733,7 +708,8 @@ test_get_chunk_info_highest_v18(hid_t fapl) TEST_ERROR; /* Attempt to get info of a chunk from an empty dataset, verify the - returned address and size in the case of H5D_ALLOC_TIME_EARLY */ + * returned address and size in the case of H5D_ALLOC_TIME_EARLY + */ chk_index = NONEXIST_CHK_INDEX; reinit_vars(&read_flt_msk, &addr, &size); ret = H5Dget_chunk_info(dset, dspace, chk_index, out_offset, &read_flt_msk, &addr, &size); @@ -758,7 +734,8 @@ test_get_chunk_info_highest_v18(hid_t fapl) TEST_ERROR; /* Attempt to get info of a chunk given its coords from an empty dataset, - verify the returned address and size */ + * verify the returned address and size + */ offset[0] = 0; offset[1] = 0; if (H5Dget_chunk_info_by_coord(dset, offset, &read_flt_msk, &addr, &size) < 0) @@ -781,7 +758,7 @@ test_get_chunk_info_highest_v18(hid_t fapl) TEST_ERROR; PASSED(); - return SUCCEED; + return 0; error: H5E_BEGIN_TRY @@ -793,8 +770,7 @@ test_get_chunk_info_highest_v18(hid_t fapl) } H5E_END_TRY - H5_FAILED(); - return FAIL; + return 1; } /* test_get_chunk_info_highest_v18() */ /*------------------------------------------------------------------------- @@ -803,18 +779,14 @@ test_get_chunk_info_highest_v18(hid_t fapl) * Purpose: Test getting various chunk information when Single Chunk * index type is used * - * Return: Success: SUCCEED - * Failure: FAIL + * Return: # of errors * * Note: Note that the dataspace argument in these new functions are * currently not used. The functionality involved the dataspace * will be implemented in the next version. - * - * Date: November 2018 - * *------------------------------------------------------------------------- */ -static herr_t +static int test_chunk_info_single_chunk(const char *filename, hid_t fapl) { hid_t chunkfile = H5I_INVALID_HID; /* File ID */ @@ -863,8 +835,7 @@ test_chunk_info_single_chunk(const char *filename, hid_t fapl) if (H5Dclose(dset) < 0) TEST_ERROR; - /* ...open it again to test the chunk query functions on a single empty - chunk */ + /* ...open it again to test the chunk query functions on a single empty chunk */ if ((dset = H5Dopen2(chunkfile, SINGLE_CHUNK_DSET_NAME, H5P_DEFAULT)) < 0) TEST_ERROR; @@ -908,7 +879,8 @@ test_chunk_info_single_chunk(const char *filename, hid_t fapl) FAIL_PUTS_ERROR("Verification of H5Dget_chunk_info_by_coord failed\n"); /* Attempt to get chunk info given an invalid chunk index and verify - * that failure occurs */ + * that failure occurs + */ chk_index = INVALID_CHK_INDEX; reinit_vars(&read_flt_msk, &addr, &size); H5E_BEGIN_TRY @@ -928,7 +900,7 @@ test_chunk_info_single_chunk(const char *filename, hid_t fapl) TEST_ERROR; PASSED(); - return SUCCEED; + return 0; error: H5E_BEGIN_TRY @@ -940,8 +912,7 @@ test_chunk_info_single_chunk(const char *filename, hid_t fapl) } H5E_END_TRY - H5_FAILED(); - return FAIL; + return 1; } /* test_chunk_info_single_chunk() */ /*------------------------------------------------------------------------- @@ -950,18 +921,14 @@ test_chunk_info_single_chunk(const char *filename, hid_t fapl) * Purpose: Test getting various chunk information when Implicit * index type is used * - * Return: Success: SUCCEED - * Failure: FAIL + * Return: # of errors * * Note: Note that the dataspace argument in these new functions are * currently not used. The functionality involved the dataspace * will be implemented in the next version. - * - * Date: November 2018 - * *------------------------------------------------------------------------- */ -static herr_t +static int test_chunk_info_implicit(char *filename, hid_t fapl) { hid_t chunkfile = H5I_INVALID_HID; /* File ID */ @@ -1016,7 +983,8 @@ test_chunk_info_implicit(char *filename, hid_t fapl) FAIL_PUTS_ERROR("Verification and write failed\n"); /* Write NUM_CHUNKS_WRITTEN chunks at the following logical coords: - (0,2) (0,3) (1,2) (1,3) */ + * (0,2) (0,3) (1,2) (1,3) + */ if (write_selected_chunks(dset, H5P_DEFAULT, start, end, flt_msk) == FAIL) FAIL_PUTS_ERROR("Writing to selected chunks failed\n"); @@ -1030,8 +998,9 @@ test_chunk_info_implicit(char *filename, hid_t fapl) FAIL_PUTS_ERROR("Verification of H5Dget_chunk_info failed\n"); /* Get info of a chunk and verify its information. Note that - all chunks in this dataset are allocated because of the property - H5D_ALLOC_TIME_EARLY */ + * all chunks in this dataset are allocated because of the property + * H5D_ALLOC_TIME_EARLY + */ if (verify_get_chunk_info_by_coord(dset, offset, CHK_SIZE, flt_msk) == FAIL) FAIL_PUTS_ERROR("Verification of H5Dget_chunk_info_by_coord failed\n"); } @@ -1047,7 +1016,7 @@ test_chunk_info_implicit(char *filename, hid_t fapl) TEST_ERROR; PASSED(); - return SUCCEED; + return 0; error: H5E_BEGIN_TRY @@ -1059,8 +1028,7 @@ test_chunk_info_implicit(char *filename, hid_t fapl) } H5E_END_TRY - H5_FAILED(); - return FAIL; + return 1; } /* test_chunk_info_implicit() */ /*------------------------------------------------------------------------- @@ -1069,18 +1037,14 @@ test_chunk_info_implicit(char *filename, hid_t fapl) * Purpose: Test getting various chunk information when Fixed Array * index type is used * - * Return: Success: SUCCEED - * Failure: FAIL + * Return: # of errors * * Note: Note that the dataspace argument in these new functions are * currently not used. The functionality involved the dataspace * will be implemented in the next version. - * - * Date: November 2018 - * *------------------------------------------------------------------------- */ -static herr_t +static int test_chunk_info_fixed_array(const char *filename, hid_t fapl) { hid_t chunkfile = H5I_INVALID_HID; /* File ID */ @@ -1138,7 +1102,8 @@ test_chunk_info_fixed_array(const char *filename, hid_t fapl) FAIL_PUTS_ERROR("Verification and write failed\n"); /* Write NUM_CHUNKS_WRITTEN chunks at the following logical coords: - (0,2) (0,3) (1,2) (1,3) */ + * (0,2) (0,3) (1,2) (1,3) + */ if (write_selected_chunks(dset, H5P_DEFAULT, start, end, flt_msk) == FAIL) FAIL_PUTS_ERROR("Writing to selected chunks failed\n"); @@ -1180,17 +1145,18 @@ test_chunk_info_fixed_array(const char *filename, hid_t fapl) /* Read and verify values of selected chunks */ if (verify_selected_chunks(dset, H5P_DEFAULT, start, end) < 0) + FAIL_PUTS_ERROR("Verification of H5Dget_chunk_info_by_coord on selected chunks failed\n"); - /* Release resource */ - if (H5Dclose(dset) < 0) - TEST_ERROR; + /* Release resource */ + if (H5Dclose(dset) < 0) + TEST_ERROR; if (H5Sclose(dspace) < 0) TEST_ERROR; if (H5Fclose(chunkfile) < 0) TEST_ERROR; PASSED(); - return SUCCEED; + return 0; error: H5E_BEGIN_TRY @@ -1202,8 +1168,7 @@ test_chunk_info_fixed_array(const char *filename, hid_t fapl) } H5E_END_TRY - H5_FAILED(); - return FAIL; + return 1; } /* test_chunk_info_fixed_array() */ /*------------------------------------------------------------------------- @@ -1212,18 +1177,14 @@ test_chunk_info_fixed_array(const char *filename, hid_t fapl) * Purpose: Test getting various chunk information when Extensible Array * index type is used * - * Return: Success: SUCCEED - * Failure: FAIL + * Return: # of errors * * Note: Note that the dataspace argument in these new functions are * currently not used. The functionality involved the dataspace * will be implemented in the next version. - * - * Date: November 2018 - * *------------------------------------------------------------------------- */ -static herr_t +static int test_chunk_info_extensible_array(const char *filename, hid_t fapl) { hid_t chunkfile = H5I_INVALID_HID; /* File ID */ @@ -1282,7 +1243,8 @@ test_chunk_info_extensible_array(const char *filename, hid_t fapl) FAIL_PUTS_ERROR("Verification and write failed\n"); /* Write NUM_CHUNKS_WRITTEN chunks at the following logical coords: - (0,2) (0,3) (1,2) (1,3) */ + * (0,2) (0,3) (1,2) (1,3) + */ if (write_selected_chunks(dset, H5P_DEFAULT, start, end, flt_msk) == FAIL) FAIL_PUTS_ERROR("Writing to selected chunks failed\n"); @@ -1339,7 +1301,7 @@ test_chunk_info_extensible_array(const char *filename, hid_t fapl) TEST_ERROR; PASSED(); - return SUCCEED; + return 0; error: H5E_BEGIN_TRY @@ -1351,8 +1313,7 @@ test_chunk_info_extensible_array(const char *filename, hid_t fapl) } H5E_END_TRY - H5_FAILED(); - return FAIL; + return 1; } /* test_chunk_info_extensible_array() */ /*------------------------------------------------------------------------- @@ -1361,18 +1322,14 @@ test_chunk_info_extensible_array(const char *filename, hid_t fapl) * Purpose: Test getting various chunk information when Version 2 B-trees * index type is used * - * Return: Success: SUCCEED - * Failure: FAIL + * Return: # of errors * * Note: Note that the dataspace argument in these new functions are * currently not used. The functionality involved the dataspace * will be implemented in the next version. - * - * Date: November 2018 - * *------------------------------------------------------------------------- */ -static herr_t +static int test_chunk_info_version2_btrees(const char *filename, hid_t fapl) { hid_t chunkfile = H5I_INVALID_HID; /* File ID */ @@ -1431,7 +1388,8 @@ test_chunk_info_version2_btrees(const char *filename, hid_t fapl) FAIL_PUTS_ERROR("Verification and write failed\n"); /* Write NUM_CHUNKS_WRITTEN chunks at the following logical coords: - (0,2) (0,3) (1,2) (1,3) */ + * (0,2) (0,3) (1,2) (1,3) + */ if (write_selected_chunks(dset, H5P_DEFAULT, start, end, flt_msk) == FAIL) FAIL_PUTS_ERROR("Writing to selected chunks failed\n"); @@ -1488,7 +1446,7 @@ test_chunk_info_version2_btrees(const char *filename, hid_t fapl) TEST_ERROR; PASSED(); - return SUCCEED; + return 0; error: H5E_BEGIN_TRY @@ -1500,8 +1458,7 @@ test_chunk_info_version2_btrees(const char *filename, hid_t fapl) } H5E_END_TRY - H5_FAILED(); - return FAIL; + return 1; } /* test_chunk_info_version2_btrees() */ typedef struct chunk_iter_info_t { @@ -1557,18 +1514,14 @@ iter_cb_fail(const hsize_t H5_ATTR_UNUSED *offset, unsigned H5_ATTR_UNUSED filte * Purpose: Tests basic operations to ensure the chunk query functions * work properly. * - * Return: Success: SUCCEED - * Failure: FAIL + * Return: # of errors * * Note: Note that the dataspace argument in these new functions are * currently not used. The functionality involved the dataspace * will be implemented in the next version. - * - * Date: August 2019 - * *------------------------------------------------------------------------- */ -static herr_t +static int test_basic_query(hid_t fapl) { char filename[FILENAME_BUF_SIZE]; /* File name */ @@ -1757,7 +1710,7 @@ test_basic_query(hid_t fapl) HDremove(filename); PASSED(); - return SUCCEED; + return 0; error: H5E_BEGIN_TRY @@ -1769,8 +1722,7 @@ test_basic_query(hid_t fapl) } H5E_END_TRY - H5_FAILED(); - return FAIL; + return 1; } /* test_basic_query() */ /*------------------------------------------------------------------------- @@ -1778,18 +1730,14 @@ test_basic_query(hid_t fapl) * * Purpose: Test attempting to use chunk query functions incorrectly. * - * Return: Success: SUCCEED - * Failure: FAIL + * Return: # of errors * * Note: Note that the dataspace argument in these new functions are * currently not used. The functionality involved the dataspace * will be implemented in the next version. - * - * Date: August 2019 - * *------------------------------------------------------------------------- */ -static herr_t +static int test_failed_attempts(const char *filename, hid_t fapl) { hid_t chunkfile = H5I_INVALID_HID; /* File ID */ @@ -1881,7 +1829,7 @@ test_failed_attempts(const char *filename, hid_t fapl) TEST_ERROR; PASSED(); - return SUCCEED; + return 0; error: H5E_BEGIN_TRY @@ -1892,8 +1840,7 @@ test_failed_attempts(const char *filename, hid_t fapl) } H5E_END_TRY - H5_FAILED(); - return FAIL; + return 1; } /* test_failed_attempts() */ /*------------------------------------------------------------------------- @@ -1901,8 +1848,7 @@ test_failed_attempts(const char *filename, hid_t fapl) * * Purpose: Test getting various chunk information in version 1.10. * - * Return: Success: SUCCEED - * Failure: FAIL + * Return: # of errors * * Note: Note that the dataspace argument in these new functions are * currently not used. The functionality involved the dataspace @@ -1912,12 +1858,9 @@ test_failed_attempts(const char *filename, hid_t fapl) * This function tests the new API functions added for HDFFV-10677: * H5Dget_num_chunks, H5Dget_chunk_info, and * H5Dget_chunk_info_by_coord for low bound beyond 1.8. - * - * Date: October 2018 - * *------------------------------------------------------------------------- */ -static herr_t +static int test_get_chunk_info_v110(hid_t fapl) { char filename[FILENAME_BUF_SIZE]; /* File name */ @@ -1973,26 +1916,21 @@ test_get_chunk_info_v110(hid_t fapl) } /* for low libver bound */ - return SUCCEED; + return 0; error: - H5_FAILED(); - return FAIL; + return 1; } /* test_get_chunk_info_v110() */ /*------------------------------------------------------------------------- * Function: test_flt_msk_with_skip_compress * - * Purpose: Test getting chunk info when compression filter is skipped. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Date: August 2019 (based on direct_chunk.c/test_skip_compress_write1) + * Purpose: Test getting chunk info when compression filter is skipped * + * Return: # of errors *------------------------------------------------------------------------- */ -static herr_t +static int test_flt_msk_with_skip_compress(hid_t fapl) { char filename[FILENAME_BUF_SIZE]; /* File name */ @@ -2166,7 +2104,7 @@ test_flt_msk_with_skip_compress(hid_t fapl) HDremove(filename); PASSED(); - return SUCCEED; + return 0; error: H5E_BEGIN_TRY @@ -2180,17 +2118,325 @@ test_flt_msk_with_skip_compress(hid_t fapl) } H5E_END_TRY - H5_FAILED(); - return FAIL; + return 1; } /* test_flt_msk_with_skip_compress() */ +#define UBLOCK_FILE_NAME "file_with_userblock.h5" +#define NO_UBLOCK_FILE_NAME "file_without_userblock.h5" +#define UBLOCK_DSET_NAME "ublock_dset" +#define UBLOCK_SIZE 2048 + +/* Helper function to create userblock files and datasets */ +static herr_t +create_userblock_file(const char *filename, hid_t fcpl_id, hid_t fapl_id) +{ + hid_t fid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t dcpl_id = H5I_INVALID_HID; + + /* The chunk size is set to 1 so we get a lot of chunks without + * writing a lot of data. + */ + int rank = 1; + hsize_t dims = {256}; + hsize_t chunk_dims = {1}; + + int *data = NULL; + + /* Create a new file */ + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) + TEST_ERROR; + + /* Create file data space for the dataset */ + if ((sid = H5Screate_simple(rank, &dims, &dims)) < 0) + TEST_ERROR; + + /* Create dataset create property list with chunking */ + if ((dcpl_id = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR; + if (H5Pset_chunk(dcpl_id, rank, &chunk_dims) < 0) + TEST_ERROR; + + /* Create a new dataset */ + if ((did = H5Dcreate2(fid, UBLOCK_DSET_NAME, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl_id, H5P_DEFAULT)) < 0) + TEST_ERROR; + + /* Create some arbitrary data */ + if (NULL == (data = (int *)malloc(256 * sizeof(int)))) + TEST_ERROR; + for (int i = 0; i < 256; i++) + data[i] = i; + + /* Write the data to the dataset */ + if (H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data) < 0) + TEST_ERROR; + + /* Close everything */ + if (H5Pclose(dcpl_id) < 0) + TEST_ERROR; + if (H5Dclose(did) < 0) + TEST_ERROR; + if (H5Sclose(sid) < 0) + TEST_ERROR; + if (H5Fclose(fid) < 0) + TEST_ERROR; + + free(data); + + return SUCCEED; +error: + H5E_BEGIN_TRY + { + H5Pclose(dcpl_id); + H5Dclose(did); + H5Sclose(sid); + H5Fclose(fid); + } + H5E_END_TRY + + free(data); + + return FAIL; +} + +/* op_data for the userblock iterator */ +struct ub_op_data { + haddr_t *addresses; + hsize_t i; + hsize_t max; +}; + +/* Callback function for iterating over dataset chunks is files both with + * and without a userblock + */ +static int +ublock_iter_cb(const hsize_t H5_ATTR_UNUSED *offset, unsigned H5_ATTR_UNUSED filter_mask, haddr_t addr, + hsize_t H5_ATTR_UNUSED size, void *op_data) +{ + struct ub_op_data *od = (struct ub_op_data *)op_data; + + /* Error if we try to iterate over too many chunks */ + if (od->i == od->max) + return H5_ITER_ERROR; + + /* Store the address for later comparison */ + od->addresses[od->i] = addr; + od->i += 1; + + return H5_ITER_CONT; +} + +/*------------------------------------------------------------------------- + * Function: test_chunk_address_with_userblock + * + * Purpose: Test that chunk addresses are correct when a file has + * a userblock + * + * Return: # of errors + *------------------------------------------------------------------------- + */ +static int +test_chunk_address_with_userblock(hid_t fapl_id) +{ + hid_t fid = H5I_INVALID_HID; + hid_t fid_ub = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t did_ub = H5I_INVALID_HID; + hid_t fcpl_id = H5I_INVALID_HID; + + hsize_t num_chunks = HSIZE_UNDEF; + hsize_t num_chunks_ub = 0; + + haddr_t *addresses = NULL; + haddr_t *addresses_ub = NULL; + + struct ub_op_data od; + struct ub_op_data od_ub; + + int fd = -1; + int fd_ub = -1; + + bool default_vfd_compatible; + + TESTING("if chunk addresses are correct when a file has a userblock"); + + if (h5_driver_is_default_vfd_compatible(fapl_id, &default_vfd_compatible) < 0) + TEST_ERROR; + if (!default_vfd_compatible) { + puts(" -- SKIPPED for incompatible VFD --"); + return 0; + } + + /* Create files with and without a userblock */ + if (create_userblock_file(NO_UBLOCK_FILE_NAME, H5P_DEFAULT, fapl_id) < 0) + TEST_ERROR; + + if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) == H5I_INVALID_HID) + TEST_ERROR; + if (H5Pset_userblock(fcpl_id, UBLOCK_SIZE) < 0) + TEST_ERROR; + + if (create_userblock_file(UBLOCK_FILE_NAME, fcpl_id, fapl_id) < 0) + TEST_ERROR; + + /* Open both files and datasets */ + if ((fid = H5Fopen(NO_UBLOCK_FILE_NAME, H5F_ACC_RDONLY, fapl_id)) == H5I_INVALID_HID) + TEST_ERROR; + if ((did = H5Dopen2(fid, UBLOCK_DSET_NAME, H5P_DEFAULT)) == H5I_INVALID_HID) + TEST_ERROR; + if ((fid_ub = H5Fopen(UBLOCK_FILE_NAME, H5F_ACC_RDONLY, fapl_id)) == H5I_INVALID_HID) + TEST_ERROR; + if ((did_ub = H5Dopen2(fid_ub, UBLOCK_DSET_NAME, H5P_DEFAULT)) == H5I_INVALID_HID) + TEST_ERROR; + + /* Get the number of chunks */ + if (H5Dget_num_chunks(did, H5S_ALL, &num_chunks) < 0) + TEST_ERROR; + if (H5Dget_num_chunks(did_ub, H5S_ALL, &num_chunks_ub) < 0) + TEST_ERROR; + + if (num_chunks != num_chunks_ub) + TEST_ERROR; + + /* Check the chunk information to make sure that the userblock file takes + * the block's size into account. + */ + for (hsize_t i = 0; i < num_chunks; i++) { + haddr_t addr = HADDR_UNDEF; + haddr_t addr_ub = 0; + + /* H5Dget_chunk_info() */ + if (H5Dget_chunk_info(did, H5S_ALL, i, NULL, NULL, &addr, NULL) < 0) + TEST_ERROR; + if (H5Dget_chunk_info(did_ub, H5S_ALL, i, NULL, NULL, &addr_ub, NULL) < 0) + TEST_ERROR; + + if (addr + UBLOCK_SIZE != addr_ub) + TEST_ERROR; + + addr = HADDR_UNDEF; + addr_ub = 0; + + /* H5Dget_chunk_info_by_coord() */ + if (H5Dget_chunk_info_by_coord(did, &i, NULL, &addr, NULL) < 0) + TEST_ERROR; + if (H5Dget_chunk_info_by_coord(did_ub, &i, NULL, &addr_ub, NULL) < 0) + TEST_ERROR; + + if (addr + UBLOCK_SIZE != addr_ub) + TEST_ERROR; + } + + /* Allocate arrays to hold the chunk addresses */ + if (NULL == (addresses = (haddr_t *)calloc(num_chunks, sizeof(haddr_t)))) + TEST_ERROR; + if (NULL == (addresses_ub = (haddr_t *)calloc(num_chunks, sizeof(haddr_t)))) + TEST_ERROR; + + od.addresses = addresses; + od.i = 0; + od.max = num_chunks; + + od_ub.addresses = addresses_ub; + od_ub.i = 0; + od_ub.max = num_chunks; + + /* Iterate over the chunks, storing the chunk addresses */ + if (H5Dchunk_iter(did, H5P_DEFAULT, ublock_iter_cb, &od) < 0) + TEST_ERROR; + if (H5Dchunk_iter(did_ub, H5P_DEFAULT, ublock_iter_cb, &od_ub) < 0) + TEST_ERROR; + + /* Compare the chunk addresses to ensure the userblock file takes the + * chunk's size into account. + */ + if (od.i != od_ub.i) + TEST_ERROR; + for (hsize_t i = 0; i < num_chunks; i++) + if (od.addresses[i] + UBLOCK_SIZE != od_ub.addresses[i]) + TEST_ERROR; + + /* Compare the raw chunk data */ + if ((fd = HDopen(NO_UBLOCK_FILE_NAME, O_RDONLY)) < 0) + TEST_ERROR; + if ((fd_ub = HDopen(UBLOCK_FILE_NAME, O_RDONLY)) < 0) + TEST_ERROR; + + for (hsize_t i = 0; i < num_chunks; i++) { + int data = -1; + int data_ub = -1; + + if (HDlseek(fd, (off_t)(od.addresses[i]), SEEK_SET) < 0) + TEST_ERROR; + if (HDlseek(fd_ub, (off_t)(od_ub.addresses[i]), SEEK_SET) < 0) + TEST_ERROR; + + if (HDread(fd, &data, sizeof(int)) != sizeof(int)) + TEST_ERROR; + if (HDread(fd_ub, &data_ub, sizeof(int)) != sizeof(int)) + TEST_ERROR; + + if (data != data_ub) + TEST_ERROR; + } + + HDclose(fd); + fd = -1; + HDclose(fd_ub); + fd_ub = -1; + + /* Close everything */ + if (H5Pclose(fcpl_id) < 0) + TEST_ERROR; + if (H5Dclose(did) < 0) + TEST_ERROR; + if (H5Dclose(did_ub) < 0) + TEST_ERROR; + if (H5Fclose(fid) < 0) + TEST_ERROR; + if (H5Fclose(fid_ub) < 0) + TEST_ERROR; + + free(addresses); + free(addresses_ub); + + if (H5Fdelete(UBLOCK_FILE_NAME, fapl_id) < 0) + TEST_ERROR; + if (H5Fdelete(NO_UBLOCK_FILE_NAME, fapl_id) < 0) + TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fcpl_id); + H5Dclose(did); + H5Dclose(did_ub); + H5Fclose(fid); + H5Fclose(fid_ub); + } + H5E_END_TRY + + if (fd >= 0) + HDclose(fd); + if (fd_ub >= 0) + HDclose(fd_ub); + + free(addresses); + free(addresses_ub); + + return 1; +} /* test_chunk_address_with_userblock() */ + /*------------------------------------------------------------------------- * Function: main * * Purpose: Tests functions related to chunk information * * Return: EXIT_SUCCESS/EXIT_FAILURE - * *------------------------------------------------------------------------- */ int @@ -2203,19 +2449,22 @@ main(void) /* Create a copy of file access property list */ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) - TEST_ERROR; + goto error; /* Test basic operations on the chunk query functions */ - nerrors += test_basic_query(fapl) < 0 ? 1 : 0; + nerrors += test_basic_query(fapl); /* Tests getting chunk information of version 1.8 and prior */ - nerrors += test_get_chunk_info_highest_v18(fapl) < 0 ? 1 : 0; + nerrors += test_get_chunk_info_highest_v18(fapl); /* Tests getting chunk information of version 1.10 */ - nerrors += test_get_chunk_info_v110(fapl) < 0 ? 1 : 0; + nerrors += test_get_chunk_info_v110(fapl); /* Tests getting filter mask when compression filter is skipped */ - nerrors += test_flt_msk_with_skip_compress(fapl) < 0 ? 1 : 0; + nerrors += test_flt_msk_with_skip_compress(fapl); + + /* Test that chunk addresses are correct when files have a userblock */ + nerrors += test_chunk_address_with_userblock(fapl); if (nerrors) goto error; @@ -2227,14 +2476,13 @@ main(void) return EXIT_SUCCESS; error: + H5E_BEGIN_TRY + { + H5Pclose(fapl); + } + H5E_END_TRY + nerrors = MAX(1, nerrors); printf("***** %d QUERY CHUNK INFO TEST%s FAILED! *****\n", nerrors, 1 == nerrors ? "" : "S"); return EXIT_FAILURE; } - -/**************************************************************************** - Additional tests to be added: -- do the query when extending the dataset (shrink or expand) -- verify that invalid input parameters are handled properly - -****************************************************************************/ diff --git a/test/cmpd_dtransform.c b/test/cmpd_dtransform.c index 8fd3788a9ab..be05b008969 100644 --- a/test/cmpd_dtransform.c +++ b/test/cmpd_dtransform.c @@ -30,7 +30,8 @@ main(void) { hsize_t dima[] = {1}; hsize_t dims[] = {LENGTH}; - hid_t str_dtyp_id = H5I_INVALID_HID, att_dtyp_id = H5I_INVALID_HID; + hid_t str_dtyp_id = H5I_INVALID_HID; + hid_t att_dtyp_id = H5I_INVALID_HID; hid_t file_id = H5I_INVALID_HID; hid_t fspace_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; @@ -43,54 +44,58 @@ main(void) att_t *atts = NULL; att_t *atts_res = NULL; + printf("Testing writing compound attributes followed by data w/ transform.\n"); + + TESTING("data types are reset properly"); + /* Compound datatype */ - if (NULL == (atts = malloc(sizeof(att_t)))) + if (NULL == (atts = (att_t *)calloc(1, sizeof(att_t)))) TEST_ERROR; strcpy(atts[0].name, "Name"); strcpy(atts[0].unit, "Unit"); /* String type */ if ((str_dtyp_id = H5Tcopy(H5T_C_S1)) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Tset_size(str_dtyp_id, 64) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; /* Attribute type */ if ((att_dtyp_id = H5Tcreate(H5T_COMPOUND, sizeof(att_t))) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Tinsert(att_dtyp_id, "NAME", HOFFSET(att_t, name), str_dtyp_id) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Tinsert(att_dtyp_id, "UNIT", HOFFSET(att_t, unit), str_dtyp_id) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; /* Create file. */ if ((file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; /* Create file dataspace. */ if ((fspace_id = H5Screate_simple(1, dims, NULL)) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; /* Create dataset. */ if ((dset_id = H5Dcreate2(file_id, "test_dset", H5T_NATIVE_INT, fspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; /* Write the attribute (compound) to the dataset */ if ((att_dspc_id = H5Screate_simple(1, dima, NULL)) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if ((att_attr_id = H5Acreate2(dset_id, "ATTRIBUTES", att_dtyp_id, att_dspc_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Awrite(att_attr_id, att_dtyp_id, atts) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; /* Create dataset transfer property list */ if ((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Pset_data_transform(dxpl_id, expr) < 0) { printf("**** ERROR: H5Pset_data_transform (expression: %s) ****\n", expr); - FAIL_STACK_ERROR; + TEST_ERROR; } if (NULL == (data = malloc(LENGTH * sizeof(int)))) @@ -104,13 +109,13 @@ main(void) /* Write the data */ if (H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl_id, data) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; /* Read attribute */ if (NULL == (atts_res = malloc(sizeof(att_t)))) TEST_ERROR; if (H5Aread(att_attr_id, att_dtyp_id, atts_res) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; /* Verify attribute */ if (strcmp(atts_res[0].name, atts[0].name) != 0) @@ -120,37 +125,40 @@ main(void) /* Read the data */ if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; /* Verify data */ for (unsigned idx = 0; idx < LENGTH; idx++) if (data[idx] != data_res[idx]) TEST_ERROR; - free(atts); - free(atts_res); - free(data); - free(data_res); - /* Close all identifiers. */ if (H5Pclose(dxpl_id) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Aclose(att_attr_id) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Sclose(att_dspc_id) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Dclose(dset_id) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Sclose(fspace_id) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Fclose(file_id) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Tclose(att_dtyp_id) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; if (H5Tclose(str_dtyp_id) < 0) - FAIL_STACK_ERROR; + TEST_ERROR; - return 0; + free(atts); + free(atts_res); + free(data); + free(data_res); + + HDremove(FILENAME); + + PASSED(); + return EXIT_SUCCESS; error: H5E_BEGIN_TRY @@ -166,14 +174,10 @@ main(void) } H5E_END_TRY - if (atts) - free(atts); - if (atts_res) - free(atts_res); - if (data) - free(data); - if (data_res) - free(data_res); + free(atts); + free(atts_res); + free(data); + free(data_res); - return 1; + return EXIT_FAILURE; } diff --git a/test/cork.c b/test/cork.c index e0a7196b601..65e19d5be55 100644 --- a/test/cork.c +++ b/test/cork.c @@ -2229,13 +2229,12 @@ main(void) for (swmr = 0; swmr <= 1; swmr++) { if (swmr) { - char *driver = NULL; + const char *driver_name = h5_get_test_driver_name(); /* Skip these tests if SWMR I/O is not supported for the VFD specified * by the environment variable. */ - driver = getenv(HDF5_DRIVER); - if (!H5FD__supports_swmr_test(driver)) { + if (!H5FD__supports_swmr_test(driver_name)) { puts("-- SKIPPED SWMR tests for SWMR-incompatible VFD --"); continue; } diff --git a/test/dangle.c b/test/dangle.c index 4079fce6f51..cad7fe202df 100644 --- a/test/dangle.c +++ b/test/dangle.c @@ -623,18 +623,16 @@ test_dangle_force(void) int main(void) { - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ int nerrors = 0; /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Don't run this test with the multi/split VFD. A bug in library shutdown * ordering causes problems with the multi VFD when IDs are left dangling. */ - if (!strcmp(env_h5_drvr, "multi") || !strcmp(env_h5_drvr, "split")) { + if (!strcmp(driver_name, "multi") || !strcmp(driver_name, "split")) { puts(" -- SKIPPED for incompatible VFD --"); return 0; } diff --git a/test/dsets.c b/test/dsets.c index 8f2d2c4d528..3cc9ccbeae6 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -526,7 +526,7 @@ test_create(hid_t file) *------------------------------------------------------------------------- */ static herr_t -test_simple_io(const char *env_h5_drvr, hid_t fapl) +test_simple_io(const char *driver_name, hid_t fapl) { char filename[FILENAME_BUF_SIZE]; hid_t file = H5I_INVALID_HID, dataset = H5I_INVALID_HID, space = H5I_INVALID_HID, xfer = H5I_INVALID_HID; @@ -541,8 +541,8 @@ test_simple_io(const char *env_h5_drvr, hid_t fapl) TESTING("simple I/O"); /* Can't run this test with multi-file VFDs because of HDopen/read/seek the file directly */ - if (strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "family") != 0) { + if (strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "family") != 0) { h5_fixname(FILENAME[4], fapl, filename, sizeof filename); /* Set up data array */ @@ -688,7 +688,7 @@ test_simple_io(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static herr_t -test_userblock_offset(const char *env_h5_drvr, hid_t fapl, bool new_format) +test_userblock_offset(const char *driver_name, hid_t fapl, bool new_format) { char filename[FILENAME_BUF_SIZE]; hid_t file = H5I_INVALID_HID, fcpl = H5I_INVALID_HID, dataset = H5I_INVALID_HID, space = H5I_INVALID_HID; @@ -702,8 +702,8 @@ test_userblock_offset(const char *env_h5_drvr, hid_t fapl, bool new_format) TESTING("dataset offset with user block"); /* Can't run this test with multi-file VFDs because of HDopen/read/seek the file directly */ - if (strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "family") != 0) { + if (strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "family") != 0) { h5_fixname(FILENAME[2], fapl, filename, sizeof filename); /* Set up data array */ @@ -9630,7 +9630,7 @@ test_big_chunks_bypass_cache(hid_t fapl) *------------------------------------------------------------------------- */ static herr_t -test_chunk_fast(const char *env_h5_driver, hid_t fapl) +test_chunk_fast(const char *driver_name, hid_t fapl) { char filename[FILENAME_BUF_SIZE]; hid_t fid = H5I_INVALID_HID; /* File ID */ @@ -9693,7 +9693,7 @@ test_chunk_fast(const char *env_h5_driver, hid_t fapl) /* Skip this iteration if SWMR I/O is not supported for the VFD specified * by the environment variable. */ - if (swmr && !H5FD__supports_swmr_test(env_h5_driver)) + if (swmr && !H5FD__supports_swmr_test(driver_name)) continue; #ifdef H5_HAVE_FILTER_DEFLATE @@ -12200,7 +12200,7 @@ test_zero_dim_dset(hid_t fapl) *------------------------------------------------------------------------- */ static herr_t -test_swmr_non_latest(const char *env_h5_driver, hid_t fapl) +test_swmr_non_latest(const char *driver_name, hid_t fapl) { char filename[FILENAME_BUF_SIZE]; hid_t fid = H5I_INVALID_HID; /* File ID */ @@ -12221,7 +12221,7 @@ test_swmr_non_latest(const char *env_h5_driver, hid_t fapl) /* Skip this test if SWMR I/O is not supported for the VFD specified * by the environment variable. */ - if (!H5FD__supports_swmr_test(env_h5_driver)) { + if (!H5FD__supports_swmr_test(driver_name)) { SKIPPED(); puts(" Test skipped due to VFD not supporting SWMR I/O."); return SUCCEED; @@ -12470,7 +12470,7 @@ test_swmr_non_latest(const char *env_h5_driver, hid_t fapl) *------------------------------------------------------------------------- */ static herr_t -test_earray_hdr_fd(const char *env_h5_driver, hid_t fapl) +test_earray_hdr_fd(const char *driver_name, hid_t fapl) { char filename[FILENAME_BUF_SIZE]; hid_t fid = H5I_INVALID_HID; @@ -12491,7 +12491,7 @@ test_earray_hdr_fd(const char *env_h5_driver, hid_t fapl) /* Skip this test if SWMR I/O is not supported for the VFD specified * by the environment variable. */ - if (!H5FD__supports_swmr_test(env_h5_driver)) { + if (!H5FD__supports_swmr_test(driver_name)) { SKIPPED(); puts(" Test skipped due to VFD not supporting SWMR I/O."); return SUCCEED; @@ -12591,7 +12591,7 @@ test_earray_hdr_fd(const char *env_h5_driver, hid_t fapl) *------------------------------------------------------------------------- */ static herr_t -test_farray_hdr_fd(const char *env_h5_driver, hid_t fapl) +test_farray_hdr_fd(const char *driver_name, hid_t fapl) { char filename[FILENAME_BUF_SIZE]; hid_t fid = H5I_INVALID_HID; @@ -12612,7 +12612,7 @@ test_farray_hdr_fd(const char *env_h5_driver, hid_t fapl) /* Skip this test if SWMR I/O is not supported for the VFD specified * by the environment variable. */ - if (!H5FD__supports_swmr_test(env_h5_driver)) { + if (!H5FD__supports_swmr_test(driver_name)) { SKIPPED(); puts(" Test skipped due to VFD not supporting SWMR I/O."); return SUCCEED; @@ -12712,7 +12712,7 @@ test_farray_hdr_fd(const char *env_h5_driver, hid_t fapl) *------------------------------------------------------------------------- */ static herr_t -test_bt2_hdr_fd(const char *env_h5_driver, hid_t fapl) +test_bt2_hdr_fd(const char *driver_name, hid_t fapl) { char filename[FILENAME_BUF_SIZE]; hid_t fid = H5I_INVALID_HID; @@ -12739,7 +12739,7 @@ test_bt2_hdr_fd(const char *env_h5_driver, hid_t fapl) /* Skip this test if SWMR I/O is not supported for the VFD specified * by the environment variable. */ - if (!H5FD__supports_swmr_test(env_h5_driver)) { + if (!H5FD__supports_swmr_test(driver_name)) { SKIPPED(); puts(" Test skipped due to VFD not supporting SWMR I/O."); return SUCCEED; @@ -15909,18 +15909,16 @@ main(void) size_t rdcc_nbytes; double rdcc_w0; int nerrors = 0; - const char *envval; + const char *driver_name; bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */ bool driver_is_default_compatible; int i; /* Don't run this test using certain file drivers */ - envval = getenv(HDF5_DRIVER); - if (envval == NULL) - envval = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Current VFD that does not support contiguous address space */ - contig_addr_vfd = (bool)(strcmp(envval, "split") != 0 && strcmp(envval, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); /* Set the random # seed */ HDsrandom((unsigned)HDtime(NULL)); @@ -16049,7 +16047,7 @@ main(void) goto error; nerrors += (test_create(file) < 0 ? 1 : 0); - nerrors += (test_simple_io(envval, my_fapl) < 0 ? 1 : 0); + nerrors += (test_simple_io(driver_name, my_fapl) < 0 ? 1 : 0); nerrors += (test_compact_io(my_fapl) < 0 ? 1 : 0); nerrors += (test_max_compact(my_fapl) < 0 ? 1 : 0); nerrors += (test_compact_open_close_dirty(my_fapl) < 0 ? 1 : 0); @@ -16075,7 +16073,7 @@ main(void) nerrors += (test_multiopen(file) < 0 ? 1 : 0); nerrors += (test_types(file) < 0 ? 1 : 0); nerrors += (test_floattypes(file) < 0 ? 1 : 0); - nerrors += (test_userblock_offset(envval, my_fapl, new_format) < 0 ? 1 : 0); + nerrors += (test_userblock_offset(driver_name, my_fapl, new_format) < 0 ? 1 : 0); if (driver_is_default_compatible) { nerrors += (test_missing_filter(file) < 0 ? 1 : 0); @@ -16105,7 +16103,7 @@ main(void) nerrors += (test_huge_chunks(my_fapl) < 0 ? 1 : 0); nerrors += (test_chunk_cache(my_fapl) < 0 ? 1 : 0); nerrors += (test_big_chunks_bypass_cache(my_fapl) < 0 ? 1 : 0); - nerrors += (test_chunk_fast(envval, my_fapl) < 0 ? 1 : 0); + nerrors += (test_chunk_fast(driver_name, my_fapl) < 0 ? 1 : 0); nerrors += (test_reopen_chunk_fast(my_fapl) < 0 ? 1 : 0); nerrors += (test_chunk_fast_bug1(my_fapl) < 0 ? 1 : 0); nerrors += (test_chunk_expand(my_fapl) < 0 ? 1 : 0); @@ -16123,10 +16121,10 @@ main(void) nerrors += (test_storage_size(my_fapl) < 0 ? 1 : 0); nerrors += (test_power2up(my_fapl) < 0 ? 1 : 0); - nerrors += (test_swmr_non_latest(envval, my_fapl) < 0 ? 1 : 0); - nerrors += (test_earray_hdr_fd(envval, my_fapl) < 0 ? 1 : 0); - nerrors += (test_farray_hdr_fd(envval, my_fapl) < 0 ? 1 : 0); - nerrors += (test_bt2_hdr_fd(envval, my_fapl) < 0 ? 1 : 0); + nerrors += (test_swmr_non_latest(driver_name, my_fapl) < 0 ? 1 : 0); + nerrors += (test_earray_hdr_fd(driver_name, my_fapl) < 0 ? 1 : 0); + nerrors += (test_farray_hdr_fd(driver_name, my_fapl) < 0 ? 1 : 0); + nerrors += (test_bt2_hdr_fd(driver_name, my_fapl) < 0 ? 1 : 0); nerrors += (test_downsize_vlen_scalar_dataset(file) < 0 ? 1 : 0); diff --git a/test/dt_arith.c b/test/dt_arith.c index 3c2189650dd..83d64bcef00 100644 --- a/test/dt_arith.c +++ b/test/dt_arith.c @@ -878,7 +878,7 @@ test_particular_fp_integer(void) /*------------------------------------------------------------------------- * Function: test_derived_flt * - * Purpose: Tests user-define and query functions of floating-point types. + * Purpose: Tests user-defined and query functions of floating-point types. * * Return: Success: 0 * @@ -903,7 +903,7 @@ test_derived_flt(void) char str[256]; /*message string */ unsigned int i, j; - TESTING("user-define and query functions of floating-point types"); + TESTING("user-defined and query functions of floating-point types"); /* Create File */ h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof filename); @@ -1324,7 +1324,7 @@ test_derived_flt(void) /*------------------------------------------------------------------------- * Function: test_derived_integer * - * Purpose: Tests user-define and query functions of integer types. + * Purpose: Tests user-defined and query functions of integer types. * * Return: Success: 0 * @@ -1347,7 +1347,7 @@ test_derived_integer(void) char str[256]; /*message string */ unsigned int i, j; - TESTING("user-define and query functions of integer types"); + TESTING("user-defined and query functions of integer types"); /* Create File */ h5_fixname(FILENAME[1], H5P_DEFAULT, filename, sizeof filename); @@ -5990,11 +5990,11 @@ main(void) /* Test H5Tcompiler_conv() for querying hard conversion. */ nerrors += (unsigned long)test_hard_query(); - /* Test user-define, query functions and software conversion + /* Test user-defined, query functions and software conversion * for user-defined floating-point types */ nerrors += (unsigned long)test_derived_flt(); - /* Test user-define, query functions and software conversion + /* Test user-defined, query functions and software conversion * for user-defined integer types */ nerrors += (unsigned long)test_derived_integer(); diff --git a/test/dtypes.c b/test/dtypes.c index 94a52155836..ea589583e65 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -6051,7 +6051,7 @@ test__Float16(void) { #ifdef H5_HAVE__FLOAT16 H5T_path_t *path = NULL; - const char *env_h5_driver; + const char *driver_name; hsize_t dims[1]; htri_t is_little_endian; H5T_t *native_dtype = NULL; @@ -6065,9 +6065,7 @@ test__Float16(void) TESTING("_Float16 datatype"); - env_h5_driver = getenv(HDF5_DRIVER); - if (env_h5_driver == NULL) - env_h5_driver = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Check that native macro maps to a valid type */ if (0 == H5Tget_size(H5T_NATIVE_FLOAT16)) { @@ -6402,7 +6400,7 @@ test__Float16(void) if (H5Fclose(fid) < 0) TEST_ERROR; - if (!h5_driver_uses_multiple_files(env_h5_driver, H5_EXCLUDE_NON_MULTIPART_DRIVERS)) { + if (!h5_driver_uses_multiple_files(driver_name, H5_EXCLUDE_NON_MULTIPART_DRIVERS)) { bool is_default_vfd_compat = false; if (h5_driver_is_default_vfd_compatible(H5P_DEFAULT, &is_default_vfd_compat) < 0) diff --git a/test/error_test.c b/test/error_test.c index 57b1eb7a6b3..bb780215574 100644 --- a/test/error_test.c +++ b/test/error_test.c @@ -781,14 +781,12 @@ main(void) hid_t fapl = H5I_INVALID_HID; hid_t estack_id = H5I_INVALID_HID; char filename[1024]; - const char *env_h5_drvr; /* File driver value from environment */ + const char *driver_name; /* File driver value from environment */ const char *FUNC_main = "main"; int i; /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); fprintf(stderr, " This program tests the Error API. There're supposed to be some error messages\n"); @@ -879,7 +877,7 @@ main(void) * the test file was pre-generated. */ h5_fixname(DATAFILE, H5P_DEFAULT, filename, sizeof filename); - if (!h5_using_default_driver(env_h5_drvr) && strcmp(env_h5_drvr, "stdio")) { + if (!h5_using_default_driver(driver_name) && strcmp(driver_name, "stdio")) { /* If not using the library's default VFD or the stdio VFD, force * the library's default VFD here. The test file was pre-generated * and can cause issues with many VFDs. diff --git a/test/fheap.c b/test/fheap.c index 19a1e6adc16..cd1f0c5ec1f 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -15958,17 +15958,15 @@ main(void) unsigned nerrors = 0; /* Cumulative error count */ unsigned num_pb_fs = 1; /* The number of settings to test for page buffering and file space handling */ int ExpressMode; /* Express testing level */ - const char *envval; /* Environment variable */ + const char *driver_name; /* Environment variable */ bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */ bool api_ctx_pushed = false; /* Whether API context pushed */ /* Don't run this test using certain file drivers */ - envval = getenv(HDF5_DRIVER); - if (envval == NULL) - envval = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Current VFD that does not support contiguous address space */ - contig_addr_vfd = (bool)(strcmp(envval, "split") != 0 && strcmp(envval, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); /* Reset library */ h5_reset(); diff --git a/test/filenotclosed.c b/test/filenotclosed.c index 806a7a498d9..a42e1a8c43e 100644 --- a/test/filenotclosed.c +++ b/test/filenotclosed.c @@ -59,20 +59,18 @@ main(void) hsize_t chunk_dim[1] = {10}; /* Chunk dimension sizes */ int buf[5] = {1, 2, 3, 4, 5}; /* The data to be written to the dataset */ char filename[100]; /* File name */ - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ bool contig_addr_vfd; /* Contiguous address vfd */ /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Skip test when using VFDs that has different address spaces for each * type of metadata allocation. * Further investigation is needed to resolve the test failure with the * split/multi driver. Please see HDFFV-10160. */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (!contig_addr_vfd) { SKIPPED(); puts(" Temporary skipped for a spilt/multi driver"); diff --git a/test/flush1.c b/test/flush1.c index 566d5614c9c..f9ecb15fa1e 100644 --- a/test/flush1.c +++ b/test/flush1.c @@ -176,20 +176,20 @@ add_dset_to_file(hid_t fid, const char *dset_name) int main(void) { - char *driver = NULL; /* name of current VFD (from env var) */ - bool vfd_supports_swmr; /* whether the current VFD supports SWMR */ - hid_t fid = H5I_INVALID_HID; /* file ID */ - hid_t fapl_id = H5I_INVALID_HID; /* file access proplist ID */ - char filename[1024]; /* filename */ - bool use_swmr; /* whether or not to use SWMR I/O */ + const char *driver_name; /* name of current VFD (from env var) */ + bool vfd_supports_swmr; /* whether the current VFD supports SWMR */ + hid_t fid = H5I_INVALID_HID; /* file ID */ + hid_t fapl_id = H5I_INVALID_HID; /* file access proplist ID */ + char filename[1024]; /* filename */ + bool use_swmr; /* whether or not to use SWMR I/O */ h5_reset(); if ((fapl_id = h5_fileaccess()) < 0) TEST_ERROR; /* Check if the current VFD supports SWMR */ - driver = getenv(HDF5_DRIVER); - vfd_supports_swmr = H5FD__supports_swmr_test(driver); + driver_name = h5_get_test_driver_name(); + vfd_supports_swmr = H5FD__supports_swmr_test(driver_name); /*************************************************/ /* NOTE: Not closing the file ID is intentional! */ diff --git a/test/flush2.c b/test/flush2.c index ccec232e3d7..12daa2be87f 100644 --- a/test/flush2.c +++ b/test/flush2.c @@ -223,7 +223,7 @@ clear_status_flags(const char *filename, hid_t fapl_id) int main(void) { - char *driver = NULL; /* name of current VFD (from env var) */ + const char *driver_name; /* name of current VFD (from env var) */ bool vfd_supports_swmr; /* whether the current VFD supports SWMR */ hid_t fapl_id = H5I_INVALID_HID; /* file access proplist ID */ char filename[1024]; /* filename */ @@ -236,8 +236,8 @@ main(void) PUTS_ERROR("bad vfd-dependent fapl"); /* Check if the current VFD supports SWMR */ - driver = getenv(HDF5_DRIVER); - vfd_supports_swmr = H5FD__supports_swmr_test(driver); + driver_name = h5_get_test_driver_name(); + vfd_supports_swmr = H5FD__supports_swmr_test(driver_name); if (h5_driver_is_default_vfd_compatible(fapl_id, &driver_is_default_vfd_compatible) < 0) { printf("Can't check if VFD is compatible with default VFD\n"); diff --git a/test/flushrefresh.c b/test/flushrefresh.c index 297db60e7ac..bab334f1c68 100644 --- a/test/flushrefresh.c +++ b/test/flushrefresh.c @@ -133,7 +133,7 @@ int main(int argc, char *argv[]) { /* Variables */ - const char *envval = NULL; + const char *driver_name = NULL; /* Initialize library */ if (H5open() < 0) @@ -146,9 +146,9 @@ main(int argc, char *argv[]) * anything. */ /* Determine driver being used */ - envval = getenv(HDF5_DRIVER); + driver_name = h5_get_test_driver_name(); - if (envval == NULL || H5FD__supports_swmr_test(envval)) { + if (driver_name == NULL || H5FD__supports_swmr_test(driver_name)) { if (test_flush() != SUCCEED) TEST_ERROR; if (test_refresh() != SUCCEED) diff --git a/test/h5test.c b/test/h5test.c index 567f8438622..ba68918c2a1 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -35,8 +35,10 @@ * this test support library. The environment variable is used in preference * to the cpp constant. If neither is defined then use some default value. * - * HDF5_DRIVER: This string describes what low level file driver to - * use for HDF5 file access. + * HDF5_DRIVER/HDF5_TEST_DRIVER: This string describes what low level file + * driver to use for HDF5 file access. The first word in the value is the + * name of the driver and subsequent data is interpreted according to the + * driver. See h5_get_vfd_fapl() for details. * * HDF5_LIBVER_BOUNDS: This string describes what library version bounds to * use for HDF5 file access. See h5_get_libver_fapl() for details. @@ -214,11 +216,8 @@ h5_delete_test_file(const char *base_name, hid_t fapl) void h5_delete_all_test_files(const char *base_name[], hid_t fapl) { - int i; /* iterator */ - - for (i = 0; base_name[i]; i++) { + for (int i = 0; base_name[i]; i++) h5_delete_test_file(base_name[i], fapl); - } /* end for */ } /* end h5_delete_all_test_files() */ @@ -452,7 +451,7 @@ h5_fixname_real(const char *base_name, hid_t fapl, const char *_suffix, char *fu bool nest_printf, bool subst_for_superblock) { const char *prefix = NULL; - const char *driver_env_var = NULL; /* HDF5_DRIVER environment variable */ + const char *driver_env_var = NULL; /* HDF5_DRIVER/HDF5_TEST_DRIVER environment variable */ char *ptr, last = '\0'; const char *suffix = _suffix; size_t i, j; @@ -467,7 +466,7 @@ h5_fixname_real(const char *base_name, hid_t fapl, const char *_suffix, char *fu /* Determine if driver is set by environment variable. If it is, * only generate a suffix if fixing the filename for the superblock * file. */ - driver_env_var = getenv(HDF5_DRIVER); + driver_env_var = h5_get_test_driver_name(); if (driver_env_var && (H5P_DEFAULT == fapl) && subst_for_superblock) fapl = H5P_FILE_ACCESS_DEFAULT; @@ -491,19 +490,16 @@ h5_fixname_real(const char *base_name, hid_t fapl, const char *_suffix, char *fu } else if (H5FD_MULTI == driver) { - /* Check the HDF5_DRIVER environment variable in case - * we are using the split driver since both of those - * use the multi VFD under the hood. + /* Check the HDF5_DRIVER/HDF5_TEST_DRIVER environment + * variable in case we are using the split driver since + * both of those use the multi VFD under the hood. */ -#ifdef HDF5_DRIVER - /* Use the environment variable, then the compile-time constant */ - if (!driver_env_var) - driver_env_var = HDF5_DRIVER; -#endif if (driver_env_var && !strcmp(driver_env_var, "split")) { /* split VFD */ if (subst_for_superblock) suffix = ".h5.meta"; + else + suffix = NULL; } else { /* multi VFD */ @@ -728,6 +724,10 @@ h5_fileaccess(void) if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) goto error; + /* Attempt to set up a file driver first */ + if (h5_get_vfd_fapl(fapl_id) < 0) + goto error; + /* Check for libver bounds */ if (h5_get_libver_fapl(fapl_id) < 0) goto error; @@ -760,6 +760,10 @@ h5_fileaccess_flags(unsigned flags) if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) goto error; + /* Attempt to set up a file driver first */ + if ((flags & H5_FILEACCESS_VFD) && h5_get_vfd_fapl(fapl_id) < 0) + goto error; + /* Check for libver bounds */ if ((flags & H5_FILEACCESS_LIBVER) && h5_get_libver_fapl(fapl_id) < 0) goto error; @@ -772,6 +776,241 @@ h5_fileaccess_flags(unsigned flags) return H5I_INVALID_HID; } /* end h5_fileaccess_flags() */ +/*------------------------------------------------------------------------- + * Function: h5_get_vfd_fapl + * + * Purpose: Sets the file driver for a FAPL according to the value + * specified in the environment variable "HDF5_DRIVER" or + * "HDF5_TEST_DRIVER". + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +h5_get_vfd_fapl(hid_t fapl) +{ + const char *env = NULL; /* HDF5_DRIVER/HDF5_TEST_DRIVER environment variable */ + const char *tok = NULL; /* strtok pointer */ + char *lasts = NULL; /* Context pointer for strtok_r() call */ + char buf[1024]; /* buffer for tokenizing HDF5_DRIVER */ + + /* Get the environment variable, if it exists */ + env = getenv(HDF5_DRIVER); + if (!env) + env = getenv("HDF5_TEST_DRIVER"); + + /* If the environment variable was not set, just return + * without modifying the FAPL. + */ + if (!env || !*env) + goto done; + + /* Get the first 'word' of the environment variable. + * If it's nothing (environment variable was whitespace) + * just return the default fapl. + */ + strncpy(buf, env, sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + if (NULL == (tok = HDstrtok_r(buf, " \t\n\r", &lasts))) + goto done; + + if (!strcmp(tok, "sec2")) { + /* POSIX (section 2) read() and write() system calls */ + if (H5Pset_fapl_sec2(fapl) < 0) + goto error; + } + else if (!strcmp(tok, "stdio")) { + /* Standard C fread() and fwrite() system calls */ + if (H5Pset_fapl_stdio(fapl) < 0) + goto error; + } + else if (!strcmp(tok, "core")) { + /* In-memory driver settings (backing store on, 1 MB increment) */ + if (H5Pset_fapl_core(fapl, (size_t)H5_MB, TRUE) < 0) + goto error; + } + else if (!strcmp(tok, "core_paged")) { + /* In-memory driver with write tracking and paging on */ + if (H5Pset_fapl_core(fapl, (size_t)H5_MB, TRUE) < 0) + goto error; + if (H5Pset_core_write_tracking(fapl, TRUE, 4096) < 0) + goto error; + } + else if (!strcmp(tok, "split")) { + /* Split meta data and raw data each using default driver */ + if (H5Pset_fapl_split(fapl, ".meta", H5P_DEFAULT, ".raw", H5P_DEFAULT) < 0) + goto error; + } + else if (!strcmp(tok, "multi")) { + /* Multi-file driver, general case of the split driver */ + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + const char *memb_name[H5FD_MEM_NTYPES]; + char *sv[H5FD_MEM_NTYPES]; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + H5FD_mem_t mt; + const size_t multi_memname_maxlen = 1024; + + memset(memb_map, 0, sizeof(memb_map)); + memset(memb_fapl, 0, sizeof(memb_fapl)); + memset(memb_name, 0, sizeof(memb_name)); + memset(memb_addr, 0, sizeof(memb_addr)); + + assert(strlen(multi_letters) == H5FD_MEM_NTYPES); + for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { + memb_fapl[mt] = H5P_DEFAULT; + if (NULL == (sv[mt] = malloc(multi_memname_maxlen))) + goto error; + snprintf(sv[mt], multi_memname_maxlen, "%%s-%c.h5", multi_letters[mt]); + memb_name[mt] = sv[mt]; + memb_addr[mt] = (haddr_t)MAX(mt - 1, 0) * (HADDR_MAX / 10); + } /* end for */ + + if (H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, memb_addr, FALSE) < 0) + goto error; + + for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) + free(sv[mt]); + } + else if (!strcmp(tok, "family")) { + /* Family of files, each 1MB and using the default driver */ + hsize_t fam_size = 100 * 1024 * 1024; /* 100 MB */ + + /* Was a family size specified in the environment variable? */ + if ((tok = HDstrtok_r(NULL, " \t\n\r", &lasts))) + fam_size = (hsize_t)(strtod(tok, NULL) * 1024 * 1024); + if (H5Pset_fapl_family(fapl, fam_size, H5P_DEFAULT) < 0) + goto error; + } + else if (!strcmp(tok, "log")) { + /* Log file access */ + unsigned log_flags = H5FD_LOG_LOC_IO | H5FD_LOG_ALLOC; + + /* Were special log file flags specified in the environment variable? */ + if ((tok = HDstrtok_r(NULL, " \t\n\r", &lasts))) + log_flags = (unsigned)strtol(tok, NULL, 0); + + if (H5Pset_fapl_log(fapl, NULL, log_flags, 0) < 0) + goto error; + } +#ifdef H5_HAVE_DIRECT + else if (!strcmp(tok, "direct")) { + /* Linux direct read() and write() system calls. Set memory boundary, + * file block size, and copy buffer size to the default values. + */ + if (H5Pset_fapl_direct(fapl, 1024, 4096, 8 * 4096) < 0) + goto error; + } +#endif + else if (!strcmp(tok, "splitter")) { + H5FD_splitter_vfd_config_t *splitter_config; + static size_t file_count = 0; + + if (NULL == (splitter_config = malloc(sizeof(*splitter_config)))) + goto error; + + splitter_config->magic = H5FD_SPLITTER_MAGIC; + splitter_config->version = H5FD_CURR_SPLITTER_VFD_CONFIG_VERSION; + splitter_config->ignore_wo_errs = false; + memset(splitter_config->log_file_path, 0, H5FD_SPLITTER_PATH_MAX + 1); + + /* + * We need access to the base filename to generate a unique name + * for the W/O file for this FAPL. Until this is refactored, just + * generate unique names with a counter. + */ + snprintf(splitter_config->wo_path, H5FD_SPLITTER_PATH_MAX + 1, "splitter_wo_file_%zu.h5", + file_count++); + + /* Setup R/W and W/O channel FAPLs since the default FAPL + * has the splitter driver set on it from the environment + */ + if ((splitter_config->rw_fapl_id = H5Pcopy(H5P_FILE_ACCESS_DEFAULT)) < 0) { + free(splitter_config); + goto error; + } + if ((splitter_config->wo_fapl_id = H5Pcopy(H5P_FILE_ACCESS_DEFAULT)) < 0) { + H5Pclose(splitter_config->rw_fapl_id); + free(splitter_config); + goto error; + } + if (H5Pset_fapl_sec2(splitter_config->rw_fapl_id) < 0) { + H5Pclose(splitter_config->rw_fapl_id); + H5Pclose(splitter_config->wo_fapl_id); + free(splitter_config); + goto error; + } + if (H5Pset_fapl_sec2(splitter_config->wo_fapl_id) < 0) { + H5Pclose(splitter_config->rw_fapl_id); + H5Pclose(splitter_config->wo_fapl_id); + free(splitter_config); + goto error; + } + + if (H5Pset_fapl_splitter(fapl, splitter_config) < 0) { + H5Pclose(splitter_config->rw_fapl_id); + H5Pclose(splitter_config->wo_fapl_id); + free(splitter_config); + goto error; + } + + free(splitter_config); + } + else if (!strcmp(tok, "onion")) { + /* TODO */ + return 0; + } +#ifdef H5_HAVE_SUBFILING_VFD + else if (!strcmp(tok, H5FD_SUBFILING_NAME)) { + /* Use default subfiling configuration */ + if (H5Pset_fapl_subfiling(fapl, NULL) < 0) + goto error; + } +#endif +#ifdef H5_HAVE_PARALLEL + else if (!strcmp(tok, "mpio")) { + int mpi_initialized, mpi_finalized; + + MPI_Initialized(&mpi_initialized); + MPI_Finalized(&mpi_finalized); + + if (mpi_initialized && !mpi_finalized) { + if (H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0) + goto error; + } + } +#endif +#ifdef H5_HAVE_MIRROR_VFD + else if (!strcmp(tok, "mirror")) { + /* TODO */ + return 0; + } +#endif +#ifdef H5_HAVE_LIBHDFS + else if (!strcmp(tok, "hdfs")) { + /* TODO */ + return 0; + } +#endif +#ifdef H5_HAVE_ROS3_VFD + else if (!strcmp(tok, "ros3")) { + /* TODO */ + return 0; + } +#endif + else { + /* Unknown driver */ + goto error; + } + +done: + return 0; + +error: + return -1; +} /* end h5_get_vfd_fapl() */ + /*------------------------------------------------------------------------- * Function: h5_get_libver_fapl * @@ -786,10 +1025,10 @@ h5_fileaccess_flags(unsigned flags) herr_t h5_get_libver_fapl(hid_t fapl) { - const char *env = NULL; /* HDF5_DRIVER environment variable */ + const char *env = NULL; /* HDF5_LIBVER_BOUNDS environment variable */ const char *tok = NULL; /* strtok pointer */ char *lasts = NULL; /* Context pointer for strtok_r() call */ - char buf[1024]; /* buffer for tokenizing HDF5_DRIVER */ + char buf[1024]; /* buffer for tokenizing HDF5_LIBVER_BOUNDS */ /* Get the environment variable, if it exists */ env = getenv("HDF5_LIBVER_BOUNDS"); @@ -1099,9 +1338,9 @@ h5_get_file_size(const char *filename, hid_t fapl) else if (driver == H5FD_MULTI) { H5FD_mem_t mt; h5_stat_size_t tot_size = 0; - char *driver_env_var = NULL; + const char *driver_env_var = NULL; - driver_env_var = getenv(HDF5_DRIVER); + driver_env_var = h5_get_test_driver_name(); if (driver_env_var && !strcmp(driver_env_var, "split")) { for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { if (mt != H5FD_MEM_DRAW && mt != H5FD_MEM_SUPER) @@ -1959,13 +2198,13 @@ H5_get_srcdir(void) int h5_duplicate_file_by_bytes(const char *orig, const char *dest) { - FILE *orig_ptr = NULL; - FILE *dest_ptr = NULL; - hsize_t fsize = 0; - hsize_t read_size = 0; - hsize_t max_buf = 0; - void *dup_buf = NULL; - int ret_value = 0; + FILE *orig_ptr = NULL; + FILE *dest_ptr = NULL; + size_t fsize = 0; + size_t read_size = 0; + size_t max_buf = 0; + void *dup_buf = NULL; + int ret_value = 0; max_buf = 4096 * sizeof(char); @@ -1976,7 +2215,7 @@ h5_duplicate_file_by_bytes(const char *orig, const char *dest) } HDfseek(orig_ptr, 0, SEEK_END); - fsize = (hsize_t)HDftell(orig_ptr); + fsize = (size_t)HDftell(orig_ptr); HDrewind(orig_ptr); dest_ptr = fopen(dest, "wb"); @@ -2193,12 +2432,38 @@ h5_using_native_vol(hid_t fapl_id, hid_t obj_id, bool *is_native_vol) return ret_value; } +/*------------------------------------------------------------------------- + * Function: h5_get_test_driver_name + * + * Purpose: Checks the HDF5_DRIVER and HDF5_TEST_DRIVER environment + * variables to see if a driver name has been set for testing. + * + * Return: Driver name if set/NULL otherwise + * + *------------------------------------------------------------------------- + */ +const char * +h5_get_test_driver_name(void) +{ + char *envval; + + assert(H5_DEFAULT_VFD == H5FD_SEC2); + + if ((envval = getenv(HDF5_DRIVER))) + return envval; + else if ((envval = getenv("HDF5_TEST_DRIVER"))) + return envval; + else + return H5_DEFAULT_VFD_NAME; +} + /*------------------------------------------------------------------------- * Function: h5_using_default_driver * * Purpose: Checks if the specified VFD name matches the library's - * default VFD. If `drv_name` is NULL, the HDF5_DRIVER - * environment is checked instead (if it is set). + * default VFD. If `drv_name` is NULL, the HDF5_DRIVER and + * HDF5_TEST_DRIVER environment variables are checked instead + * (if set). * * Return: true/false * @@ -2212,10 +2477,10 @@ h5_using_default_driver(const char *drv_name) assert(H5_DEFAULT_VFD == H5FD_SEC2); if (!drv_name) - drv_name = getenv(HDF5_DRIVER); + drv_name = h5_get_test_driver_name(); if (drv_name) - return (!strcmp(drv_name, "sec2") || !strcmp(drv_name, "nomatch")); + return !strcmp(drv_name, H5_DEFAULT_VFD_NAME); return ret_val; } @@ -2333,7 +2598,7 @@ h5_driver_uses_multiple_files(const char *drv_name, unsigned flags) bool ret_val = false; if (!drv_name) - drv_name = getenv(HDF5_DRIVER); + drv_name = h5_get_test_driver_name(); if (drv_name) { if ((flags & H5_EXCLUDE_MULTIPART_DRIVERS) == 0) { diff --git a/test/h5test.h b/test/h5test.h index 8f785674abc..9ef94943a81 100644 --- a/test/h5test.h +++ b/test/h5test.h @@ -230,7 +230,8 @@ H5TEST_DLLVAR MPI_Info h5_io_info_g; /* MPI INFO object for IO */ #define H5_ALARM_SEC 1200 /* default is 20 minutes */ /* Flags for h5_fileaccess_flags() */ -#define H5_FILEACCESS_LIBVER 0x01 +#define H5_FILEACCESS_VFD 0x01 +#define H5_FILEACCESS_LIBVER 0x02 /* Flags for h5_driver_uses_multiple_files() */ #define H5_EXCLUDE_MULTIPART_DRIVERS 0x01 @@ -292,12 +293,14 @@ H5TEST_DLL int h5_duplicate_file_by_bytes(const char *orig, const cha H5TEST_DLL herr_t h5_check_if_file_locking_enabled(bool *are_enabled); H5TEST_DLL void h5_check_file_locking_env_var(htri_t *use_locks, htri_t *ignore_disabled_locks); H5TEST_DLL herr_t h5_using_native_vol(hid_t fapl_id, hid_t obj_id, bool *is_native_vol); +H5TEST_DLL const char *h5_get_test_driver_name(void); H5TEST_DLL bool h5_using_default_driver(const char *drv_name); H5TEST_DLL herr_t h5_using_parallel_driver(hid_t fapl_id, bool *driver_is_parallel); H5TEST_DLL herr_t h5_driver_is_default_vfd_compatible(hid_t fapl_id, bool *default_vfd_compatible); H5TEST_DLL bool h5_driver_uses_multiple_files(const char *drv_name, unsigned flags); /* Functions that will replace components of a FAPL */ +H5TEST_DLL herr_t h5_get_vfd_fapl(hid_t fapl_id); H5TEST_DLL herr_t h5_get_libver_fapl(hid_t fapl_id); /* h5_clean_files() replacements */ diff --git a/test/links.c b/test/links.c index 87efae8107b..4ea612ebdfd 100644 --- a/test/links.c +++ b/test/links.c @@ -9537,7 +9537,7 @@ external_set_elink_fapl3(bool new_format) *------------------------------------------------------------------------- */ static int -external_set_elink_acc_flags(const char *env_h5_drvr, hid_t fapl, bool new_format) +external_set_elink_acc_flags(const char *driver_name, hid_t fapl, bool new_format) { hid_t file1 = H5I_INVALID_HID, file2 = H5I_INVALID_HID, group = H5I_INVALID_HID, subgroup = H5I_INVALID_HID, gapl = H5I_INVALID_HID; @@ -9671,7 +9671,7 @@ external_set_elink_acc_flags(const char *env_h5_drvr, hid_t fapl, bool new_forma TEST_ERROR; /* Only run this part with VFDs that support SWMR */ - if (H5FD__supports_swmr_test(env_h5_drvr)) { + if (H5FD__supports_swmr_test(driver_name)) { /* Reopen file1, with read-write and SWMR-write access */ /* Only supported under the latest file format */ @@ -12663,7 +12663,7 @@ external_link_strong(hid_t fapl, bool new_format) *------------------------------------------------------------------------- */ static int -external_symlink(const char *env_h5_drvr, hid_t fapl, bool new_format) +external_symlink(const char *driver_name, hid_t fapl, bool new_format) { #ifdef H5_HAVE_SYMLINK hid_t file1 = H5I_INVALID_HID; @@ -12698,8 +12698,7 @@ external_symlink(const char *env_h5_drvr, hid_t fapl, bool new_format) /* Skip test when using VFDs that can't provide a POSIX compatible file * descriptor. */ - have_posix_compat_vfd = (bool)(!strcmp(env_h5_drvr, "sec2") || !strcmp(env_h5_drvr, "core") || - !strcmp(env_h5_drvr, "nomatch")); + have_posix_compat_vfd = (bool)(!strcmp(driver_name, "sec2") || !strcmp(driver_name, "core")); if (!have_posix_compat_vfd) { SKIPPED(); puts(" Current VFD doesn't support POSIX I/O calls"); @@ -23108,12 +23107,10 @@ main(void) unsigned new_format; /* Whether to use the new format or not */ unsigned minimize_dset_oh; unsigned efc; /* Whether to use the external file cache */ - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ bool driver_is_default_compatible; - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); h5_reset(); fapl = h5_fileaccess(); @@ -23182,7 +23179,7 @@ main(void) #endif /* H5_NO_DEPRECATED_SYMBOLS */ /* Skip external link tests for splitter VFD, which has external link-related bugs */ - if (strcmp(env_h5_drvr, "splitter")) { + if (strcmp(driver_name, "splitter")) { /* tests for external link */ /* Test external file cache first, so it sees the default efc setting on the fapl @@ -23197,7 +23194,7 @@ main(void) /* This test cannot run with the EFC because the EFC cannot currently * reopen a cached file with a different intent */ - nerrors += external_set_elink_acc_flags(env_h5_drvr, my_fapl, new_format) < 0 ? 1 : 0; + nerrors += external_set_elink_acc_flags(driver_name, my_fapl, new_format) < 0 ? 1 : 0; /* Try external link tests both with and without the external file cache */ for (efc = false; efc <= true; efc++) { @@ -23269,7 +23266,7 @@ main(void) nerrors += external_link_win8(my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_link_win9(my_fapl, new_format) < 0 ? 1 : 0; #endif - nerrors += external_symlink(env_h5_drvr, my_fapl, new_format) < 0 ? 1 : 0; + nerrors += external_symlink(driver_name, my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_copy_invalid_object(my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_dont_fail_to_source(my_fapl, new_format) < 0 ? 1 : 0; nerrors += external_open_twice(my_fapl, new_format) < 0 ? 1 : 0; diff --git a/test/links_env.c b/test/links_env.c index 1eae52a5128..ed9c3ba7f0c 100644 --- a/test/links_env.c +++ b/test/links_env.c @@ -144,17 +144,15 @@ external_link_env(hid_t fapl, bool new_format) int main(void) { - const char *env_h5_drvr; /* File driver value from environment */ + const char *driver_name; /* File driver value from environment */ hid_t fapl; /* File access property lists */ int nerrors = 0; /* Error from tests */ /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Splitter VFD has issues with external links */ - if (!strcmp(env_h5_drvr, "splitter")) { + if (!strcmp(driver_name, "splitter")) { puts(" -- SKIPPED for incompatible VFD --"); exit(EXIT_SUCCESS); } diff --git a/test/mf.c b/test/mf.c index 269419f546c..909a7ec89f1 100644 --- a/test/mf.c +++ b/test/mf.c @@ -108,47 +108,47 @@ typedef enum { static int check_stats(const H5F_t *f, const H5FS_t *frsp, H5FS_stat_t *state); -static unsigned test_mf_eoa(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_eoa_shrink(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_eoa_extend(const char *env_h5_drvr, hid_t fapl); +static unsigned test_mf_eoa(const char *driver_name, hid_t fapl); +static unsigned test_mf_eoa_shrink(const char *driver_name, hid_t fapl); +static unsigned test_mf_eoa_extend(const char *driver_name, hid_t fapl); static unsigned test_dichotomy(hid_t fapl); static unsigned test_mf_fs_start(hid_t fapl); static unsigned test_mf_fs_alloc_free(hid_t fapl); static unsigned test_mf_fs_extend(hid_t fapl); -static unsigned test_mf_fs_absorb(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_aggr_alloc1(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_aggr_alloc2(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_aggr_alloc3(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_aggr_alloc4(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_aggr_alloc5(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_aggr_alloc6(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_aggr_alloc7(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_aggr_extend(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_aggr_absorb(const char *env_h5_drvr, hid_t fapl); -static unsigned test_mf_align_eoa(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl); -static unsigned test_mf_align_fs(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl); -static unsigned test_mf_align_alloc1(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl); -static unsigned test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl); -static unsigned test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl); -static unsigned test_mf_align_alloc4(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl); -static unsigned test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl); -static unsigned test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl); -static unsigned test_mf_tmp(const char *env_h5_drvr, hid_t fapl, bool new_format); -static unsigned test_mf_fs_gone(const char *env_h5_drvr, hid_t fapl, bool new_format); -static unsigned test_mf_strat_thres_gone(const char *env_h5_drvr, hid_t fapl, bool new_format); -static unsigned test_mf_fs_persist(const char *env_h5_drvr, hid_t fapl, bool new_format); -static unsigned test_mf_strat_thres_persist(const char *env_h5_drvr, hid_t fapl, bool new_format); +static unsigned test_mf_fs_absorb(const char *driver_name, hid_t fapl); +static unsigned test_mf_aggr_alloc1(const char *driver_name, hid_t fapl); +static unsigned test_mf_aggr_alloc2(const char *driver_name, hid_t fapl); +static unsigned test_mf_aggr_alloc3(const char *driver_name, hid_t fapl); +static unsigned test_mf_aggr_alloc4(const char *driver_name, hid_t fapl); +static unsigned test_mf_aggr_alloc5(const char *driver_name, hid_t fapl); +static unsigned test_mf_aggr_alloc6(const char *driver_name, hid_t fapl); +static unsigned test_mf_aggr_alloc7(const char *driver_name, hid_t fapl); +static unsigned test_mf_aggr_extend(const char *driver_name, hid_t fapl); +static unsigned test_mf_aggr_absorb(const char *driver_name, hid_t fapl); +static unsigned test_mf_align_eoa(const char *driver_name, hid_t fapl, hid_t new_fapl); +static unsigned test_mf_align_fs(const char *driver_name, hid_t fapl, hid_t new_fapl); +static unsigned test_mf_align_alloc1(const char *driver_name, hid_t fapl, hid_t new_fapl); +static unsigned test_mf_align_alloc2(const char *driver_name, hid_t fapl, hid_t new_fapl); +static unsigned test_mf_align_alloc3(const char *driver_name, hid_t fapl, hid_t new_fapl); +static unsigned test_mf_align_alloc4(const char *driver_name, hid_t fapl, hid_t new_fapl); +static unsigned test_mf_align_alloc5(const char *driver_name, hid_t fapl, hid_t new_fapl); +static unsigned test_mf_align_alloc6(const char *driver_name, hid_t fapl, hid_t new_fapl); +static unsigned test_mf_tmp(const char *driver_name, hid_t fapl, bool new_format); +static unsigned test_mf_fs_gone(const char *driver_name, hid_t fapl, bool new_format); +static unsigned test_mf_strat_thres_gone(const char *driver_name, hid_t fapl, bool new_format); +static unsigned test_mf_fs_persist(const char *driver_name, hid_t fapl, bool new_format); +static unsigned test_mf_strat_thres_persist(const char *driver_name, hid_t fapl, bool new_format); #ifdef PB_OUT static unsigned test_mf_fs_persist_split(void); static unsigned test_mf_fs_persist_multi(void); #endif -static unsigned test_page_alloc_xfree(const char *env_h5_drvr, hid_t fapl); -static unsigned test_page_small(const char *env_h5_drvr, hid_t fapl); -static unsigned test_page_large(const char *env_h5_drvr, hid_t fapl); -static unsigned test_page_large_try_extend(const char *env_h5_drvr, hid_t fapl); -static unsigned test_page_small_try_extend(const char *env_h5_drvr, hid_t fapl); -static unsigned test_page_try_shrink(const char *env_h5_drvr, hid_t fapl); -static unsigned test_page_alignment(const char *env_h5_drvr, hid_t fapl); +static unsigned test_page_alloc_xfree(const char *driver_name, hid_t fapl); +static unsigned test_page_small(const char *driver_name, hid_t fapl); +static unsigned test_page_large(const char *driver_name, hid_t fapl); +static unsigned test_page_large_try_extend(const char *driver_name, hid_t fapl); +static unsigned test_page_small_try_extend(const char *driver_name, hid_t fapl); +static unsigned test_page_try_shrink(const char *driver_name, hid_t fapl); +static unsigned test_page_alignment(const char *driver_name, hid_t fapl); /* * Verify statistics for the free-space manager @@ -210,7 +210,7 @@ check_stats(const H5F_t *f, const H5FS_t *frsp, H5FS_stat_t *state) *------------------------------------------------------------------------- */ static unsigned -test_mf_eoa(const char *env_h5_drvr, hid_t fapl) +test_mf_eoa(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ hid_t fapl_new = H5I_INVALID_HID; /* copy of fapl */ @@ -228,8 +228,8 @@ test_mf_eoa(const char *env_h5_drvr, hid_t fapl) /* Skip test when using VFDs that has different address spaces for each * type of metadata allocation. Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -359,7 +359,7 @@ test_mf_eoa(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_eoa_shrink(const char *env_h5_drvr, hid_t fapl) +test_mf_eoa_shrink(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ hid_t fapl_new = H5I_INVALID_HID; /* copy of fapl */ @@ -377,8 +377,8 @@ test_mf_eoa_shrink(const char *env_h5_drvr, hid_t fapl) /* Skip test when using VFDs that has different address spaces for each * type of metadata allocation. Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -646,7 +646,7 @@ test_mf_eoa_shrink(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_eoa_extend(const char *env_h5_drvr, hid_t fapl) +test_mf_eoa_extend(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ hid_t fapl_new = H5I_INVALID_HID; /* copy of fapl */ @@ -665,8 +665,8 @@ test_mf_eoa_extend(const char *env_h5_drvr, hid_t fapl) /* Skip test when using VFDs that has different address spaces for each * type of metadata allocation. Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -861,7 +861,7 @@ test_mf_eoa_extend(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_tmp(const char *env_h5_drvr, hid_t fapl, bool new_format) +test_mf_tmp(const char *driver_name, hid_t fapl, bool new_format) { hid_t file = H5I_INVALID_HID; /* File ID */ hid_t fapl2 = H5I_INVALID_HID; /* File access property list */ @@ -873,7 +873,7 @@ test_mf_tmp(const char *env_h5_drvr, hid_t fapl, bool new_format) TESTING("'temporary' file space allocation with old library format"); /* Can't run this test with multi-file VFDs */ - if (!h5_driver_uses_multiple_files(env_h5_drvr, 0)) { + if (!h5_driver_uses_multiple_files(driver_name, 0)) { char filename[FILENAME_LEN]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ h5_stat_size_t file_size, new_file_size; /* file size */ @@ -2002,7 +2002,7 @@ test_mf_fs_extend(hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_fs_absorb(const char *env_h5_drvr, hid_t fapl) +test_mf_fs_absorb(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -2017,7 +2017,7 @@ test_mf_fs_absorb(const char *env_h5_drvr, hid_t fapl) TESTING("A free-space section absorbs an aggregator: test 1"); /* Skip test when using VFDs that don't use the metadata aggregator */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -2177,7 +2177,7 @@ test_mf_fs_absorb(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_aggr_alloc1(const char *env_h5_drvr, hid_t fapl) +test_mf_aggr_alloc1(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -2193,8 +2193,8 @@ test_mf_aggr_alloc1(const char *env_h5_drvr, hid_t fapl) TESTING("H5MF_alloc() of meta/sdata aggregator:test 1"); /* Skip test when using VFDs that don't use the metadata aggregator. Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -2330,7 +2330,7 @@ test_mf_aggr_alloc1(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_aggr_alloc2(const char *env_h5_drvr, hid_t fapl) +test_mf_aggr_alloc2(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -2345,8 +2345,8 @@ test_mf_aggr_alloc2(const char *env_h5_drvr, hid_t fapl) TESTING("H5MF_alloc() of meta/sdata aggregator:test 2"); /* Skip test when using VFDs that don't use the metadata aggregator. Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -2487,7 +2487,7 @@ test_mf_aggr_alloc2(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_aggr_alloc3(const char *env_h5_drvr, hid_t fapl) +test_mf_aggr_alloc3(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -2504,7 +2504,7 @@ test_mf_aggr_alloc3(const char *env_h5_drvr, hid_t fapl) TESTING("H5MF_alloc() of meta/sdata aggregator: test 3"); /* Skip test when using VFDs that don't use the metadata aggregator */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -2657,7 +2657,7 @@ test_mf_aggr_alloc3(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_aggr_alloc4(const char *env_h5_drvr, hid_t fapl) +test_mf_aggr_alloc4(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -2672,7 +2672,7 @@ test_mf_aggr_alloc4(const char *env_h5_drvr, hid_t fapl) TESTING("H5MF_alloc() of meta/sdata aggregator:test 4"); /* Skip test when using VFDs that don't use the metadata aggregator */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -2806,7 +2806,7 @@ test_mf_aggr_alloc4(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_aggr_alloc5(const char *env_h5_drvr, hid_t fapl) +test_mf_aggr_alloc5(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -2821,7 +2821,7 @@ test_mf_aggr_alloc5(const char *env_h5_drvr, hid_t fapl) TESTING("H5MF_alloc() of meta/sdata aggregator:test 5"); /* Skip test when using VFDs that don't use the metadata aggregator */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -2943,7 +2943,7 @@ test_mf_aggr_alloc5(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_aggr_alloc6(const char *env_h5_drvr, hid_t fapl) +test_mf_aggr_alloc6(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -2959,7 +2959,7 @@ test_mf_aggr_alloc6(const char *env_h5_drvr, hid_t fapl) TESTING("H5MF_alloc() of meta/sdata aggregator:test 6"); /* Skip test when using VFDs that don't use the metadata aggregator */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -3117,7 +3117,7 @@ test_mf_aggr_alloc6(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_aggr_alloc7(const char *env_h5_drvr, hid_t fapl) +test_mf_aggr_alloc7(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -3133,7 +3133,7 @@ test_mf_aggr_alloc7(const char *env_h5_drvr, hid_t fapl) TESTING("H5MF_alloc() of meta/sdata aggregator:test 7"); /* Skip test when using VFDs that don't use the metadata aggregator */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -3288,7 +3288,7 @@ test_mf_aggr_alloc7(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_aggr_extend(const char *env_h5_drvr, hid_t fapl) +test_mf_aggr_extend(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -3304,7 +3304,7 @@ test_mf_aggr_extend(const char *env_h5_drvr, hid_t fapl) TESTING("H5MF_try_extend() of meta/sdata aggregator: test 1"); /* Skip test when using VFDs that don't use the metadata aggregator */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -3585,7 +3585,7 @@ test_mf_aggr_extend(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_aggr_absorb(const char *env_h5_drvr, hid_t fapl) +test_mf_aggr_absorb(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -3602,7 +3602,7 @@ test_mf_aggr_absorb(const char *env_h5_drvr, hid_t fapl) TESTING("H5MF_try_shrink() of meta/sdata aggregator: test 1"); /* Skip test when using VFDs that don't use the metadata aggregator */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -3835,7 +3835,7 @@ test_mf_aggr_absorb(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_align_eoa(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) +test_mf_align_eoa(const char *driver_name, hid_t fapl, hid_t new_fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ hid_t fapl1 = H5I_INVALID_HID; @@ -3857,8 +3857,8 @@ test_mf_align_eoa(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) * don't push mis-aligned space fragments on the file free space list. * Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 && - strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "stdio") != 0 && strcmp(driver_name, "split") != 0 && + strcmp(driver_name, "multi") != 0 && strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -4132,7 +4132,7 @@ test_mf_align_eoa(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_align_fs(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) +test_mf_align_fs(const char *driver_name, hid_t fapl, hid_t new_fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -4307,8 +4307,8 @@ test_mf_align_fs(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) * don't push mis-aligned space fragments on the file free space list * Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 && - strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "stdio") != 0 && strcmp(driver_name, "split") != 0 && + strcmp(driver_name, "multi") != 0 && strcmp(driver_name, "direct") != 0); if (suitable_vfd) { if ((file_size = h5_get_file_size(filename, new_fapl)) < 0) TEST_ERROR; @@ -4493,7 +4493,7 @@ test_mf_align_fs(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_align_alloc1(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) +test_mf_align_alloc1(const char *driver_name, hid_t fapl, hid_t new_fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -4514,8 +4514,8 @@ test_mf_align_alloc1(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) * don't push mis-aligned space fragments on the file free space list. * Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 && - strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "stdio") != 0 && strcmp(driver_name, "split") != 0 && + strcmp(driver_name, "multi") != 0 && strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -4757,7 +4757,7 @@ test_mf_align_alloc1(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) +test_mf_align_alloc2(const char *driver_name, hid_t fapl, hid_t new_fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -4777,8 +4777,8 @@ test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) * don't push mis-aligned space fragments on the file free space list. * Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 && - strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "stdio") != 0 && strcmp(driver_name, "split") != 0 && + strcmp(driver_name, "multi") != 0 && strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -5102,7 +5102,7 @@ test_mf_align_alloc2(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) +test_mf_align_alloc3(const char *driver_name, hid_t fapl, hid_t new_fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -5123,8 +5123,8 @@ test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) * don't push mis-aligned space fragments on the file free space list. * Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 && - strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "stdio") != 0 && strcmp(driver_name, "split") != 0 && + strcmp(driver_name, "multi") != 0 && strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -5417,7 +5417,7 @@ test_mf_align_alloc3(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_align_alloc4(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) +test_mf_align_alloc4(const char *driver_name, hid_t fapl, hid_t new_fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -5437,8 +5437,8 @@ test_mf_align_alloc4(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) * don't push mis-aligned space fragments on the file free space list. * Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 && - strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "stdio") != 0 && strcmp(driver_name, "split") != 0 && + strcmp(driver_name, "multi") != 0 && strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -5635,7 +5635,7 @@ test_mf_align_alloc4(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) +test_mf_align_alloc5(const char *driver_name, hid_t fapl, hid_t new_fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -5656,8 +5656,8 @@ test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) * don't push mis-aligned space fragments on the file free space list. * Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 && - strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "stdio") != 0 && strcmp(driver_name, "split") != 0 && + strcmp(driver_name, "multi") != 0 && strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -5906,7 +5906,7 @@ test_mf_align_alloc5(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) *------------------------------------------------------------------------- */ static unsigned -test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) +test_mf_align_alloc6(const char *driver_name, hid_t fapl, hid_t new_fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ char filename[FILENAME_LEN]; /* Filename to use */ @@ -5927,8 +5927,8 @@ test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) * don't push mis-aligned space fragments on the file free space list. * Also skip test for Direct VFD. */ - suitable_vfd = (bool)(strcmp(env_h5_drvr, "stdio") != 0 && strcmp(env_h5_drvr, "split") != 0 && - strcmp(env_h5_drvr, "multi") != 0 && strcmp(env_h5_drvr, "direct") != 0); + suitable_vfd = (bool)(strcmp(driver_name, "stdio") != 0 && strcmp(driver_name, "split") != 0 && + strcmp(driver_name, "multi") != 0 && strcmp(driver_name, "direct") != 0); if (suitable_vfd) { /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -6116,7 +6116,7 @@ test_mf_align_alloc6(const char *env_h5_drvr, hid_t fapl, hid_t new_fapl) * endpoint is extended to allocate an aligned object */ static unsigned -test_mf_bug1(const char *env_h5_drvr, hid_t fapl) +test_mf_bug1(const char *driver_name, hid_t fapl) { hid_t file = H5I_INVALID_HID; /* File ID */ hid_t copied_fapl = H5I_INVALID_HID; /* FAPL to use for this test */ @@ -6147,9 +6147,9 @@ test_mf_bug1(const char *env_h5_drvr, hid_t fapl) TEST_ERROR; /* Check for split or multi driver */ - if (!strcmp(env_h5_drvr, "split")) + if (!strcmp(driver_name, "split")) split = true; - else if (!strcmp(env_h5_drvr, "multi")) + else if (!strcmp(driver_name, "multi")) multi = true; /* Add alignment to member files for split/multi driver */ @@ -6931,7 +6931,7 @@ test_mf_fs_persist_multi(void) *------------------------------------------------------------------------- */ static unsigned -test_mf_fs_persist(const char *env_h5_drvr, hid_t fapl, bool new_format) +test_mf_fs_persist(const char *driver_name, hid_t fapl, bool new_format) { hid_t file = H5I_INVALID_HID; /* File ID */ hid_t fcpl = H5I_INVALID_HID; /* File creation property list ID */ @@ -6949,7 +6949,7 @@ test_mf_fs_persist(const char *env_h5_drvr, hid_t fapl, bool new_format) else TESTING("File's free-space is persistent with old library format"); - if (strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0) { + if (strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0) { /* File creation property list template */ if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) @@ -7106,7 +7106,7 @@ test_mf_fs_persist(const char *env_h5_drvr, hid_t fapl, bool new_format) *------------------------------------------------------------------------- */ static unsigned -test_mf_fs_gone(const char *env_h5_drvr, hid_t fapl, bool new_format) +test_mf_fs_gone(const char *driver_name, hid_t fapl, bool new_format) { hid_t file = H5I_INVALID_HID; /* File ID */ hid_t fcpl = H5I_INVALID_HID; /* File creation property list */ @@ -7126,7 +7126,7 @@ test_mf_fs_gone(const char *env_h5_drvr, hid_t fapl, bool new_format) TESTING("File's free-space is going away with old library format"); /* Current VFD that does not support contiguous address space */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { @@ -7296,7 +7296,7 @@ test_mf_fs_gone(const char *env_h5_drvr, hid_t fapl, bool new_format) *------------------------------------------------------------------------- */ static unsigned -test_mf_strat_thres_persist(const char *env_h5_drvr, hid_t fapl, bool new_format) +test_mf_strat_thres_persist(const char *driver_name, hid_t fapl, bool new_format) { hid_t file = H5I_INVALID_HID; /* File ID */ hid_t fcpl = H5I_INVALID_HID; /* File creation property list template */ @@ -7317,7 +7317,7 @@ test_mf_strat_thres_persist(const char *env_h5_drvr, hid_t fapl, bool new_format TESTING("File space strategy/persisting/threshold with old library format"); /* Current VFD that does not support contiguous address space */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -7465,7 +7465,7 @@ test_mf_strat_thres_persist(const char *env_h5_drvr, hid_t fapl, bool new_format *------------------------------------------------------------------------- */ static unsigned -test_mf_strat_thres_gone(const char *env_h5_drvr, hid_t fapl, bool new_format) +test_mf_strat_thres_gone(const char *driver_name, hid_t fapl, bool new_format) { hid_t file = H5I_INVALID_HID; /* File ID */ hid_t fcpl = H5I_INVALID_HID; /* File creation property list template */ @@ -7487,7 +7487,7 @@ test_mf_strat_thres_gone(const char *env_h5_drvr, hid_t fapl, bool new_format) TESTING("File space merge/shrink for section size < threshold with old library format"); /* Current VFD that does not support contiguous address space */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -7801,7 +7801,7 @@ set_multi_split(hid_t fapl, hsize_t pagesize, bool is_multi_or_split) *------------------------------------------------------------------------- */ static unsigned -test_page_alloc_xfree(const char *env_h5_drvr, hid_t fapl) +test_page_alloc_xfree(const char *driver_name, hid_t fapl) { hid_t fid = H5I_INVALID_HID; /* File ID */ @@ -7819,9 +7819,9 @@ test_page_alloc_xfree(const char *env_h5_drvr, hid_t fapl) TESTING("Paged aggregation for file space: H5MF_alloc/H5MF_xfree"); /* Check for split or multi driver */ - if (!strcmp(env_h5_drvr, "split")) + if (!strcmp(driver_name, "split")) split = true; - else if (!strcmp(env_h5_drvr, "multi")) + else if (!strcmp(driver_name, "multi")) multi = true; if (!multi && !split) { @@ -8031,7 +8031,7 @@ test_page_alloc_xfree(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_page_try_shrink(const char *env_h5_drvr, hid_t fapl) +test_page_try_shrink(const char *driver_name, hid_t fapl) { hid_t fid = H5I_INVALID_HID; /* File ID */ @@ -8048,7 +8048,7 @@ test_page_try_shrink(const char *env_h5_drvr, hid_t fapl) TESTING("Paged aggregation for file space: H5MF_try_shrink()"); /* Current VFD that does not support continuous address space */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { @@ -8160,7 +8160,7 @@ test_page_try_shrink(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_page_small_try_extend(const char *env_h5_drvr, hid_t fapl) +test_page_small_try_extend(const char *driver_name, hid_t fapl) { hid_t fid = H5I_INVALID_HID; /* File ID */ @@ -8175,8 +8175,8 @@ test_page_small_try_extend(const char *env_h5_drvr, hid_t fapl) TESTING("Paged aggregation for file space: H5MF_try_extend() a small block"); /* Current VFD that does not support continuous address space */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "family") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "family") != 0); if (contig_addr_vfd) { @@ -8338,7 +8338,7 @@ test_page_small_try_extend(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_page_large_try_extend(const char *env_h5_drvr, hid_t fapl) +test_page_large_try_extend(const char *driver_name, hid_t fapl) { hid_t fid = H5I_INVALID_HID; /* File ID */ @@ -8352,7 +8352,7 @@ test_page_large_try_extend(const char *env_h5_drvr, hid_t fapl) TESTING("Paged aggregation for file space: H5MF_try_extend() a large block"); /* Current VFD that does not support continuous address space */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { @@ -8499,7 +8499,7 @@ test_page_large_try_extend(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_page_large(const char *env_h5_drvr, hid_t fapl) +test_page_large(const char *driver_name, hid_t fapl) { hid_t fid = H5I_INVALID_HID; /* File ID */ @@ -8514,7 +8514,7 @@ test_page_large(const char *env_h5_drvr, hid_t fapl) TESTING("Paged aggregation for file space: large allocations and de-allocations"); /* Current VFD that does not support continuous address space */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); if (contig_addr_vfd) { @@ -8652,7 +8652,7 @@ test_page_large(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_page_small(const char *env_h5_drvr, hid_t fapl) +test_page_small(const char *driver_name, hid_t fapl) { hid_t fid = H5I_INVALID_HID; /* File ID */ hid_t fcpl = H5I_INVALID_HID; /* File creation property list */ @@ -8666,11 +8666,11 @@ test_page_small(const char *env_h5_drvr, hid_t fapl) TESTING("Paged aggregation for file space: small allocations and de-allocations"); - if (!strcmp(env_h5_drvr, "split")) + if (!strcmp(driver_name, "split")) split = true; - else if (!strcmp(env_h5_drvr, "multi")) + else if (!strcmp(driver_name, "multi")) multi = true; - else if (!strcmp(env_h5_drvr, "family")) + else if (!strcmp(driver_name, "family")) family = true; if (!multi && !split) { @@ -8822,7 +8822,7 @@ test_page_small(const char *env_h5_drvr, hid_t fapl) *------------------------------------------------------------------------- */ static unsigned -test_page_alignment(const char *env_h5_drvr, hid_t fapl) +test_page_alignment(const char *driver_name, hid_t fapl) { hid_t fid = H5I_INVALID_HID; /* File ID */ @@ -8839,9 +8839,9 @@ test_page_alignment(const char *env_h5_drvr, hid_t fapl) TESTING("Paged aggregation and H5Pset_alignment: verify proper alignment is used"); /* Check for split or multi driver */ - if (!strcmp(env_h5_drvr, "split")) + if (!strcmp(driver_name, "split")) split = true; - else if (!strcmp(env_h5_drvr, "multi")) + else if (!strcmp(driver_name, "multi")) multi = true; if (!multi && !split) { @@ -9130,13 +9130,11 @@ main(void) hid_t new_fapl = H5I_INVALID_HID; /* File access property list for alignment & aggr setting */ unsigned nerrors = 0; /* Cumulative error count */ test_type_t curr_test; /* Current test being worked on */ - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ bool api_ctx_pushed = false; /* Whether API context pushed */ /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); h5_reset(); @@ -9151,9 +9149,9 @@ main(void) if ((new_fapl = H5Pcopy(fapl)) < 0) TEST_ERROR; /* For old library format--interaction with file allocation */ - nerrors += test_mf_eoa(env_h5_drvr, fapl); - nerrors += test_mf_eoa_shrink(env_h5_drvr, fapl); - nerrors += test_mf_eoa_extend(env_h5_drvr, fapl); + nerrors += test_mf_eoa(driver_name, fapl); + nerrors += test_mf_eoa_shrink(driver_name, fapl); + nerrors += test_mf_eoa_extend(driver_name, fapl); /* For old library format */ nerrors += test_dichotomy(new_fapl); @@ -9162,18 +9160,18 @@ main(void) nerrors += test_mf_fs_start(fapl); nerrors += test_mf_fs_alloc_free(fapl); nerrors += test_mf_fs_extend(fapl); - nerrors += test_mf_fs_absorb(env_h5_drvr, fapl); + nerrors += test_mf_fs_absorb(driver_name, fapl); /* For old library format--interaction with meta/sdata aggregator */ - nerrors += test_mf_aggr_alloc1(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc2(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc3(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc4(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc5(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc6(env_h5_drvr, fapl); - nerrors += test_mf_aggr_alloc7(env_h5_drvr, fapl); - nerrors += test_mf_aggr_extend(env_h5_drvr, fapl); - nerrors += test_mf_aggr_absorb(env_h5_drvr, fapl); + nerrors += test_mf_aggr_alloc1(driver_name, fapl); + nerrors += test_mf_aggr_alloc2(driver_name, fapl); + nerrors += test_mf_aggr_alloc3(driver_name, fapl); + nerrors += test_mf_aggr_alloc4(driver_name, fapl); + nerrors += test_mf_aggr_alloc5(driver_name, fapl); + nerrors += test_mf_aggr_alloc6(driver_name, fapl); + nerrors += test_mf_aggr_alloc7(driver_name, fapl); + nerrors += test_mf_aggr_extend(driver_name, fapl); + nerrors += test_mf_aggr_absorb(driver_name, fapl); /* For old library format--tests for alignment */ for (curr_test = TEST_NORMAL; curr_test < TEST_NTESTS; curr_test++) { @@ -9195,43 +9193,43 @@ main(void) break; } /* end switch */ - nerrors += test_mf_align_eoa(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_fs(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc1(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc2(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc3(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc4(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc5(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc6(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_eoa(driver_name, fapl, new_fapl); + nerrors += test_mf_align_fs(driver_name, fapl, new_fapl); + nerrors += test_mf_align_alloc1(driver_name, fapl, new_fapl); + nerrors += test_mf_align_alloc2(driver_name, fapl, new_fapl); + nerrors += test_mf_align_alloc3(driver_name, fapl, new_fapl); + nerrors += test_mf_align_alloc4(driver_name, fapl, new_fapl); + nerrors += test_mf_align_alloc5(driver_name, fapl, new_fapl); + nerrors += test_mf_align_alloc6(driver_name, fapl, new_fapl); } /* end for */ /* For old and new format--interaction with temporary file space allocation */ - nerrors += test_mf_tmp(env_h5_drvr, fapl, false); - nerrors += test_mf_tmp(env_h5_drvr, fapl, true); + nerrors += test_mf_tmp(driver_name, fapl, false); + nerrors += test_mf_tmp(driver_name, fapl, true); /* For old and new format--free-space merge/shrunk away */ /* Temporary: modify to skip testing for multi/split driver: fail file create when persisting free-space or using paged aggregation strategy */ - nerrors += test_mf_fs_gone(env_h5_drvr, fapl, false); - nerrors += test_mf_fs_gone(env_h5_drvr, fapl, true); + nerrors += test_mf_fs_gone(driver_name, fapl, false); + nerrors += test_mf_fs_gone(driver_name, fapl, true); /* Temporary: modify to skip testing multi/split driver: fail file create when persisting free-space or using paged aggregation strategy */ - nerrors += test_mf_strat_thres_gone(env_h5_drvr, fapl, false); - nerrors += test_mf_strat_thres_gone(env_h5_drvr, fapl, true); + nerrors += test_mf_strat_thres_gone(driver_name, fapl, false); + nerrors += test_mf_strat_thres_gone(driver_name, fapl, true); /* For old and new format--persisting free-space */ /* Temporary: Modify to skip testing for multi/split driver: fail file create when persisting free-space or using paged aggregation strategy */ - nerrors += test_mf_fs_persist(env_h5_drvr, fapl, false); - nerrors += test_mf_fs_persist(env_h5_drvr, fapl, true); + nerrors += test_mf_fs_persist(driver_name, fapl, false); + nerrors += test_mf_fs_persist(driver_name, fapl, true); /* Temporary: modify to skip testing for multi/split driver: fail file create when persisting free-space or using paged aggregation strategy */ - nerrors += test_mf_strat_thres_persist(env_h5_drvr, fapl, false); - nerrors += test_mf_strat_thres_persist(env_h5_drvr, fapl, true); + nerrors += test_mf_strat_thres_persist(driver_name, fapl, false); + nerrors += test_mf_strat_thres_persist(driver_name, fapl, true); /* Temporary skipped for multi/split drivers: fail file create when persisting free-space or using paged aggregation strategy */ @@ -9246,16 +9244,16 @@ main(void) */ /* Temporary: The following 7 tests are modified to skip testing for multi/split driver: fail file create when persisting free-space or using paged aggregation strategy */ - nerrors += test_page_small(env_h5_drvr, fapl); - nerrors += test_page_large(env_h5_drvr, fapl); - nerrors += test_page_large_try_extend(env_h5_drvr, fapl); - nerrors += test_page_small_try_extend(env_h5_drvr, fapl); - nerrors += test_page_try_shrink(env_h5_drvr, fapl); - nerrors += test_page_alloc_xfree(env_h5_drvr, fapl); /* can handle multi/split */ - nerrors += test_page_alignment(env_h5_drvr, fapl); /* can handle multi/split */ + nerrors += test_page_small(driver_name, fapl); + nerrors += test_page_large(driver_name, fapl); + nerrors += test_page_large_try_extend(driver_name, fapl); + nerrors += test_page_small_try_extend(driver_name, fapl); + nerrors += test_page_try_shrink(driver_name, fapl); + nerrors += test_page_alloc_xfree(driver_name, fapl); /* can handle multi/split */ + nerrors += test_page_alignment(driver_name, fapl); /* can handle multi/split */ /* tests for specific bugs */ - nerrors += test_mf_bug1(env_h5_drvr, fapl); + nerrors += test_mf_bug1(driver_name, fapl); if (H5Pclose(new_fapl) < 0) FAIL_STACK_ERROR; diff --git a/test/objcopy.c b/test/objcopy.c index 08e7b07fbe5..9205e961c22 100644 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -17124,13 +17124,11 @@ main(void) unsigned max_compact, min_dense; int configuration; /* Configuration of tests. */ int ExpressMode; - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ bool same_file; /* Whether to run tests that only use one file */ bool driver_is_default_compatible; - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Setup */ h5_reset(); @@ -17292,7 +17290,7 @@ main(void) false, "H5Ocopy(): expand external link"); /* Splitter VFD currently has external link-related bugs */ - if (strcmp(env_h5_drvr, "splitter")) { + if (strcmp(driver_name, "splitter")) { nerrors += test_copy_option(fcpl_src, fcpl_dst, src_fapl, dst_fapl, H5O_COPY_EXPAND_SOFT_LINK_FLAG | H5O_COPY_EXPAND_EXT_LINK_FLAG, false, "H5Ocopy(): expand soft and external links"); diff --git a/test/ohdr.c b/test/ohdr.c index 99b979b0777..87f88f64ac5 100644 --- a/test/ohdr.c +++ b/test/ohdr.c @@ -1827,7 +1827,7 @@ main(void) hid_t fapl = H5I_INVALID_HID; hid_t file = H5I_INVALID_HID; H5F_t *f = NULL; - const char *env_h5_drvr; /* File driver value from environment */ + const char *driver_name; /* File driver value from environment */ bool single_file_vfd; /* Whether VFD used stores data in a single file */ char filename[1024]; H5O_hdr_info_t hdr_info; /* Object info */ @@ -1839,12 +1839,10 @@ main(void) herr_t ret; /* Generic return value */ /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Check for VFD which stores data in multiple files */ - single_file_vfd = !h5_driver_uses_multiple_files(env_h5_drvr, 0); + single_file_vfd = !h5_driver_uses_multiple_files(driver_name, 0); /* Reset library */ h5_reset(); @@ -2132,7 +2130,7 @@ main(void) if (h5_verify_cached_stabs(FILENAME, fapl) < 0) TEST_ERROR; - if (H5FD__supports_swmr_test(env_h5_drvr)) { + if (H5FD__supports_swmr_test(driver_name)) { /* A test to exercise the re-read of the object header for SWMR access */ if (test_ohdr_swmr(true) < 0) TEST_ERROR; diff --git a/test/onion.c b/test/onion.c index 5b9bb929dc6..1632c410b83 100644 --- a/test/onion.c +++ b/test/onion.c @@ -4908,8 +4908,8 @@ test_integration_create_by_name(void) int main(void) { - const char *env_h5_drvr = NULL; /* VFD value from environment */ - int nerrors = 0; + const char *driver_name; /* VFD value from environment */ + int nerrors = 0; printf("Testing Onion VFD functionality.\n"); @@ -4918,10 +4918,8 @@ main(void) /* The onion VFD only supports the sec2 VFD under the hood, so skip this * test when the environment variable has been set to something else */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; - if ((0 != strcmp(env_h5_drvr, "nomatch")) && (0 != strcmp(env_h5_drvr, "sec2"))) { + driver_name = h5_get_test_driver_name(); + if (0 != strcmp(driver_name, "sec2")) { SKIPPED(); puts("Onion VFD test skipped due to non-sec2 default VFD"); exit(EXIT_SUCCESS); diff --git a/test/page_buffer.c b/test/page_buffer.c index 651e84a348c..8c977fedf44 100644 --- a/test/page_buffer.c +++ b/test/page_buffer.c @@ -39,17 +39,17 @@ /* test routines */ #ifdef H5_HAVE_PARALLEL -static unsigned verify_page_buffering_disabled(hid_t orig_fapl, const char *env_h5_drvr); +static unsigned verify_page_buffering_disabled(hid_t orig_fapl, const char *driver_name); #else #define NUM_DSETS 5 #define NX 100 #define NY 50 -static unsigned test_args(hid_t fapl, const char *env_h5_drvr); -static unsigned test_raw_data_handling(hid_t orig_fapl, const char *env_h5_drvr); -static unsigned test_lru_processing(hid_t orig_fapl, const char *env_h5_drvr); -static unsigned test_min_threshold(hid_t orig_fapl, const char *env_h5_drvr); -static unsigned test_stats_collection(hid_t orig_fapl, const char *env_h5_drvr); +static unsigned test_args(hid_t fapl, const char *driver_name); +static unsigned test_raw_data_handling(hid_t orig_fapl, const char *driver_name); +static unsigned test_lru_processing(hid_t orig_fapl, const char *driver_name); +static unsigned test_min_threshold(hid_t orig_fapl, const char *driver_name); +static unsigned test_stats_collection(hid_t orig_fapl, const char *driver_name); /* helper routines */ static unsigned create_file(char *filename, hid_t fcpl, hid_t fapl); @@ -299,7 +299,7 @@ open_file(char *filename, hid_t fapl, hsize_t page_size, size_t page_buffer_size * */ static unsigned -set_multi_split(const char *env_h5_drvr, hid_t fapl, hsize_t pagesize) +set_multi_split(const char *driver_name, hid_t fapl, hsize_t pagesize) { bool split = false; bool multi = false; @@ -311,9 +311,9 @@ set_multi_split(const char *env_h5_drvr, hid_t fapl, hsize_t pagesize) H5FD_mem_t mt; /* Check for split or multi driver */ - if (!strcmp(env_h5_drvr, "split")) + if (!strcmp(driver_name, "split")) split = true; - else if (!strcmp(env_h5_drvr, "multi")) + else if (!strcmp(driver_name, "multi")) multi = true; if (split || multi) { @@ -374,7 +374,7 @@ set_multi_split(const char *env_h5_drvr, hid_t fapl, hsize_t pagesize) *------------------------------------------------------------------------- */ static unsigned -test_args(hid_t orig_fapl, const char *env_h5_drvr) +test_args(hid_t orig_fapl, const char *driver_name) { char filename[FILENAME_LEN]; /* Filename to use */ hid_t file_id = H5I_INVALID_HID; /* File ID */ @@ -440,7 +440,7 @@ test_args(hid_t orig_fapl, const char *env_h5_drvr) if (ret >= 0) TEST_ERROR; - if (set_multi_split(env_h5_drvr, fapl, 512) != 0) + if (set_multi_split(driver_name, fapl, 512) != 0) TEST_ERROR; /* Test setting a page buffer with a size equal to a single page size */ @@ -477,7 +477,7 @@ test_args(hid_t orig_fapl, const char *env_h5_drvr) if (open_file(filename, fapl, 512, 512) != 0) TEST_ERROR; - if (set_multi_split(env_h5_drvr, fapl, 4194304) != 0) + if (set_multi_split(driver_name, fapl, 4194304) != 0) TEST_ERROR; /* Test setting a large page buffer size and page size */ @@ -496,7 +496,7 @@ test_args(hid_t orig_fapl, const char *env_h5_drvr) if (open_file(filename, fapl, 4194304, 16777216) != 0) TEST_ERROR; - if (set_multi_split(env_h5_drvr, fapl, 1) != 0) + if (set_multi_split(driver_name, fapl, 1) != 0) TEST_ERROR; /* Test setting a 512 byte page buffer size and page size */ @@ -545,7 +545,7 @@ test_args(hid_t orig_fapl, const char *env_h5_drvr) *------------------------------------------------------------------------- */ static unsigned -test_raw_data_handling(hid_t orig_fapl, const char *env_h5_drvr) +test_raw_data_handling(hid_t orig_fapl, const char *driver_name) { char filename[FILENAME_LEN]; /* Filename to use */ hid_t file_id = H5I_INVALID_HID; /* File ID */ @@ -565,7 +565,7 @@ test_raw_data_handling(hid_t orig_fapl, const char *env_h5_drvr) if ((fapl = H5Pcopy(orig_fapl)) < 0) TEST_ERROR; - if (set_multi_split(env_h5_drvr, fapl, sizeof(int) * 200) != 0) + if (set_multi_split(driver_name, fapl, sizeof(int) * 200) != 0) TEST_ERROR; if ((data = (int *)calloc((size_t)num_elements, sizeof(int))) == NULL) @@ -808,7 +808,7 @@ test_raw_data_handling(hid_t orig_fapl, const char *env_h5_drvr) */ static unsigned -test_lru_processing(hid_t orig_fapl, const char *env_h5_drvr) +test_lru_processing(hid_t orig_fapl, const char *driver_name) { char filename[FILENAME_LEN]; /* Filename to use */ hid_t file_id = H5I_INVALID_HID; /* File ID */ @@ -830,7 +830,7 @@ test_lru_processing(hid_t orig_fapl, const char *env_h5_drvr) if ((fapl = H5Pcopy(orig_fapl)) < 0) FAIL_STACK_ERROR; - if (set_multi_split(env_h5_drvr, fapl, sizeof(int) * 200) != 0) + if (set_multi_split(driver_name, fapl, sizeof(int) * 200) != 0) TEST_ERROR; if ((data = (int *)calloc((size_t)num_elements, sizeof(int))) == NULL) @@ -1047,7 +1047,7 @@ test_lru_processing(hid_t orig_fapl, const char *env_h5_drvr) */ static unsigned -test_min_threshold(hid_t orig_fapl, const char *env_h5_drvr) +test_min_threshold(hid_t orig_fapl, const char *driver_name) { char filename[FILENAME_LEN]; /* Filename to use */ hid_t file_id = H5I_INVALID_HID; /* File ID */ @@ -1071,7 +1071,7 @@ test_min_threshold(hid_t orig_fapl, const char *env_h5_drvr) if ((fapl = H5Pcopy(orig_fapl)) < 0) TEST_ERROR; - if (set_multi_split(env_h5_drvr, fapl, sizeof(int) * 200) != 0) + if (set_multi_split(driver_name, fapl, sizeof(int) * 200) != 0) TEST_ERROR; if ((data = (int *)calloc((size_t)num_elements, sizeof(int))) == NULL) @@ -1665,7 +1665,7 @@ test_min_threshold(hid_t orig_fapl, const char *env_h5_drvr) *------------------------------------------------------------------------- */ static unsigned -test_stats_collection(hid_t orig_fapl, const char *env_h5_drvr) +test_stats_collection(hid_t orig_fapl, const char *driver_name) { char filename[FILENAME_LEN]; /* Filename to use */ hid_t file_id = H5I_INVALID_HID; /* File ID */ @@ -1687,7 +1687,7 @@ test_stats_collection(hid_t orig_fapl, const char *env_h5_drvr) if ((fapl = H5Pcopy(orig_fapl)) < 0) TEST_ERROR; - if (set_multi_split(env_h5_drvr, fapl, sizeof(int) * 200) != 0) + if (set_multi_split(driver_name, fapl, sizeof(int) * 200) != 0) TEST_ERROR; if ((data = (int *)calloc((size_t)num_elements, sizeof(int))) == NULL) @@ -1954,7 +1954,7 @@ test_stats_collection(hid_t orig_fapl, const char *env_h5_drvr) #ifdef H5_HAVE_PARALLEL static unsigned -verify_page_buffering_disabled(hid_t orig_fapl, const char *env_h5_drvr) +verify_page_buffering_disabled(hid_t orig_fapl, const char *driver_name) { char filename[FILENAME_LEN]; /* Filename to use */ hid_t file_id = H5I_INVALID_HID; /* File ID */ @@ -1969,7 +1969,7 @@ verify_page_buffering_disabled(hid_t orig_fapl, const char *env_h5_drvr) if ((fapl = H5Pcopy(orig_fapl)) < 0) TEST_ERROR; - if (set_multi_split(env_h5_drvr, fapl, 4096) != 0) + if (set_multi_split(driver_name, fapl, 4096) != 0) TEST_ERROR; if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) @@ -2066,21 +2066,19 @@ main(void) { hid_t fapl = H5I_INVALID_HID; /* File access property list for data files */ unsigned nerrors = 0; /* Cumulative error count */ - const char *env_h5_drvr = NULL; /* File Driver value from environment */ + const char *driver_name = NULL; /* File Driver value from environment */ bool api_ctx_pushed = false; /* Whether API context pushed */ h5_reset(); /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Temporary skip testing with multi/split drivers: * Page buffering depends on paged aggregation which is * currently disabled for multi/split drivers. */ - if ((0 == strcmp(env_h5_drvr, "multi")) || (0 == strcmp(env_h5_drvr, "split"))) { + if ((0 == strcmp(driver_name, "multi")) || (0 == strcmp(driver_name, "split"))) { SKIPPED(); puts("Skip page buffering test because paged aggregation is disabled for multi/split drivers"); @@ -2100,15 +2098,15 @@ main(void) #ifdef H5_HAVE_PARALLEL puts("Page Buffering is disabled for parallel."); - nerrors += verify_page_buffering_disabled(fapl, env_h5_drvr); + nerrors += verify_page_buffering_disabled(fapl, driver_name); #else /* H5_HAVE_PARALLEL */ - nerrors += test_args(fapl, env_h5_drvr); - nerrors += test_raw_data_handling(fapl, env_h5_drvr); - nerrors += test_lru_processing(fapl, env_h5_drvr); - nerrors += test_min_threshold(fapl, env_h5_drvr); - nerrors += test_stats_collection(fapl, env_h5_drvr); + nerrors += test_args(fapl, driver_name); + nerrors += test_raw_data_handling(fapl, driver_name); + nerrors += test_lru_processing(fapl, driver_name); + nerrors += test_min_threshold(fapl, driver_name); + nerrors += test_stats_collection(fapl, driver_name); #endif /* H5_HAVE_PARALLEL */ diff --git a/test/reserved.c b/test/reserved.c index 5540d044b62..3762bd9deb4 100644 --- a/test/reserved.c +++ b/test/reserved.c @@ -462,16 +462,15 @@ main(void) * (Also, we should try to make this test work with all the VFDs) */ #ifdef BROKEN + const char *driver_name; int num_errs = 0; hid_t fapl; - const char *envval = NULL; - envval = getenv(HDF5_DRIVER); - if (envval == NULL) - envval = "nomatch"; + driver_name = h5_get_test_driver_name(); + /* QAK: should be able to use the core driver? */ - if (strcmp(envval, "core") && strcmp(envval, "split") && strcmp(envval, "multi") && - strcmp(envval, "family")) { + if (strcmp(driver_name, "core") && strcmp(driver_name, "split") && strcmp(driver_name, "multi") && + strcmp(driver_name, "family")) { num_errs += rsrv_ohdr(); num_errs += rsrv_heap(); num_errs += rsrv_vlen(); diff --git a/test/select_io_dset.c b/test/select_io_dset.c index 1ff7fe22f9e..2f440d8eec0 100644 --- a/test/select_io_dset.c +++ b/test/select_io_dset.c @@ -2934,12 +2934,11 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_ /* Check for (currently) incompatible combinations */ if (test_mode & TEST_PAGE_BUFFER) { - char *env_h5_drvr = NULL; + const char *driver_name = h5_get_test_driver_name(); /* The split and multi driver are not compatible with page buffering. No message since the other * cases aren't skipped. */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr && (!strcmp(env_h5_drvr, "split") || !strcmp(env_h5_drvr, "multi"))) + if (driver_name && (!strcmp(driver_name, "split") || !strcmp(driver_name, "multi"))) return 0; } @@ -3389,9 +3388,19 @@ main(void) h5_cleanup(FILENAME, fapl); + H5Pclose(fapl2); + exit(EXIT_SUCCESS); error: + H5E_BEGIN_TRY + { + H5Pclose(fapl); + H5Pclose(fapl2); + H5Fclose(fid); + } + H5E_END_TRY + nerrors = MAX(1, nerrors); printf("***** %d SELECTION I/O DATASET TEST%s FAILED! *****\n", nerrors, 1 == nerrors ? "" : "S"); exit(EXIT_FAILURE); diff --git a/test/set_extent.c b/test/set_extent.c index 6e2b7c5d1bd..018421df45f 100644 --- a/test/set_extent.c +++ b/test/set_extent.c @@ -110,14 +110,13 @@ main(void) unsigned new_format; /* Whether to use the latest file format */ unsigned chunk_cache; /* Whether to enable chunk caching */ int nerrors = 0; - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); + /* Current VFD that does not support contiguous address space */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); /* Initialize random number seed */ HDsrandom((unsigned)HDtime(NULL)); diff --git a/test/stab.c b/test/stab.c index 1b7da018822..357f7682712 100644 --- a/test/stab.c +++ b/test/stab.c @@ -1375,18 +1375,16 @@ main(void) hid_t fapl, fapl2; /* File access property list IDs */ hid_t fcpl, fcpl2; /* File creation property list ID */ unsigned new_format; /* Whether to use the new format or not */ - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ bool contig_addr_vfd; /* Whether VFD used has a contiguous address space */ bool driver_is_default_compatible; int nerrors = 0; /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* VFD that does not support contiguous address space */ - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); /* Reset library */ h5_reset(); @@ -1433,8 +1431,8 @@ main(void) nerrors += test_large(my_fcpl, my_fapl, new_format); } /* end for */ - /* New format group specific tests (require new format features) */ if (contig_addr_vfd) { + /* New format group specific tests (require new format features) */ nerrors += lifecycle(fcpl2, fapl2); nerrors += long_compact(fcpl2, fapl2); @@ -1444,10 +1442,10 @@ main(void) nerrors += no_compact(fcpl2, fapl2); nerrors += gcpl_on_root(fapl2); - } - /* Old group API specific tests */ - nerrors += old_api(fapl); + /* Old group API specific tests */ + nerrors += old_api(fapl); + } if (driver_is_default_compatible) { nerrors += corrupt_stab_msg(); diff --git a/test/swmr.c b/test/swmr.c index aacf498b22e..94c98737c59 100644 --- a/test/swmr.c +++ b/test/swmr.c @@ -7729,12 +7729,12 @@ test_multiple_same(hid_t in_fapl, bool new_format) int main(void) { - int nerrors = 0; /* The # of errors */ - hid_t fapl = H5I_INVALID_HID; /* File access property list ID */ - char *driver = NULL; /* VFD string (from env variable) */ - char *lock_env_var = NULL; /* file locking env var pointer */ - bool use_file_locking; /* read from env var */ - bool file_locking_enabled = false; /* Checks if the file system supports locks */ + const char *driver_name = NULL; /* VFD string (from env variable) */ + int nerrors = 0; /* The # of errors */ + hid_t fapl = H5I_INVALID_HID; /* File access property list ID */ + char *lock_env_var = NULL; /* file locking env var pointer */ + bool use_file_locking; /* read from env var */ + bool file_locking_enabled = false; /* Checks if the file system supports locks */ /* Testing setup */ h5_reset(); @@ -7742,8 +7742,8 @@ main(void) /* Skip this test if SWMR I/O is not supported for the VFD specified * by the environment variable. */ - driver = getenv(HDF5_DRIVER); - if (!H5FD__supports_swmr_test(driver)) { + driver_name = h5_get_test_driver_name(); + if (!H5FD__supports_swmr_test(driver_name)) { printf("This VFD does not support SWMR I/O\n"); return EXIT_SUCCESS; } @@ -7828,7 +7828,7 @@ main(void) /* Tests SWMR VFD compatibility flag. * Only needs to run when the VFD is the default (sec2). */ - if (NULL == driver || !strcmp(driver, "") || !strcmp(driver, "sec2")) + if (NULL == driver_name || !strcmp(driver_name, "") || !strcmp(driver_name, H5_DEFAULT_VFD_NAME)) nerrors += test_swmr_vfd_flag(); /* Test multiple opens via different locking flags */ diff --git a/test/tarray.c b/test/tarray.c index 09f300dc311..0f9e3e44faa 100644 --- a/test/tarray.c +++ b/test/tarray.c @@ -1935,6 +1935,14 @@ test_compat(void) * the tarrold.h5 file. */ + /* Check if VFD used is native file format compatible */ + CHECK(h5_driver_is_default_vfd_compatible(H5P_DEFAULT, &driver_is_default_compatible), FAIL, + "h5_driver_is_default_vfd_compatible"); + if (!driver_is_default_compatible) { + MESSAGE(5, (" -- SKIPPED --\n")); + return; + } + /* Open the testfile */ fid1 = H5Fopen(testfile, H5F_ACC_RDONLY, H5P_DEFAULT); CHECK_I(fid1, "H5Fopen"); @@ -1946,14 +1954,6 @@ test_compat(void) MESSAGE(5, (" -- SKIPPED --\n")); return; } - /* Check if VFD used is native file format compatible */ - CHECK(h5_driver_is_default_vfd_compatible(H5P_DEFAULT, &driver_is_default_compatible), FAIL, - "h5_driver_is_default_vfd_compatible"); - if (!driver_is_default_compatible) { - CHECK(H5Fclose(fid1), FAIL, "H5Fclose"); - MESSAGE(5, (" -- SKIPPED --\n")); - return; - } /* Only try to proceed if the file is around */ if (fid1 >= 0) { diff --git a/test/test_flush_refresh.sh.in b/test/test_flush_refresh.sh.in index ff24913d0ac..14cdfbba6eb 100644 --- a/test/test_flush_refresh.sh.in +++ b/test/test_flush_refresh.sh.in @@ -58,14 +58,14 @@ srcdir=@srcdir@ utils_testdir=@abs_top_builddir@/@H5_UTILS_TEST_BUILDDIR@ testdir=@abs_top_builddir@/@H5_TEST_BUILDDIR@ -# Check to see if the VFD specified by the HDF5_DRIVER environment variable -# supports SWMR. +# Check to see if the VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER +# environment variable supports SWMR. $utils_testdir/swmr_check_compat_vfd rc=$? if [ $rc -ne 0 ] ; then echo - echo "The VFD specified by the HDF5_DRIVER environment variable" - echo "does not support SWMR." + echo "The VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER" + echo "environment variable does not support SWMR." echo echo "flush/refresh tests skipped" echo diff --git a/test/test_plugin.sh.in b/test/test_plugin.sh.in index 1d04760fb3a..d96aba4e331 100644 --- a/test/test_plugin.sh.in +++ b/test/test_plugin.sh.in @@ -18,7 +18,7 @@ TOP_BUILDDIR=@top_builddir@ EXIT_SUCCESS=0 EXIT_FAILURE=1 -CP="cp -p" # Use -p to preserve mode,ownership, timestamps +CP="cp -rp" # Use -p to preserve mode,ownership, timestamps RM="rm -rf" nerrors=0 diff --git a/test/test_swmr.pwsh.in b/test/test_swmr.pwsh.in index 8f09740c2c5..becebb3d454 100644 --- a/test/test_swmr.pwsh.in +++ b/test/test_swmr.pwsh.in @@ -87,14 +87,14 @@ function Wait-Message { ## ############################################################################### -# Check to see if the VFD specified by the HDF5_DRIVER environment variable -# supports SWMR. +# Check to see if the VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER +# environment variable supports SWMR. $testprog = Join-Path -Path $utils_testdir -ChildPath swmr_check_compat_vfd.exe $rp = Start-Process -FilePath $testprog -PassThru -Wait -NoNewWindow if ($rp.ExitCode -ne 0) { Write-Output "" - Write-Output "The VFD specified by the HDF5_DRIVER environment variable" - Write-Output "does not support SWMR." + Write-Output "The VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER" + Write-Output "environment variable does not support SWMR." Write-Output "" Write-Output "SWMR acceptance tests skipped" Write-Output "" diff --git a/test/test_swmr.sh.in b/test/test_swmr.sh.in index e4c75466b40..38a32041538 100644 --- a/test/test_swmr.sh.in +++ b/test/test_swmr.sh.in @@ -85,14 +85,14 @@ WAIT_MESSAGE() { ## ############################################################################### -# Check to see if the VFD specified by the HDF5_DRIVER environment variable -# supports SWMR. +# Check to see if the VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER +# environment variable supports SWMR. $utils_testdir/swmr_check_compat_vfd rc=$? if [ $rc -ne 0 ] ; then echo - echo "The VFD specified by the HDF5_DRIVER environment variable" - echo "does not support SWMR." + echo "The VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER" + echo "environment variable does not support SWMR." echo echo "SWMR acceptance tests skipped" echo diff --git a/test/test_use_cases.sh.in b/test/test_use_cases.sh.in index f1d7ec587f4..2b327f8b5fe 100644 --- a/test/test_use_cases.sh.in +++ b/test/test_use_cases.sh.in @@ -34,14 +34,14 @@ srcdir=@srcdir@ utils_testdir=@abs_top_builddir@/@H5_UTILS_TEST_BUILDDIR@ testdir=@abs_top_builddir@/@H5_TEST_BUILDDIR@ -# Check to see if the VFD specified by the HDF5_DRIVER environment variable -# supports SWMR. +# Check to see if the VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER +# environment variable supports SWMR. $utils_testdir/swmr_check_compat_vfd rc=$? if [[ $rc != 0 ]] ; then echo - echo "The VFD specified by the HDF5_DRIVER environment variable" - echo "does not support SWMR" + echo "The VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER" + echo "environment variable does not support SWMR." echo echo "SWMR use case tests skipped" echo diff --git a/test/test_vds_swmr.pwsh.in b/test/test_vds_swmr.pwsh.in index bf5aabbd14a..97761935599 100644 --- a/test/test_vds_swmr.pwsh.in +++ b/test/test_vds_swmr.pwsh.in @@ -80,14 +80,14 @@ function Wait-Message { ## Main ############################################################################### -# Check to see if the VFD specified by the HDF5_DRIVER environment variable -# supports SWMR. +# Check to see if the VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER +# environment variable supports SWMR. $testprog = Join-Path -Path $utils_testdir -ChildPath swmr_check_compat_vfd.exe $rp = Start-Process -FilePath $testprog -PassThru -Wait -NoNewWindow if ($rp.ExitCode -ne 0) { Write-Output "" - Write-Output "The VFD specified by the HDF5_DRIVER environment variable" - Write-Output "does not support SWMR." + Write-Output "The VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER" + Write-Output "environment variable does not support SWMR." Write-Output "" Write-Output "SWMR acceptance tests skipped" Write-Output "" diff --git a/test/test_vds_swmr.sh.in b/test/test_vds_swmr.sh.in index 8eae3edceb8..f5a9043bf06 100644 --- a/test/test_vds_swmr.sh.in +++ b/test/test_vds_swmr.sh.in @@ -77,14 +77,14 @@ WAIT_MESSAGE() { ## Main ############################################################################### -# Check to see if the VFD specified by the HDF5_DRIVER environment variable -# supports SWMR. +# Check to see if the VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER +# environment variable supports SWMR. $utils_testdir/swmr_check_compat_vfd rc=$? if [ $rc -ne 0 ] ; then echo - echo "The VFD specified by the HDF5_DRIVER environment variable" - echo "does not support SWMR." + echo "The VFD specified by the HDF5_DRIVER or HDF5_TEST_DRIVER" + echo "environment variable does not support SWMR." echo echo "SWMR acceptance tests skipped" echo diff --git a/test/testfiles/tmisc38a.h5 b/test/testfiles/tmisc38a.h5 new file mode 100644 index 00000000000..cf516f0a2ab Binary files /dev/null and b/test/testfiles/tmisc38a.h5 differ diff --git a/test/testfiles/tmisc38b.h5 b/test/testfiles/tmisc38b.h5 new file mode 100644 index 00000000000..7f58280ac8d Binary files /dev/null and b/test/testfiles/tmisc38b.h5 differ diff --git a/test/tfile.c b/test/tfile.c index bc50b94647b..de476eadf51 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -185,8 +185,8 @@ static const char *FILESPACE_NAME[] = {"tfilespace", NULL}; #define DSET_DS1 "DS1" /* Local test function declarations for version bounds */ -static void test_libver_bounds_low_high(const char *env_h5_drvr); -static void test_libver_bounds_super(hid_t fapl, const char *env_h5_drvr); +static void test_libver_bounds_low_high(const char *driver_name); +static void test_libver_bounds_super(hid_t fapl, const char *driver_name); static void test_libver_bounds_super_create(hid_t fapl, hid_t fcpl, htri_t is_swmr, htri_t non_def_fsm); static void test_libver_bounds_super_open(hid_t fapl, hid_t fcpl, htri_t is_swmr, htri_t non_def_fsm); static void test_libver_bounds_obj(hid_t fapl); @@ -533,7 +533,7 @@ test_file_create(void) ** ****************************************************************/ static void -test_file_open(const char *env_h5_drvr) +test_file_open(const char *driver_name) { hid_t fid1, fid2; /*HDF5 File IDs */ hid_t did; /*dataset ID */ @@ -553,7 +553,7 @@ test_file_open(const char *env_h5_drvr) */ /* Only run this test with sec2/default driver */ - if (!h5_using_default_driver(env_h5_drvr)) + if (!h5_using_default_driver(driver_name)) return; /* Output message about test being performed */ @@ -1747,7 +1747,7 @@ test_file_perm2(void) #define FILE_IS_ACCESSIBLE "tfile_is_accessible" #define FILE_IS_ACCESSIBLE_NON_HDF5 "tfile_is_accessible_non_hdf5" static void -test_file_is_accessible(const char *env_h5_drvr) +test_file_is_accessible(const char *driver_name) { hid_t fid = H5I_INVALID_HID; /* File opened with read-write permission */ hid_t fcpl_id = H5I_INVALID_HID; /* File creation property list */ @@ -1832,7 +1832,7 @@ test_file_is_accessible(const char *env_h5_drvr) /* This test is not currently working for the family VFD. * There are failures when creating files with userblocks. */ - if (0 != strcmp(env_h5_drvr, "family")) { + if (0 != strcmp(driver_name, "family")) { /* Create a file creation property list with a non-default user block size */ fcpl_id = H5Pcreate(H5P_FILE_CREATE); CHECK(fcpl_id, H5I_INVALID_HID, "H5Pcreate"); @@ -1918,7 +1918,7 @@ test_file_is_accessible(const char *env_h5_drvr) *****************************************************************/ #ifndef H5_NO_DEPRECATED_SYMBOLS static void -test_file_ishdf5(const char *env_h5_drvr) +test_file_ishdf5(const char *driver_name) { hid_t fid = H5I_INVALID_HID; /* File opened with read-write permission */ hid_t fcpl_id = H5I_INVALID_HID; /* File creation property list */ @@ -1934,7 +1934,7 @@ test_file_ishdf5(const char *env_h5_drvr) bool vol_is_native; herr_t ret; /* Return value from HDF5 calls */ - if (!h5_using_default_driver(env_h5_drvr)) + if (!h5_using_default_driver(driver_name)) return; /* Output message about test being performed */ @@ -3055,7 +3055,7 @@ test_file_double_datatype_open(void) ** *****************************************************************/ static void -test_userblock_file_size(const char *env_h5_drvr) +test_userblock_file_size(const char *driver_name) { hid_t file1_id, file2_id; hid_t group1_id, group2_id; @@ -3069,8 +3069,8 @@ test_userblock_file_size(const char *env_h5_drvr) herr_t ret; /* Generic return value */ /* Don't run with multi/split, family or direct drivers */ - if (!strcmp(env_h5_drvr, "multi") || !strcmp(env_h5_drvr, "split") || !strcmp(env_h5_drvr, "family") || - !strcmp(env_h5_drvr, "direct")) + if (!strcmp(driver_name, "multi") || !strcmp(driver_name, "split") || !strcmp(driver_name, "family") || + !strcmp(driver_name, "direct")) return; /* Output message about test being performed */ @@ -3495,7 +3495,7 @@ test_userblock_alignment_helper2(hid_t fapl, bool open_rw) ** *****************************************************************/ static void -test_userblock_alignment(const char *env_h5_drvr) +test_userblock_alignment(const char *driver_name) { hid_t fid; /* File ID */ hid_t fcpl; /* File creation property list ID */ @@ -3503,7 +3503,7 @@ test_userblock_alignment(const char *env_h5_drvr) herr_t ret; /* Generic return value */ /* Only run with sec2 driver */ - if (!h5_using_default_driver(env_h5_drvr)) + if (!h5_using_default_driver(driver_name)) return; /* Output message about test being performed */ @@ -3715,7 +3715,7 @@ test_userblock_alignment(const char *env_h5_drvr) ** *****************************************************************/ static void -test_userblock_alignment_paged(const char *env_h5_drvr) +test_userblock_alignment_paged(const char *driver_name) { hid_t fid; /* File ID */ hid_t fcpl; /* File creation property list ID */ @@ -3723,7 +3723,7 @@ test_userblock_alignment_paged(const char *env_h5_drvr) herr_t ret; /* Generic return value */ /* Only run with sec2 driver */ - if (!h5_using_default_driver(env_h5_drvr)) + if (!h5_using_default_driver(driver_name)) return; /* Output message about test being performed */ @@ -4139,7 +4139,7 @@ test_userblock_alignment_paged(const char *env_h5_drvr) ** ****************************************************************/ static void -test_filespace_info(const char *env_h5_drvr) +test_filespace_info(const char *driver_name) { hid_t fid; /* File IDs */ hid_t fapl, new_fapl; /* File access property lists */ @@ -4161,7 +4161,7 @@ test_filespace_info(const char *env_h5_drvr) MESSAGE(5, ("Testing file creation public routines: H5Pget/set_file_space_strategy & " "H5Pget/set_file_space_page_size\n")); - contig_addr_vfd = (bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0); + contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0); fapl = h5_fileaccess(); h5_fixname(FILESPACE_NAME[0], fapl, filename, sizeof filename); @@ -4556,7 +4556,7 @@ set_multi_split(hid_t fapl, hsize_t pagesize, bool split) ** *****************************************************************/ static void -test_file_freespace(const char *env_h5_drvr) +test_file_freespace(const char *driver_name) { hid_t file; /* File opened with read-write permission */ h5_stat_size_t empty_filesize; /* Size of file when empty */ @@ -4578,8 +4578,8 @@ test_file_freespace(const char *env_h5_drvr) bool vol_is_native; herr_t ret; /* Return value */ - split_vfd = !strcmp(env_h5_drvr, "split"); - multi_vfd = !strcmp(env_h5_drvr, "multi"); + split_vfd = !strcmp(driver_name, "split"); + multi_vfd = !strcmp(driver_name, "multi"); if (split_vfd || multi_vfd) return; @@ -4731,7 +4731,7 @@ test_file_freespace(const char *env_h5_drvr) ** *****************************************************************/ static void -test_sects_freespace(const char *env_h5_drvr, bool new_format) +test_sects_freespace(const char *driver_name, bool new_format) { char filename[FILENAME_LEN]; /* Filename to use */ hid_t file; /* File ID */ @@ -4762,8 +4762,8 @@ test_sects_freespace(const char *env_h5_drvr, bool new_format) /* Output message about test being performed */ MESSAGE(5, ("Testing H5Fget_free_sections()--free-space section info in the file\n")); - split_vfd = !strcmp(env_h5_drvr, "split"); - multi_vfd = !strcmp(env_h5_drvr, "multi"); + split_vfd = !strcmp(driver_name, "split"); + multi_vfd = !strcmp(driver_name, "multi"); if (split_vfd || multi_vfd) { MESSAGE(5, (" -- SKIPPED --\n")); @@ -5900,7 +5900,7 @@ test_libver_bounds(void) ** **************************************************************************************/ static void -test_libver_bounds_low_high(const char *env_h5_drvr) +test_libver_bounds_low_high(const char *driver_name) { hid_t fapl = H5I_INVALID_HID; /* File access property list */ H5F_libver_t low, high; /* Low and high bounds */ @@ -5948,7 +5948,7 @@ test_libver_bounds_low_high(const char *env_h5_drvr) VERIFY(ret, SUCCEED, "H5Pset_libver_bounds"); /* Tests to verify version bounds */ - test_libver_bounds_super(fapl, env_h5_drvr); + test_libver_bounds_super(fapl, driver_name); test_libver_bounds_obj(fapl); test_libver_bounds_dataset(fapl); test_libver_bounds_dataspace(fapl); @@ -5981,7 +5981,7 @@ test_libver_bounds_low_high(const char *env_h5_drvr) ** *************************************************************************/ static void -test_libver_bounds_super(hid_t fapl, const char *env_h5_drvr) +test_libver_bounds_super(hid_t fapl, const char *driver_name) { hid_t fcpl = H5I_INVALID_HID; /* File creation property list */ herr_t ret; /* The return value */ @@ -5993,13 +5993,13 @@ test_libver_bounds_super(hid_t fapl, const char *env_h5_drvr) /* Verify superblock version when creating a file with input fapl, fcpl #A and with/without SWMR access */ - if (H5FD__supports_swmr_test(env_h5_drvr)) + if (H5FD__supports_swmr_test(driver_name)) test_libver_bounds_super_create(fapl, fcpl, true, false); test_libver_bounds_super_create(fapl, fcpl, false, false); /* Verify superblock version when opening a file which is created with input fapl, fcpl #A and with/without SWMR access */ - if (H5FD__supports_swmr_test(env_h5_drvr)) + if (H5FD__supports_swmr_test(driver_name)) test_libver_bounds_super_open(fapl, fcpl, true, false); test_libver_bounds_super_open(fapl, fcpl, false, false); @@ -6016,13 +6016,13 @@ test_libver_bounds_super(hid_t fapl, const char *env_h5_drvr) /* Verify superblock version when creating a file with input fapl, fcpl #B and with/without SWMR access */ - if (H5FD__supports_swmr_test(env_h5_drvr)) + if (H5FD__supports_swmr_test(driver_name)) test_libver_bounds_super_create(fapl, fcpl, true, false); test_libver_bounds_super_create(fapl, fcpl, false, false); /* Verify superblock version when opening a file which is created with input fapl, fcpl #B and with/without SWMR access */ - if (H5FD__supports_swmr_test(env_h5_drvr)) + if (H5FD__supports_swmr_test(driver_name)) test_libver_bounds_super_open(fapl, fcpl, true, false); test_libver_bounds_super_open(fapl, fcpl, false, false); @@ -6041,13 +6041,13 @@ test_libver_bounds_super(hid_t fapl, const char *env_h5_drvr) /* Verify superblock version when creating a file with input fapl, fcpl #C and with/without SWMR access */ - if (H5FD__supports_swmr_test(env_h5_drvr)) + if (H5FD__supports_swmr_test(driver_name)) test_libver_bounds_super_create(fapl, fcpl, true, false); test_libver_bounds_super_create(fapl, fcpl, false, false); /* Verify superblock version when opening a file which is created with input fapl, fcpl #C and with/without SWMR access */ - if (H5FD__supports_swmr_test(env_h5_drvr)) + if (H5FD__supports_swmr_test(driver_name)) test_libver_bounds_super_open(fapl, fcpl, true, false); test_libver_bounds_super_open(fapl, fcpl, false, false); @@ -6055,7 +6055,7 @@ test_libver_bounds_super(hid_t fapl, const char *env_h5_drvr) ret = H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); - if (h5_using_default_driver(env_h5_drvr)) { + if (h5_using_default_driver(driver_name)) { /* Create a fcpl with persistent free-space manager enabled: #D */ /* This will result in superblock version 2 */ fcpl = H5Pcreate(H5P_FILE_CREATE); @@ -6065,13 +6065,13 @@ test_libver_bounds_super(hid_t fapl, const char *env_h5_drvr) /* Verify superblock version when creating a file with input fapl, fcpl #D and with/without SWMR access */ - if (H5FD__supports_swmr_test(env_h5_drvr)) + if (H5FD__supports_swmr_test(driver_name)) test_libver_bounds_super_create(fapl, fcpl, true, true); test_libver_bounds_super_create(fapl, fcpl, false, true); /* Verify superblock version when opening a file which is created with input fapl, fcpl #D and with/without SWMR access */ - if (H5FD__supports_swmr_test(env_h5_drvr)) + if (H5FD__supports_swmr_test(driver_name)) test_libver_bounds_super_open(fapl, fcpl, true, true); test_libver_bounds_super_open(fapl, fcpl, false, true); @@ -8104,7 +8104,7 @@ test_min_dset_ohdr(void) ****************************************************************/ #ifndef H5_NO_DEPRECATED_SYMBOLS static void -test_deprec(const char *env_h5_drvr) +test_deprec(const char *driver_name) { hid_t file; /* File IDs for old & new files */ hid_t fcpl; /* File creation property list */ @@ -8167,7 +8167,7 @@ test_deprec(const char *env_h5_drvr) CHECK(ret, FAIL, "H5Fclose"); /* Only run this part of the test with the sec2/default driver */ - if (h5_using_default_driver(env_h5_drvr)) { + if (h5_using_default_driver(driver_name)) { /* Create a file creation property list */ fcpl = H5Pcreate(H5P_FILE_CREATE); CHECK(fcpl, FAIL, "H5Pcreate"); @@ -8342,7 +8342,7 @@ test_deprec(const char *env_h5_drvr) void test_file(void) { - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ hid_t fapl_id = H5I_INVALID_HID; /* VFD-dependent fapl ID */ bool driver_is_default_compatible; herr_t ret; @@ -8351,9 +8351,7 @@ test_file(void) MESSAGE(5, ("Testing Low-Level File I/O\n")); /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Improved version of VFD-dependent checks */ fapl_id = h5_fileaccess(); @@ -8363,14 +8361,14 @@ test_file(void) CHECK(ret, FAIL, "h5_driver_is_default_vfd_compatible"); test_file_create(); /* Test file creation(also creation templates)*/ - test_file_open(env_h5_drvr); /* Test file opening */ + test_file_open(driver_name); /* Test file opening */ test_file_reopen(); /* Test file reopening */ test_file_close(); /* Test file close behavior */ test_get_file_id(); /* Test H5Iget_file_id */ test_get_obj_ids(); /* Test H5Fget_obj_ids for Jira Issue 8528 */ test_file_perm(); /* Test file access permissions */ test_file_perm2(); /* Test file access permission again */ - test_file_is_accessible(env_h5_drvr); /* Test detecting HDF5 files correctly */ + test_file_is_accessible(driver_name); /* Test detecting HDF5 files correctly */ test_file_delete(fapl_id); /* Test H5Fdelete */ test_file_open_dot(); /* Test opening objects with "." for a name */ test_file_open_overlap(); /* Test opening files in an overlapping manner */ @@ -8382,7 +8380,7 @@ test_file(void) test_file_double_file_dataset_open(true); test_file_double_file_dataset_open(false); test_userblock_file_size( - env_h5_drvr); /* Tests that files created with a userblock have the correct size */ + driver_name); /* Tests that files created with a userblock have the correct size */ test_cached_stab_info(); /* Tests that files are created with cached stab info in the superblock */ if (driver_is_default_compatible) { @@ -8390,20 +8388,20 @@ test_file(void) } test_userblock_alignment( - env_h5_drvr); /* Tests that files created with a userblock and alignment interact properly */ - test_userblock_alignment_paged(env_h5_drvr); /* Tests files created with a userblock and alignment (via + driver_name); /* Tests that files created with a userblock and alignment interact properly */ + test_userblock_alignment_paged(driver_name); /* Tests files created with a userblock and alignment (via paged aggregation) interact properly */ - test_filespace_info(env_h5_drvr); /* Test file creation public routines: */ + test_filespace_info(driver_name); /* Test file creation public routines: */ /* H5Pget/set_file_space_strategy() & H5Pget/set_file_space_page_size() */ /* Skipped testing for multi/split drivers */ - test_file_freespace(env_h5_drvr); /* Test file public routine H5Fget_freespace() */ + test_file_freespace(driver_name); /* Test file public routine H5Fget_freespace() */ /* Skipped testing for multi/split drivers */ /* Setup for multi/split drivers are there already */ - test_sects_freespace(env_h5_drvr, + test_sects_freespace(driver_name, true); /* Test file public routine H5Fget_free_sections() for new format */ /* Skipped testing for multi/split drivers */ /* Setup for multi/split drivers are there already */ - test_sects_freespace(env_h5_drvr, false); /* Test file public routine H5Fget_free_sections() */ + test_sects_freespace(driver_name, false); /* Test file public routine H5Fget_free_sections() */ /* Skipped testing for multi/split drivers */ if (driver_is_default_compatible) { @@ -8416,14 +8414,14 @@ test_file(void) } test_libver_bounds(); /* Test compatibility for file space management */ - test_libver_bounds_low_high(env_h5_drvr); + test_libver_bounds_low_high(driver_name); test_libver_macros(); /* Test the macros for library version comparison */ test_libver_macros2(); /* Test the macros for library version comparison */ test_incr_filesize(); /* Test H5Fincrement_filesize() and H5Fget_eoa() */ test_min_dset_ohdr(); /* Test dataset object header minimization */ #ifndef H5_NO_DEPRECATED_SYMBOLS - test_file_ishdf5(env_h5_drvr); /* Test detecting HDF5 files correctly */ - test_deprec(env_h5_drvr); /* Test deprecated routines */ + test_file_ishdf5(driver_name); /* Test detecting HDF5 files correctly */ + test_deprec(driver_name); /* Test deprecated routines */ #endif /* H5_NO_DEPRECATED_SYMBOLS */ ret = H5Pclose(fapl_id); diff --git a/test/tmisc.c b/test/tmisc.c index 67e92c0898b..a9d94a5ec97 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -337,9 +337,19 @@ typedef struct { See https://nvd.nist.gov/vuln/detail/CVE-2020-10812 */ #define CVE_2020_10812_FILENAME "cve_2020_10812.h5" -#define MISC38_FILE "type_conversion_path_table_issue.h5" -#define MISC39_FILE "set_est_link_info.h5" -#define MISC40_FILE "obj_props_intermediate.h5" +/* Definitions for misc. test #38 */ +#define MISC38A_FILE "tmisc38a.h5" +#define MISC38A_DSETNAME "Fletcher_float_data_be" +#define MISC38B_FILE "tmisc38b.h5" +#define MISC38B_DSETNAME "unusual_datatype" +#define MISC38C_FILE "tmisc38c.h5" +#define MISC38C_DSETNAME "dset_unusual_datatype" +#define MISC38C_TYPENAME "type_unusual_datatype" +#define MISC38C_ATTRNAME "attr_unusual_datatype" + +#define MISC39_FILE "type_conversion_path_table_issue.h5" +#define MISC40_FILE "set_est_link_info.h5" +#define MISC41_FILE "obj_props_intermediate.h5" /**************************************************************** ** @@ -1828,6 +1838,14 @@ test_misc10(void) /* Output message about test being performed */ MESSAGE(5, ("Testing using old dataset creation property list\n")); + /* Check if VFD used is native file format compatible */ + CHECK(h5_driver_is_default_vfd_compatible(H5P_DEFAULT, &driver_is_default_compatible), FAIL, + "h5_driver_is_default_vfd_compatible"); + if (!driver_is_default_compatible) { + MESSAGE(5, (" -- SKIPPED --\n")); + return; + } + /* * Open the old file and the dataset and get old settings. */ @@ -1841,14 +1859,6 @@ test_misc10(void) MESSAGE(5, (" -- SKIPPED --\n")); return; } - /* Check if VFD used is native file format compatible */ - CHECK(h5_driver_is_default_vfd_compatible(H5P_DEFAULT, &driver_is_default_compatible), FAIL, - "h5_driver_is_default_vfd_compatible"); - if (!driver_is_default_compatible) { - CHECK(H5Fclose(file), FAIL, "H5Fclose"); - MESSAGE(5, (" -- SKIPPED --\n")); - return; - } fcpl = H5Fget_create_plist(file); CHECK(fcpl, FAIL, "H5Fget_create_plist"); @@ -3972,7 +3982,7 @@ test_misc21(void) /* Allocate space for the buffer */ buf = (char *)calloc(MISC21_SPACE_DIM0 * MISC21_SPACE_DIM1, 1); - CHECK(buf, NULL, "calloc"); + CHECK_PTR(buf, "calloc"); /* Create the file */ fid = H5Fcreate(MISC21_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); @@ -4025,6 +4035,7 @@ test_misc21(void) static void test_misc22(void) { + hid_t fapl; /* File access property list */ hid_t fid, sid, dcpl, dsid, dcpl2; char *buf; hsize_t dims[2] = {MISC22_SPACE_DIM0, MISC22_SPACE_DIM1}, @@ -4057,12 +4068,24 @@ test_misc22(void) /* Allocate space for the buffer */ buf = (char *)calloc(MISC22_SPACE_DIM0 * MISC22_SPACE_DIM1, 8); - CHECK(buf, NULL, "calloc"); + CHECK_PTR(buf, "calloc"); + + /* Create a file access property list */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); + + /* Set property to allow unusual datatypes to be created */ + ret = H5Pset_relax_file_integrity_checks(fapl, H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS); + CHECK(ret, FAIL, "H5Pset_relax_file_integrity_checks"); /* Create the file */ - fid = H5Fcreate(MISC22_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + fid = H5Fcreate(MISC22_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); CHECK(fid, FAIL, "H5Fcreate"); + /* Close file access property list */ + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); + /* Create the dataspace for the dataset */ sid = H5Screate_simple(MISC22_SPACE_RANK, dims, NULL); CHECK(sid, FAIL, "H5Screate_simple"); @@ -6264,6 +6287,223 @@ test_misc37(void) /**************************************************************** ** ** test_misc38(): +** Test for seg fault issue when opening dataset with corrupted +** object header. +** +****************************************************************/ +static void +test_misc38(void) +{ + const char *testfile = H5_get_srcdir_filename(MISC38A_FILE); /* Corrected test file name */ + const char *testfile2 = H5_get_srcdir_filename(MISC38B_FILE); /* Corrected test file name */ + bool driver_is_default_compatible; + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + hid_t fid = H5I_INVALID_HID; /* File ID */ + hid_t did = H5I_INVALID_HID; /* Dataset ID */ + hid_t sid = H5I_INVALID_HID; /* Dataspace ID */ + hid_t tid = H5I_INVALID_HID; /* Datatype ID */ + hid_t gid = H5I_INVALID_HID; /* Group ID */ + hid_t aid = H5I_INVALID_HID; /* Attribute ID */ + size_t type_size; /* Size of dataset's datatype */ + uint64_t rfic_flags; /* Value of RFIC flags property for FAPL & file */ + herr_t ret; + + /* Output message about test being performed */ + MESSAGE(5, ("Fix for detecting numeric datatypes with unusually large numbers of unused bits")); + + ret = h5_driver_is_default_vfd_compatible(H5P_DEFAULT, &driver_is_default_compatible); + CHECK(ret, FAIL, "h5_driver_is_default_vfd_compatible"); + + if (!driver_is_default_compatible) { + printf("-- SKIPPED --\n"); + return; + } + + fid = H5Fopen(testfile, H5F_ACC_RDONLY, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + /* This should fail due to the illegal datatype encoding in the corrupted + * object header. + * It should fail gracefully and not seg fault + */ + H5E_BEGIN_TRY + { + did = H5Dopen2(fid, MISC38A_DSETNAME, H5P_DEFAULT); + } + H5E_END_TRY + VERIFY(did, H5I_INVALID_HID, "H5Dopen2"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Create a file access property list */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, H5I_INVALID_HID, "H5Pcreate"); + + /* Get property to allow unusual datatypes to be opened */ + rfic_flags = H5F_RFIC_ALL; + ret = H5Pget_relax_file_integrity_checks(fapl, &rfic_flags); + CHECK(ret, FAIL, "H5Pget_relax_file_integrity_checks"); + VERIFY(rfic_flags, 0, "H5Pget_relax_file_integrity_checks"); + + /* Set property to allow unusual datatypes to be opened */ + ret = H5Pset_relax_file_integrity_checks(fapl, H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS); + CHECK(ret, FAIL, "H5Pset_relax_file_integrity_checks"); + + /* Get property to allow unusual datatypes to be opened */ + rfic_flags = 0; + ret = H5Pget_relax_file_integrity_checks(fapl, &rfic_flags); + CHECK(ret, FAIL, "H5Pget_relax_file_integrity_checks"); + VERIFY(rfic_flags, H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS, "H5Pget_relax_file_integrity_checks"); + + /* Open valid file */ + fid = H5Fopen(testfile2, H5F_ACC_RDONLY, fapl); + CHECK(fid, H5I_INVALID_HID, "H5Fopen"); + + /* Close file access property list */ + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Open dataset w/unusual datatype + * It should succeed and not return an error or seg fault + */ + did = H5Dopen2(fid, MISC38B_DSETNAME, H5P_DEFAULT); + CHECK(did, H5I_INVALID_HID, "H5Dopen2"); + + /* Get the dataset's datatype */ + tid = H5Dget_type(did); + CHECK(tid, H5I_INVALID_HID, "H5Dget_type"); + + type_size = H5Tget_size(tid); + CHECK(type_size, 0, "H5Tget_size"); + VERIFY(type_size, 1000, "H5Tget_size"); + + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + + /* Check that property is handled correctly */ + fapl = H5Fget_access_plist(fid); + CHECK(fapl, H5I_INVALID_HID, "H5Fget_access_plist"); + + /* Get property to allow unusual datatypes to be opened */ + rfic_flags = 0; + ret = H5Pget_relax_file_integrity_checks(fapl, &rfic_flags); + CHECK(ret, FAIL, "H5Pget_relax_file_integrity_checks"); + VERIFY(rfic_flags, H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS, "H5Pget_relax_file_integrity_checks"); + + /* Close file access property list */ + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Create objects with unusual datatypes and verify correct behavior */ + for (unsigned u = 0; u < 3; u++) { + /* Create a file access property list */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, H5I_INVALID_HID, "H5Pcreate"); + + if (1 == u) { + /* Set property to allow unusual datatypes to be opened */ + ret = H5Pset_relax_file_integrity_checks(fapl, H5F_RFIC_UNUSUAL_NUM_UNUSED_NUMERIC_BITS); + CHECK(ret, FAIL, "H5Pset_relax_file_integrity_checks"); + } + else if (2 == u) { + /* Use a later version of the file format, with checksummed object headers */ + ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); + CHECK(ret, FAIL, "H5Pset_libver_bounds"); + } + + fid = H5Fcreate(MISC38C_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid, H5I_INVALID_HID, "H5Fcreate"); + + /* Close file access property list */ + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); + + sid = H5Screate(H5S_SCALAR); + CHECK(sid, H5I_INVALID_HID, "H5Screate"); + + tid = H5Tcopy(H5T_NATIVE_INT); + CHECK(tid, H5I_INVALID_HID, "H5Tcopy"); + + /* Set type to have unusual size, for precision */ + ret = H5Tset_size(tid, 1000); + CHECK(ret, FAIL, "H5Tset_size"); + + /* Create a dataset with the unusual datatype */ + H5E_BEGIN_TRY + { + did = H5Dcreate2(fid, MISC38C_DSETNAME, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY + if (u > 0) { + CHECK(did, H5I_INVALID_HID, "H5Dcreate2"); + + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + } + else { + VERIFY(did, H5I_INVALID_HID, "H5Dcreate2"); + } + + gid = H5Gopen2(fid, "/", H5P_DEFAULT); + CHECK(gid, H5I_INVALID_HID, "H5Gopen2"); + + /* Create an attribute with the unusual datatype */ + H5E_BEGIN_TRY + { + aid = H5Acreate2(gid, MISC38C_ATTRNAME, tid, sid, H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY + if (u > 0) { + CHECK(aid, H5I_INVALID_HID, "H5Acreate2"); + + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + } + else { + VERIFY(aid, H5I_INVALID_HID, "H5Acreate2"); + } + + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Create a committed datatype with the unusual datatype */ + H5E_BEGIN_TRY + { + ret = H5Tcommit2(fid, MISC38C_TYPENAME, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY + if (u > 0) { + CHECK(ret, FAIL, "H5Tcommit2"); + } + else { + VERIFY(ret, FAIL, "H5Tcommit2"); + } + + if (tid != H5I_INVALID_HID) { + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + } + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + } +} /* end test_misc38() */ + +/**************************************************************** +** +** test_misc39(): ** Test for issue where the type conversion path table cache ** would grow continuously when variable-length datatypes ** are involved due to file VOL object comparisons causing @@ -6271,7 +6511,7 @@ test_misc37(void) ** ****************************************************************/ static void -test_misc38(void) +test_misc39(void) { H5VL_object_t *file_vol_obj = NULL; const char *buf[] = {"attr_value"}; @@ -6309,7 +6549,7 @@ test_misc38(void) */ init_npaths = H5T__get_path_table_npaths(); - file_id = H5Fcreate(MISC38_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + file_id = H5Fcreate(MISC39_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(file_id, H5I_INVALID_HID, "H5Fcreate"); /* Check if native VOL is being used */ @@ -6444,7 +6684,7 @@ test_misc38(void) CHECK_PTR(vlen_rbuf, "vlen varstr read buf allocation"); for (size_t i = 0; i < 10; i++) { - file_id = H5Fopen(MISC38_FILE, H5F_ACC_RDONLY, H5P_DEFAULT); + file_id = H5Fopen(MISC39_FILE, H5F_ACC_RDONLY, H5P_DEFAULT); CHECK(file_id, H5I_INVALID_HID, "H5Fopen"); /* Retrieve file's VOL object field for further use */ @@ -6546,7 +6786,7 @@ test_misc38(void) /**************************************************************** ** -** test_misc39(): Ensure H5Pset_est_link_info() handles large +** test_misc40(): Ensure H5Pset_est_link_info() handles large ** values ** ** H5Pset_est_link_info() values can be set to large values, @@ -6560,7 +6800,7 @@ test_misc38(void) ** ****************************************************************/ static void -test_misc39(void) +test_misc40(void) { hid_t fid = H5I_INVALID_HID; /* File ID */ hid_t gid = H5I_INVALID_HID; /* Group ID */ @@ -6581,7 +6821,7 @@ test_misc39(void) CHECK(ret, FAIL, "H5Pset_libver_bounds"); /* Create the file */ - fid = H5Fcreate(MISC39_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + fid = H5Fcreate(MISC40_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); CHECK(fid, H5I_INVALID_HID, "H5Fcreate"); /* Compose group creation property list */ @@ -6639,16 +6879,16 @@ test_misc39(void) ret = H5Pclose(gcpl); CHECK(ret, FAIL, "H5Pclose"); -} /* end test_misc39() */ +} /* end test_misc40() */ /**************************************************************** ** -** test_misc40(): Test that object creation properties are propagated +** test_misc41(): Test that object creation properties are propagated ** to intermediate groups. ** ****************************************************************/ static void -test_misc40(void) +test_misc41(void) { hid_t lcpl = H5I_INVALID_HID; hid_t gcpl = H5I_INVALID_HID; @@ -6675,7 +6915,7 @@ test_misc40(void) status = H5Pset_create_intermediate_group(lcpl, 1); CHECK(status, FAIL, "H5Pset_create_intermediate_group"); - fid = H5Fcreate(MISC40_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + fid = H5Fcreate(MISC41_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(fid, FAIL, "H5Fcreate"); /* @@ -6856,7 +7096,7 @@ test_misc40(void) status = H5Pclose(lcpl); CHECK(status, FAIL, "H5Pclose"); -} /* end test_misc40() */ +} /* end test_misc41() */ /**************************************************************** ** @@ -6893,7 +7133,11 @@ test_misc(void) } test_misc14(); /* Test that deleted dataset's data is removed from sieve buffer correctly */ - test_misc15(); /* Test that checking a file's access property list more than once works */ + + if (default_driver) { + test_misc15(); /* Test that checking a file's access property list more than once works */ + } + test_misc16(); /* Test array of fixed-length string */ test_misc17(); /* Test array of ASCII character */ test_misc18(); /* Test new object header information in H5O_info_t struct */ @@ -6926,9 +7170,10 @@ test_misc(void) test_misc35(); /* Test behavior of free-list & allocation statistics API calls */ test_misc36(); /* Exercise H5atclose and H5is_library_terminating */ test_misc37(); /* Test for seg fault failure at file close */ - test_misc38(); /* Test for type conversion path table issue */ - test_misc39(); /* Ensure H5Pset_est_link_info() handles large values */ - test_misc40(); /* Test object properties propagated to intermediate groups */ + test_misc38(); /* Test for seg fault when opening corrupted object header */ + test_misc39(); /* Test for type conversion path table issue */ + test_misc40(); /* Ensure H5Pset_est_link_info() handles large values */ + test_misc41(); /* Test object properties propagated to intermediate groups */ } /* test_misc() */ @@ -6984,9 +7229,10 @@ cleanup_misc(void) #ifndef H5_NO_DEPRECATED_SYMBOLS H5Fdelete(MISC31_FILE, H5P_DEFAULT); #endif /* H5_NO_DEPRECATED_SYMBOLS */ - H5Fdelete(MISC38_FILE, H5P_DEFAULT); + H5Fdelete(MISC38C_FILE, H5P_DEFAULT); H5Fdelete(MISC39_FILE, H5P_DEFAULT); H5Fdelete(MISC40_FILE, H5P_DEFAULT); + H5Fdelete(MISC41_FILE, H5P_DEFAULT); } H5E_END_TRY } /* end cleanup_misc() */ diff --git a/test/trefer.c b/test/trefer.c index b8f91a03363..fc0d8942045 100644 --- a/test/trefer.c +++ b/test/trefer.c @@ -3592,15 +3592,13 @@ void test_reference(void) { H5F_libver_t low, high; /* Low and high bounds */ - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ /* Output message about test being performed */ MESSAGE(5, ("Testing References\n")); /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); test_reference_params(); /* Test for correct parameter checking */ test_reference_obj(); /* Test basic H5R object reference code */ @@ -3622,7 +3620,7 @@ test_reference(void) } /* end low bound */ /* The following test is currently broken with the Direct VFD */ - if (strcmp(env_h5_drvr, "direct") != 0) { + if (strcmp(driver_name, "direct") != 0) { test_reference_obj_deleted(); /* Test H5R object reference code for deleted objects */ } diff --git a/test/tselect.c b/test/tselect.c index 20b85916739..e07b1b62dfb 100644 --- a/test/tselect.c +++ b/test/tselect.c @@ -16078,16 +16078,14 @@ test_select(void) size_t rdcc_nbytes; /* Raw data number of bytes */ double rdcc_w0; /* Raw data write percentage */ hssize_t offset[SPACE7_RANK] = {1, 1}; /* Offset for testing selection offsets */ - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Selections\n")); /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Create a dataset transfer property list */ plist_id = H5Pcreate(H5P_DATASET_XFER); @@ -16152,7 +16150,7 @@ test_select(void) test_select_hyper_valid_combination(); /* Test different input combinations */ /* The following tests are currently broken with the Direct VFD */ - if (strcmp(env_h5_drvr, "direct") != 0) { + if (strcmp(driver_name, "direct") != 0) { test_select_hyper_and_2d(); /* Test hyperslab intersection (AND) code for 2-D dataset */ test_select_hyper_xor_2d(); /* Test hyperslab XOR code for 2-D dataset */ test_select_hyper_notb_2d(); /* Test hyperslab NOTB code for 2-D dataset */ diff --git a/test/tsohm.c b/test/tsohm.c index 542fd688b81..e6b9e0b5e2a 100644 --- a/test/tsohm.c +++ b/test/tsohm.c @@ -3208,7 +3208,7 @@ test_sohm_extlink(void) CHECK_I(ret, "h5_driver_is_default_vfd_compatible"); if (!driver_is_default_compatible) { - printf("-- SKIPPED --\n"); + MESSAGE(5, ("-- SKIPPED --\n")); return; } @@ -3710,7 +3710,7 @@ test_sohm_external_dtype(void) void test_sohm(void) { - const char *env_h5_drvr; + const char *driver_name; bool vol_is_native; bool default_driver; @@ -3724,11 +3724,8 @@ test_sohm(void) } /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; - - default_driver = h5_using_default_driver(env_h5_drvr); + driver_name = h5_get_test_driver_name(); + default_driver = h5_using_default_driver(driver_name); test_sohm_fcpl(); /* Test SOHMs and file creation plists */ test_sohm_fcpl_errors(); /* Bogus H5P* calls for SOHMs */ diff --git a/test/vds.c b/test/vds.c index c2546e57f00..c08eec09288 100644 --- a/test/vds.c +++ b/test/vds.c @@ -12316,13 +12316,11 @@ main(void) int test_api_config; unsigned bit_config; H5F_libver_t low, high; /* Low and high bounds */ - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ bool driver_is_parallel; int nerrors = 0; - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Testing setup */ h5_reset(); @@ -12336,7 +12334,7 @@ main(void) * doesn't support parallel reads and the splitter VFD has external * link-related bugs. */ - if (driver_is_parallel || !strcmp(env_h5_drvr, "splitter")) { + if (driver_is_parallel || !strcmp(driver_name, "splitter")) { puts(" -- SKIPPED for incompatible VFD --"); exit(EXIT_SUCCESS); } diff --git a/test/vds_env.c b/test/vds_env.c index e9649566fd9..4432e0aad53 100644 --- a/test/vds_env.c +++ b/test/vds_env.c @@ -327,13 +327,11 @@ main(void) hid_t fapl, my_fapl; unsigned bit_config; H5F_libver_t low, high; /* Low and high bounds */ - const char *env_h5_drvr; /* File Driver value from environment */ + const char *driver_name; /* File Driver value from environment */ bool driver_is_parallel; int nerrors = 0; - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); /* Testing setup */ h5_reset(); @@ -347,7 +345,7 @@ main(void) * doesn't support parallel reads and the splitter VFD has external * link-related bugs. */ - if (driver_is_parallel || !strcmp(env_h5_drvr, "splitter")) { + if (driver_is_parallel || !strcmp(driver_name, "splitter")) { puts(" -- SKIPPED for incompatible VFD --"); exit(EXIT_SUCCESS); } diff --git a/test/vfd.c b/test/vfd.c index 5a86920652e..7025de907df 100644 --- a/test/vfd.c +++ b/test/vfd.c @@ -5873,16 +5873,16 @@ test_selection_io(const char *vfd_name) int main(void) { - char *env_h5_drvr = NULL; - int nerrors = 0; + const char *driver_name; + int nerrors = 0; - /* Don't run VFD tests when HDF5_DRIVER is set. These tests expect a - * specific VFD to be set and HDF5_DRIVER being set can interfere - * with that. + /* Don't run VFD tests when HDF5_DRIVER or HDF5_TEST_DRIVER is set. These + * tests expect a specific VFD to be set and HDF5_DRIVER/HDF5_TEST_DRIVER + * being set can interfere with that. */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr) { - printf(" -- SKIPPED VFD tests because %s is set -- \n", HDF5_DRIVER); + driver_name = h5_get_test_driver_name(); + if (driver_name) { + printf(" -- SKIPPED VFD tests because driver environment variable is set -- \n"); exit(EXIT_SUCCESS); } diff --git a/test/vfd_plugin.c b/test/vfd_plugin.c index 8bfc09f07aa..91f8ec50c41 100644 --- a/test/vfd_plugin.c +++ b/test/vfd_plugin.c @@ -19,8 +19,6 @@ #include "null_vfd_plugin.h" -#define DEFAULT_DRIVER_NAME "sec2" - /*------------------------------------------------------------------------- * Function: test_set_by_name() * @@ -301,7 +299,7 @@ test_get_config_str(void) TEST_ERROR; /* Set a new configuration string on the FAPL and retrieve it */ - if (H5Pset_driver_by_name(fapl_id, DEFAULT_DRIVER_NAME, config_str) < 0) + if (H5Pset_driver_by_name(fapl_id, H5_DEFAULT_VFD_NAME, config_str) < 0) TEST_ERROR; if ((config_str_len = H5Pget_driver_config_str(fapl_id, config_str_buf, 128)) < 0) TEST_ERROR; diff --git a/test/vol.c b/test/vol.c index e29c6bb940f..395b164bfe7 100644 --- a/test/vol.c +++ b/test/vol.c @@ -857,7 +857,7 @@ test_native_vol_init(void) *------------------------------------------------------------------------- */ static herr_t -test_basic_file_operation(const char *env_h5_drvr) +test_basic_file_operation(const char *driver_name) { hid_t fid = H5I_INVALID_HID; hid_t fid_reopen = H5I_INVALID_HID; @@ -933,10 +933,10 @@ test_basic_file_operation(const char *env_h5_drvr) TEST_ERROR; /* Can't compare VFD properties for several VFDs */ - if ((bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "family") != 0 && strcmp(env_h5_drvr, "direct") != 0 && - strcmp(env_h5_drvr, "core") != 0 && strcmp(env_h5_drvr, "core_paged") != 0 && - strcmp(env_h5_drvr, "mpio") != 0 && strcmp(env_h5_drvr, "splitter") != 0)) { + if ((bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "family") != 0 && strcmp(driver_name, "direct") != 0 && + strcmp(driver_name, "core") != 0 && strcmp(driver_name, "core_paged") != 0 && + strcmp(driver_name, "mpio") != 0 && strcmp(driver_name, "splitter") != 0)) { /* H5Fget_access_plist */ if ((fapl_id2 = H5Fget_access_plist(fid)) < 0) TEST_ERROR; @@ -957,8 +957,8 @@ test_basic_file_operation(const char *env_h5_drvr) TEST_ERROR; /* Can't retrieve VFD handle for split / multi / family VFDs */ - if ((bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "family") != 0)) { + if ((bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "family") != 0)) { /* H5Fget_vfd_handle */ if (H5Fget_vfd_handle(fid, H5P_DEFAULT, &os_file_handle) < 0) TEST_ERROR; @@ -997,10 +997,10 @@ test_basic_file_operation(const char *env_h5_drvr) TEST_ERROR; /* Can't compare VFD properties for several VFDs */ - if ((bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "family") != 0 && strcmp(env_h5_drvr, "direct") != 0 && - strcmp(env_h5_drvr, "core") != 0 && strcmp(env_h5_drvr, "core_paged") != 0 && - strcmp(env_h5_drvr, "mpio") != 0 && strcmp(env_h5_drvr, "splitter") != 0)) { + if ((bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "family") != 0 && strcmp(driver_name, "direct") != 0 && + strcmp(driver_name, "core") != 0 && strcmp(driver_name, "core_paged") != 0 && + strcmp(driver_name, "mpio") != 0 && strcmp(driver_name, "splitter") != 0)) { /* H5Fget_access_plist */ if ((fapl_id2 = H5Fget_access_plist(fid)) < 0) TEST_ERROR; @@ -1014,10 +1014,10 @@ test_basic_file_operation(const char *env_h5_drvr) TEST_ERROR; /* Can't compare VFD properties for several VFDs */ - if ((bool)(strcmp(env_h5_drvr, "split") != 0 && strcmp(env_h5_drvr, "multi") != 0 && - strcmp(env_h5_drvr, "family") != 0 && strcmp(env_h5_drvr, "direct") != 0 && - strcmp(env_h5_drvr, "core") != 0 && strcmp(env_h5_drvr, "core_paged") != 0 && - strcmp(env_h5_drvr, "mpio") != 0 && strcmp(env_h5_drvr, "splitter") != 0)) { + if ((bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0 && + strcmp(driver_name, "family") != 0 && strcmp(driver_name, "direct") != 0 && + strcmp(driver_name, "core") != 0 && strcmp(driver_name, "core_paged") != 0 && + strcmp(driver_name, "mpio") != 0 && strcmp(driver_name, "splitter") != 0)) { /* H5Fget_access_plist */ if ((fapl_id2 = H5Fget_access_plist(fid_reopen)) < 0) TEST_ERROR; @@ -2645,13 +2645,11 @@ test_query_optional(void) int main(void) { - const char *env_h5_drvr; /* File driver value from environment */ + const char *driver_name; /* File driver value from environment */ int nerrors = 0; /* Get the VFD to use */ - env_h5_drvr = getenv(HDF5_DRIVER); - if (env_h5_drvr == NULL) - env_h5_drvr = "nomatch"; + driver_name = h5_get_test_driver_name(); h5_reset(); @@ -2660,7 +2658,7 @@ main(void) nerrors += test_vol_registration() < 0 ? 1 : 0; nerrors += test_register_opt_operation() < 0 ? 1 : 0; nerrors += test_native_vol_init() < 0 ? 1 : 0; - nerrors += test_basic_file_operation(env_h5_drvr) < 0 ? 1 : 0; + nerrors += test_basic_file_operation(driver_name) < 0 ? 1 : 0; nerrors += test_basic_group_operation() < 0 ? 1 : 0; nerrors += test_basic_dataset_operation() < 0 ? 1 : 0; nerrors += test_basic_attribute_operation() < 0 ? 1 : 0; diff --git a/testpar/t_pflush1.c b/testpar/t_pflush1.c index a61e6749a53..733898f9839 100644 --- a/testpar/t_pflush1.c +++ b/testpar/t_pflush1.c @@ -107,7 +107,7 @@ main(int argc, char *argv[]) hid_t fapl_id = H5I_INVALID_HID; MPI_File *mpifh_p = NULL; char name[1024]; - const char *envval = NULL; + const char *driver_name; int mpi_size; int mpi_rank; MPI_Comm comm = MPI_COMM_WORLD; @@ -121,11 +121,9 @@ main(int argc, char *argv[]) TESTING("H5Fflush (part1)"); /* Don't run using the split VFD */ - envval = getenv(HDF5_DRIVER); - if (envval == NULL) - envval = "nomatch"; + driver_name = h5_get_test_driver_name(); - if (!strcmp(envval, "split")) { + if (!strcmp(driver_name, "split")) { if (mpi_rank == 0) { SKIPPED(); puts(" Test not compatible with current Virtual File Driver"); diff --git a/testpar/t_pflush2.c b/testpar/t_pflush2.c index e1dce1bbfd7..2f860d4417d 100644 --- a/testpar/t_pflush2.c +++ b/testpar/t_pflush2.c @@ -132,12 +132,11 @@ main(int argc, char *argv[]) hid_t fapl_id2 = H5I_INVALID_HID; H5E_auto2_t func; char name[1024]; - const char *envval = NULL; - - int mpi_size; - int mpi_rank; - MPI_Comm comm = MPI_COMM_WORLD; - MPI_Info info = MPI_INFO_NULL; + const char *driver_name; + int mpi_size; + int mpi_rank; + MPI_Comm comm = MPI_COMM_WORLD; + MPI_Info info = MPI_INFO_NULL; MPI_Init(&argc, &argv); MPI_Comm_size(comm, &mpi_size); @@ -147,11 +146,9 @@ main(int argc, char *argv[]) TESTING("H5Fflush (part2 with flush)"); /* Don't run using the split VFD */ - envval = getenv(HDF5_DRIVER); - if (envval == NULL) - envval = "nomatch"; + driver_name = h5_get_test_driver_name(); - if (!strcmp(envval, "split")) { + if (!strcmp(driver_name, "split")) { if (mpi_rank == 0) { SKIPPED(); puts(" Test not compatible with current Virtual File Driver"); diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index ca6bba21854..16253b195d5 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -79,20 +79,12 @@ const char *volnames[] = { * */ const char *drivernames[] = { - [SEC2_VFD_IDX] = "sec2", - [DIRECT_VFD_IDX] = "direct", - [LOG_VFD_IDX] = "log", - [WINDOWS_VFD_IDX] = "windows", - [STDIO_VFD_IDX] = "stdio", - [CORE_VFD_IDX] = "core", - [FAMILY_VFD_IDX] = "family", - [SPLIT_VFD_IDX] = "split", - [MULTI_VFD_IDX] = "multi", - [MPIO_VFD_IDX] = "mpio", - [ROS3_VFD_IDX] = "ros3", - [HDFS_VFD_IDX] = "hdfs", - [SUBFILING_VFD_IDX] = H5FD_SUBFILING_NAME, - [ONION_VFD_IDX] = "onion", + [SEC2_VFD_IDX] = "sec2", [DIRECT_VFD_IDX] = "direct", [LOG_VFD_IDX] = "log", + [WINDOWS_VFD_IDX] = "windows", [STDIO_VFD_IDX] = "stdio", [CORE_VFD_IDX] = "core", + [FAMILY_VFD_IDX] = "family", [SPLIT_VFD_IDX] = "split", [MULTI_VFD_IDX] = "multi", + [MPIO_VFD_IDX] = "mpio", [MIRROR_VFD_IDX] = "mirror", [SPLITTER_VFD_IDX] = "splitter", + [ROS3_VFD_IDX] = "ros3", [HDFS_VFD_IDX] = "hdfs", [SUBFILING_VFD_IDX] = H5FD_SUBFILING_NAME, + [ONION_VFD_IDX] = "onion", }; #define NUM_VOLS (sizeof(volnames) / sizeof(volnames[0])) diff --git a/tools/lib/h5tools.h b/tools/lib/h5tools.h index b636806e2e9..b4ace197d7f 100644 --- a/tools/lib/h5tools.h +++ b/tools/lib/h5tools.h @@ -602,6 +602,8 @@ typedef enum { SPLIT_VFD_IDX, MULTI_VFD_IDX, MPIO_VFD_IDX, + MIRROR_VFD_IDX, + SPLITTER_VFD_IDX, ROS3_VFD_IDX, HDFS_VFD_IDX, SUBFILING_VFD_IDX, diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index 47893ec9390..44e9e681371 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -1207,54 +1207,58 @@ h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t contai /* * Object references -- show the type and OID of the referenced object. */ - H5O_info2_t oi; - char *obj_tok_str = NULL; - H5TOOLS_DEBUG("H5T_REFERENCE:H5T_STD_REF_OBJ"); obj = H5Rdereference2(container, H5P_DEFAULT, H5R_OBJECT, vp); - H5Oget_info3(obj, &oi, H5O_INFO_BASIC); + if (obj >= 0) { + H5O_info2_t oi; + char *obj_tok_str = NULL; + + H5Oget_info3(obj, &oi, H5O_INFO_BASIC); + + /* Print object type and close object */ + switch (oi.type) { + case H5O_TYPE_GROUP: + h5tools_str_append(str, H5_TOOLS_GROUP); + break; + + case H5O_TYPE_DATASET: + h5tools_str_append(str, H5_TOOLS_DATASET); + break; + + case H5O_TYPE_NAMED_DATATYPE: + h5tools_str_append(str, H5_TOOLS_DATATYPE); + break; + + case H5O_TYPE_MAP: + h5tools_str_append(str, H5_TOOLS_MAP); + break; + + case H5O_TYPE_UNKNOWN: + case H5O_TYPE_NTYPES: + default: + h5tools_str_append(str, "%u-", (unsigned)oi.type); + break; + } - /* Print object type and close object */ - switch (oi.type) { - case H5O_TYPE_GROUP: - h5tools_str_append(str, H5_TOOLS_GROUP); - break; + /* Print OID */ + H5Otoken_to_str(obj, &oi.token, &obj_tok_str); - case H5O_TYPE_DATASET: - h5tools_str_append(str, H5_TOOLS_DATASET); - break; + H5Oclose(obj); - case H5O_TYPE_NAMED_DATATYPE: - h5tools_str_append(str, H5_TOOLS_DATATYPE); - break; + if (info->obj_hidefileno) + h5tools_str_append(str, info->obj_format, obj_tok_str); + else + h5tools_str_append(str, info->obj_format, oi.fileno, obj_tok_str); - case H5O_TYPE_MAP: - h5tools_str_append(str, H5_TOOLS_MAP); - break; + if (obj_tok_str) { + H5free_memory(obj_tok_str); + obj_tok_str = NULL; + } - case H5O_TYPE_UNKNOWN: - case H5O_TYPE_NTYPES: - default: - h5tools_str_append(str, "%u-", (unsigned)oi.type); - break; + h5tools_str_sprint_old_reference(str, container, H5R_OBJECT, vp); } - - /* Print OID */ - H5Otoken_to_str(obj, &oi.token, &obj_tok_str); - - H5Oclose(obj); - - if (info->obj_hidefileno) - h5tools_str_append(str, info->obj_format, obj_tok_str); else - h5tools_str_append(str, info->obj_format, oi.fileno, obj_tok_str); - - if (obj_tok_str) { - H5free_memory(obj_tok_str); - obj_tok_str = NULL; - } - - h5tools_str_sprint_old_reference(str, container, H5R_OBJECT, vp); + h5tools_str_append(str, ""); } /* end else if (H5Tequal(type, H5T_STD_REF_OBJ)) */ } break; diff --git a/tools/libtest/h5tools_test_utils.c b/tools/libtest/h5tools_test_utils.c index 32f109b0caf..369472e8d86 100644 --- a/tools/libtest/h5tools_test_utils.c +++ b/tools/libtest/h5tools_test_utils.c @@ -983,28 +983,28 @@ test_set_configured_fapl(void) "(common) H5P_DEFAULT with no struct should succeed", 1, UTIL_TEST_DEFAULT, - "sec2", + H5_DEFAULT_VFD_NAME, NULL, }, { "(common) H5P_DEFAULT with (ignored) struct should succeed", 1, UTIL_TEST_DEFAULT, - "sec2", + H5_DEFAULT_VFD_NAME, &wrong_fa, }, { "(common) provided fapl entry should not fail", 1, UTIL_TEST_CREATE, - "sec2", + H5_DEFAULT_VFD_NAME, NULL, }, { "(common) provided fapl entry should not fail; ignores struct", 1, UTIL_TEST_CREATE, - "sec2", + H5_DEFAULT_VFD_NAME, &wrong_fa, }, { diff --git a/tools/test/h5dump/CMakeTests.cmake b/tools/test/h5dump/CMakeTests.cmake index 3a863bdee72..2369f63c746 100644 --- a/tools/test/h5dump/CMakeTests.cmake +++ b/tools/test/h5dump/CMakeTests.cmake @@ -1285,7 +1285,7 @@ ADD_H5_COMP_TEST (tfletcher32 0 0 --enable-error-stack -H -p -d fletcher32 tfilters.h5) # nbit - ADD_H5_COMP_TEST (tnbit 0 10 --enable-error-stack -H -p -d nbit tfilters.h5) + ADD_H5_COMP_TEST (tnbit 0 1 --enable-error-stack -H -p -d nbit tfilters.h5) # scaleoffset ADD_H5_COMP_TEST (tscaleoffset 0 4 --enable-error-stack -H -p -d scaleoffset tfilters.h5) diff --git a/tools/test/h5dump/expected/tnbit.ddl b/tools/test/h5dump/expected/tnbit.ddl index 35c111fb5b3..3801c1bf655 100644 --- a/tools/test/h5dump/expected/tnbit.ddl +++ b/tools/test/h5dump/expected/tnbit.ddl @@ -1,10 +1,10 @@ HDF5 "tfilters.h5" { DATASET "nbit" { - DATATYPE 32-bit little-endian integer 3-bit precision + DATATYPE 32-bit little-endian integer 17-bit precision DATASPACE SIMPLE { ( 20, 10 ) / ( 20, 10 ) } STORAGE_LAYOUT { CHUNKED ( 10, 5 ) - SIZE XXXX (10.XXX:1 COMPRESSION) + SIZE XXXX (1.XXX:1 COMPRESSION) } FILTERS { COMPRESSION NBIT diff --git a/tools/test/h5dump/expected/treadintfilter.ddl b/tools/test/h5dump/expected/treadintfilter.ddl index fbad3f67369..7a670a2a25d 100644 --- a/tools/test/h5dump/expected/treadintfilter.ddl +++ b/tools/test/h5dump/expected/treadintfilter.ddl @@ -78,29 +78,29 @@ DATASET "fletcher32" { } } DATASET "nbit" { - DATATYPE 32-bit little-endian integer 3-bit precision + DATATYPE 32-bit little-endian integer 17-bit precision DATASPACE SIMPLE { ( 20, 10 ) / ( 20, 10 ) } DATA { - (0,0): 0, 1, 2, 3, -4, -3, -2, -1, 0, 1, - (1,0): 2, 3, -4, -3, -2, -1, 0, 1, 2, 3, - (2,0): -4, -3, -2, -1, 0, 1, 2, 3, -4, -3, - (3,0): -2, -1, 0, 1, 2, 3, -4, -3, -2, -1, - (4,0): 0, 1, 2, 3, -4, -3, -2, -1, 0, 1, - (5,0): 2, 3, -4, -3, -2, -1, 0, 1, 2, 3, - (6,0): -4, -3, -2, -1, 0, 1, 2, 3, -4, -3, - (7,0): -2, -1, 0, 1, 2, 3, -4, -3, -2, -1, - (8,0): 0, 1, 2, 3, -4, -3, -2, -1, 0, 1, - (9,0): 2, 3, -4, -3, -2, -1, 0, 1, 2, 3, - (10,0): -4, -3, -2, -1, 0, 1, 2, 3, -4, -3, - (11,0): -2, -1, 0, 1, 2, 3, -4, -3, -2, -1, - (12,0): 0, 1, 2, 3, -4, -3, -2, -1, 0, 1, - (13,0): 2, 3, -4, -3, -2, -1, 0, 1, 2, 3, - (14,0): -4, -3, -2, -1, 0, 1, 2, 3, -4, -3, - (15,0): -2, -1, 0, 1, 2, 3, -4, -3, -2, -1, - (16,0): 0, 1, 2, 3, -4, -3, -2, -1, 0, 1, - (17,0): 2, 3, -4, -3, -2, -1, 0, 1, 2, 3, - (18,0): -4, -3, -2, -1, 0, 1, 2, 3, -4, -3, - (19,0): -2, -1, 0, 1, 2, 3, -4, -3, -2, -1 + (0,0): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + (1,0): 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + (2,0): 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + (3,0): 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + (4,0): 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + (5,0): 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + (6,0): 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + (7,0): 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + (8,0): 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + (9,0): 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + (10,0): 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + (11,0): 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + (12,0): 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + (13,0): 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + (14,0): 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + (15,0): 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + (16,0): 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + (17,0): 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + (18,0): 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + (19,0): 190, 191, 192, 193, 194, 195, 196, 197, 198, 199 } } DATASET "scaleoffset" { diff --git a/tools/test/h5dump/h5dumpgentest.c b/tools/test/h5dump/h5dumpgentest.c index 46e0f997707..c7d5fe66c28 100644 --- a/tools/test/h5dump/h5dumpgentest.c +++ b/tools/test/h5dump/h5dumpgentest.c @@ -5615,7 +5615,7 @@ gent_filters(void) assert(ret >= 0); tid = H5Tcopy(H5T_NATIVE_INT); - H5Tset_precision(tid, H5Tget_size(tid) - 1); + H5Tset_precision(tid, (H5Tget_size(tid) * 4) + 1); ret = make_dset(fid, "nbit", sid, tid, dcpl, buf1); assert(ret >= 0); @@ -10689,19 +10689,19 @@ gent_compound_complex2(void) { /* Third-level nested compound */ typedef struct { - short deep_nested_short[10]; - int deep_nested_int[10]; - long deep_nested_long[10]; - double deep_nested_double[10]; - float deep_nested_float[10]; + int16_t deep_nested_short[10]; + int32_t deep_nested_int[10]; + int64_t deep_nested_long[10]; + double deep_nested_double[10]; + float deep_nested_float[10]; } third_level_compound; /* Second-level multiply-nested compounds */ typedef struct { - unsigned int multiple_nested_a[5]; - int multiple_nested_b[5]; - unsigned long multiple_nested_c[5]; - long multiple_nested_d[5]; + uint32_t multiple_nested_a[5]; + int32_t multiple_nested_b[5]; + uint64_t multiple_nested_c[5]; + int64_t multiple_nested_d[5]; } further_nested; typedef struct { @@ -10727,8 +10727,8 @@ gent_compound_complex2(void) /* Compound datatype with different member types */ typedef struct { /* Arrays nested inside compound */ - unsigned int a[4]; - int b[6]; + uint32_t a[4]; + int32_t b[6]; float c[2][4]; nested_compound d; /* Compound inside compound */ multiple_nested_compound e; /* Compound inside compound with further nested compound */ diff --git a/tools/test/h5dump/testfiles/tfilters.h5 b/tools/test/h5dump/testfiles/tfilters.h5 index 7c33e55aae1..23d68a9b72b 100644 Binary files a/tools/test/h5dump/testfiles/tfilters.h5 and b/tools/test/h5dump/testfiles/tfilters.h5 differ diff --git a/tools/test/h5dump/testh5dump.sh.in b/tools/test/h5dump/testh5dump.sh.in index daba93b3509..0964d7dda6d 100644 --- a/tools/test/h5dump/testh5dump.sh.in +++ b/tools/test/h5dump/testh5dump.sh.in @@ -1430,7 +1430,7 @@ TOOLTEST tshuffle.ddl --enable-error-stack -H -p -d shuffle tfilters.h5 # fletcher32 TOOLTESTC 0 tfletcher32.ddl --enable-error-stack -H -p -d fletcher32 tfilters.h5 # nbit -TOOLTESTC 10 tnbit.ddl --enable-error-stack -H -p -d nbit tfilters.h5 +TOOLTESTC 1 tnbit.ddl --enable-error-stack -H -p -d nbit tfilters.h5 # scaleoffset TOOLTESTC 4 tscaleoffset.ddl --enable-error-stack -H -p -d scaleoffset tfilters.h5 # all diff --git a/tools/test/h5stat/expected/h5stat_filters-F.ddl b/tools/test/h5stat/expected/h5stat_filters-F.ddl index d44445bb2e3..065d0c97477 100644 --- a/tools/test/h5stat/expected/h5stat_filters-F.ddl +++ b/tools/test/h5stat/expected/h5stat_filters-F.ddl @@ -4,12 +4,12 @@ File space information for file metadata (in bytes): Superblock extension: 0 User block: 0 Object headers: (total/unused) - Groups: 48/8 - Datasets(exclude compact data): 4136/1344 + Groups: 40/0 + Datasets(exclude compact data): 4128/1088 Datatypes: 80/0 Groups: B-tree/List: 1200 - Heap: 288 + Heap: 384 Attributes: B-tree/List: 0 Heap: 0 diff --git a/tools/test/h5stat/expected/h5stat_filters-UD.ddl b/tools/test/h5stat/expected/h5stat_filters-UD.ddl index 4efafd13c40..9f6335aaed6 100644 --- a/tools/test/h5stat/expected/h5stat_filters-UD.ddl +++ b/tools/test/h5stat/expected/h5stat_filters-UD.ddl @@ -1,5 +1,5 @@ Filename: h5stat_filters.h5 File space information for datasets' metadata (in bytes): - Object headers (total/unused): 4136/1344 + Object headers (total/unused): 4128/1088 Index for Chunked datasets: 31392 Heap: 72 diff --git a/tools/test/h5stat/expected/h5stat_filters-d.ddl b/tools/test/h5stat/expected/h5stat_filters-d.ddl index 6e6dd6140dd..eee7e1845d4 100644 --- a/tools/test/h5stat/expected/h5stat_filters-d.ddl +++ b/tools/test/h5stat/expected/h5stat_filters-d.ddl @@ -12,7 +12,7 @@ Dataset dimension information: # of datasets with dimension size 100 - 999: 1 Total # of datasets: 1 Dataset storage information: - Total raw data size: 8659 + Total raw data size: 9046 Total external raw data size: 400 Dataset layout information: Dataset layout counts[COMPACT]: 1 diff --git a/tools/test/h5stat/expected/h5stat_filters-dT.ddl b/tools/test/h5stat/expected/h5stat_filters-dT.ddl index b14ca9f9745..e513b3a5f28 100644 --- a/tools/test/h5stat/expected/h5stat_filters-dT.ddl +++ b/tools/test/h5stat/expected/h5stat_filters-dT.ddl @@ -12,7 +12,7 @@ Dataset dimension information: # of datasets with dimension size 100 - 999: 1 Total # of datasets: 1 Dataset storage information: - Total raw data size: 8659 + Total raw data size: 9046 Total external raw data size: 400 Dataset layout information: Dataset layout counts[COMPACT]: 1 diff --git a/tools/test/h5stat/expected/h5stat_filters.ddl b/tools/test/h5stat/expected/h5stat_filters.ddl index 9f9e146f08f..7383f0b31ff 100644 --- a/tools/test/h5stat/expected/h5stat_filters.ddl +++ b/tools/test/h5stat/expected/h5stat_filters.ddl @@ -12,12 +12,12 @@ File space information for file metadata (in bytes): Superblock extension: 0 User block: 0 Object headers: (total/unused) - Groups: 48/8 - Datasets(exclude compact data): 4136/1344 + Groups: 40/0 + Datasets(exclude compact data): 4128/1088 Datatypes: 80/0 Groups: B-tree/List: 1200 - Heap: 288 + Heap: 384 Attributes: B-tree/List: 0 Heap: 0 @@ -50,7 +50,7 @@ Dataset dimension information: # of datasets with dimension size 100 - 999: 1 Total # of datasets: 1 Dataset storage information: - Total raw data size: 8659 + Total raw data size: 9046 Total external raw data size: 400 Dataset layout information: Dataset layout counts[COMPACT]: 1 @@ -91,9 +91,9 @@ Free-space section bins: File space management strategy: H5F_FSPACE_STRATEGY_FSM_AGGR File space page size: 4096 bytes Summary of file space information: - File metadata: 37312 bytes - Raw data: 8659 bytes + File metadata: 37392 bytes + Raw data: 9046 bytes Amount/Percent of tracked free space: 0 bytes/0.0% - Unaccounted space: 301 bytes -Total space: 46272 bytes + Unaccounted space: 258 bytes +Total space: 46696 bytes External raw data: 400 bytes diff --git a/tools/test/h5stat/testfiles/h5stat_filters.h5 b/tools/test/h5stat/testfiles/h5stat_filters.h5 index 5b5f4bb7a68..23d68a9b72b 100644 Binary files a/tools/test/h5stat/testfiles/h5stat_filters.h5 and b/tools/test/h5stat/testfiles/h5stat_filters.h5 differ diff --git a/utils/test/swmr_check_compat_vfd.c b/utils/test/swmr_check_compat_vfd.c index b5cfb1ba35c..eeaae726f47 100644 --- a/utils/test/swmr_check_compat_vfd.c +++ b/utils/test/swmr_check_compat_vfd.c @@ -10,8 +10,9 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* Purpose: This is a small program that checks if the HDF5_DRIVER - * environment variable is set to a value that supports SWMR. +/* Purpose: This is a small program that checks if the HDF5_DRIVER or + * HDF5_TEST_DRIVER environment variable is set to a value that + * supports SWMR. * * It is intended for use in shell scripts. */ @@ -26,9 +27,9 @@ /*------------------------------------------------------------------------- * Function: main * - * Purpose: Inspects the HDF5_DRIVER environment variable, which - * determines the VFD that the test harness will use with - * the majority of the tests. + * Purpose: Inspects the HDF5_DRIVER and HDF5_TEST_DRIVER environment + * variables, which determines the VFD that the test harness + * will use with the majority of the tests. * * Return: VFD supports SWMR: EXIT_SUCCESS * @@ -43,6 +44,8 @@ main(void) char *driver = NULL; driver = getenv(HDF5_DRIVER); + if (!driver) + driver = getenv("HDF5_TEST_DRIVER"); if (H5FD__supports_swmr_test(driver)) return EXIT_SUCCESS;