summaryrefslogtreecommitdiffstats
path: root/tools/src/misc
diff options
context:
space:
mode:
Diffstat (limited to 'tools/src/misc')
-rw-r--r--tools/src/misc/CMakeLists.txt147
-rw-r--r--tools/src/misc/Makefile.am36
-rw-r--r--tools/src/misc/h5clear.c371
-rw-r--r--tools/src/misc/h5debug.c832
-rw-r--r--tools/src/misc/h5delete.c66
-rw-r--r--tools/src/misc/h5mkgrp.c394
-rw-r--r--tools/src/misc/h5repart.c510
7 files changed, 2356 insertions, 0 deletions
diff --git a/tools/src/misc/CMakeLists.txt b/tools/src/misc/CMakeLists.txt
new file mode 100644
index 0000000..054c888
--- /dev/null
+++ b/tools/src/misc/CMakeLists.txt
@@ -0,0 +1,147 @@
+cmake_minimum_required (VERSION 3.18)
+project (HDF5_TOOLS_SRC_MISC C)
+
+# --------------------------------------------------------------------
+# Add the misc executables
+# --------------------------------------------------------------------
+#-- Misc Executables
+if (NOT ONLY_SHARED_LIBS)
+ add_executable (h5debug ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5debug.c)
+ target_include_directories (h5debug PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
+ target_compile_options(h5debug PRIVATE "${HDF5_CMAKE_C_FLAGS}")
+ TARGET_C_PROPERTIES (h5debug STATIC)
+ target_link_libraries (h5debug PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+ set_target_properties (h5debug PROPERTIES FOLDER tools)
+ set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5debug")
+
+ add_executable (h5repart ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5repart.c)
+ target_include_directories (h5repart PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
+ target_compile_options(h5repart PRIVATE "${HDF5_CMAKE_C_FLAGS}")
+ TARGET_C_PROPERTIES (h5repart STATIC)
+ target_link_libraries (h5repart PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+ set_target_properties (h5repart PROPERTIES FOLDER tools)
+ set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5repart")
+
+ add_executable (h5mkgrp ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5mkgrp.c)
+ target_include_directories (h5mkgrp PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
+ target_compile_options(h5mkgrp PRIVATE "${HDF5_CMAKE_C_FLAGS}")
+ TARGET_C_PROPERTIES (h5mkgrp STATIC)
+ target_link_libraries (h5mkgrp PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+ set_target_properties (h5mkgrp PROPERTIES FOLDER tools)
+ set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5mkgrp")
+
+ add_executable (h5clear ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5clear.c)
+ target_include_directories (h5clear PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
+ target_compile_options(h5clear PRIVATE "${HDF5_CMAKE_C_FLAGS}")
+ TARGET_C_PROPERTIES (h5clear STATIC)
+ target_link_libraries (h5clear PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+ set_target_properties (h5clear PROPERTIES FOLDER tools)
+ set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5clear")
+
+ add_executable (h5delete ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5delete.c)
+ target_include_directories (h5delete PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
+ target_compile_options(h5delete PRIVATE "${HDF5_CMAKE_C_FLAGS}")
+ TARGET_C_PROPERTIES (h5delete STATIC)
+ target_link_libraries (h5delete PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET})
+ set_target_properties (h5delete PROPERTIES FOLDER tools)
+ set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5delete")
+
+ set (H5_DEP_EXECUTABLES
+ h5debug
+ h5repart
+ h5mkgrp
+ h5clear
+ h5delete
+ )
+endif ()
+if (BUILD_SHARED_LIBS)
+ add_executable (h5debug-shared ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5debug.c)
+ target_include_directories (h5debug-shared PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
+ TARGET_C_PROPERTIES (h5debug-shared SHARED)
+ target_compile_options(h5debug-shared PRIVATE "${HDF5_CMAKE_C_FLAGS}")
+ target_link_libraries (h5debug-shared PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET})
+ set_target_properties (h5debug-shared PROPERTIES FOLDER tools)
+ set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5debug-shared")
+
+ add_executable (h5repart-shared ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5repart.c)
+ target_include_directories (h5repart-shared PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
+ target_compile_options(h5repart-shared PRIVATE "${HDF5_CMAKE_C_FLAGS}")
+ TARGET_C_PROPERTIES (h5repart-shared SHARED)
+ target_link_libraries (h5repart-shared PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET})
+ set_target_properties (h5repart-shared PROPERTIES FOLDER tools)
+ set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5repart-shared")
+
+ add_executable (h5mkgrp-shared ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5mkgrp.c)
+ target_include_directories (h5mkgrp-shared PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
+ target_compile_options(h5mkgrp-shared PRIVATE "${HDF5_CMAKE_C_FLAGS}")
+ TARGET_C_PROPERTIES (h5mkgrp-shared SHARED)
+ target_link_libraries (h5mkgrp-shared PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET})
+ set_target_properties (h5mkgrp-shared PROPERTIES FOLDER tools)
+ set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5mkgrp-shared")
+
+ add_executable (h5clear-shared ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5clear.c)
+ target_include_directories (h5clear-shared PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
+ target_compile_options(h5clear-shared PRIVATE "${HDF5_CMAKE_C_FLAGS}")
+ TARGET_C_PROPERTIES (h5clear-shared SHARED)
+ target_link_libraries (h5clear-shared PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET})
+ set_target_properties (h5clear-shared PROPERTIES FOLDER tools)
+ set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5clear-shared")
+
+ add_executable (h5delete-shared ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5delete.c)
+ target_include_directories (h5delete-shared PRIVATE "${HDF5_TOOLS_DIR}/lib;${HDF5_SRC_INCLUDE_DIRS};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>")
+ target_compile_options(h5delete-shared PRIVATE "${HDF5_CMAKE_C_FLAGS}")
+ TARGET_C_PROPERTIES (h5delete-shared SHARED)
+ target_link_libraries (h5delete-shared PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET})
+ set_target_properties (h5delete-shared PROPERTIES FOLDER tools)
+ set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5delete-shared")
+
+ set (H5_DEP_EXECUTABLES ${H5_DEP_EXECUTABLES}
+ h5debug-shared
+ h5repart-shared
+ h5mkgrp-shared
+ h5clear-shared
+ h5delete-shared
+ )
+endif ()
+
+#-----------------------------------------------------------------------------
+# Add Target to clang-format
+#-----------------------------------------------------------------------------
+if (HDF5_ENABLE_FORMATTERS)
+ if (NOT ONLY_SHARED_LIBS)
+ clang_format (HDF5_H5DEBUG_SRC_FORMAT h5debug)
+ clang_format (HDF5_H5REPART_SRC_FORMAT h5repart)
+ clang_format (HDF5_H5MKGRP_SRC_FORMAT h5mkgrp)
+ clang_format (HDF5_H5CLEAR_SRC_FORMAT h5clear)
+ clang_format (HDF5_H5DELETE_SRC_FORMAT h5delete)
+ else ()
+ clang_format (HDF5_H5DEBUG_SRC_FORMAT h5debug-shared)
+ clang_format (HDF5_H5REPART_SRC_FORMAT h5repart-shared)
+ clang_format (HDF5_H5MKGRP_SRC_FORMAT h5mkgrp-shared)
+ clang_format (HDF5_H5CLEAR_SRC_FORMAT h5clear-shared)
+ clang_format (HDF5_H5DELETE_SRC_FORMAT h5delete-shared)
+ endif ()
+endif ()
+
+##############################################################################
+##############################################################################
+### I N S T A L L A T I O N ###
+##############################################################################
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# Rules for Installation of tools using make Install target
+#-----------------------------------------------------------------------------
+if (HDF5_EXPORTED_TARGETS)
+ foreach (exec ${H5_DEP_EXECUTABLES})
+ INSTALL_PROGRAM_PDB (${exec} ${HDF5_INSTALL_BIN_DIR} toolsapplications)
+ endforeach ()
+
+ install (
+ TARGETS
+ ${H5_DEP_EXECUTABLES}
+ EXPORT
+ ${HDF5_EXPORTED_TARGETS}
+ RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications
+ )
+endif ()
diff --git a/tools/src/misc/Makefile.am b/tools/src/misc/Makefile.am
new file mode 100644
index 0000000..709be6e
--- /dev/null
+++ b/tools/src/misc/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Copyright by The HDF Group.
+# All rights reserved.
+#
+# This file is part of HDF5. The full HDF5 copyright notice, including
+# terms governing use, modification, and redistribution, is contained in
+# the COPYING file, which can be found at the root of the source code
+# distribution tree, or in https://www.hdfgroup.org/licenses.
+# If you do not have access to either file, you may request a copy from
+# help@hdfgroup.org.
+##
+## Makefile.am
+## Run automake to generate a Makefile.in from this file.
+#
+# HDF5 Library Makefile(.in)
+#
+
+include $(top_srcdir)/config/commence.am
+
+# Include src directory
+AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
+
+# These are our main targets, the tools
+bin_PROGRAMS=h5debug h5repart h5mkgrp h5clear h5delete
+
+# Add h5debug, h5repart, and h5mkgrp specific linker flags here
+h5debug_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+h5repart_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+h5mkgrp_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+h5clear_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+h5delete_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS)
+
+# All programs rely on hdf5 library and h5tools library
+LDADD=$(LIBH5TOOLS) $(LIBHDF5)
+
+include $(top_srcdir)/config/conclude.am
diff --git a/tools/src/misc/h5clear.c b/tools/src/misc/h5clear.c
new file mode 100644
index 0000000..faf7d94
--- /dev/null
+++ b/tools/src/misc/h5clear.c
@@ -0,0 +1,371 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://www.hdfgroup.org/licenses. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: A tool used to do the following:
+ * (1) -s, --status: clear the status_flags field from the file's superblock
+ * (2) -m, --image: remove the metadata cache image from the file
+ * (3) --increment=C: set the file's EOA to the maximum of (EOA, EOF) + C
+ * (4) --filesize: print the file's EOA and EOF
+ */
+#include "hdf5.h"
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/* Name of tool */
+#define PROGRAMNAME "h5clear"
+
+/* Make these private properties (defined in H5Fprivate.h) available to h5clear. */
+#define H5F_ACS_CLEAR_STATUS_FLAGS_NAME "clear_status_flags"
+#define H5F_ACS_NULL_FSM_ADDR_NAME "null_fsm_addr"
+#define H5F_ACS_SKIP_EOF_CHECK_NAME "skip_eof_check"
+
+/* Default increment is 1 megabytes for the --increment option */
+#define DEFAULT_INCREMENT (1024 * 1024)
+
+static char *fname_g = NULL;
+static hbool_t clear_status_flags = FALSE;
+static hbool_t remove_cache_image = FALSE;
+static hbool_t print_filesize = FALSE;
+static hbool_t increment_eoa_eof = FALSE;
+static hsize_t increment = DEFAULT_INCREMENT;
+
+/*
+ * Command-line options: only publicize long options
+ */
+static const char *s_opts = "hVsmzi*";
+static struct h5_long_options l_opts[] = {
+ {"help", no_arg, 'h'}, {"version", no_arg, 'V'}, {"status", no_arg, 's'},
+ {"image", no_arg, 'm'}, {"filesize", no_arg, 'z'}, {"increment", optional_arg, 'i'},
+ {NULL, 0, '\0'}};
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Prints a usage message
+ *
+ * Return: void
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage(const char *prog)
+{
+ HDfprintf(stdout, "usage: %s [OPTIONS] file_name\n", prog);
+ HDfprintf(stdout, " OPTIONS\n");
+ HDfprintf(stdout, " -h, --help Print a usage message and exit\n");
+ HDfprintf(stdout, " -V, --version Print version number and exit\n");
+ HDfprintf(stdout, " -s, --status Clear the status_flags field in the file's superblock\n");
+ HDfprintf(stdout, " -m, --image Remove the metadata cache image from the file\n");
+ HDfprintf(stdout, " --filesize Print the file's EOA and EOF\n");
+ HDfprintf(stdout,
+ " --increment=C Set the file's EOA to the maximum of (EOA, EOF) + C for\n");
+ HDfprintf(stdout, " the file <file_name>.\n");
+ HDfprintf(stdout,
+ " C is >= 0; C is optional and will default to 1M when not set.\n");
+ HDfprintf(
+ stdout,
+ " This option helps to repair a crashed file where the stored EOA\n");
+ HDfprintf(stdout, " in the superblock is different from the actual EOF.\n");
+ HDfprintf(stdout,
+ " The file’s EOA and EOF will be the same after applying\n");
+ HDfprintf(stdout, " this option to the file.\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout, "Examples of use:\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout, "h5clear -s file_name\n");
+ HDfprintf(stdout, " Clear the status_flags field in the superblock of the HDF5 file <file_name>.\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout, "h5clear -m file_name\n");
+ HDfprintf(stdout, " Remove the metadata cache image from the HDF5 file <file_name>.\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout, "h5clear --increment file_name\n");
+ HDfprintf(stdout, " Set the EOA to the maximum of (EOA, EOF) + 1M for the file <file_name>.\n");
+ HDfprintf(stdout, "\n");
+ HDfprintf(stdout, "h5clear --increment=512 file_name\n");
+ HDfprintf(stdout, " Set the EOA to the maximum of (EOA, EOF) + 512 for the file <file_name>.\n");
+} /* usage() */
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: Parses command line and sets up global variable to control output
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+parse_command_line(int argc, const char *const *argv)
+{
+ int opt;
+
+ /* no arguments */
+ if (argc == 1) {
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+ }
+
+ /* parse command line options */
+ while ((opt = H5_get_option(argc, argv, s_opts, l_opts)) != EOF) {
+ switch ((char)opt) {
+ case 'h':
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+
+ case 'V':
+ print_version(h5tools_getprogname());
+ h5tools_setstatus(EXIT_SUCCESS);
+ goto done;
+
+ case 's':
+ clear_status_flags = TRUE;
+ break;
+
+ case 'm':
+ remove_cache_image = TRUE;
+ break;
+
+ case 'z':
+ print_filesize = TRUE;
+ break;
+
+ case 'i':
+ increment_eoa_eof = TRUE;
+ if (H5_optarg != NULL) {
+ if (HDatoi(H5_optarg) < 0) {
+ usage(h5tools_getprogname());
+ goto done;
+ }
+ increment = (hsize_t)HDatoi(H5_optarg);
+ }
+ break;
+
+ default:
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+ } /* end switch */
+ } /* end while */
+
+ /* check for file name to be processed */
+ if (argc <= H5_optind) {
+ error_msg("missing file name\n");
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ goto error;
+ } /* end if */
+
+ fname_g = HDstrdup(argv[H5_optind]);
+
+done:
+ return (0);
+
+error:
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: leave
+ *
+ * Purpose: Close the tools library and exit
+ *
+ * Return: Does not return
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+leave(int ret)
+{
+ h5tools_close();
+ HDexit(ret);
+} /* leave() */
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: The options are:
+ * (1) -s, --status: clear the status_flags field from the file's superblock
+ * (2) -m, --image: remove the metadata cache image from the file
+ * (3) --increment=C: set the file's EOA to the maximum of (EOA, EOF) + C
+ * (4) --filesize: print the file's EOA and EOF
+ *
+ * The three options: -s, -m, and --increment will modify the file
+ * so the file is opened with write access.
+ * The --filesize option just prints the EOA and EOF, so the file
+ * is opened with read access.
+ *
+ * The -s option will activate the private property:
+ * --H5F_ACS_CLEAR_STATUS_FLAGS_NAME
+ * The --increment option will active these two private properties:
+ * --H5F_ACS_NULL_FSM_ADDR_NAME
+ * --H5F_ACS_SKIP_EOF_CHECK_NAME
+ * The --filesize will activate the private property:
+ * --H5F_ACS_SKIP_EOF_CHECK_NAME
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, char *argv[])
+{
+ char *fname = NULL; /* File name */
+ hid_t fapl = H5I_INVALID_HID; /* File access property list */
+ hid_t fid = H5I_INVALID_HID; /* File ID */
+ haddr_t image_addr;
+ hsize_t image_len;
+ unsigned flags = H5F_ACC_RDWR; /* file access flags */
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* initialize h5tools lib */
+ h5tools_init();
+
+ /* Parse command line options */
+ if (parse_command_line(argc, (const char *const *)argv) < 0)
+ goto done;
+
+ if (fname_g == NULL)
+ goto done;
+
+ /* enable error reporting if command line option */
+ h5tools_error_report();
+
+ /* Print usage/exit if not using at least one of the options */
+ if (!clear_status_flags && !remove_cache_image && !increment_eoa_eof && !print_filesize) {
+ usage(h5tools_getprogname());
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ /* Cannot combine the --filesize option with other options */
+ if (print_filesize && (clear_status_flags || remove_cache_image || increment_eoa_eof)) {
+ error_msg("Cannot combine --filesize with other options\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ /* Duplicate the file name */
+ fname = HDstrdup(fname_g);
+
+ /* Get a copy of the file access property list */
+ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) {
+ error_msg("H5Pcreate\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ /* -s option */
+ if (clear_status_flags) {
+ /* Set to clear the status_flags in the file's superblock */
+ /* Activate this private property */
+ if (H5Pset(fapl, H5F_ACS_CLEAR_STATUS_FLAGS_NAME, &clear_status_flags) < 0) {
+ error_msg("H5Pset\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ }
+
+ /* --increment option */
+ if (increment_eoa_eof) {
+ /* Activate this private property */
+ if (H5Pset(fapl, H5F_ACS_SKIP_EOF_CHECK_NAME, &increment_eoa_eof) < 0) {
+ error_msg("H5Pset\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ /* Activate this private property */
+ if (H5Pset(fapl, H5F_ACS_NULL_FSM_ADDR_NAME, &increment_eoa_eof) < 0) {
+ error_msg("H5Pset\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ }
+
+ /* --filesize option; open the file read-only */
+ if (print_filesize) {
+ /* Activate this private property */
+ if (H5Pset(fapl, H5F_ACS_SKIP_EOF_CHECK_NAME, &print_filesize) < 0) {
+ error_msg("H5Pset\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ flags = H5F_ACC_RDONLY;
+ }
+
+ /* Open the file */
+ if ((fid = h5tools_fopen(fname, flags, fapl, FALSE, NULL, (size_t)0)) < 0) {
+ error_msg("h5tools_fopen\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+
+ /* --filesize option */
+ if (print_filesize) {
+ h5_stat_t st; /* Stat info call */
+ haddr_t eoa; /* The EOA value */
+
+ /* Get the file's EOA and EOF */
+ if (H5Fget_eoa(fid, &eoa) < 0 || HDstat(fname, &st) < 0) {
+ error_msg("H5Fget_eoa or HDstat\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ HDfprintf(stdout, "EOA is %" PRIuHADDR "; EOF is %" PRIuHADDR " \n", eoa, (haddr_t)st.st_size);
+ }
+
+ /* --increment option */
+ if (increment_eoa_eof) {
+ /* Set the file's EOA to the maximum of (EOA, EOF) + increment */
+ if (H5Fincrement_filesize(fid, increment) < 0) {
+ error_msg("H5Fset_eoa\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ }
+
+ /* -m option */
+ if (remove_cache_image) {
+ if (H5Fget_mdc_image_info(fid, &image_addr, &image_len) < 0) {
+ error_msg("H5Fget_mdc_image_info\n");
+ h5tools_setstatus(EXIT_FAILURE);
+ goto done;
+ }
+ if (image_addr == HADDR_UNDEF && image_len == 0)
+ warn_msg("No cache image in the file\n");
+ }
+
+ h5tools_setstatus(EXIT_SUCCESS);
+
+done:
+ if (fname)
+ HDfree(fname);
+ if (fname_g)
+ HDfree(fname_g);
+
+ H5E_BEGIN_TRY
+ {
+ H5Pclose(fapl);
+ H5Fclose(fid);
+ }
+ H5E_END_TRY
+
+ leave(h5tools_getstatus());
+} /* main() */
diff --git a/tools/src/misc/h5debug.c b/tools/src/misc/h5debug.c
new file mode 100644
index 0000000..b15ae09
--- /dev/null
+++ b/tools/src/misc/h5debug.c
@@ -0,0 +1,832 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://www.hdfgroup.org/licenses. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: debug.c
+ * Jul 18 1997
+ * Robb Matzke
+ *
+ * Purpose: Debugs an existing HDF5 file at a low level.
+ *
+ *-------------------------------------------------------------------------
+ */
+#define H5A_FRIEND /*suppress error about including H5Apkg */
+#define H5B2_FRIEND /*suppress error about including H5B2pkg */
+#define H5B2_TESTING /*suppress warning about H5B2 testing funcs*/
+#define H5D_FRIEND /*suppress error about including H5Dpkg */
+#define H5EA_FRIEND /*suppress error about including H5EApkg */
+#define H5EA_TESTING /*suppress warning about H5EA testing funcs*/
+#define H5FA_FRIEND /*suppress error about including H5FApkg */
+#define H5FA_TESTING /*suppress warning about H5FA testing funcs*/
+#define H5F_FRIEND /*suppress error about including H5Fpkg */
+#define H5G_FRIEND /*suppress error about including H5Gpkg */
+#define H5HF_FRIEND /*suppress error about including H5HFpkg */
+#define H5O_FRIEND /*suppress error about including H5Opkg */
+#define H5SM_FRIEND /*suppress error about including H5SMpkg */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Apkg.h" /* Attributes */
+#include "H5B2pkg.h" /* v2 B-trees */
+#include "H5CXprivate.h" /* API Contexts */
+#include "H5Dpkg.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5EApkg.h" /* Extensible Arrays */
+#include "H5FApkg.h" /* Fixed Arrays */
+#include "H5Fpkg.h" /* File access */
+#include "H5FSprivate.h" /* Free space manager */
+#include "H5Gpkg.h" /* Groups */
+#include "H5HFpkg.h" /* Fractal heaps */
+#include "H5HGprivate.h" /* Global Heaps */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Opkg.h" /* Object headers */
+#include "H5SMpkg.h" /* Implicitly shared messages */
+
+/* File drivers */
+#include "H5FDfamily.h"
+
+#define VCOL 50
+
+/*-------------------------------------------------------------------------
+ * Function: get_H5B2_class
+ *
+ * Purpose: Determine the v2 B-tree class from the buffer read in.
+ * B-trees are debugged through the B-tree subclass. The subclass
+ * identifier is two bytes after the B-tree signature.
+ *
+ * Return: Non-NULL on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static const H5B2_class_t *
+get_H5B2_class(const uint8_t *sig)
+{
+ H5B2_subid_t subtype = (H5B2_subid_t)sig[H5_SIZEOF_MAGIC + 1];
+ const H5B2_class_t *cls = NULL;
+
+ switch (subtype) {
+ case H5B2_TEST_ID:
+ cls = H5B2_TEST;
+ break;
+
+ case H5B2_FHEAP_HUGE_INDIR_ID:
+ cls = H5HF_HUGE_BT2_INDIR;
+ break;
+
+ case H5B2_FHEAP_HUGE_FILT_INDIR_ID:
+ cls = H5HF_HUGE_BT2_FILT_INDIR;
+ break;
+
+ case H5B2_FHEAP_HUGE_DIR_ID:
+ cls = H5HF_HUGE_BT2_DIR;
+ break;
+
+ case H5B2_FHEAP_HUGE_FILT_DIR_ID:
+ cls = H5HF_HUGE_BT2_FILT_DIR;
+ break;
+
+ case H5B2_GRP_DENSE_NAME_ID:
+ cls = H5G_BT2_NAME;
+ break;
+
+ case H5B2_GRP_DENSE_CORDER_ID:
+ cls = H5G_BT2_CORDER;
+ break;
+
+ case H5B2_SOHM_INDEX_ID:
+ cls = H5SM_INDEX;
+ break;
+
+ case H5B2_ATTR_DENSE_NAME_ID:
+ cls = H5A_BT2_NAME;
+ break;
+
+ case H5B2_ATTR_DENSE_CORDER_ID:
+ cls = H5A_BT2_CORDER;
+ break;
+
+ case H5B2_CDSET_ID:
+ cls = H5D_BT2;
+ break;
+
+ case H5B2_CDSET_FILT_ID:
+ cls = H5D_BT2_FILT;
+ break;
+
+ case H5B2_TEST2_ID:
+ cls = H5B2_TEST2;
+ break;
+
+ case H5B2_NUM_BTREE_ID:
+ default:
+ HDfprintf(stderr, "Unknown v2 B-tree subtype %u\n", (unsigned)(subtype));
+ } /* end switch */
+
+ return (cls);
+} /* end get_H5B2_class() */
+
+/*-------------------------------------------------------------------------
+ * Function: get_H5EA_class
+ *
+ * Purpose: Determine the extensible array class from the buffer read in.
+ * Extensible arrays are debugged through the array subclass.
+ * The subclass identifier is two bytes after the signature.
+ *
+ * Return: Non-NULL on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static const H5EA_class_t *
+get_H5EA_class(const uint8_t *sig)
+{
+ H5EA_cls_id_t clsid = (H5EA_cls_id_t)sig[H5_SIZEOF_MAGIC + 1];
+ const H5EA_class_t *cls = NULL;
+
+ switch (clsid) {
+ case H5EA_CLS_TEST_ID:
+ cls = H5EA_CLS_TEST;
+ break;
+
+ case H5EA_CLS_CHUNK_ID:
+ cls = H5EA_CLS_CHUNK;
+ break;
+
+ case H5EA_CLS_FILT_CHUNK_ID:
+ cls = H5EA_CLS_FILT_CHUNK;
+ break;
+
+ case H5EA_NUM_CLS_ID:
+ default:
+ HDfprintf(stderr, "Unknown extensible array class %u\n", (unsigned)(clsid));
+ } /* end switch */
+
+ return (cls);
+} /* end get_H5EA_class() */
+
+/*-------------------------------------------------------------------------
+ * Function: get_H5FA_class
+ *
+ * Purpose: Determine the fixed array class from the buffer read in.
+ * Extensible arrays are debugged through the array subclass.
+ * The subclass identifier is two bytes after the signature.
+ *
+ * Return: Non-NULL on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * Sep 11 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static const H5FA_class_t *
+get_H5FA_class(const uint8_t *sig)
+{
+ H5FA_cls_id_t clsid = (H5FA_cls_id_t)sig[H5_SIZEOF_MAGIC + 1];
+ const H5FA_class_t *cls = NULL;
+
+ switch (clsid) {
+ case H5FA_CLS_TEST_ID:
+ cls = H5FA_CLS_TEST;
+ break;
+
+ case H5FA_CLS_CHUNK_ID:
+ cls = H5FA_CLS_CHUNK;
+ break;
+
+ case H5FA_CLS_FILT_CHUNK_ID:
+ cls = H5FA_CLS_FILT_CHUNK;
+ break;
+
+ case H5FA_NUM_CLS_ID:
+ default:
+ HDfprintf(stderr, "Unknown fixed array class %u\n", (unsigned)(clsid));
+ } /* end switch */
+
+ return (cls);
+} /* end get_H5FA_class() */
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Usage: debug FILENAME [OFFSET]
+ *
+ * Return: Success: exit (0)
+ *
+ * Failure: exit (non-zero)
+ *
+ * Programmer: Robb Matzke
+ * Jul 18 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, char *argv[])
+{
+ hid_t fid = H5I_INVALID_HID;
+ hid_t fapl = H5I_INVALID_HID;
+ H5VL_object_t *vol_obj;
+ H5F_t *f;
+ haddr_t addr = 0;
+ int extra_count = 0; /* Number of extra arguments */
+ haddr_t extra[10];
+ uint8_t sig[H5F_SIGNATURE_LEN];
+ size_t u;
+ H5E_auto2_t func = NULL;
+ void *edata = NULL;
+ hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */
+ herr_t status = SUCCEED;
+ int exit_value = 0;
+
+ if (argc == 1) {
+ HDfprintf(stderr, "Usage: %s filename [signature-addr [extra]*]\n", argv[0]);
+ exit_value = 1;
+ goto done;
+ } /* end if */
+
+ /* Initialize the library */
+ if (H5open() < 0) {
+ HDfprintf(stderr, "cannot initialize the library\n");
+ exit_value = 1;
+ goto done;
+ } /* end if */
+
+ /* Disable error reporting */
+ H5Eget_auto2(H5E_DEFAULT, &func, &edata);
+ H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
+
+ /*
+ * Open the file and get the file descriptor.
+ */
+ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) {
+ HDfprintf(stderr, "cannot create file access property list\n");
+ exit_value = 1;
+ goto done;
+ } /* end if */
+ if (HDstrchr(argv[1], '%'))
+ if (H5Pset_fapl_family(fapl, (hsize_t)0, H5P_DEFAULT) < 0) {
+ HDfprintf(stderr, "cannot set file access property list\n");
+ exit_value = 1;
+ goto done;
+ }
+ if ((fid = H5Fopen(argv[1], H5F_ACC_RDONLY, fapl)) < 0) {
+ HDfprintf(stderr, "cannot open file\n");
+ exit_value = 1;
+ goto done;
+ } /* end if */
+
+ /* Push API context */
+ if (H5CX_push() < 0) {
+ HDfprintf(stderr, "cannot set API context\n");
+ exit_value = 1;
+ goto done;
+ }
+ api_ctx_pushed = TRUE;
+
+ if (NULL == (vol_obj = (H5VL_object_t *)H5VL_vol_object(fid))) {
+ HDfprintf(stderr, "cannot obtain vol_obj pointer\n");
+ exit_value = 2;
+ goto done;
+ } /* end if */
+
+ if (NULL == (f = (H5F_t *)H5VL_object_data(vol_obj))) {
+ HDfprintf(stderr, "cannot obtain H5F_t pointer\n");
+ exit_value = 2;
+ goto done;
+ } /* end if */
+
+ /* Ignore metadata tags while using h5debug */
+ if (H5AC_ignore_tags(f) < 0) {
+ HDfprintf(stderr, "cannot ignore metadata tags\n");
+ exit_value = 1;
+ goto done;
+ }
+
+ /*
+ * Parse command arguments.
+ */
+
+ /* Primary data structure to dump */
+ if (argc > 2)
+ addr = (haddr_t)HDstrtoll(argv[2], NULL, 0);
+
+ /* Extra arguments for primary data structure */
+ HDmemset(extra, 0, sizeof(extra));
+ if (argc > 3) {
+ /* Number of extra arguments */
+ extra_count = argc - 3;
+
+ /* Range check against 'extra' array size */
+ if (extra_count > (int)(sizeof(extra) / sizeof(haddr_t))) {
+ HDfprintf(stderr, "\nWARNING: Only using first %d extra parameters\n\n",
+ (int)(sizeof(extra) / sizeof(haddr_t)));
+ extra_count = (int)(sizeof(extra) / sizeof(haddr_t));
+ } /* end if */
+
+ for (u = 0; u < (size_t)extra_count; u++)
+ extra[u] = (haddr_t)HDstrtoll(argv[u + 3], NULL, 0);
+ } /* end if */
+
+ /*
+ * Read the signature at the specified file position.
+ */
+ HDfprintf(stdout, "Reading signature at address %" PRIuHADDR " (rel)\n", addr);
+ if (H5F_block_read(f, H5FD_MEM_SUPER, addr, sizeof(sig), sig) < 0) {
+ HDfprintf(stderr, "cannot read signature\n");
+ exit_value = 3;
+ goto done;
+ }
+ if (!HDmemcmp(sig, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN)) {
+ /*
+ * Debug the file's super block.
+ */
+ status = H5F_debug(f, stdout, 0, VCOL);
+ }
+ else if (!HDmemcmp(sig, H5HL_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a local heap.
+ */
+ status = H5HL_debug(f, addr, stdout, 0, VCOL);
+ }
+ else if (!HDmemcmp(sig, H5HG_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a global heap collection.
+ */
+ status = H5HG_debug(f, addr, stdout, 0, VCOL);
+ }
+ else if (!HDmemcmp(sig, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a symbol table node.
+ */
+
+ /* Check for extra parameters */
+ if (extra_count == 0 || extra[0] == 0) {
+ HDfprintf(stderr,
+ "\nWarning: Providing the group's local heap address will give more information\n");
+ HDfprintf(stderr, "Symbol table node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <Symbol table node address> <address of local heap>\n\n");
+ } /* end if */
+
+ status = H5G_node_debug(f, addr, stdout, 0, VCOL, extra[0]);
+ }
+ else if (!HDmemcmp(sig, H5B_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a B-tree. B-trees are debugged through the B-tree
+ * subclass. The subclass identifier is the byte immediately
+ * after the B-tree signature.
+ */
+ H5B_subid_t subtype = (H5B_subid_t)sig[H5_SIZEOF_MAGIC];
+ unsigned ndims;
+ uint32_t dim[H5O_LAYOUT_NDIMS];
+
+ switch (subtype) {
+ case H5B_SNODE_ID:
+ /* Check for extra parameters */
+ if (extra_count == 0 || extra[0] == 0) {
+ HDfprintf(
+ stderr,
+ "\nWarning: Providing the group's local heap address will give more information\n");
+ HDfprintf(stderr, "B-tree symbol table node usage:\n");
+ HDfprintf(stderr,
+ "\th5debug <filename> <B-tree node address> <address of local heap>\n\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5G_node_debug(f, addr, stdout, 0, VCOL, extra[0]);
+ break;
+
+ case H5B_CHUNK_ID:
+ /* Check for extra parameters */
+ if (extra_count == 0 || extra[0] == 0) {
+ HDfprintf(
+ stderr,
+ "ERROR: Need number of dimensions of chunk in order to dump chunk B-tree node\n");
+ HDfprintf(stderr, "B-tree chunked storage node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <B-tree node address> <# of dimensions> <slowest "
+ "chunk dim>...<fastest chunk dim>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ /* Set # of dimensions */
+ ndims = (unsigned)extra[0];
+
+ /* Check for dimension error */
+ if (ndims > 9) {
+ HDfprintf(stderr, "ERROR: Only 9 dimensions support currently (fix h5debug)\n");
+ HDfprintf(stderr, "B-tree chunked storage node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <B-tree node address> <# of dimensions> <slowest "
+ "chunk dim>...<fastest chunk dim>\n");
+ exit_value = 4;
+ goto done;
+ } /* end for */
+
+ /* Build array of chunk dimensions */
+ for (u = 0; u < ndims; u++)
+ dim[u] = (uint32_t)extra[u + 1];
+
+ /* Check for dimension error */
+ for (u = 0; u < ndims; u++)
+ if (0 == dim[u]) {
+ HDfprintf(stderr, "ERROR: Chunk dimensions should be >0\n");
+ HDfprintf(stderr, "B-tree chunked storage node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <B-tree node address> <# of dimensions> "
+ "<slowest chunk dim>...<fastest chunk dim>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ /* Set the last dimension (the element size) to zero */
+ dim[ndims] = 0;
+
+ status = H5D_btree_debug(f, addr, stdout, 0, VCOL, ndims, dim);
+ break;
+
+ case H5B_NUM_BTREE_ID:
+ default:
+ HDfprintf(stderr, "Unknown v1 B-tree subtype %u\n", (unsigned)(subtype));
+ exit_value = 4;
+ goto done;
+ }
+ }
+ else if (!HDmemcmp(sig, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a v2 B-tree header.
+ */
+ const H5B2_class_t *cls = get_H5B2_class(sig);
+ HDassert(cls);
+
+ if ((cls == H5D_BT2 || cls == H5D_BT2_FILT) && (extra_count == 0 || extra[0] == 0)) {
+ HDfprintf(stderr, "ERROR: Need v2 B-tree header address and object header address containing the "
+ "layout message in order to dump header\n");
+ HDfprintf(stderr, "v2 B-tree hdr usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <v2 B-tree header address> <object header address>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5B2__hdr_debug(f, addr, stdout, 0, VCOL, cls, (haddr_t)extra[0]);
+ }
+ else if (!HDmemcmp(sig, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a v2 B-tree internal node.
+ */
+ const H5B2_class_t *cls = get_H5B2_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if ((cls == H5D_BT2 || cls == H5D_BT2_FILT) &&
+ (extra_count == 0 || extra[0] == 0 || extra[1] == 0 || extra[2] == 0 || extra[3] == 0)) {
+ HDfprintf(stderr,
+ "ERROR: Need v2 B-tree header address, the node's number of records, depth, and object "
+ "header address containing the layout message in order to dump internal node\n");
+ HDfprintf(stderr,
+ "NOTE: Leaf nodes are depth 0, the internal nodes above them are depth 1, etc.\n");
+ HDfprintf(stderr, "v2 B-tree internal node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <internal node address> <v2 B-tree header address> "
+ "<number of records> <depth> <object header address>\n");
+ exit_value = 4;
+ goto done;
+ }
+ else if (extra_count == 0 || extra[0] == 0 || extra[1] == 0 || extra[2] == 0) {
+ HDfprintf(stderr, "ERROR: Need v2 B-tree header address and the node's number of records and "
+ "depth in order to dump internal node\n");
+ HDfprintf(stderr,
+ "NOTE: Leaf nodes are depth 0, the internal nodes above them are depth 1, etc.\n");
+ HDfprintf(stderr, "v2 B-tree internal node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <internal node address> <v2 B-tree header address> "
+ "<number of records> <depth>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5B2__int_debug(f, addr, stdout, 0, VCOL, cls, extra[0], (unsigned)extra[1],
+ (unsigned)extra[2], (haddr_t)extra[3]);
+ }
+ else if (!HDmemcmp(sig, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a v2 B-tree leaf node.
+ */
+ const H5B2_class_t *cls = get_H5B2_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if ((cls == H5D_BT2 || cls == H5D_BT2_FILT) &&
+ (extra_count == 0 || extra[0] == 0 || extra[1] == 0 || extra[2] == 0)) {
+
+ HDfprintf(stderr, "ERROR: Need v2 B-tree header address, number of records, and object header "
+ "address containing the layout message in order to dump leaf node\n");
+ HDfprintf(stderr, "v2 B-tree leaf node usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <leaf node address> <v2 B-tree header address> <number "
+ "of records> <object header address>\n");
+ exit_value = 4;
+ goto done;
+ }
+ else if (extra_count == 0 || extra[0] == 0 || extra[1] == 0) {
+ HDfprintf(
+ stderr,
+ "ERROR: Need v2 B-tree header address and number of records in order to dump leaf node\n");
+ HDfprintf(stderr, "v2 B-tree leaf node usage:\n");
+ HDfprintf(
+ stderr,
+ "\th5debug <filename> <leaf node address> <v2 B-tree header address> <number of records>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status =
+ H5B2__leaf_debug(f, addr, stdout, 0, VCOL, cls, extra[0], (unsigned)extra[1], (haddr_t)extra[2]);
+ }
+ else if (!HDmemcmp(sig, H5HF_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a fractal heap header.
+ */
+ status = H5HF_hdr_debug(f, addr, stdout, 0, VCOL);
+ }
+ else if (!HDmemcmp(sig, H5HF_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a fractal heap direct block.
+ */
+
+ /* Check for enough valid parameters */
+ if (extra_count == 0 || extra[0] == 0 || extra[1] == 0) {
+ HDfprintf(stderr, "ERROR: Need fractal heap header address and size of direct block in order to "
+ "dump direct block\n");
+ HDfprintf(stderr, "Fractal heap direct block usage:\n");
+ HDfprintf(
+ stderr,
+ "\th5debug <filename> <direct block address> <heap header address> <size of direct block>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5HF_dblock_debug(f, addr, stdout, 0, VCOL, extra[0], (size_t)extra[1]);
+ }
+ else if (!HDmemcmp(sig, H5HF_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a fractal heap indirect block.
+ */
+
+ /* Check for enough valid parameters */
+ if (extra_count == 0 || extra[0] == 0 || extra[1] == 0) {
+ HDfprintf(stderr, "ERROR: Need fractal heap header address and number of rows in order to dump "
+ "indirect block\n");
+ HDfprintf(stderr, "Fractal heap indirect block usage:\n");
+ HDfprintf(
+ stderr,
+ "\th5debug <filename> <indirect block address> <heap header address> <number of rows>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5HF_iblock_debug(f, addr, stdout, 0, VCOL, extra[0], (unsigned)extra[1]);
+ }
+ else if (!HDmemcmp(sig, H5FS_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a free space header.
+ */
+
+ status = H5FS_debug(f, addr, stdout, 0, VCOL);
+ }
+ else if (!HDmemcmp(sig, H5FS_SINFO_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug free space serialized sections.
+ */
+
+ /* Check for enough valid parameters */
+ if (extra_count == 0 || extra[0] == 0 || extra[1] == 0) {
+ HDfprintf(stderr, "ERROR: Need free space header address and client address in order to dump "
+ "serialized sections\n");
+ HDfprintf(stderr, "Free space serialized sections usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <serialized sections address> <free space header "
+ "address> <client address>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5FS_sects_debug(f, addr, stdout, 0, VCOL, extra[0], extra[1]);
+ }
+ else if (!HDmemcmp(sig, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug shared message master table.
+ */
+
+ status = H5SM_table_debug(f, addr, stdout, 0, VCOL, UINT_MAX, UINT_MAX);
+ }
+ else if (!HDmemcmp(sig, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug shared message list index.
+ */
+
+ /* Check for enough valid parameters */
+ if (extra_count == 0 || extra[0] == 0) {
+ HDfprintf(stderr, "ERROR: Need shared message header address in order to shared message list\n");
+ HDfprintf(stderr, "Shared message list usage:\n");
+ HDfprintf(stderr,
+ "\th5debug <filename> <shared message list address> <shared message header address>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5SM_list_debug(f, addr, stdout, 0, VCOL, (haddr_t)extra[0]);
+ }
+ else if (!HDmemcmp(sig, H5EA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug an extensible array header.
+ */
+ const H5EA_class_t *cls = get_H5EA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if (extra_count == 0 || extra[0] == 0) {
+ HDfprintf(
+ stderr,
+ "ERROR: Need object header address containing the layout message in order to dump header\n");
+ HDfprintf(stderr, "Extensible array header block usage:\n");
+ HDfprintf(stderr,
+ "\th5debug <filename> <Extensible Array header address> <object header address>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5EA__hdr_debug(f, addr, stdout, 0, VCOL, cls, extra[0]);
+ }
+ else if (!HDmemcmp(sig, H5EA_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug an extensible array index block.
+ */
+ const H5EA_class_t *cls = get_H5EA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if (extra_count == 0 || extra[0] == 0 || extra[1] == 0) {
+ HDfprintf(stderr, "ERROR: Need extensible array header address and object header address "
+ "containing the layout message in order to dump index block\n");
+ HDfprintf(stderr, "Extensible array index block usage:\n");
+ HDfprintf(
+ stderr,
+ "\th5debug <filename> <index block address> <array header address> <object header address\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5EA__iblock_debug(f, addr, stdout, 0, VCOL, cls, extra[0], extra[1]);
+ }
+ else if (!HDmemcmp(sig, H5EA_SBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug an extensible array super block.
+ */
+ const H5EA_class_t *cls = get_H5EA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if (extra_count == 0 || extra[0] == 0 || extra[1] == 0 || extra[2] == 0) {
+ HDfprintf(stderr, "ERROR: Need extensible array header address, super block index and object "
+ "header address containing the layout message in order to dump super block\n");
+ HDfprintf(stderr, "Extensible array super block usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <super block address> <array header address> <super "
+ "block index> <object header address>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5EA__sblock_debug(f, addr, stdout, 0, VCOL, cls, extra[0], (unsigned)extra[1], extra[2]);
+ }
+ else if (!HDmemcmp(sig, H5EA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug an extensible array data block.
+ */
+ const H5EA_class_t *cls = get_H5EA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if (extra_count == 0 || extra[0] == 0 || extra[1] == 0 || extra[2] == 0) {
+ HDfprintf(stderr,
+ "ERROR: Need extensible array header address, # of elements in data block and object "
+ "header address containing the layout message in order to dump data block\n");
+ HDfprintf(stderr, "Extensible array data block usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <data block address> <array header address> <# of "
+ "elements in data block> <object header address\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5EA__dblock_debug(f, addr, stdout, 0, VCOL, cls, extra[0], (size_t)extra[1], extra[2]);
+ }
+ else if (!HDmemcmp(sig, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a fixed array header.
+ */
+ const H5FA_class_t *cls = get_H5FA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if (extra_count == 0 || extra[0] == 0) {
+ HDfprintf(
+ stderr,
+ "ERROR: Need object header address containing the layout message in order to dump header\n");
+ HDfprintf(stderr, "Fixed array header block usage:\n");
+ HDfprintf(stderr, "\th5debug <filename> <Fixed Array header address> <object header address>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5FA__hdr_debug(f, addr, stdout, 0, VCOL, cls, extra[0]);
+ }
+ else if (!HDmemcmp(sig, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug a fixed array data block.
+ */
+ const H5FA_class_t *cls = get_H5FA_class(sig);
+ HDassert(cls);
+
+ /* Check for enough valid parameters */
+ if (extra_count == 0 || extra[0] == 0 || extra[1] == 0) {
+ HDfprintf(stderr, "ERROR: Need fixed array header address and object header address containing "
+ "the layout message in order to dump data block\n");
+ HDfprintf(stderr, "fixed array data block usage:\n");
+ HDfprintf(
+ stderr,
+ "\th5debug <filename> <data block address> <array header address> <object header address>\n");
+ exit_value = 4;
+ goto done;
+ } /* end if */
+
+ status = H5FA__dblock_debug(f, addr, stdout, 0, VCOL, cls, extra[0], extra[1]);
+ }
+ else if (!HDmemcmp(sig, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
+ /*
+ * Debug v2 object header (which have signatures).
+ */
+
+ status = H5O_debug(f, addr, stdout, 0, VCOL);
+ }
+ else if (sig[0] == H5O_VERSION_1) {
+ /*
+ * This could be a v1 object header. Since they don't have a signature
+ * it's a somewhat "ify" detection.
+ */
+ status = H5O_debug(f, addr, stdout, 0, VCOL);
+ }
+ else {
+ /*
+ * Got some other unrecognized signature.
+ */
+ HDprintf("%-*s ", VCOL, "Signature:");
+ for (u = 0; u < sizeof(sig); u++) {
+ if (sig[u] > ' ' && sig[u] <= '~' && '\\' != sig[u])
+ HDputchar(sig[u]);
+ else if ('\\' == sig[u]) {
+ HDputchar('\\');
+ HDputchar('\\');
+ }
+ else
+ HDprintf("\\%03o", sig[u]);
+ }
+ HDputchar('\n');
+
+ HDfprintf(stderr, "unknown signature\n");
+ exit_value = 4;
+ goto done;
+ } /* end else */
+
+ /* Check for an error when dumping information */
+ if (status < 0) {
+ HDfprintf(stderr, "An error occurred!\n");
+ H5Eprint2(H5E_DEFAULT, stderr);
+ exit_value = 5;
+ goto done;
+ } /* end if */
+
+done:
+ if (fapl > 0)
+ H5Pclose(fapl);
+ if (fid > 0) {
+ if (H5Fclose(fid) < 0) {
+ HDfprintf(stderr, "Error in closing file!\n");
+ exit_value = 1;
+ }
+ }
+
+ /* Pop API context */
+ if (api_ctx_pushed)
+ H5CX_pop(FALSE);
+
+ H5Eset_auto2(H5E_DEFAULT, func, edata);
+
+ return exit_value;
+} /* main() */
diff --git a/tools/src/misc/h5delete.c b/tools/src/misc/h5delete.c
new file mode 100644
index 0000000..20e81a1
--- /dev/null
+++ b/tools/src/misc/h5delete.c
@@ -0,0 +1,66 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://www.hdfgroup.org/licenses. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* h5delete tool
+ *
+ * Deletes storage via H5Fdelete() using the VOL connector specified in the
+ * environment variable.
+ */
+
+#include "H5private.h"
+#include "H5Eprivate.h"
+#include "H5Pprivate.h"
+
+static void usage(void);
+
+static void
+usage(void)
+{
+ HDfprintf(stderr, "Usage: h5delete [-f] <filename>\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ hbool_t quiet = FALSE;
+ const char *name = NULL;
+ int ret = 0;
+
+ switch (argc) {
+ case 3:
+ if (HDstrcmp(argv[1], "-f") != 0) {
+ usage();
+ return EXIT_FAILURE;
+ }
+ quiet = TRUE;
+ name = argv[2];
+ break;
+ case 2:
+ name = argv[1];
+ break;
+ default:
+ usage();
+ return EXIT_FAILURE;
+ }
+
+ H5E_BEGIN_TRY
+ {
+ /* Only uses the environment variable at this time */
+ ret = (int)H5Fdelete(name, H5P_DEFAULT);
+ }
+ H5E_END_TRY;
+
+ if (ret < 0 && !quiet)
+ HDfprintf(stderr, "Unable to delete storage at: %s\n", name);
+
+ return ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/tools/src/misc/h5mkgrp.c b/tools/src/misc/h5mkgrp.c
new file mode 100644
index 0000000..fc7d5b6
--- /dev/null
+++ b/tools/src/misc/h5mkgrp.c
@@ -0,0 +1,394 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://www.hdfgroup.org/licenses. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "H5private.h"
+#include "h5tools.h"
+#include "h5tools_utils.h"
+
+/* Name of tool */
+#define PROGRAMNAME "h5mkgrp"
+
+/* Exit status for tools library routines */
+int d_status = EXIT_SUCCESS;
+
+/* command-line options: short and long-named parameters */
+static const char *s_opts = "hlpvV";
+static struct h5_long_options l_opts[] = {
+ {"help", no_arg, 'h'}, {"latest", no_arg, 'l'}, {"parents", no_arg, 'p'},
+ {"verbose", no_arg, 'v'}, {"version", no_arg, 'V'}, {"vol-value", require_arg, '1'},
+ {"vol-name", require_arg, '2'}, {"vol-info", require_arg, '3'}, {"vfd-value", require_arg, '4'},
+ {"vfd-name", require_arg, '5'}, {"vfd-info", require_arg, '6'}, {NULL, 0, '\0'}};
+
+/* Command line parameter settings */
+typedef struct mkgrp_opt_t {
+ char *fname; /* File name to operate on */
+ hbool_t latest; /* Whether file should use latest format versions */
+ hbool_t verbose; /* Whether output should be verbose */
+ hbool_t parents; /* Whether to create intermediate groups */
+ size_t ngroups; /* Number of groups to create */
+ char **groups; /* Pointer to array of group names */
+ hid_t fapl_id; /* fapl to use when opening the file */
+} mkgrp_opt_t;
+
+mkgrp_opt_t params_g; /* Command line parameter settings */
+
+/*-------------------------------------------------------------------------
+ * Function: leave
+ *
+ * Purpose: Shutdown MPI and/or HDF5 and call exit()
+ *
+ * Return: Does not return
+ *
+ * Programmer: Quincey Koziol, 2/13/2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+leave(int ret)
+{
+ size_t curr_group;
+
+ if (params_g.fname)
+ HDfree(params_g.fname);
+ if (params_g.ngroups) {
+ for (curr_group = 0; curr_group < params_g.ngroups; curr_group++)
+ HDfree(params_g.groups[curr_group]);
+ HDfree(params_g.groups);
+ }
+ if (H5I_INVALID_HID != params_g.fapl_id && H5P_DEFAULT != params_g.fapl_id)
+ if (H5Pclose(params_g.fapl_id) < 0)
+ error_msg("Could not close file access property list\n");
+
+ h5tools_close();
+ HDexit(ret);
+} /* end leave() */
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Prints a usage message on stderr and then returns.
+ *
+ * Return: void
+ *
+ * Programmer: Quincey Koziol, 2/13/2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage(const char *prog)
+{
+ FLUSHSTREAM(rawoutstream);
+ PRINTSTREAM(rawoutstream, "usage: %s [OPTIONS] FILE GROUP...\n", prog);
+ PRINTVALSTREAM(rawoutstream, " OPTIONS\n");
+ PRINTVALSTREAM(rawoutstream, " -h, --help Print a usage message and exit\n");
+ PRINTVALSTREAM(rawoutstream,
+ " -l, --latest Use latest version of file format to create groups\n");
+ PRINTVALSTREAM(rawoutstream,
+ " -p, --parents No error if existing, make parent groups as needed\n");
+ PRINTVALSTREAM(rawoutstream, " -v, --verbose Print information about OBJECTS and OPTIONS\n");
+ PRINTVALSTREAM(rawoutstream, " -V, --version Print version number and exit\n");
+ PRINTVALSTREAM(rawoutstream,
+ " --vol-value Value (ID) of the VOL connector to use for opening the\n");
+ PRINTVALSTREAM(rawoutstream, " HDF5 file specified\n");
+ PRINTVALSTREAM(rawoutstream,
+ " --vol-name Name of the VOL connector to use for opening the\n");
+ PRINTVALSTREAM(rawoutstream, " HDF5 file specified\n");
+ PRINTVALSTREAM(rawoutstream,
+ " --vol-info VOL-specific info to pass to the VOL connector used for\n");
+ PRINTVALSTREAM(rawoutstream, " opening the HDF5 file specified\n");
+ PRINTVALSTREAM(rawoutstream,
+ " --vfd-value Value (ID) of the VFL driver to use for opening the\n");
+ PRINTVALSTREAM(rawoutstream, " HDF5 file specified\n");
+ PRINTVALSTREAM(rawoutstream, " --vfd-name Name of the VFL driver to use for opening the\n");
+ PRINTVALSTREAM(rawoutstream, " HDF5 file specified\n");
+ PRINTVALSTREAM(rawoutstream,
+ " --vfd-info VFD-specific info to pass to the VFL driver used for\n");
+ PRINTVALSTREAM(rawoutstream, " opening the HDF5 file specified\n");
+ PRINTVALSTREAM(rawoutstream, "\n");
+} /* end usage() */
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: Parses command line and sets up global variable to control
+ * output
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol, 2/13/2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+parse_command_line(int argc, const char *const *argv, mkgrp_opt_t *options)
+{
+ int opt; /* Option from command line */
+ size_t curr_group; /* Current group name to copy */
+ hbool_t custom_vol = FALSE;
+ hbool_t custom_vfd = FALSE;
+ h5tools_vol_info_t vol_info;
+ h5tools_vfd_info_t vfd_info;
+ hid_t tmp_fapl_id = H5I_INVALID_HID;
+
+ /* Check for empty command line */
+ if (argc == 1) {
+ usage(h5tools_getprogname());
+ leave(EXIT_SUCCESS);
+ }
+
+ /* Initialize fapl info structs */
+ HDmemset(&vol_info, 0, sizeof(h5tools_vol_info_t));
+ HDmemset(&vfd_info, 0, sizeof(h5tools_vfd_info_t));
+
+ /* Parse command line options */
+ while ((opt = H5_get_option(argc, argv, s_opts, l_opts)) != EOF) {
+ switch ((char)opt) {
+ /* Display 'help' */
+ case 'h':
+ usage(h5tools_getprogname());
+ leave(EXIT_SUCCESS);
+ break;
+
+ /* Create objects with the latest version of the format */
+ case 'l':
+ options->latest = TRUE;
+ break;
+
+ /* Create parent groups */
+ case 'p':
+ options->parents = TRUE;
+ break;
+
+ /* Verbose output */
+ case 'v':
+ options->verbose = TRUE;
+ break;
+
+ /* Display version */
+ case 'V':
+ print_version(h5tools_getprogname());
+ leave(EXIT_SUCCESS);
+ break;
+
+ case '1':
+ vol_info.type = VOL_BY_VALUE;
+ vol_info.u.value = (H5VL_class_value_t)HDatoi(H5_optarg);
+ custom_vol = TRUE;
+ break;
+
+ case '2':
+ vol_info.type = VOL_BY_NAME;
+ vol_info.u.name = H5_optarg;
+ custom_vol = TRUE;
+ break;
+
+ case '3':
+ vol_info.info_string = H5_optarg;
+ break;
+
+ case '4':
+ vfd_info.type = VFD_BY_VALUE;
+ vfd_info.u.value = (H5FD_class_value_t)HDatoi(H5_optarg);
+ custom_vfd = TRUE;
+ break;
+
+ case '5':
+ vfd_info.type = VFD_BY_NAME;
+ vfd_info.u.name = H5_optarg;
+ custom_vfd = TRUE;
+ break;
+
+ case '6':
+ vfd_info.info = (const void *)H5_optarg;
+ break;
+
+ /* Bad command line argument */
+ default:
+ usage(h5tools_getprogname());
+ leave(EXIT_FAILURE);
+ } /* end switch */
+ } /* end while */
+
+ /* Check for file name to be processed */
+ if (argc <= H5_optind) {
+ error_msg("missing file name\n");
+ usage(h5tools_getprogname());
+ leave(EXIT_FAILURE);
+ }
+
+ /* Retrieve file name */
+ options->fname = HDstrdup(argv[H5_optind]);
+ H5_optind++;
+
+ /* Check for group(s) to be created */
+ if (argc <= H5_optind) {
+ error_msg("missing group name(s)\n");
+ usage(h5tools_getprogname());
+ leave(EXIT_FAILURE);
+ }
+
+ /* Allocate space for the group name pointers */
+ options->ngroups = (size_t)(argc - H5_optind);
+ options->groups = (char **)HDmalloc(options->ngroups * sizeof(char *));
+
+ /* Retrieve the group names */
+ curr_group = 0;
+ while (H5_optind < argc) {
+ options->groups[curr_group] = HDstrdup(argv[H5_optind]);
+ curr_group++;
+ H5_optind++;
+ }
+
+ /* Setup a custom fapl for file accesses */
+ if (custom_vol || custom_vfd) {
+ if ((tmp_fapl_id = h5tools_get_fapl(options->fapl_id, custom_vol ? &vol_info : NULL,
+ custom_vfd ? &vfd_info : NULL)) < 0) {
+ error_msg("failed to setup file access property list (fapl) for file\n");
+ leave(EXIT_FAILURE);
+ }
+
+ /* Close the old fapl */
+ if (options->fapl_id != H5P_DEFAULT)
+ if (H5Pclose(options->fapl_id) < 0) {
+ error_msg("failed to close file access property list (fapl)\n");
+ leave(EXIT_FAILURE);
+ }
+
+ options->fapl_id = tmp_fapl_id;
+ }
+
+ return 0;
+} /* parse_command_line() */
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Create group(s) in an HDF5 file
+ *
+ * Programmer: Quincey Koziol, 2/13/2007
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, char *argv[])
+{
+ hid_t fid = H5I_INVALID_HID; /* HDF5 file ID */
+ hid_t lcpl_id = H5I_INVALID_HID; /* Link creation property list ID */
+ size_t curr_group; /* Current group to create */
+
+ h5tools_setprogname(PROGRAMNAME);
+ h5tools_setstatus(EXIT_SUCCESS);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ /* Initialize the parameters */
+ HDmemset(&params_g, 0, sizeof(params_g));
+
+ /* Create file access property list */
+ if ((params_g.fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) {
+ error_msg("Could not create file access property list\n");
+ leave(EXIT_FAILURE);
+ }
+
+ /* Parse command line */
+ if (parse_command_line(argc, (const char *const *)argv, &params_g) < 0) {
+ error_msg("unable to parse command line arguments\n");
+ leave(EXIT_FAILURE);
+ }
+
+ /* enable error reporting if command line option */
+ h5tools_error_report();
+
+ /* Check for creating groups with new format version */
+ if (params_g.latest) {
+ /* Set the "use the latest version of the format" bounds */
+ if (H5Pset_libver_bounds(params_g.fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) {
+ error_msg("Could not set property for using latest version of the format\n");
+ leave(EXIT_FAILURE);
+ }
+
+ /* Display some output if requested */
+ if (params_g.verbose)
+ HDprintf("%s: Creating groups with latest version of the format\n", h5tools_getprogname());
+ }
+
+ /* Attempt to open an existing HDF5 file first */
+ fid = h5tools_fopen(params_g.fname, H5F_ACC_RDWR, params_g.fapl_id, (params_g.fapl_id != H5P_DEFAULT),
+ NULL, 0);
+
+ /* If we couldn't open an existing file, try creating file */
+ /* (use "EXCL" instead of "TRUNC", so we don't blow away existing non-HDF5 file) */
+ if (fid < 0)
+ fid = H5Fcreate(params_g.fname, H5F_ACC_EXCL, H5P_DEFAULT, params_g.fapl_id);
+
+ /* Test for error in opening file */
+ if (fid < 0) {
+ error_msg("Could not open output file '%s'\n", params_g.fname);
+ leave(EXIT_FAILURE);
+ }
+
+ /* Create link creation property list */
+ if ((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) {
+ error_msg("Could not create link creation property list\n");
+ leave(EXIT_FAILURE);
+ }
+
+ /* Check for creating intermediate groups */
+ if (params_g.parents) {
+ /* Set the intermediate group creation property */
+ if (H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) {
+ error_msg("Could not set property for creating parent groups\n");
+ leave(EXIT_FAILURE);
+ }
+
+ /* Display some output if requested */
+ if (params_g.verbose)
+ HDprintf("%s: Creating parent groups\n", h5tools_getprogname());
+ }
+
+ /* Loop over creating requested groups */
+ for (curr_group = 0; curr_group < params_g.ngroups; curr_group++) {
+ hid_t gid; /* Group ID */
+
+ /* Attempt to create a group */
+ if ((gid = H5Gcreate2(fid, params_g.groups[curr_group], lcpl_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
+ error_msg("Could not create group '%s'\n", params_g.groups[curr_group]);
+ leave(EXIT_FAILURE);
+ }
+
+ /* Close the group */
+ if (H5Gclose(gid) < 0) {
+ error_msg("Could not close group '%s'??\n", params_g.groups[curr_group]);
+ leave(EXIT_FAILURE);
+ }
+
+ /* Display some output if requested */
+ if (params_g.verbose)
+ HDprintf("%s: created group '%s'\n", h5tools_getprogname(), params_g.groups[curr_group]);
+ } /* end for */
+
+ /* Close link creation property list */
+ if (H5Pclose(lcpl_id) < 0) {
+ error_msg("Could not close link creation property list\n");
+ leave(EXIT_FAILURE);
+ }
+
+ /* Close file */
+ if (H5Fclose(fid) < 0) {
+ error_msg("Could not close output file '%s'??\n", params_g.fname);
+ leave(EXIT_FAILURE);
+ }
+
+ leave(EXIT_SUCCESS);
+} /* end main() */
diff --git a/tools/src/misc/h5repart.c b/tools/src/misc/h5repart.c
new file mode 100644
index 0000000..ac10944
--- /dev/null
+++ b/tools/src/misc/h5repart.c
@@ -0,0 +1,510 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://www.hdfgroup.org/licenses. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Robb Matzke
+ * Wednesday, May 13, 1998
+ *
+ * Purpose: Repartitions a file family. This program can be used to
+ * split a single file into a family of files, join a family of
+ * files into a single file, or copy one family to another while
+ * changing the size of the family members. It can also be used
+ * to copy a single file to a single file with holes.
+ */
+
+/* See H5private.h for how to include system headers */
+#include "hdf5.h"
+#include "H5private.h"
+
+#define NAMELEN 4096
+#define GB *1024 * 1024 * 1024
+
+/* Make these 2 private properties(defined in H5Fprivate.h) available to h5repart.
+ * The first one updates the member file size in the superblock. The second one
+ * change file driver from family to a single file driver.
+ */
+#define H5F_ACS_FAMILY_NEWSIZE_NAME "family_newsize"
+#define H5F_ACS_FAMILY_TO_SINGLE_NAME "family_to_single"
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Prints a usage message.
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, May 13, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage(const char *progname)
+{
+ HDfprintf(stderr, "usage: %s [-v] [-V] [-[b|m] N[g|m|k]] [-family_to_sec2|-family_to_single] SRC DST\n",
+ progname);
+ HDfprintf(stderr, " -v Produce verbose output\n");
+ HDfprintf(stderr, " -V Print a version number and exit\n");
+ HDfprintf(stderr, " -b N The I/O block size, defaults to 1kB\n");
+ HDfprintf(stderr, " -m N The destination member size or 1GB\n");
+ HDfprintf(stderr, " -family_to_sec2 Deprecated version of -family_to_single (below)\n");
+ HDfprintf(stderr, " -family_to_single Change file driver from family to the default single-file VFD "
+ "(windows or sec2)\n");
+ HDfprintf(stderr, " SRC The name of the source file\n");
+ HDfprintf(stderr, " DST The name of the destination files\n");
+ HDfprintf(stderr, "Sizes may be suffixed with 'g' for GB, 'm' for MB or "
+ "'k' for kB.\n");
+ HDfprintf(stderr, "File family names include an integer printf "
+ "format such as '%%d'\n");
+ HDexit(EXIT_FAILURE);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: get_size
+ *
+ * Purpose: Reads a size option of the form `-XNS' where `X' is any
+ * letter, `N' is a multi-character positive decimal number, and
+ * `S' is an optional suffix letter in the set [GgMmk]. The
+ * option may also be split among two arguments as: `-X NS'.
+ * The input value of ARGNO is the argument number for the
+ * switch in the ARGV vector and ARGC is the number of entries
+ * in that vector.
+ *
+ * Return: Success: The value N multiplied according to the
+ * suffix S. On return ARGNO will be the number
+ * of the next argument to process.
+ *
+ * Failure: Calls usage() which exits with a non-zero
+ * status.
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, May 13, 1998
+ *-------------------------------------------------------------------------
+ */
+static off_t
+get_size(const char *progname, int *argno, int argc, char *argv[])
+{
+ off_t retval = -1;
+ char *suffix = NULL;
+
+ if (isdigit((int)(argv[*argno][2]))) {
+ retval = HDstrtol(argv[*argno] + 2, &suffix, 10);
+ (*argno)++;
+ }
+ else if (argv[*argno][2] || *argno + 1 >= argc) {
+ usage(progname);
+ }
+ else {
+ retval = HDstrtol(argv[*argno + 1], &suffix, 0);
+ if (suffix == argv[*argno + 1])
+ usage(progname);
+ *argno += 2;
+ }
+ if (suffix && suffix[0] && !suffix[1]) {
+ switch (*suffix) {
+ case 'G':
+ case 'g':
+ retval *= 1024 * 1024 * 1024;
+ break;
+ case 'M':
+ case 'm':
+ retval *= 1024 * 1024;
+ break;
+ case 'k':
+ retval *= 1024;
+ break;
+ default:
+ usage(progname);
+ }
+ }
+ else if (suffix && suffix[0]) {
+ usage(progname);
+ }
+ return retval;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Split an hdf5 file
+ *
+ * Return: Success:
+ *
+ * Failure:
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, May 13, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_GCC_CLANG_DIAG_OFF("format-nonliteral")
+int
+main(int argc, char *argv[])
+{
+ const char *prog_name; /*program name */
+ size_t blk_size = 1024; /*size of each I/O block */
+ char *buf = NULL; /*I/O block buffer */
+ size_t n, i; /*counters */
+ ssize_t nio; /*I/O return value */
+ int argno = 1; /*program argument number */
+ int src, dst = -1; /*source & destination files */
+ int need_seek = FALSE; /*destination needs to seek? */
+ int need_write; /*data needs to be written? */
+ h5_stat_t sb; /*temporary file stat buffer */
+
+ int verbose = FALSE; /*display file names? */
+
+ const char *src_gen_name; /*general source name */
+ char *src_name = NULL; /*source member name */
+
+ int src_is_family; /*is source name a family name? */
+ int src_membno = 0; /*source member number */
+
+ const char *dst_gen_name; /*general destination name */
+ char *dst_name = NULL; /*destination member name */
+ int dst_is_family; /*is dst name a family name? */
+ int dst_membno = 0; /*destination member number */
+
+ off_t left_overs = 0; /*amount of zeros left over */
+ off_t src_offset = 0; /*offset in source member */
+ off_t dst_offset = 0; /*offset in destination member */
+ off_t src_size; /*source logical member size */
+ off_t src_act_size; /*source actual member size */
+ off_t dst_size = 1 GB; /*destination logical memb size */
+ hid_t fapl; /*file access property list */
+ hid_t file;
+ hsize_t hdsize; /*destination logical memb size */
+ hbool_t family_to_single = FALSE; /*change family to single file driver? */
+
+ /*
+ * Get the program name from argv[0]. Use only the last component.
+ */
+ if ((prog_name = HDstrrchr(argv[0], '/')))
+ prog_name++;
+ else
+ prog_name = argv[0];
+
+ /*
+ * Parse switches.
+ */
+ while (argno < argc && '-' == argv[argno][0]) {
+ if (!HDstrcmp(argv[argno], "-v")) {
+ verbose = TRUE;
+ argno++;
+ }
+ else if (!HDstrcmp(argv[argno], "-V")) {
+ HDprintf("This is %s version %u.%u release %u\n", prog_name, H5_VERS_MAJOR, H5_VERS_MINOR,
+ H5_VERS_RELEASE);
+ HDexit(EXIT_SUCCESS);
+ }
+ else if (!HDstrcmp(argv[argno], "-family_to_sec2")) {
+ family_to_single = TRUE;
+ argno++;
+ }
+ else if (!HDstrcmp(argv[argno], "-family_to_single")) {
+ family_to_single = TRUE;
+ argno++;
+ }
+ else if ('b' == argv[argno][1]) {
+ blk_size = (size_t)get_size(prog_name, &argno, argc, argv);
+ }
+ else if ('m' == argv[argno][1]) {
+ dst_size = get_size(prog_name, &argno, argc, argv);
+ }
+ else {
+ usage(prog_name);
+ } /* end if */
+ } /* end while */
+
+ /* allocate names */
+ if (NULL == (src_name = (char *)HDcalloc((size_t)NAMELEN, sizeof(char))))
+ HDexit(EXIT_FAILURE);
+ if (NULL == (dst_name = (char *)HDcalloc((size_t)NAMELEN, sizeof(char))))
+ HDexit(EXIT_FAILURE);
+
+ /*
+ * Get the name for the source file and open the first member. The size
+ * of the first member determines the logical size of all the members.
+ */
+ if (argno >= argc)
+ usage(prog_name);
+ src_gen_name = argv[argno++];
+ HDsnprintf(src_name, NAMELEN, src_gen_name, src_membno);
+ src_is_family = strcmp(src_name, src_gen_name);
+
+ if ((src = HDopen(src_name, O_RDONLY)) < 0) {
+ HDperror(src_name);
+ HDexit(EXIT_FAILURE);
+ }
+
+ if (HDfstat(src, &sb) < 0) {
+ HDperror("fstat");
+ HDexit(EXIT_FAILURE);
+ }
+ src_size = src_act_size = sb.st_size;
+ if (verbose)
+ HDfprintf(stderr, "< %s\n", src_name);
+
+ /*
+ * Get the name for the destination file and open the first member.
+ */
+ if (argno >= argc)
+ usage(prog_name);
+ dst_gen_name = argv[argno++];
+ HDsnprintf(dst_name, NAMELEN, dst_gen_name, dst_membno);
+ dst_is_family = HDstrcmp(dst_name, dst_gen_name);
+
+ if ((dst = HDopen(dst_name, O_RDWR | O_CREAT | O_TRUNC, H5_POSIX_CREATE_MODE_RW)) < 0) {
+ HDperror(dst_name);
+ HDexit(EXIT_FAILURE);
+ }
+ if (verbose)
+ HDfprintf(stderr, "> %s\n", dst_name);
+
+ /* No more arguments */
+ if (argno < argc)
+ usage(prog_name);
+
+ /* Now the real work, split the file */
+ buf = (char *)HDmalloc(blk_size);
+ while (src_offset < src_size) {
+
+ /* Read a block. The amount to read is the minimum of:
+ * 1. The I/O block size
+ * 2. What's left to write in the destination member
+ * 3. Left over zeros or what's left in the source member.
+ */
+ n = blk_size;
+ if (dst_is_family)
+ n = (size_t)MIN((off_t)n, dst_size - dst_offset);
+ if (left_overs) {
+ n = (size_t)MIN((off_t)n, left_overs);
+ left_overs = left_overs - (off_t)n;
+ need_write = FALSE;
+ }
+ else if (src_offset < src_act_size) {
+ n = (size_t)MIN((off_t)n, src_act_size - src_offset);
+ if ((nio = HDread(src, buf, n)) < 0) {
+ HDperror("read");
+ HDexit(EXIT_FAILURE);
+ }
+ else if ((size_t)nio != n) {
+ HDfprintf(stderr, "%s: short read\n", src_name);
+ HDexit(EXIT_FAILURE);
+ }
+ for (i = 0; i < n; i++) {
+ if (buf[i])
+ break;
+ }
+ need_write = (i < n);
+ }
+ else {
+ n = 0;
+ left_overs = src_size - src_act_size;
+ need_write = FALSE;
+ }
+
+ /*
+ * If the block contains non-zero data then write it to the
+ * destination, otherwise just remember that we'll have to do a seek
+ * later in the destination when we finally get non-zero data.
+ */
+ if (need_write) {
+ if (need_seek && HDlseek(dst, dst_offset, SEEK_SET) < 0) {
+ HDperror("HDlseek");
+ HDexit(EXIT_FAILURE);
+ }
+ if ((nio = HDwrite(dst, buf, n)) < 0) {
+ HDperror("write");
+ HDexit(EXIT_FAILURE);
+ }
+ else if ((size_t)nio != n) {
+ HDfprintf(stderr, "%s: short write\n", dst_name);
+ HDexit(EXIT_FAILURE);
+ }
+ need_seek = FALSE;
+ }
+ else {
+ need_seek = TRUE;
+ }
+
+ /*
+ * Update the source offset and open the next source family member if
+ * necessary. The source stream ends at the first member which
+ * cannot be opened because it doesn't exist. At the end of the
+ * source stream, update the destination offset and break out of the
+ * loop. The destination offset must be updated so we can fix
+ * trailing holes.
+ */
+ src_offset = src_offset + (off_t)n;
+ if (src_offset == src_act_size) {
+ HDclose(src);
+ if (!src_is_family) {
+ dst_offset = dst_offset + (off_t)n;
+ break;
+ }
+ HDsnprintf(src_name, NAMELEN, src_gen_name, ++src_membno);
+ if ((src = HDopen(src_name, O_RDONLY)) < 0 && ENOENT == errno) {
+ dst_offset = dst_offset + (off_t)n;
+ break;
+ }
+ else if (src < 0) {
+ HDperror(src_name);
+ HDexit(EXIT_FAILURE);
+ }
+ if (HDfstat(src, &sb) < 0) {
+ HDperror("fstat");
+ HDexit(EXIT_FAILURE);
+ }
+ src_act_size = sb.st_size;
+ if (src_act_size > src_size) {
+ HDfprintf(stderr, "%s: member truncated to %lu bytes\n", src_name, (unsigned long)src_size);
+ }
+ src_offset = 0;
+ if (verbose)
+ HDfprintf(stderr, "< %s\n", src_name);
+ }
+
+ /*
+ * Update the destination offset, opening a new member if one will be
+ * needed. The first member is extended to the logical member size
+ * but other members might be smaller if they end with a hole.
+ */
+ dst_offset = dst_offset + (off_t)n;
+ if (dst_is_family && dst_offset == dst_size) {
+ if (0 == dst_membno) {
+ if (HDlseek(dst, dst_size - 1, SEEK_SET) < 0) {
+ HDperror("HDHDlseek");
+ HDexit(EXIT_FAILURE);
+ }
+ if (HDread(dst, buf, 1) < 0) {
+ HDperror("read");
+ HDexit(EXIT_FAILURE);
+ }
+ if (HDlseek(dst, dst_size - 1, SEEK_SET) < 0) {
+ HDperror("HDlseek");
+ HDexit(EXIT_FAILURE);
+ }
+ if (HDwrite(dst, buf, 1) < 0) {
+ HDperror("write");
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ HDclose(dst);
+ HDsnprintf(dst_name, NAMELEN, dst_gen_name, ++dst_membno);
+ if ((dst = HDopen(dst_name, O_RDWR | O_CREAT | O_TRUNC, H5_POSIX_CREATE_MODE_RW)) < 0) {
+ HDperror(dst_name);
+ HDexit(EXIT_FAILURE);
+ }
+ dst_offset = 0;
+ need_seek = FALSE;
+ if (verbose)
+ HDfprintf(stderr, "> %s\n", dst_name);
+ }
+ }
+
+ /*
+ * Make sure the last family member is the right size and then close it.
+ * The last member can't end with a hole or hdf5 will think that the
+ * family has been truncated.
+ */
+ if (need_seek) {
+ if (HDlseek(dst, dst_offset - 1, SEEK_SET) < 0) {
+ HDperror("HDlseek");
+ HDexit(EXIT_FAILURE);
+ }
+ if (HDread(dst, buf, 1) < 0) {
+ HDperror("read");
+ HDexit(EXIT_FAILURE);
+ }
+ if (HDlseek(dst, dst_offset - 1, SEEK_SET) < 0) {
+ HDperror("HDlseek");
+ HDexit(EXIT_FAILURE);
+ }
+ if (HDwrite(dst, buf, 1) < 0) {
+ HDperror("write");
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ HDclose(dst);
+
+ /* Modify family driver information saved in superblock through private property.
+ * These private properties are for this tool only. */
+ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) {
+ HDperror("H5Pcreate");
+ HDexit(EXIT_FAILURE);
+ }
+
+ if (family_to_single) {
+ /* The user wants to change file driver from family to a single-file VFD.
+ * Open the file with the sec2, windows, etc. driver. This property signals
+ * the library to ignore the family driver information saved in the superblock.
+ */
+ if (H5Pset(fapl, H5F_ACS_FAMILY_TO_SINGLE_NAME, &family_to_single) < 0) {
+ HDperror("H5Pset");
+ HDexit(EXIT_FAILURE);
+ }
+ }
+ else {
+ /* Modify family size saved in superblock through private property. It signals
+ * library to save the new member size(specified in command line) in superblock.
+ * This private property is for this tool only. */
+ if (H5Pset_fapl_family(fapl, H5F_FAMILY_DEFAULT, H5P_DEFAULT) < 0) {
+ HDperror("H5Pset_fapl_family");
+ HDexit(EXIT_FAILURE);
+ }
+
+ /* Set the property of the new member size as hsize_t */
+ hdsize = (hsize_t)dst_size;
+ if (H5Pset(fapl, H5F_ACS_FAMILY_NEWSIZE_NAME, &hdsize) < 0) {
+ HDperror("H5Pset");
+ HDexit(EXIT_FAILURE);
+ }
+ }
+
+ /* If the new file is a family file, try to open file for "read and write" to
+ * flush metadata. Flushing metadata will update the superblock to the new
+ * member size. If the original file is a family file and the new file is a single
+ * file, the property FAMILY_TO_SINGLE will signal the library to switch to default
+ * single-file driver when the new file is opened. If the original file is a single
+ * file and the new file can only be a single file, reopen the new file should fail.
+ * There's nothing to do in this case.
+ */
+ H5E_BEGIN_TRY
+ {
+ file = H5Fopen(dst_gen_name, H5F_ACC_RDWR, fapl);
+ }
+ H5E_END_TRY;
+
+ if (file >= 0) {
+ if (H5Fclose(file) < 0) {
+ HDperror("H5Fclose");
+ HDexit(EXIT_FAILURE);
+ } /* end if */
+ } /* end if */
+
+ if (H5Pclose(fapl) < 0) {
+ HDperror("H5Pclose");
+ HDexit(EXIT_FAILURE);
+ } /* end if */
+
+ /* Free resources and return */
+ HDfree(src_name);
+ HDfree(dst_name);
+ HDfree(buf);
+ return EXIT_SUCCESS;
+} /* end main */
+H5_GCC_CLANG_DIAG_ON("format-nonliteral")