diff options
author | Allen Byrne <byrn@hdfgroup.org> | 2016-10-27 15:06:00 (GMT) |
---|---|---|
committer | Allen Byrne <byrn@hdfgroup.org> | 2016-10-27 15:06:00 (GMT) |
commit | 2c6dbbf2129c4997606be4b130346d42fe12eae3 (patch) | |
tree | db8430aa5757b32f3bd46928798cc2b686a72bfb /tools/src/misc | |
parent | 5b562d9ce9b2945d0378b9c03e01f42923da80f4 (diff) | |
download | hdf5-2c6dbbf2129c4997606be4b130346d42fe12eae3.zip hdf5-2c6dbbf2129c4997606be4b130346d42fe12eae3.tar.gz hdf5-2c6dbbf2129c4997606be4b130346d42fe12eae3.tar.bz2 |
Split tools into src and test - add folders
Diffstat (limited to 'tools/src/misc')
-rw-r--r-- | tools/src/misc/CMakeLists.txt | 67 | ||||
-rw-r--r-- | tools/src/misc/Makefile.am | 61 | ||||
-rw-r--r-- | tools/src/misc/h5cc.in | 401 | ||||
-rw-r--r-- | tools/src/misc/h5debug.c | 723 | ||||
-rw-r--r-- | tools/src/misc/h5mkgrp.c | 336 | ||||
-rw-r--r-- | tools/src/misc/h5redeploy.in | 218 | ||||
-rw-r--r-- | tools/src/misc/h5repart.c | 510 |
7 files changed, 2316 insertions, 0 deletions
diff --git a/tools/src/misc/CMakeLists.txt b/tools/src/misc/CMakeLists.txt new file mode 100644 index 0000000..6fcff9c --- /dev/null +++ b/tools/src/misc/CMakeLists.txt @@ -0,0 +1,67 @@ +cmake_minimum_required (VERSION 3.1.0) +PROJECT (HDF5_TOOLS_SRC_MISC) + +#----------------------------------------------------------------------------- +# Setup include Directories +#----------------------------------------------------------------------------- +INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib) + +# -------------------------------------------------------------------- +# Add the misc executables +# -------------------------------------------------------------------- +#-- Misc Executables +add_executable (h5debug ${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5debug.c) +TARGET_NAMING (h5debug STATIC) +TARGET_C_PROPERTIES (h5debug STATIC " " " ") +target_link_libraries (h5debug ${HDF5_LIB_TARGET} ${HDF5_TOOLS_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_NAMING (h5repart STATIC) +TARGET_C_PROPERTIES (h5repart STATIC " " " ") +target_link_libraries (h5repart ${HDF5_LIB_TARGET} ${HDF5_TOOLS_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_NAMING (h5mkgrp STATIC) +TARGET_C_PROPERTIES (h5mkgrp STATIC " " " ") +target_link_libraries (h5mkgrp ${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") + +set (H5_DEP_EXECUTABLES + h5debug + h5repart + h5mkgrp +) + +#----------------------------------------------------------------------------- +# Generate the h5cc file containing settings needed to compile programs +#----------------------------------------------------------------------------- +#if (NOT WIN32) +# configure_file (${HDF5_TOOLS_SRC_MISC_SOURCE_DIR}/h5cc.in ${HDF5_BINARY_DIR}/h5cc @ONLY) +#endif (NOT WIN32) + +############################################################################## +############################################################################## +### I N S T A L L A T I O N ### +############################################################################## +############################################################################## + +#----------------------------------------------------------------------------- +# Rules for Installation of tools using make Install target +#----------------------------------------------------------------------------- + +#INSTALL_PROGRAM_PDB (h5debug ${HDF5_INSTALL_BIN_DIR} toolsapplications) +#INSTALL_PROGRAM_PDB (h5repart ${HDF5_INSTALL_BIN_DIR} toolsapplications) +#INSTALL_PROGRAM_PDB (h5mkgrp ${HDF5_INSTALL_BIN_DIR} toolsapplications) + +install ( + TARGETS + h5debug h5repart h5mkgrp + EXPORT + ${HDF5_EXPORTED_TARGETS} + RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications +) diff --git a/tools/src/misc/Makefile.am b/tools/src/misc/Makefile.am new file mode 100644 index 0000000..c069e9a --- /dev/null +++ b/tools/src/misc/Makefile.am @@ -0,0 +1,61 @@ +# +# Copyright by The HDF Group. +# Copyright by the Board of Trustees of the University of Illinois. +# 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 files COPYING and Copyright.html. COPYING can be found at the root +# of the source code distribution tree; Copyright.html can be found at the +# root level of an installed copy of the electronic HDF5 document set and +# is linked from the top-level documents page. It can also be found at +# http://hdfgroup.org/HDF5/doc/Copyright.html. 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 +bin_SCRIPTS=h5redeploy + +# 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) + +# Tell automake to clean h5redeploy script +CLEANFILES=h5redeploy + +# These were generated by configure. Remove them only when distclean. +DISTCLEANFILES=h5cc + +# All programs rely on hdf5 library and h5tools library +LDADD=$(LIBH5TOOLS) $(LIBHDF5) + +# h5cc needs custom install and uninstall rules, since it may be +# named h5pcc if hdf5 is being built in parallel mode. +if BUILD_PARALLEL_CONDITIONAL + H5CC_NAME=h5pcc +else + H5CC_NAME=h5cc +endif + +install-exec-local: + @$(INSTALL) h5cc $(DESTDIR)$(bindir)/$(H5CC_NAME) +uninstall-local: + @$(RM) $(DESTDIR)$(bindir)/$(H5CC_NAME) + +# How to build h5redeploy script +h5redeploy: h5redeploy.in + @cp $(srcdir)/$@.in $@ + +include $(top_srcdir)/config/conclude.am diff --git a/tools/src/misc/h5cc.in b/tools/src/misc/h5cc.in new file mode 100644 index 0000000..1645855 --- /dev/null +++ b/tools/src/misc/h5cc.in @@ -0,0 +1,401 @@ +#! /bin/sh +## +# Copyright by The HDF Group. +# Copyright by the Board of Trustees of the University of Illinois. +# 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 files COPYING and Copyright.html. COPYING can be found at the root +# of the source code distribution tree; Copyright.html can be found at the +# root level of an installed copy of the electronic HDF5 document set and +# is linked from the top-level documents page. It can also be found at +# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have +# access to either file, you may request a copy from help@hdfgroup.org. +## + +# This tool is adapted from the mpicc command of the MPICH Software. + +############################################################################ +## ## +## Things You May Have to Modify: ## +## ## +## If the following paths don't point to the place were HDF5 is installed ## +## on your system (i.e., you received a binary distribution or moved the ## +## files from the originally installed directory to another directory) ## +## then modify them accordingly to represent the new paths. ## +## ## +############################################################################ +prefix="@prefix@" +exec_prefix="@exec_prefix@" +libdir="@libdir@" +includedir="@includedir@" +HL="@HL@" + +############################################################################ +## ## +## Things You Can Modify to Override HDF5 Library Build Components: ## +## ## +## (Advanced usage - know what you're doing - you're on your own here.) ## +## The four variables below can be used to insert paths and flags in ## +## CPPFLAGS, CFLAGS, LDFLAGS, or LIBS in the h5cc compile line: ## +## $CLINKER $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CFLAGS $CFLAGS $LDFLAGS ## +## $LIBS $clibpath $link_objs $link_args $shared_link ## +## ## +## These settings can be overriden by setting HDF5_CFLAGS, ## +## HDF5_CPPFLAGS, HDF5_LDFLAGS, or HDF5_LIBS in the environment. ## +## ## +############################################################################ +CFLAGSBASE="" +CPPFLAGSBASE="" +LDFLAGSBASE="" +LIBSBASE="" + +############################################################################ +## ## +## You shouldn't have to modify anything below this line. ## +## ## +############################################################################ + +# Constants definitions +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +host_os="@host_os@" + +prog_name="`basename $0`" + +allargs="" +compile_args="" +libraries="" +link_args="" +link_objs="" +clibpath="" + +do_link="yes" +do_compile="no" +dash_o="no" +dash_c="no" +get_output_file="no" + +SHOW="eval" +CCBASE="@CC@" +CLINKERBASE="@CC@" + +# CFLAGS, CPPFLAGS and LDFLAGS are reserved for use by the script user. +# FLAGS brought from the hdf5 build are put in H5BLD_*FLAGS. + +# User's CPPFLAGS and CFLAGS come after their H5BLD counterparts. User's +# LDFLAGS come just before clibpath, user's LIBS come after $link_objs and +# before the hdf5 libraries in $link_args, followed by any external library +# paths and libraries from AM_LDFLAGS, LDFLAGS, AM_LIBS or LIBS carried in +# from the hdf5 build. The order of the flags is intended to give precedence +# to the user's flags. +H5BLD_CFLAGS="@AM_CFLAGS@ @CFLAGS@" +H5BLD_CPPFLAGS="@AM_CPPFLAGS@ @CPPFLAGS@" +H5BLD_LDFLAGS="@AM_LDFLAGS@ @LDFLAGS@" +H5BLD_LIBS="@LIBS@" + +CC="${HDF5_CC:-$CCBASE}" +CLINKER="${HDF5_CLINKER:-$CLINKERBASE}" +CFLAGS="${HDF5_CFLAGS:-$CFLAGSBASE}" +CPPFLAGS="${HDF5_CPPFLAGS:-$CPPFLAGSBASE}" +LDFLAGS="${HDF5_LDFLAGS:-$LDFLAGSBASE}" +LIBS="${HDF5_LIBS:-$LIBSBASE}" + +# If a static library is available, the default will be to use it. If the only +# available library is shared, it will be used by default. The user can +# override either default, although choosing an unavailable library will result +# in link errors. +STATIC_AVAILABLE="@enable_static@" +if test "${STATIC_AVAILABLE}" = "yes"; then + USE_SHARED_LIB="${HDF5_USE_SHLIB:-no}" +else + USE_SHARED_LIB="${HDF5_USE_SHLIB:-yes}" +fi + + +usage() { + # A wonderfully informative "usage" message. + echo "usage: $prog_name [OPTIONS] <compile line>" + echo " OPTIONS:" + echo " -help This help message." + echo " -echo Show all the shell commands executed" + echo " -prefix=DIR Prefix directory to find HDF5 lib/ and include/" + echo " subdirectories [default: $prefix]" + # A wonderfully informative "usage" message. + echo "usage: $prog_name [OPTIONS] <compile line>" + echo " OPTIONS:" + echo " -help This help message." + echo " -echo Show all the shell commands executed" + echo " -prefix=DIR Prefix directory to find HDF5 lib/ and include/" + echo " subdirectories [default: $prefix]" + echo " -show Show the commands without executing them" + echo " -showconfig Show the HDF5 library configuration summary" + echo " -shlib Compile with shared HDF5 libraries [default for hdf5 built" + echo " without static libraries]" + echo " -noshlib Compile with static HDF5 libraries [default for hdf5 built" + echo " with static libraries]" + echo " " + echo " <compile line> - the normal compile line options for your compiler." + echo " $prog_name uses the same compiler you used to compile" + echo " HDF5. Check with your compiler's man pages for more" + echo " information on which options are needed." + echo " " + echo " You can override the compiler, linker, and whether or not to use static" + echo " or shared libraries to compile your program by setting the following" + echo " environment variables accordingly:" + echo " " + echo " HDF5_CC - use a different C compiler" + echo " HDF5_CLINKER - use a different linker" + echo " HDF5_USE_SHLIB=[yes|no] - use shared or static version of the HDF5 library" + echo " [default: no except when built with only" + echo " shared libraries]" + echo " " + echo " You can also add or change paths and flags to the compile line using" + echo " the following environment varibles or by assigning them to their counterparts" + echo " in the 'Things You Can Modify to Override...'" section of $prog_name + echo " " + echo " Variable Current value to be replaced" + echo " HDF5_CPPFLAGS \"$CPPFLAGSBASE\"" + echo " HDF5_CFLAGS \"$CFLAGSBASE\"" + echo " HDF5_LDFLAGS \"$LDFLAGSBASE\"" + echo " HDF5_LIBS \"$LIBSBASE\"" + echo " " + echo " Note that adding library paths to HDF5_LDFLAGS where another hdf5 version" + echo " is located may link your program with that other hdf5 library version." + echo " " + exit $EXIT_FAILURE +} + +# Show the configuration summary of the library recorded in the +# libhdf5.settings file reside in the lib directory. +showconfigure() +{ + cat ${libdir}/libhdf5.settings + status=$? +} + +# Main +status=$EXIT_SUCCESS + +if test "$#" = "0"; then + # No parameters specified, issue usage statement and exit. + usage +fi + +case "$CC" in + gcc) + kind="gcc" + ;; + mpicc|mpcc|mpicc_r) + # Is this gcc masquarading as an MPI compiler? + if test "`${CC} -v 2>&1 | sed -n 2p | cut -c1-3`" = "gcc"; then + kind="gcc" + else + # Nope + kind="$host_os" + fi + ;; + *) + kind="$host_os" + ;; +esac + +for arg in $@ ; do + if test "x$get_output_file" = "xyes"; then + link_args="$link_args $arg" + output_file="$arg" + get_output_file="no" + continue + fi + + case "$arg" in + -c) + allargs="$allargs $arg" + compile_args="$compile_args $arg" + + if test "x$do_link" = "xyes" -a -n "$output_file"; then + compile_args="$compile_args -o $output_file" + fi + + do_link="no" + dash_c="yes" + ;; + -o) + allargs="$allargs $arg" + dash_o="yes" + + if test "x$dash_c" = "xyes"; then + compile_args="$compile_args $arg" + else + link_args="$link_args $arg" + do_link="yes" + get_output_file="yes" + fi + ;; + -E|-M|-MT) + allargs="$allargs $arg" + compile_args="$compile_args $arg" + dash_c="yes" + do_link="no" + ;; + -l*) + libraries=" $libraries $arg " + allargs="$allargs $arg" + ;; + -prefix=*) + prefix="`expr "$arg" : '-prefix=\(.*\)'`" + ;; + -echo) + set -x + ;; + -show) + SHOW="echo" + ;; + -showconfig) + showconfigure + exit $status + ;; + -shlib) + USE_SHARED_LIB="yes" + ;; + -noshlib) + USE_SHARED_LIB="no" + ;; + -help) + usage + ;; + *\"*) + qarg="'"$arg"'" + allargs="$allargs $qarg" + ;; + *\'*) + qarg='\"'"$arg"'\"' + allargs="$allargs $qarg" + ;; + *) + allargs="$allargs $qarg" + + if test -s "$arg"; then + ext=`expr "$arg" : '.*\(\..*\)'` + + if test "x$ext" = "x.c"; then + do_compile="yes" + compile_args="$compile_args $arg" + fname=`basename $arg .c` + link_objs="$link_objs $fname.o" + elif test "x$ext" = "x.o"; then + if test "x$dash_c" = "xyes"; then + compile_args="$compile_args $arg" + else + do_link="yes" + link_objs="$link_objs $arg" + fi + elif test "x$ext" = "x.a"; then + # This is an archive that we're linking in + libraries=" $libraries $arg " + else + compile_args="$compile_args $arg" + link_args="$link_args $arg" + fi + else + compile_args="$compile_args $arg" + link_args="$link_args $arg" + fi + ;; + esac +done + +if test "$dash_c" = "yes" -a "$do_compile" = no -a "$do_link" = no ; then + # -c was specified. Force do_compile on. + do_compile=yes +fi + +if test "x$do_compile" = "xyes"; then + if test "x$dash_c" != "xyes"; then + compile_args="-c $compile_args" + fi + + $SHOW $CC -I$includedir $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CFLAGS $CFLAGS $compile_args + status=$? + + if test "$status" != "0"; then + exit $status + fi +fi + +if test "x$do_link" = "xyes"; then + shared_link="" +# conditionnaly link with the hl library + if test "X$HL" = "Xhl"; then + libraries=" $libraries -lhdf5_hl -lhdf5 " + else + libraries=" $libraries -lhdf5 " + fi + link_args="$link_args -L${libdir}" + + case "$kind" in + gcc|linux*) + # MacOS X doesn't support the "-Wl,-rpath -Wl," style of linker flags. + # It appears to want none of them specified. + case "$host_os" in + darwin*) flag="" ;; + *) flag="-Wl,-rpath -Wl," ;; + esac + ;; + hpux*) flag="-Wl,+b -Wl," ;; + freebsd*|solaris*) flag="-R" ;; + rs6000*|aix*) flag="-L" ;; + sgi) flag="-rpath " ;; + *) flag="" ;; + esac + + if test -n "$flag"; then + shared_link="${flag}${libdir}" + fi + + if test "x$USE_SHARED_LIB" != "xyes"; then + # The "-lhdf5" & "-lhdf5_hl" flags are in here already...This is a static + # compile though, so change it to the static version (.a) of the library. + new_libraries="" + for lib in $libraries; do + case "$lib" in + -lhdf5) + new_libraries="$new_libraries ${libdir}/libhdf5.a" + ;; + -lhdf5_hl) + new_libraries="$new_libraries ${libdir}/libhdf5_hl.a" + ;; + *) + new_libraries="$new_libraries $lib" + ;; + esac + done + libraries="$new_libraries" + fi + + for lib in $libraries; do + if echo $link_args | grep " $lib " > /dev/null || + echo $link_args | grep " $lib$" > /dev/null; then + : + else + link_args="$link_args $lib " + fi + done + + # The LIBS are just a bunch of -l* libraries necessary for the HDF5 + # module. It's okay if they're included twice in the compile line. + link_args="$link_args $H5BLD_LDFLAGS $H5BLD_LIBS" + + # User's CPPFLAGS and CFLAGS come after their H5BLD counterparts. User's + # LDFLAGS come just before clibpath, user's LIBS come after $link_objs and + # before the hdf5 libraries in $link_args, followed by any external library + # paths and libraries from AM_LDFLAGS, LDFLAGS, AM_LIBS or LIBS carried in + # from the hdf5 build. The order of the flags is intended to give precedence + # to the user's flags. + $SHOW $CLINKER $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CFLAGS $CFLAGS $LDFLAGS $clibpath $link_objs $LIBS $link_args $shared_link + status=$? +fi + +exit $status diff --git a/tools/src/misc/h5debug.c b/tools/src/misc/h5debug.c new file mode 100644 index 0000000..ae64952 --- /dev/null +++ b/tools/src/misc/h5debug.c @@ -0,0 +1,723 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. 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 <matzke@llnl.gov> + * + * 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 "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 + * koziol@hdfgroup.org + * 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; + + 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)); + HDexit(4); + } /* 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 + * koziol@hdfgroup.org + * 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; + + 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)); + HDexit(4); + } /* 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 + * koziol@hdfgroup.org + * 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; + + 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)); + HDexit(4); + } /* 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 + * matzke@llnl.gov + * Jul 18 1997 + * + *------------------------------------------------------------------------- + */ +int +main(int argc, char *argv[]) +{ + hid_t fid, fapl, dxpl; + H5F_t *f; + haddr_t addr = 0, extra = 0, extra2 = 0, extra3 = 0, extra4 = 0; + uint8_t sig[H5F_SIGNATURE_LEN]; + size_t u; + H5E_auto2_t func; + void *edata; + herr_t status = SUCCEED; + + if(argc == 1) { + HDfprintf(stderr, "Usage: %s filename [signature-addr [extra]]\n", argv[0]); + HDexit(1); + } /* end if */ + + /* Initialize the library */ + if(H5open() < 0) { + HDfprintf(stderr, "cannot initialize the library\n"); + HDexit(1); + } /* 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. + */ + dxpl = H5AC_ind_read_dxpl_id; + if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { + HDfprintf(stderr, "cannot create file access property list\n"); + HDexit(1); + } /* end if */ + if(HDstrchr(argv[1], '%')) + if(H5Pset_fapl_family (fapl, (hsize_t)0, H5P_DEFAULT) < 0) { + fprintf(stderr, "cannot set file access property list\n"); + HDexit(1); + } + if((fid = H5Fopen(argv[1], H5F_ACC_RDONLY, fapl)) < 0) { + HDfprintf(stderr, "cannot open file\n"); + HDexit(1); + } /* end if */ + if(NULL == (f = (H5F_t *)H5I_object(fid))) { + HDfprintf(stderr, "cannot obtain H5F_t pointer\n"); + HDexit(2); + } /* end if */ + + /* Ignore metadata tags while using h5debug */ + if(H5AC_ignore_tags(f) < 0) { + HDfprintf(stderr, "cannot ignore metadata tags\n"); + HDexit(1); + } + + /* + * Parse command arguments. + */ + if(argc > 2) + addr = (haddr_t)HDstrtoll(argv[2], NULL, 0); + if(argc > 3) + extra = (haddr_t)HDstrtoll(argv[3], NULL, 0); + if(argc > 4) + extra2 = (haddr_t)HDstrtoll(argv[4], NULL, 0); + if(argc > 5) + extra3 = (haddr_t)HDstrtoll(argv[5], NULL, 0); + if(argc > 6) + extra4 = (haddr_t)HDstrtoll(argv[6], NULL, 0); + + /* + * Read the signature at the specified file position. + */ + HDfprintf(stdout, "Reading signature at address %a (rel)\n", addr); + if(H5F_block_read(f, H5FD_MEM_SUPER, addr, sizeof(sig), dxpl, sig) < 0) { + HDfprintf(stderr, "cannot read signature\n"); + HDexit(3); + } + 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, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL); + + } else if(!HDmemcmp (sig, H5HG_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug a global heap collection. + */ + status = H5HG_debug (f, H5AC_ind_read_dxpl_id, 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 == 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, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra); + + } 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 == 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"); + HDexit(4); + } /* end if */ + + status = H5G_node_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra); + break; + + case H5B_CHUNK_ID: + /* Check for extra parameters */ + if(extra == 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"); + HDexit(4); + } /* end if */ + + /* Build array of chunk dimensions */ + ndims = (unsigned)extra; + dim[0] = (uint32_t)extra2; + if(ndims > 1) + dim[1] = (uint32_t)extra3; + if(ndims > 2) + dim[2] = (uint32_t)extra4; + + /* Check for dimension error */ + if(ndims > 3) { + HDfprintf(stderr, "ERROR: Only 3 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"); + HDexit(4); + } /* end for */ + 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"); + HDexit(4); + } /* end if */ + + /* Set the last dimension (the element size) to zero */ + dim[ndims] = 0; + + status = H5D_btree_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, ndims, dim); + break; + + case H5B_NUM_BTREE_ID: + default: + HDfprintf(stderr, "Unknown v1 B-tree subtype %u\n", (unsigned)(subtype)); + HDexit(4); + } + + } 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 == 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"); + HDexit(4); + } /* end if */ + + status = H5B2__hdr_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, (haddr_t)extra); + + } 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 == 0 || extra2 == 0 || extra3 == 0 || extra4 == 0)) { + + fprintf(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"); + fprintf(stderr, "NOTE: Leaf nodes are depth 0, the internal nodes above them are depth 1, etc.\n"); + fprintf(stderr, "v2 B-tree internal node usage:\n"); + fprintf(stderr, "\th5debug <filename> <internal node address> <v2 B-tree header address> <number of records> <depth> <object header address>\n"); + HDexit(4); + + } else if(extra == 0 || extra2 == 0 || extra3 == 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"); + HDexit(4); + } /* end if */ + + status = H5B2__int_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, (unsigned)extra3, (haddr_t)extra4); + + } 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 == 0 || extra2 == 0 || extra3 == 0 )) { + + fprintf(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"); + fprintf(stderr, "v2 B-tree leaf node usage:\n"); + fprintf(stderr, "\th5debug <filename> <leaf node address> <v2 B-tree header address> <number of records> <object header address>\n"); + HDexit(4); + + } else if(extra == 0 || extra2 == 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"); + HDexit(4); + } /* end if */ + + status = H5B2__leaf_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, (haddr_t)extra3); + + } else if(!HDmemcmp(sig, H5HF_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug a fractal heap header. + */ + status = H5HF_hdr_debug(f, H5AC_ind_read_dxpl_id, 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 == 0 || extra2 == 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"); + HDexit(4); + } /* end if */ + + status = H5HF_dblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra, (size_t)extra2); + + } 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 == 0 || extra2 == 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"); + HDexit(4); + } /* end if */ + + status = H5HF_iblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra, (unsigned)extra2); + + } else if(!HDmemcmp(sig, H5FS_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug a free space header. + */ + + status = H5FS_debug(f, H5AC_ind_read_dxpl_id, 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 == 0 || extra2 == 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"); + HDexit(4); + } /* end if */ + + status = H5FS_sects_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra, extra2); + + } else if(!HDmemcmp(sig, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug shared message master table. + */ + + status = H5SM_table_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, (unsigned) UFAIL, (unsigned) UFAIL); + + } else if(!HDmemcmp(sig, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug shared message list index. + */ + + /* Check for enough valid parameters */ + if(extra == 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"); + HDexit(4); + } /* end if */ + + status = H5SM_list_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, (haddr_t)extra); + + } else if(!HDmemcmp(sig, H5EA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug an extensible aray header. + */ + const H5EA_class_t *cls = get_H5EA_class(sig); + HDassert(cls); + + /* Check for enough valid parameters */ + if(extra == 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"); + HDexit(4); + } /* end if */ + + status = H5EA__hdr_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra); + + } else if(!HDmemcmp(sig, H5EA_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug an extensible aray index block. + */ + const H5EA_class_t *cls = get_H5EA_class(sig); + HDassert(cls); + + /* Check for enough valid parameters */ + if(extra == 0 || extra2 == 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"); + HDexit(4); + } /* end if */ + + status = H5EA__iblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, extra2); + + } else if(!HDmemcmp(sig, H5EA_SBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug an extensible aray super block. + */ + const H5EA_class_t *cls = get_H5EA_class(sig); + HDassert(cls); + + /* Check for enough valid parameters */ + if(extra == 0 || extra2 == 0 || extra3 == 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"); + HDexit(4); + } /* end if */ + + status = H5EA__sblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, extra3); + + } else if(!HDmemcmp(sig, H5EA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug an extensible aray data block. + */ + const H5EA_class_t *cls = get_H5EA_class(sig); + HDassert(cls); + + /* Check for enough valid parameters */ + if(extra == 0 || extra2 == 0 || extra3 == 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"); + HDexit(4); + } /* end if */ + + status = H5EA__dblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (size_t)extra2, extra3); + + } 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 == 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"); + HDexit(4); + } /* end if */ + + status = H5FA__hdr_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra); + + } 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 == 0 || extra2 == 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"); + HDexit(4); + } /* end if */ + + status = H5FA__dblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, extra2); + + } else if(!HDmemcmp(sig, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug v2 object header (which have signatures). + */ + + status = H5O_debug(f, H5AC_ind_read_dxpl_id, 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, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL); + + } else { + /* + * Got some other unrecognized signature. + */ + printf("%-*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 + printf("\\%03o", sig[u]); + } + HDputchar('\n'); + + HDfprintf(stderr, "unknown signature\n"); + HDexit(4); + } /* end else */ + + /* Check for an error when dumping information */ + if(status < 0) { + HDfprintf(stderr, "An error occurred!\n"); + H5Eprint2(H5E_DEFAULT, stderr); + HDexit(5); + } /* end if */ + + H5Pclose(fapl); + H5Fclose(fid); + + H5Eset_auto2(H5E_DEFAULT, func, edata); + + return 0; +} /* main() */ + diff --git a/tools/src/misc/h5mkgrp.c b/tools/src/misc/h5mkgrp.c new file mode 100644 index 0000000..ad2d306 --- /dev/null +++ b/tools/src/misc/h5mkgrp.c @@ -0,0 +1,336 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. 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" +#include <string.h> +#include <stdlib.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 long_options l_opts[] = { + { "help", no_arg, 'h' }, + { "latest", no_arg, 'l' }, + { "parents", no_arg, 'p' }, + { "verbose", no_arg, 'v' }, + { "version", no_arg, 'V' }, + { NULL, 0, '\0' } +}; + +/* Command line parameter settings */ +typedef struct { + 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 */ +} param_t; +param_t params; /* 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.fname) + HDfree (params.fname); + if (params.ngroups) { + for(curr_group = 0; curr_group < params.ngroups; curr_group++) + HDfree (params.groups[curr_group]); + HDfree (params.groups); + } + 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(void) +{ + HDfprintf(stdout, "\ +usage: h5mkgrp [OPTIONS] FILE GROUP...\n\ + OPTIONS\n\ + -h, --help Print a usage message and exit\n\ + -l, --latest Use latest version of file format to create groups\n\ + -p, --parents No error if existing, make parent groups as needed\n\ + -v, --verbose Print information about OBJECTS and OPTIONS\n\ + -V, --version Print version number and exit\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 *argv[], param_t *parms) +{ + int opt; /* Option from command line */ + size_t curr_group; /* Current group name to copy */ + + /* Check for empty command line */ + if(argc == 1) { + usage(); + leave(EXIT_SUCCESS); + } /* end if */ + + /* Parse command line options */ + while((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) { + switch((char)opt) { + /* Display 'help' */ + case 'h': + usage(); + leave(EXIT_SUCCESS); + + /* Create objects with the latest version of the format */ + case 'l': + parms->latest = TRUE; + break; + + /* Create parent groups */ + case 'p': + parms->parents = TRUE; + break; + + /* Verbose output */ + case 'v': + parms->verbose = TRUE; + break; + + /* Display version */ + case 'V': + print_version(h5tools_getprogname()); + leave(EXIT_SUCCESS); + + /* Bad command line argument */ + default: + usage(); + leave(EXIT_FAILURE); + } /* end switch */ + } /* end while */ + + /* Check for file name to be processed */ + if(argc <= opt_ind) { + error_msg("missing file name\n"); + usage(); + leave(EXIT_FAILURE); + } /* end if */ + + /* Retrieve file name */ + parms->fname = HDstrdup(argv[opt_ind]); + opt_ind++; + + /* Check for group(s) to be created */ + if(argc <= opt_ind) { + error_msg("missing group name(s)\n"); + usage(); + leave(EXIT_FAILURE); + } /* end if */ + + /* Allocate space for the group name pointers */ + parms->ngroups = (size_t)(argc - opt_ind); + parms->groups = (char **)HDmalloc(parms->ngroups * sizeof(char *)); + + /* Retrieve the group names */ + curr_group = 0; + while(opt_ind < argc) { + parms->groups[curr_group] = HDstrdup(argv[opt_ind]); + curr_group++; + opt_ind++; + } /* end while */ + +#ifdef QAK +HDfprintf(stderr, "parms->parents = %t\n", parms->parents); +HDfprintf(stderr, "parms->verbose = %t\n", parms->verbose); +HDfprintf(stderr, "parms->fname = '%s'\n", parms->fname); +HDfprintf(stderr, "parms->ngroups = %Zu\n", parms->ngroups); +for(curr_group = 0; curr_group < parms->ngroups; curr_group++) + HDfprintf(stderr, "parms->group[%Zu] = '%s'\n", curr_group, parms->groups[curr_group]); +#endif /* QAK */ + + 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, const char *argv[]) +{ + hid_t fid; /* HDF5 file ID */ + hid_t fapl_id; /* File access property list ID */ + hid_t lcpl_id; /* Link creation property list ID */ + size_t curr_group; /* Current group to create */ + + h5tools_setprogname(PROGRAMNAME); + h5tools_setstatus(EXIT_SUCCESS); + + /* Disable the HDF5 library's error reporting */ + H5Eset_auto2(H5E_DEFAULT, NULL, NULL); + + /* Initialize h5tools lib */ + h5tools_init(); + + /* Parse command line */ + HDmemset(¶ms, 0, sizeof(params)); + if(parse_command_line(argc, argv, ¶ms) < 0) { + error_msg("unable to parse command line arguments\n"); + leave(EXIT_FAILURE); + } /* end if */ + + /* Create file access property list */ + if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) { + error_msg("Could not create file access property list\n"); + leave(EXIT_FAILURE); + } /* end if */ + + /* Check for creating groups with new format version */ + if(params.latest) { + /* Set the "use the latest version of the format" bounds */ + if(H5Pset_libver_bounds(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); + } /* end if */ + + /* Display some output if requested */ + if(params.verbose) + printf("%s: Creating groups with latest version of the format\n", h5tools_getprogname()); + } /* end if */ + + /* Attempt to open an existing HDF5 file first */ + fid = h5tools_fopen(params.fname, H5F_ACC_RDWR, fapl_id, NULL, 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.fname, H5F_ACC_EXCL, H5P_DEFAULT, fapl_id); + + /* Test for error in opening file */ + if(fid < 0) { + error_msg("Could not open output file '%s'\n", params.fname); + leave(EXIT_FAILURE); + } /* end if */ + + /* 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); + } /* end if */ + + /* Check for creating intermediate groups */ + if(params.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); + } /* end if */ + + /* Display some output if requested */ + if(params.verbose) + printf("%s: Creating parent groups\n", h5tools_getprogname()); + } /* end if */ + + /* Loop over creating requested groups */ + for(curr_group = 0; curr_group < params.ngroups; curr_group++) { + hid_t gid; /* Group ID */ + + /* Attempt to create a group */ + if((gid = H5Gcreate2(fid, params.groups[curr_group], lcpl_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + error_msg("Could not create group '%s'\n", params.groups[curr_group]); + leave(EXIT_FAILURE); + } /* end if */ + + /* Close the group */ + if(H5Gclose(gid) < 0) { + error_msg("Could not close group '%s'??\n", params.groups[curr_group]); + leave(EXIT_FAILURE); + } /* end if */ + + /* Display some output if requested */ + if(params.verbose) + printf("%s: created group '%s'\n", h5tools_getprogname(), params.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); + } /* end if */ + + /* Close file */ + if(H5Fclose(fid) < 0) { + error_msg("Could not close output file '%s'??\n", params.fname); + leave(EXIT_FAILURE); + } /* end if */ + + /* Close file access property list */ + if(H5Pclose(fapl_id) < 0) { + error_msg("Could not close file access property list\n"); + leave(EXIT_FAILURE); + } /* end if */ + + /* Shut down h5tools lib */ + h5tools_close(); + + leave(EXIT_SUCCESS); +} /* end main() */ + diff --git a/tools/src/misc/h5redeploy.in b/tools/src/misc/h5redeploy.in new file mode 100644 index 0000000..6b6ef87 --- /dev/null +++ b/tools/src/misc/h5redeploy.in @@ -0,0 +1,218 @@ +#! /bin/sh +# +# Copyright by The HDF Group. +# Copyright by the Board of Trustees of the University of Illinois. +# 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 files COPYING and Copyright.html. COPYING can be found at the root +# of the source code distribution tree; Copyright.html can be found at the +# root level of an installed copy of the electronic HDF5 document set and +# is linked from the top-level documents page. It can also be found at +# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have +# access to either file, you may request a copy from help@hdfgroup.org. +# + +## Update HDF5 compiler tools after the HDF5 software has been installed ## +## in a new location. ## +## For help page, use "h5redeploy -help" ## +## ## + +# Constants definitions +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +# Function definitions + +# show help page +usage() { + # A wonderfully informative "usage" message. + echo "usage: $prog_name [OPTIONS]" + echo " OPTIONS:" + echo " -help|help This help message" + echo " -echo Show all the shell commands executed" + echo " -force No prompt, just do it" + echo " -prefix=DIR New directory to find HDF5 lib/ and include/" + echo " subdirectories [default: current directory]" + echo " -exec-prefix=DIR New directory to find HDF5 lib/" + echo " subdirectory [default: <prefix>]" + echo " -libdir=DIR New directory for the HDF5 lib directory" + echo " [default: <exec-prefix>/lib]" + echo " -includedir=DIR New directory for the HDF5 header files" + echo " [default: <prefix>/include]" + echo " -tool=TOOL Tool to update. TOOL must be in the current" + echo " directory and writable. [default: $h5tools]" + echo " -show Show the commands without executing them" + echo " " + exit $EXIT_FAILURE +} + +# display variable values +dump_vars(){ + echo "====Showing all variable values=====" + echo prefix=$prefix + echo h5tools=$h5tools + echo "====End Showing=====" +} + +# show actions to be taken +show_action() +{ + echo "Update the following tools because they are now installed at a new directory" + for t in $foundtools; do + echo "${t}:" + echo " current setting=`sed -e '/^prefix=/s/prefix=//p' -e d $t`" + echo " new setting="\""$prefix"\" + done +} + + +# Report Error message +ERROR() +{ + echo "***ERROR***" + echo "$1" +} + +# Main +# +############################################################################ +## Installation directories: ## +## prefix architecture-independent files. ## +## exec_prefix architecture-dependent files, default is <prefix>. ## +## libdir libraries, default is <exec_prefix>/lib. ## +## includedir header files, default is <prefix/include>. ## +## Not used here: ## +## bindir executables, <exec_prefix/bin>. ## +############################################################################ +# Initialization +h5tools="h5cc h5pcc h5fc h5pfc h5c++" # possible hdf5 tools +foundtools= # tools found and will be modified +fmode= # force mode, default is off +prefix= +exec_prefix= +libdir= +includedir= + +# Parse options +for arg in $@ ; do + case "$arg" in + -prefix=*) + prefix="`echo $arg | cut -f2 -d=`" + ;; + -exec-prefix=*) + exec_prefix="`echo $arg | cut -f2 -d=`" + ;; + -libdir=*) + libdir="`echo $arg | cut -f2 -d=`" + ;; + -includedir=*) + includedir="`echo $arg | cut -f2 -d=`" + ;; + -echo) + set -x + ;; + -show) + SHOW="echo" + ;; + -tool=*) + h5tools="`echo $arg | cut -f2 -d=`" + ;; + -help|help) + usage + ;; + -force) + fmode=yes + ;; + *) + ERROR "Unknown Option($arg)" + usage + exit $EXIT_FAILURE + ;; + esac +done + +# Set to default value, one above where i am, if not given by user +if [ -z "$prefix" ]; then + prefix=`(cd ..;pwd)` +fi +if [ -z "$exec_prefix" ]; then + exec_prefix='${prefix}' # use single quotes to prevent expansion of $ +fi +if [ -z "$libdir" ]; then + libdir='${exec_prefix}'/lib # use single quotes to prevent expansion of $ +fi +if [ -z "$includedir" ]; then + includedir='${prefix}'/include # use single quotes to prevent expansion of $ +fi + +for x in $h5tools; do + if [ -f $x ]; then + foundtools="$foundtools $x" + if [ ! -w $x ]; then + ERROR "h5tool($x) is not writable" + exit $EXIT_FAILURE + fi + fi +done + +if [ -z "$foundtools" ]; then + ERROR "found no tools to modify" + exit $EXIT_FAILURE +fi + +# Show actions to be taken and get consent +show_action +# Ask confirmation unless fmode is on +if [ x-$fmode = x- ]; then + echo "Continue? (yes/no)" + read ansx + ans=`echo $ansx | tr "[A-Z]" "[a-z]"` + if [ x-$ans != x-yes ]; then + echo ABORT. No tools changed. + exit $EXIT_FAILURE + fi +fi + + +# Create the update commands +CMDFILE=/tmp/h5redeploy.$$ +touch $CMDFILE +chmod 0600 $CMDFILE +echo "/^prefix=/c" >> $CMDFILE +echo prefix=\""$prefix"\" >> $CMDFILE +echo . >> $CMDFILE +echo "/^exec_prefix=/c" >> $CMDFILE +echo exec_prefix=\""$exec_prefix"\" >> $CMDFILE +echo . >> $CMDFILE +echo "/^libdir=/c" >> $CMDFILE +echo libdir=\""$libdir"\" >> $CMDFILE +echo . >> $CMDFILE +echo "/^includedir=/c" >> $CMDFILE +echo includedir=\""$includedir"\" >> $CMDFILE +echo . >> $CMDFILE +(echo w; echo q) >> $CMDFILE + + +# Update them +if [ "$SHOW" = "echo" ]; then + echo "===Update commands are:====" + cat $CMDFILE + echo "===End Update commands=====" +fi + +for t in $foundtools; do + echo Update $t ... + COMMAND="ed - $t" + if [ "$SHOW" = "echo" ]; then + echo $COMMAND + else + $COMMAND < $CMDFILE + fi +done + + +# Cleanup +rm -f $CMDFILE +exit $EXIT_SUCCESS diff --git a/tools/src/misc/h5repart.c b/tools/src/misc/h5repart.c new file mode 100644 index 0000000..e44c957 --- /dev/null +++ b/tools/src/misc/h5repart.c @@ -0,0 +1,510 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Robb Matzke <matzke@llnl.gov> + * 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" +#ifdef H5_STDC_HEADERS +# include <ctype.h> +# include <errno.h> +# include <fcntl.h> +# include <stdio.h> +# include <stdlib.h> +# include <string.h> +#endif + +#ifdef H5_HAVE_UNISTD_H +# include <sys/types.h> +# include <unistd.h> +#endif + +#ifdef H5_HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif + +#ifndef FALSE +# define FALSE 0 +#endif +#ifndef TRUE +# define TRUE 1 +#endif +# define NAMELEN 4096 +#define GB *1024*1024*1024 + +#ifndef MIN +# define MIN(X,Y) ((X)<(Y)?(X):(Y)) +#endif +#ifndef MIN3 +# define MIN3(X,Y,Z) MIN(MIN(X,Y),Z) +#endif + +/*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 sec2. */ +#define H5F_ACS_FAMILY_NEWSIZE_NAME "family_newsize" +#define H5F_ACS_FAMILY_TO_SEC2_NAME "family_to_sec2" + + +/*------------------------------------------------------------------------- + * Function: usage + * + * Purpose: Prints a usage message. + * + * Return: void + * + * Programmer: Robb Matzke + * Wednesday, May 13, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void +usage (const char *progname) +{ + fprintf(stderr, "usage: %s [-v] [-V] [-[b|m] N[g|m|k]] [-family_to_sec2] SRC DST\n", + progname); + fprintf(stderr, " -v Produce verbose output\n"); + fprintf(stderr, " -V Print a version number and exit\n"); + fprintf(stderr, " -b N The I/O block size, defaults to 1kB\n"); + fprintf(stderr, " -m N The destination member size or 1GB\n"); + fprintf(stderr, " -family_to_sec2 Change file driver from family to sec2\n"); + fprintf(stderr, " SRC The name of the source file\n"); + fprintf(stderr, " DST The name of the destination files\n"); + fprintf(stderr, "Sizes may be suffixed with `g' for GB, `m' for MB or " + "`k' for kB.\n"); + fprintf(stderr, "File family names include an integer printf " + "format such as `%%d'\n"); + exit (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 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static off_t +get_size (const char *progname, int *argno, int argc, char *argv[]) +{ + off_t retval=-1; + char *suffix; + + if (isdigit ((int)(argv[*argno][2]))) { + retval = strtol (argv[*argno]+2, &suffix, 10); + (*argno)++; + } else if (argv[*argno][2] || *argno+1>=argc) { + usage (progname); + } else { + retval = strtol (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: + * + *------------------------------------------------------------------------- + */ +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_sec2=FALSE; /*change family to sec2 driver? */ + + /* + * Get the program name from argv[0]. Use only the last component. + */ + if ((prog_name=strrchr (argv[0], '/'))) prog_name++; + else prog_name = argv[0]; + + /* + * Parse switches. + */ + while (argno<argc && '-'==argv[argno][0]) { + if (!strcmp (argv[argno], "-v")) { + verbose = TRUE; + argno++; + } else if (!strcmp(argv[argno], "-V")) { + printf("This is %s version %u.%u release %u\n", + prog_name, H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE); + exit(EXIT_SUCCESS); + } else if (!strcmp (argv[argno], "-family_to_sec2")) { + family_to_sec2 = 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)))) + exit(EXIT_FAILURE); + if(NULL == (dst_name = (char *)HDcalloc((size_t)NAMELEN, sizeof(char)))) + exit(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++]; + sprintf (src_name, src_gen_name, src_membno); + src_is_family = strcmp (src_name, src_gen_name); + + if ((src=HDopen(src_name, O_RDONLY,0))<0) { + perror (src_name); + exit (EXIT_FAILURE); + } + + if (HDfstat(src, &sb)<0) { + perror ("fstat"); + exit (EXIT_FAILURE); + } + src_size = src_act_size = sb.st_size; + if (verbose) fprintf (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++]; + sprintf (dst_name, dst_gen_name, dst_membno); + dst_is_family = strcmp (dst_name, dst_gen_name); + + if ((dst=HDopen (dst_name, O_RDWR|O_CREAT|O_TRUNC, 0666))<0) { + perror (dst_name); + exit (EXIT_FAILURE); + } + if (verbose) fprintf (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) { + perror ("read"); + exit (EXIT_FAILURE); + } else if ((size_t)nio!=n) { + fprintf (stderr, "%s: short read\n", src_name); + exit (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) { + perror ("HDlseek"); + exit (EXIT_FAILURE); + } + if ((nio=HDwrite (dst, buf, n))<0) { + perror ("write"); + exit (EXIT_FAILURE); + } else if ((size_t)nio!=n) { + fprintf (stderr, "%s: short write\n", dst_name); + exit (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; + } + sprintf (src_name, src_gen_name, ++src_membno); + if ((src=HDopen (src_name, O_RDONLY,0))<0 && ENOENT==errno) { + dst_offset = dst_offset + (off_t)n; + break; + } else if (src<0) { + perror (src_name); + exit (EXIT_FAILURE); + } + if (HDfstat (src, &sb)<0) { + perror ("fstat"); + exit (EXIT_FAILURE); + } + src_act_size = sb.st_size; + if (src_act_size>src_size) { + fprintf (stderr, "%s: member truncated to %lu bytes\n", + src_name, (unsigned long)src_size); + } + src_offset = 0; + if (verbose) fprintf (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) { + perror ("HDHDlseek"); + exit (EXIT_FAILURE); + } + if (HDread (dst, buf, 1)<0) { + perror ("read"); + exit (EXIT_FAILURE); + } + if (HDlseek (dst, dst_size-1, SEEK_SET)<0) { + perror ("HDlseek"); + exit (EXIT_FAILURE); + } + if (HDwrite (dst, buf, 1)<0) { + perror ("write"); + exit (EXIT_FAILURE); + } + } + HDclose (dst); + sprintf (dst_name, dst_gen_name, ++dst_membno); + if ((dst=HDopen (dst_name, O_RDWR|O_CREAT|O_TRUNC, 0666))<0) { + perror (dst_name); + exit (EXIT_FAILURE); + } + dst_offset = 0; + need_seek = FALSE; + if (verbose) fprintf (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) { + perror ("HDlseek"); + exit (EXIT_FAILURE); + } + if (HDread (dst, buf, 1)<0) { + perror ("read"); + exit (EXIT_FAILURE); + } + if (HDlseek (dst, dst_offset-1, SEEK_SET)<0) { + perror ("HDlseek"); + exit (EXIT_FAILURE); + } + if (HDwrite (dst, buf, 1)<0) { + perror ("write"); + exit (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) { + perror ("H5Pcreate"); + exit (EXIT_FAILURE); + } + + if(family_to_sec2) { + /* The user wants to change file driver from family to sec2. Open the file + * with sec2 driver. This property signals the library to ignore the family + * driver information saved in the superblock. */ + if(H5Pset(fapl, H5F_ACS_FAMILY_TO_SEC2_NAME, &family_to_sec2) < 0) { + perror ("H5Pset"); + exit (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) { + perror ("H5Pset_fapl_family"); + exit (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) { + perror ("H5Pset"); + exit (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 sec2 + * file, the property FAMILY_TO_SEC2 will signal the library to switch to sec2 + * driver when the new file is opened. If the original file is a sec2 file and the + * new file can only be a sec2 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) { + perror ("H5Fclose"); + exit (EXIT_FAILURE); + } /* end if */ + } /* end if */ + + if(H5Pclose(fapl)<0) { + perror ("H5Pclose"); + exit (EXIT_FAILURE); + } /* end if */ + + /* Free resources and return */ + HDfree(src_name); + HDfree(dst_name); + HDfree(buf); + return EXIT_SUCCESS; +} /* end main */ |