summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-02-14 13:54:11 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-02-14 13:54:11 (GMT)
commitbb392083b2a81aa942678e06a537a3c0ab5c08aa (patch)
tree9243c5965897315e4cbeef983f71b224498718c0 /tools
parentdf075c5b9266b3b7a038fb1377d130ed315aa15c (diff)
downloadhdf5-bb392083b2a81aa942678e06a537a3c0ab5c08aa.zip
hdf5-bb392083b2a81aa942678e06a537a3c0ab5c08aa.tar.gz
hdf5-bb392083b2a81aa942678e06a537a3c0ab5c08aa.tar.bz2
[svn-r13297] Description:
Add small 'h5mkgrp' tool to create groups in an HDF5 file from the command line, allowing the group structure for a file to be created in a script. This tool closely follows the 'mkdir' command line tool in UNIX/Linux. Allow tool library applications to pass a FAPL to the h5tool_fopen() call, giving some additional flexibility to tools which are adding objects to an existing HDF5 file (like h5copy & h5mkgrp). Fix missing files in MANIFEST from previous checkin(s). Tested on: Linux/32 2.6 (chicago) Linux/64 2.6 (chicago2)
Diffstat (limited to 'tools')
-rw-r--r--tools/h5copy/h5copy.c6
-rw-r--r--tools/h5copy/testh5copy.sh11
-rw-r--r--tools/h5dump/h5dump.c2
-rw-r--r--tools/h5ls/h5ls.c2
-rw-r--r--tools/h5repack/h5repack_copy.c2
-rw-r--r--tools/h5repack/h5repack_list.c2
-rw-r--r--tools/lib/h5tools.c128
-rw-r--r--tools/lib/h5tools.h2
-rw-r--r--tools/misc/Makefile.am6
-rw-r--r--tools/misc/Makefile.in18
-rw-r--r--tools/misc/h5mkgrp.c330
-rw-r--r--tools/misc/h5stat.c2
-rw-r--r--tools/misc/testh5mkgrp.sh176
-rw-r--r--tools/testfiles/h5mkgrp_help.ls4
-rw-r--r--tools/testfiles/h5mkgrp_nested.ls10
-rw-r--r--tools/testfiles/h5mkgrp_nested_latest.ls12
-rw-r--r--tools/testfiles/h5mkgrp_nested_mult.ls16
-rw-r--r--tools/testfiles/h5mkgrp_nested_mult_latest.ls20
-rw-r--r--tools/testfiles/h5mkgrp_several.ls10
-rw-r--r--tools/testfiles/h5mkgrp_several_latest.ls12
-rw-r--r--tools/testfiles/h5mkgrp_single.ls7
-rw-r--r--tools/testfiles/h5mkgrp_single_latest.ls8
-rw-r--r--tools/testfiles/h5mkgrp_version.ls4
23 files changed, 703 insertions, 87 deletions
diff --git a/tools/h5copy/h5copy.c b/tools/h5copy/h5copy.c
index 9b4f629..926be0f 100644
--- a/tools/h5copy/h5copy.c
+++ b/tools/h5copy/h5copy.c
@@ -272,7 +272,7 @@ main (int argc, const char *argv[])
* open input file
*-------------------------------------------------------------------------*/
- fid_src = h5tools_fopen(fname_src, H5F_ACC_RDONLY, NULL, NULL, 0);
+ fid_src = h5tools_fopen(fname_src, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, 0);
/*-------------------------------------------------------------------------
* test for error in opening input file
@@ -290,10 +290,10 @@ main (int argc, const char *argv[])
*-------------------------------------------------------------------------*/
/* Attempt to open an existing HDF5 file first */
- fid_dst = h5tools_fopen(fname_dst, H5F_ACC_RDWR, NULL, NULL, 0);
+ fid_dst = h5tools_fopen(fname_dst, H5F_ACC_RDWR, H5P_DEFAULT, 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 */
+ /* (use "EXCL" instead of "TRUNC", so we don't blow away existing non-HDF5 file) */
if(fid_dst < 0)
fid_dst = H5Fcreate(fname_dst, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT);
diff --git a/tools/h5copy/testh5copy.sh b/tools/h5copy/testh5copy.sh
index a905148..4106fe0 100644
--- a/tools/h5copy/testh5copy.sh
+++ b/tools/h5copy/testh5copy.sh
@@ -63,7 +63,7 @@ VERIFY()
VERIFY_H5LS()
{
SPACES=" "
- echo "Verifying h5diff file structure $* $SPACES" | cut -c1-70 | tr -d '\012'
+ echo "Verifying h5ls file structure $* $SPACES" | cut -c1-70 | tr -d '\012'
}
# Run a test and print PASS or *FAIL*. If h5copy can complete
@@ -137,17 +137,16 @@ H5LSTEST()
{
expect="$srcdir/../testfiles/`basename $1 .h5`.ls"
actual="../testfiles/`basename $1 .h5`.out"
- actual_err="../testfiles/`basename $1 .h5`.err"
+ # Stderr is included in stdout so that the diff can detect
+ # any unexpected output from that stream too.
VERIFY_H5LS $@
-
- (
+ (
echo "#############################"
echo "Expected output for '$H5LS $@'"
echo "#############################"
$RUNSERIAL $H5LS_BIN $H5LS_ARGS $@
- ) >$actual 2>$actual_err
- cat $actual_err >> $actual
+ ) 2>&1 >$actual
if [ ! -f $expect ]; then
diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c
index 1f34b65..4ab68cf 100644
--- a/tools/h5dump/h5dump.c
+++ b/tools/h5dump/h5dump.c
@@ -3775,7 +3775,7 @@ main(int argc, const char *argv[])
}
fname = HDstrdup(argv[opt_ind]);
- fid = h5tools_fopen(fname, H5F_ACC_RDONLY, driver, NULL, 0);
+ fid = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, driver, NULL, 0);
if (fid < 0) {
error_msg(progname, "unable to open file \"%s\"\n", fname);
diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c
index c8ce958..8ae42b7 100644
--- a/tools/h5ls/h5ls.c
+++ b/tools/h5ls/h5ls.c
@@ -2280,7 +2280,7 @@ main (int argc, const char *argv[])
file = -1;
while (fname && *fname) {
- file = h5tools_fopen(fname, H5F_ACC_RDONLY, preferred_driver, drivername, sizeof drivername);
+ file = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, preferred_driver, drivername, sizeof drivername);
if (file>=0) {
if (verbose_g) {
diff --git a/tools/h5repack/h5repack_copy.c b/tools/h5repack/h5repack_copy.c
index e43831e..ec6f2bf 100644
--- a/tools/h5repack/h5repack_copy.c
+++ b/tools/h5repack/h5repack_copy.c
@@ -181,7 +181,7 @@ int copy_objects(const char* fnamein,
* open the files
*-------------------------------------------------------------------------
*/
- if ((fidin=h5tools_fopen(fnamein, H5F_ACC_RDONLY, NULL, NULL, 0))<0 ){
+ if ((fidin=h5tools_fopen(fnamein, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, 0))<0 ){
error_msg(progname, "<%s>: %s\n", fnamein, H5FOPENERROR );
goto out;
}
diff --git a/tools/h5repack/h5repack_list.c b/tools/h5repack/h5repack_list.c
index b1d8ee9..203f8a2 100644
--- a/tools/h5repack/h5repack_list.c
+++ b/tools/h5repack/h5repack_list.c
@@ -51,7 +51,7 @@ int check_objects(const char* fname,
* open the file
*-------------------------------------------------------------------------
*/
- if ((fid=h5tools_fopen(fname, H5F_ACC_RDONLY, NULL, NULL, 0))<0){
+ if ((fid=h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, 0))<0){
printf("<%s>: %s\n", fname, H5FOPENERROR );
return -1;
}
diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c
index 429898a..a713092 100644
--- a/tools/lib/h5tools.c
+++ b/tools/lib/h5tools.c
@@ -161,67 +161,67 @@ h5tools_close(void)
*-------------------------------------------------------------------------
*/
static hid_t
-h5tools_get_fapl(const char *driver, unsigned *drivernum)
+h5tools_get_fapl(hid_t fapl, const char *driver, unsigned *drivernum)
{
- hid_t fapl = H5P_DEFAULT;
+ hid_t new_fapl; /* Copy of file access property list passed in, or new property list */
+
+ /* Make a copy of the FAPL, for the file open call to use, eventually */
+ if(fapl == H5P_DEFAULT) {
+ if((new_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
+ goto error;
+ } /* end if */
+ else {
+ if((new_fapl = H5Pcopy(fapl)) < 0)
+ goto error;
+ } /* end else */
/* Determine which driver the user wants to open the file with. Try
* that driver. If it can't open it, then fail. */
- if (!strcmp(driver, drivernames[SEC2_IDX])) {
+ if(!strcmp(driver, drivernames[SEC2_IDX])) {
if(drivernum)
*drivernum = SEC2_IDX;
- } else if (!strcmp(driver, drivernames[FAMILY_IDX])) {
+ } else if(!strcmp(driver, drivernames[FAMILY_IDX])) {
/* FAMILY Driver */
- if((fapl = H5Pcreate(H5P_FILE_ACCESS))>=0) {
- /* Set member size to be 0 to indicate the current first member size
- * is the member size.
- */
- if (H5Pset_fapl_family(fapl, (hsize_t)0, H5P_DEFAULT)<0)
- goto error;
- if(drivernum)
- *drivernum = FAMILY_IDX;
- } /* end if */
- } else if (!strcmp(driver, drivernames[SPLIT_IDX])) {
+ /* Set member size to be 0 to indicate the current first member size
+ * is the member size.
+ */
+ if(H5Pset_fapl_family(new_fapl, (hsize_t)0, H5P_DEFAULT) < 0)
+ goto error;
+
+ if(drivernum)
+ *drivernum = FAMILY_IDX;
+ } else if(!strcmp(driver, drivernames[SPLIT_IDX])) {
/* SPLIT Driver */
- if((fapl = H5Pcreate(H5P_FILE_ACCESS))>=0) {
-
- if (H5Pset_fapl_split(fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT)<0)
- goto error;
+ if(H5Pset_fapl_split(new_fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0)
+ goto error;
- if(drivernum)
- *drivernum = SPLIT_IDX;
- } /* end if */
- } else if (!strcmp(driver, drivernames[MULTI_IDX])) {
+ if(drivernum)
+ *drivernum = SPLIT_IDX;
+ } else if(!strcmp(driver, drivernames[MULTI_IDX])) {
/* MULTI Driver */
- if((fapl = H5Pcreate(H5P_FILE_ACCESS))>=0) {
-
- if (H5Pset_fapl_multi(fapl, NULL, NULL, NULL, NULL, TRUE)<0)
- goto error;
+ if(H5Pset_fapl_multi(new_fapl, NULL, NULL, NULL, NULL, TRUE) < 0)
+ goto error;
- if(drivernum)
- *drivernum = MULTI_IDX;
- } /* end if */
+ if(drivernum)
+ *drivernum = MULTI_IDX;
#ifdef H5_HAVE_STREAM
- } else if (!strcmp(driver, drivernames[STREAM_IDX])) {
+ } else if(!strcmp(driver, drivernames[STREAM_IDX])) {
/* STREAM Driver */
- if((fapl = H5Pcreate(H5P_FILE_ACCESS))>=0) {
-
- if (H5Pset_fapl_stream(fapl, NULL)<0)
- goto error;
+ if(H5Pset_fapl_stream(new_fapl, NULL) < 0)
+ goto error;
- if(drivernum)
- *drivernum = STREAM_IDX;
- } /* end if */
+ if(drivernum)
+ *drivernum = STREAM_IDX;
#endif /* H5_HAVE_STREAM */
#ifdef H5_HAVE_PARALLEL
- } else if (!strcmp(driver, drivernames[MPIO_IDX])) {
+ } else if(!strcmp(driver, drivernames[MPIO_IDX])) {
/* MPI-I/O Driver */
/* check if MPI has been initialized. */
- if (!h5tools_mpi_init_g)
+ if(!h5tools_mpi_init_g)
MPI_Initialized(&h5tools_mpi_init_g);
- if (h5tools_mpi_init_g && ((fapl = H5Pcreate(H5P_FILE_ACCESS))>=0)) {
- if (H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL)<0)
+ if(h5tools_mpi_init_g) {
+ if(H5Pset_fapl_mpio(new_fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0)
goto error;
if(drivernum)
@@ -230,10 +230,10 @@ h5tools_get_fapl(const char *driver, unsigned *drivernum)
} else if (!strcmp(driver, drivernames[MPIPOSIX_IDX])) {
/* MPI-I/O Driver */
/* check if MPI has been initialized. */
- if (!h5tools_mpi_init_g)
+ if(!h5tools_mpi_init_g)
MPI_Initialized(&h5tools_mpi_init_g);
- if (h5tools_mpi_init_g && ((fapl = H5Pcreate(H5P_FILE_ACCESS))>=0)) {
- if (H5Pset_fapl_mpiposix(fapl, MPI_COMM_WORLD, TRUE)<0)
+ if(h5tools_mpi_init_g) {
+ if(H5Pset_fapl_mpiposix(new_fapl, MPI_COMM_WORLD, TRUE) < 0)
goto error;
if(drivernum)
@@ -241,14 +241,14 @@ h5tools_get_fapl(const char *driver, unsigned *drivernum)
} /* end if */
#endif /* H5_HAVE_PARALLEL */
} else {
- fapl=(-1);
+ goto error;
}
- return(fapl);
+ return(new_fapl);
error:
- if(fapl!=H5P_DEFAULT)
- H5Pclose(fapl);
+ if(new_fapl != H5P_DEFAULT)
+ H5Pclose(new_fapl);
return -1;
}
@@ -308,49 +308,49 @@ error:
*-------------------------------------------------------------------------
*/
hid_t
-h5tools_fopen(const char *fname, unsigned flags, const char *driver,
+h5tools_fopen(const char *fname, unsigned flags, hid_t fapl, const char *driver,
char *drivername, size_t drivername_size)
{
unsigned drivernum;
hid_t fid = FAIL;
- hid_t fapl = H5P_DEFAULT;
+ hid_t my_fapl = H5P_DEFAULT;
- if (driver && *driver) {
+ if(driver && *driver) {
/* Get the correct FAPL for the given driver */
- if((fapl=h5tools_get_fapl(driver,&drivernum))<0)
+ if((my_fapl = h5tools_get_fapl(fapl, driver, &drivernum)) < 0)
goto done;
H5E_BEGIN_TRY {
- fid = H5Fopen(fname, flags, fapl);
+ fid = H5Fopen(fname, flags, my_fapl);
} H5E_END_TRY;
- if (fid == FAIL)
+ if(fid == FAIL)
goto done;
} else {
/* Try to open the file using each of the drivers */
- for (drivernum = 0; drivernum < NUM_DRIVERS; drivernum++) {
+ for(drivernum = 0; drivernum < NUM_DRIVERS; drivernum++) {
/* Get the correct FAPL for the given driver */
- if((fapl=h5tools_get_fapl(drivernames[drivernum],NULL))<0)
+ if((my_fapl = h5tools_get_fapl(fapl, drivernames[drivernum], NULL)) < 0)
goto done;
H5E_BEGIN_TRY {
- fid = H5Fopen(fname, flags, fapl);
+ fid = H5Fopen(fname, flags, my_fapl);
} H5E_END_TRY;
- if (fid != FAIL)
+ if(fid != FAIL)
break;
else {
/* Close the FAPL */
- H5Pclose(fapl);
- fapl=H5P_DEFAULT;
+ H5Pclose(my_fapl);
+ my_fapl = H5P_DEFAULT;
} /* end else */
}
}
/* Save the driver name */
- if (drivername && drivername_size) {
- if (fid != FAIL) {
+ if(drivername && drivername_size) {
+ if(fid != FAIL) {
strncpy(drivername, drivernames[drivernum], drivername_size);
drivername[drivername_size - 1] = '\0';
} else {
@@ -360,8 +360,8 @@ h5tools_fopen(const char *fname, unsigned flags, const char *driver,
}
done:
- if(fapl!=H5P_DEFAULT)
- H5Pclose(fapl);
+ if(my_fapl != H5P_DEFAULT)
+ H5Pclose(my_fapl);
return fid;
}
diff --git a/tools/lib/h5tools.h b/tools/lib/h5tools.h
index 929cdd5..61b02a5 100644
--- a/tools/lib/h5tools.h
+++ b/tools/lib/h5tools.h
@@ -387,7 +387,7 @@ extern int bin_form; /* binary form */
/* Definitions of useful routines */
extern void h5tools_init(void);
extern void h5tools_close(void);
-extern hid_t h5tools_fopen(const char *fname, unsigned flags,
+extern hid_t h5tools_fopen(const char *fname, unsigned flags, hid_t fapl,
const char *driver, char *drivername, size_t drivername_len);
extern int h5tools_dump_dset(FILE *stream, const h5tool_format_t *info, hid_t dset,
hid_t p_typ, struct subset_t *sset, int indentlevel);
diff --git a/tools/misc/Makefile.am b/tools/misc/Makefile.am
index 5b746f9..423a28b 100644
--- a/tools/misc/Makefile.am
+++ b/tools/misc/Makefile.am
@@ -25,14 +25,14 @@ INCLUDES=-I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
#test script and program
TEST_PROG=h5repart_gentest
-TEST_SCRIPT=testh5repart.sh testh5stat.sh
+TEST_SCRIPT=testh5repart.sh testh5stat.sh $(srcdir)/testh5mkgrp.sh
check_PROGRAMS=$(TEST_PROG) repart_test
check_SCRIPTS=$(TEST_SCRIPT)
-SCRIPT_DEPEND=h5repart$(EXEEXT) h5stat$(EXEEXT)
+SCRIPT_DEPEND=h5repart$(EXEEXT) h5stat$(EXEEXT) h5mkgrp$(EXEEXT)
# These are our main targets, the tools
-bin_PROGRAMS=h5debug h5repart h5stat
+bin_PROGRAMS=h5debug h5repart h5stat h5mkgrp
bin_SCRIPTS=h5redeploy
# Tell automake to clean h5redeploy script
diff --git a/tools/misc/Makefile.in b/tools/misc/Makefile.in
index 9331bc8..3aec239 100644
--- a/tools/misc/Makefile.in
+++ b/tools/misc/Makefile.in
@@ -59,7 +59,7 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/testh5stat.sh.in $(top_srcdir)/config/commence.am \
$(top_srcdir)/config/conclude.am
check_PROGRAMS = $(am__EXEEXT_1) repart_test$(EXEEXT)
-bin_PROGRAMS = h5debug$(EXEEXT) h5repart$(EXEEXT) h5stat$(EXEEXT)
+bin_PROGRAMS = h5debug$(EXEEXT) h5repart$(EXEEXT) h5stat$(EXEEXT) h5mkgrp$(EXEEXT)
subdir = tools/misc
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
@@ -91,6 +91,10 @@ h5stat_SOURCES = h5stat.c
h5stat_OBJECTS = h5stat.$(OBJEXT)
h5stat_LDADD = $(LDADD)
h5stat_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
+h5mkgrp_SOURCES = h5mkgrp.c
+h5mkgrp_OBJECTS = h5mkgrp.$(OBJEXT)
+h5mkgrp_LDADD = $(LDADD)
+h5mkgrp_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
repart_test_SOURCES = repart_test.c
repart_test_OBJECTS = repart_test.$(OBJEXT)
repart_test_LDADD = $(LDADD)
@@ -108,9 +112,9 @@ LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = h5debug.c h5repart.c h5repart_gentest.c h5stat.c \
+SOURCES = h5debug.c h5repart.c h5repart_gentest.c h5stat.c h5mkgrp.c \
repart_test.c
-DIST_SOURCES = h5debug.c h5repart.c h5repart_gentest.c h5stat.c \
+DIST_SOURCES = h5debug.c h5repart.c h5repart_gentest.c h5stat.c h5mkgrp.c \
repart_test.c
ETAGS = etags
CTAGS = ctags
@@ -362,9 +366,9 @@ INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/tools/lib
#test script and program
TEST_PROG = h5repart_gentest
-TEST_SCRIPT = testh5repart.sh testh5stat.sh
+TEST_SCRIPT = testh5repart.sh testh5stat.sh $(srcdir)/testh5mkgrp.sh
check_SCRIPTS = $(TEST_SCRIPT)
-SCRIPT_DEPEND = h5repart$(EXEEXT) h5stat$(EXEEXT)
+SCRIPT_DEPEND = h5repart$(EXEEXT) h5stat$(EXEEXT) h5mkgrp$(EXEEXT)
bin_SCRIPTS = h5redeploy
# Tell automake to clean h5redeploy script
@@ -483,6 +487,9 @@ h5repart_gentest$(EXEEXT): $(h5repart_gentest_OBJECTS) $(h5repart_gentest_DEPEND
h5stat$(EXEEXT): $(h5stat_OBJECTS) $(h5stat_DEPENDENCIES)
@rm -f h5stat$(EXEEXT)
$(LINK) $(h5stat_LDFLAGS) $(h5stat_OBJECTS) $(h5stat_LDADD) $(LIBS)
+h5mkgrp$(EXEEXT): $(h5mkgrp_OBJECTS) $(h5mkgrp_DEPENDENCIES)
+ @rm -f h5mkgrp$(EXEEXT)
+ $(LINK) $(h5mkgrp_LDFLAGS) $(h5mkgrp_OBJECTS) $(h5mkgrp_LDADD) $(LIBS)
repart_test$(EXEEXT): $(repart_test_OBJECTS) $(repart_test_DEPENDENCIES)
@rm -f repart_test$(EXEEXT)
$(LINK) $(repart_test_LDFLAGS) $(repart_test_OBJECTS) $(repart_test_LDADD) $(LIBS)
@@ -516,6 +523,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5repart.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5repart_gentest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5stat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5mkgrp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repart_test.Po@am__quote@
.c.o:
diff --git a/tools/misc/h5mkgrp.c b/tools/misc/h5mkgrp.c
new file mode 100644
index 0000000..048523a
--- /dev/null
+++ b/tools/misc/h5mkgrp.c
@@ -0,0 +1,330 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 */
+const char *progname = "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;
+
+
+/*-------------------------------------------------------------------------
+ * 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)
+{
+ h5tools_close();
+ exit(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)
+{
+ fprintf(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 *params)
+{
+ 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':
+ params->latest = TRUE;
+ break;
+
+ /* Create parent groups */
+ case 'p':
+ params->parents = TRUE;
+ break;
+
+ /* Verbose output */
+ case 'v':
+ params->verbose = TRUE;
+ break;
+
+ /* Display version */
+ case 'V':
+ print_version(progname);
+ 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(progname, "missing file name\n");
+ usage();
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Retrieve file name */
+ params->fname = HDstrdup(argv[opt_ind]);
+ opt_ind++;
+
+ /* Check for group(s) to be created */
+ if(argc <= opt_ind) {
+ error_msg(progname, "missing group name(s)\n");
+ usage();
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Allocate space for the group name pointers */
+ params->ngroups = (argc - opt_ind);
+ params->groups = HDmalloc(params->ngroups * sizeof(char *));
+
+ /* Retrieve the group names */
+ curr_group = 0;
+ while(opt_ind < argc) {
+ params->groups[curr_group] = HDstrdup(argv[opt_ind]);
+ curr_group++;
+ opt_ind++;
+ } /* end while */
+
+#ifdef QAK
+HDfprintf(stderr, "params->parents = %t\n", params->parents);
+HDfprintf(stderr, "params->verbose = %t\n", params->verbose);
+HDfprintf(stderr, "params->fname = '%s'\n", params->fname);
+HDfprintf(stderr, "params->ngroups = %Zu\n", params->ngroups);
+for(curr_group = 0; curr_group < params->ngroups; curr_group++)
+ HDfprintf(stderr, "params->group[%Zu] = '%s'\n", curr_group, params->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[])
+{
+ param_t params; /* Command line parameter settings */
+ 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 */
+
+ /* Disable the HDF5 library's error reporting */
+ H5Eset_auto_stack(H5E_DEFAULT, NULL, NULL);
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ /* Parse command line */
+ HDmemset(&params, 0, sizeof(params));
+ if(parse_command_line(argc, argv, &params) < 0) {
+ error_msg(progname, "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(progname, "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 flag */
+ if(H5Pset_latest_format(fapl_id, TRUE) < 0) {
+ error_msg(progname, "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", progname);
+ } /* 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(progname, "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(progname, "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(progname, "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", progname);
+ } /* 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 = H5Gcreate_expand(fid, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
+ error_msg(progname, "Could not create group\n");
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Link new group into group hierarchy */
+ if(H5Llink(fid, params.groups[curr_group], gid, lcpl_id, H5P_DEFAULT) < 0) {
+ error_msg(progname, "Could not create link to group '%s'\n", params.groups[curr_group]);
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Close the group */
+ if(H5Gclose(gid) < 0) {
+ error_msg(progname, "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", progname, params.groups[curr_group]);
+ } /* end for */
+
+ /* Close link creation property list */
+ if(H5Pclose(lcpl_id) < 0) {
+ error_msg(progname, "Could not close link creation property list\n");
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) {
+ error_msg(progname, "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(progname, "Could not close file access property list\n");
+ leave(EXIT_FAILURE);
+ } /* end if */
+
+ /* Shut down h5tools lib */
+ h5tools_close();
+
+ return 0;
+} /* end main() */
+
diff --git a/tools/misc/h5stat.c b/tools/misc/h5stat.c
index 5795b4a..8db92c1 100644
--- a/tools/misc/h5stat.c
+++ b/tools/misc/h5stat.c
@@ -183,7 +183,7 @@ leave(int ret)
}
-static void usage(const char *prog)
+static void usage(const char *prog)
{
fflush(stdout);
fprintf(stdout, "\n");
diff --git a/tools/misc/testh5mkgrp.sh b/tools/misc/testh5mkgrp.sh
new file mode 100644
index 0000000..e4912bb
--- /dev/null
+++ b/tools/misc/testh5mkgrp.sh
@@ -0,0 +1,176 @@
+#! /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.
+#
+# Tests for the h5mkgrp tool
+#
+# Quincey Koziol (koziol@hdfgroup.org)
+# Tuesday, February 13, 2007
+#
+
+H5MKGRP=h5mkgrp # The tool name
+H5MKGRP_BIN=`pwd`/$H5MKGRP # The path of the tool binary
+H5LS=h5ls # The h5ls tool name
+H5LS_ARGS=-vr # Arguments to the h5ls tool
+H5LS_BIN=`pwd`/../h5ls/$H5LS # The path of the h5ls tool binary
+
+nerrors=0
+verbose=yes
+
+CMP='cmp -s'
+DIFF='diff -c'
+
+# The build (current) directory might be different than the source directory.
+if test -z "$srcdir"; then
+ srcdir=.
+fi
+test -d ../testfiles || mkdir ../testfiles
+
+# Print a line-line message left justified in a field of 70 characters
+# beginning with the word "Testing".
+TESTING()
+{
+ SPACES=" "
+ echo "Testing $* $SPACES" |cut -c1-70 |tr -d '\012'
+}
+
+# Print a line-line message left justified in a field of 70 characters
+# beginning with the word "Verifying".
+#
+VERIFY_H5LS()
+{
+ SPACES=" "
+ echo "Verifying h5ls file structure $* $SPACES" | cut -c1-70 | tr -d '\012'
+}
+
+# Run a test and print PASS or *FAIL*. If h5mkgrp can complete
+# with exit status 0, consider it pass. If a test fails then increment
+# the `nerrors' global variable.
+# Assumed arguments:
+# $* arguments for h5mkgrp.
+
+TOOLTEST()
+{
+ TESTING $H5MKGRP $@
+ (
+ echo "#############################"
+ echo " output for '$H5MKGRP $@'"
+ echo "#############################"
+ $RUNSERIAL $H5MKGRP_BIN $@
+ ) > output.out
+ RET=$?
+ if [ $RET != 0 ]; then
+ echo "*FAILED*"
+ echo "failed result is:"
+ cat output.out
+ nerrors="`expr $nerrors + 1`"
+ else
+ echo " PASSED"
+ fi
+}
+
+# Call the h5ls tool to verify the correct output data in the destination file
+#
+H5LSTEST()
+{
+ expect="$srcdir/../testfiles/`basename $1 .h5`.ls"
+ actual="../testfiles/`basename $1 .h5`.out"
+
+ # Stderr is included in stdout so that the diff can detect
+ # any unexpected output from that stream too.
+ VERIFY_H5LS $@
+ (
+ echo "#############################"
+ echo "Expected output for '$H5LS $@'"
+ echo "#############################"
+ $RUNSERIAL $H5LS_BIN $H5LS_ARGS $@
+ ) 2>&1 |sed 's/Modified:.*/Modified: XXXX-XX-XX XX:XX:XX XXX/' >$actual
+
+
+ if [ ! -f $expect ]; then
+ # Create the expect file if it doesn't yet exist.
+ echo " CREATED"
+ cp $actual $expect
+ elif $CMP $expect $actual; then
+ echo " PASSED"
+ else
+ echo "*FAILED*"
+ echo " Expected result (*.ls) differs from actual result (*.out)"
+ nerrors="`expr $nerrors + 1`"
+ test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /'
+ fi
+}
+
+# Single run of tool
+#
+# Assumed arguments:
+# $1 is test file name
+# $2 is h5mkgrp options
+# $* are groups to create
+RUNTEST()
+{
+ FILEOUT=../testfiles/$1
+ shift
+ H5MKGRP_ARGS=$1
+ shift
+
+ # Remove any output file left over from previous test run
+ rm -f $FILEOUT
+
+ # Run test
+ TOOLTEST $H5MKGRP_ARGS $FILEOUT $@
+
+ # Verify that the file created above is correct
+ H5LSTEST $FILEOUT
+
+ # Remove output file created, if the "no cleanup" environment variable is
+ # not defined
+ if [ x$HDF5_NOCLEANUP = "x" ]; then
+ rm -f $FILEOUT
+ fi
+}
+
+##############################################################################
+### T H E T E S T S ###
+##############################################################################
+
+# Check that help & version is displayed properly
+RUNTEST h5mkgrp_help.h5 "-h"
+RUNTEST h5mkgrp_version.h5 "-V"
+
+# Create single group at root level
+RUNTEST h5mkgrp_single.h5 " " single
+RUNTEST h5mkgrp_single.h5 "-v" single
+RUNTEST h5mkgrp_single.h5 "-p" single
+RUNTEST h5mkgrp_single_latest.h5 "-l" latest
+
+# Create several groups at root level
+RUNTEST h5mkgrp_several.h5 " " one two
+RUNTEST h5mkgrp_several.h5 "-v" one two
+RUNTEST h5mkgrp_several.h5 "-p" one two
+RUNTEST h5mkgrp_several_latest.h5 "-l" one two
+
+# Create various nested groups
+RUNTEST h5mkgrp_nested.h5 "-p" /one/two
+RUNTEST h5mkgrp_nested_latest.h5 "-lp" /one/two
+RUNTEST h5mkgrp_nested_mult.h5 "-p" /one/two /three/four
+RUNTEST h5mkgrp_nested_mult_latest.h5 "-lp" /one/two /three/four
+
+
+if test $nerrors -eq 0 ; then
+ echo "All h5mkgrp tests passed."
+fi
+
+exit $nerrors
+
diff --git a/tools/testfiles/h5mkgrp_help.ls b/tools/testfiles/h5mkgrp_help.ls
new file mode 100644
index 0000000..ad2bd0f
--- /dev/null
+++ b/tools/testfiles/h5mkgrp_help.ls
@@ -0,0 +1,4 @@
+#############################
+Expected output for 'h5ls ../testfiles/h5mkgrp_help.h5'
+#############################
+../testfiles/h5mkgrp_help.h5: unable to open file
diff --git a/tools/testfiles/h5mkgrp_nested.ls b/tools/testfiles/h5mkgrp_nested.ls
new file mode 100644
index 0000000..acc3aba
--- /dev/null
+++ b/tools/testfiles/h5mkgrp_nested.ls
@@ -0,0 +1,10 @@
+#############################
+Expected output for 'h5ls ../testfiles/h5mkgrp_nested.h5'
+#############################
+Opened "../testfiles/h5mkgrp_nested.h5" with sec2 driver.
+/one Group
+ Location: 1:1520
+ Links: 1
+/one/two Group
+ Location: 1:808
+ Links: 1
diff --git a/tools/testfiles/h5mkgrp_nested_latest.ls b/tools/testfiles/h5mkgrp_nested_latest.ls
new file mode 100644
index 0000000..d47e358
--- /dev/null
+++ b/tools/testfiles/h5mkgrp_nested_latest.ls
@@ -0,0 +1,12 @@
+#############################
+Expected output for 'h5ls ../testfiles/h5mkgrp_nested_latest.h5'
+#############################
+Opened "../testfiles/h5mkgrp_nested_latest.h5" with sec2 driver.
+/one Group
+ Location: 1:612
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
+/one/two Group
+ Location: 1:354
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
diff --git a/tools/testfiles/h5mkgrp_nested_mult.ls b/tools/testfiles/h5mkgrp_nested_mult.ls
new file mode 100644
index 0000000..162da0c
--- /dev/null
+++ b/tools/testfiles/h5mkgrp_nested_mult.ls
@@ -0,0 +1,16 @@
+#############################
+Expected output for 'h5ls ../testfiles/h5mkgrp_nested_mult.h5'
+#############################
+Opened "../testfiles/h5mkgrp_nested_mult.h5" with sec2 driver.
+/one Group
+ Location: 1:1520
+ Links: 1
+/one/two Group
+ Location: 1:808
+ Links: 1
+/three Group
+ Location: 1:3600
+ Links: 1
+/three/four Group
+ Location: 1:2888
+ Links: 1
diff --git a/tools/testfiles/h5mkgrp_nested_mult_latest.ls b/tools/testfiles/h5mkgrp_nested_mult_latest.ls
new file mode 100644
index 0000000..548cf21
--- /dev/null
+++ b/tools/testfiles/h5mkgrp_nested_mult_latest.ls
@@ -0,0 +1,20 @@
+#############################
+Expected output for 'h5ls ../testfiles/h5mkgrp_nested_mult_latest.h5'
+#############################
+Opened "../testfiles/h5mkgrp_nested_mult_latest.h5" with sec2 driver.
+/one Group
+ Location: 1:612
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
+/one/two Group
+ Location: 1:354
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
+/three Group
+ Location: 1:1128
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
+/three/four Group
+ Location: 1:870
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
diff --git a/tools/testfiles/h5mkgrp_several.ls b/tools/testfiles/h5mkgrp_several.ls
new file mode 100644
index 0000000..e71e7a5
--- /dev/null
+++ b/tools/testfiles/h5mkgrp_several.ls
@@ -0,0 +1,10 @@
+#############################
+Expected output for 'h5ls ../testfiles/h5mkgrp_several.h5'
+#############################
+Opened "../testfiles/h5mkgrp_several.h5" with sec2 driver.
+/one Group
+ Location: 1:808
+ Links: 1
+/two Group
+ Location: 1:1848
+ Links: 1
diff --git a/tools/testfiles/h5mkgrp_several_latest.ls b/tools/testfiles/h5mkgrp_several_latest.ls
new file mode 100644
index 0000000..894855d
--- /dev/null
+++ b/tools/testfiles/h5mkgrp_several_latest.ls
@@ -0,0 +1,12 @@
+#############################
+Expected output for 'h5ls ../testfiles/h5mkgrp_several_latest.h5'
+#############################
+Opened "../testfiles/h5mkgrp_several_latest.h5" with sec2 driver.
+/one Group
+ Location: 1:354
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
+/two Group
+ Location: 1:612
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
diff --git a/tools/testfiles/h5mkgrp_single.ls b/tools/testfiles/h5mkgrp_single.ls
new file mode 100644
index 0000000..800b002
--- /dev/null
+++ b/tools/testfiles/h5mkgrp_single.ls
@@ -0,0 +1,7 @@
+#############################
+Expected output for 'h5ls ../testfiles/h5mkgrp_single.h5'
+#############################
+Opened "../testfiles/h5mkgrp_single.h5" with sec2 driver.
+/single Group
+ Location: 1:808
+ Links: 1
diff --git a/tools/testfiles/h5mkgrp_single_latest.ls b/tools/testfiles/h5mkgrp_single_latest.ls
new file mode 100644
index 0000000..d10628b
--- /dev/null
+++ b/tools/testfiles/h5mkgrp_single_latest.ls
@@ -0,0 +1,8 @@
+#############################
+Expected output for 'h5ls ../testfiles/h5mkgrp_single_latest.h5'
+#############################
+Opened "../testfiles/h5mkgrp_single_latest.h5" with sec2 driver.
+/latest Group
+ Location: 1:354
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
diff --git a/tools/testfiles/h5mkgrp_version.ls b/tools/testfiles/h5mkgrp_version.ls
new file mode 100644
index 0000000..907f0ad
--- /dev/null
+++ b/tools/testfiles/h5mkgrp_version.ls
@@ -0,0 +1,4 @@
+#############################
+Expected output for 'h5ls ../testfiles/h5mkgrp_version.h5'
+#############################
+../testfiles/h5mkgrp_version.h5: unable to open file