diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2007-02-14 13:54:11 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2007-02-14 13:54:11 (GMT) |
commit | bb392083b2a81aa942678e06a537a3c0ab5c08aa (patch) | |
tree | 9243c5965897315e4cbeef983f71b224498718c0 /tools | |
parent | df075c5b9266b3b7a038fb1377d130ed315aa15c (diff) | |
download | hdf5-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.c | 6 | ||||
-rw-r--r-- | tools/h5copy/testh5copy.sh | 11 | ||||
-rw-r--r-- | tools/h5dump/h5dump.c | 2 | ||||
-rw-r--r-- | tools/h5ls/h5ls.c | 2 | ||||
-rw-r--r-- | tools/h5repack/h5repack_copy.c | 2 | ||||
-rw-r--r-- | tools/h5repack/h5repack_list.c | 2 | ||||
-rw-r--r-- | tools/lib/h5tools.c | 128 | ||||
-rw-r--r-- | tools/lib/h5tools.h | 2 | ||||
-rw-r--r-- | tools/misc/Makefile.am | 6 | ||||
-rw-r--r-- | tools/misc/Makefile.in | 18 | ||||
-rw-r--r-- | tools/misc/h5mkgrp.c | 330 | ||||
-rw-r--r-- | tools/misc/h5stat.c | 2 | ||||
-rw-r--r-- | tools/misc/testh5mkgrp.sh | 176 | ||||
-rw-r--r-- | tools/testfiles/h5mkgrp_help.ls | 4 | ||||
-rw-r--r-- | tools/testfiles/h5mkgrp_nested.ls | 10 | ||||
-rw-r--r-- | tools/testfiles/h5mkgrp_nested_latest.ls | 12 | ||||
-rw-r--r-- | tools/testfiles/h5mkgrp_nested_mult.ls | 16 | ||||
-rw-r--r-- | tools/testfiles/h5mkgrp_nested_mult_latest.ls | 20 | ||||
-rw-r--r-- | tools/testfiles/h5mkgrp_several.ls | 10 | ||||
-rw-r--r-- | tools/testfiles/h5mkgrp_several_latest.ls | 12 | ||||
-rw-r--r-- | tools/testfiles/h5mkgrp_single.ls | 7 | ||||
-rw-r--r-- | tools/testfiles/h5mkgrp_single_latest.ls | 8 | ||||
-rw-r--r-- | tools/testfiles/h5mkgrp_version.ls | 4 |
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(¶ms, 0, sizeof(params)); + if(parse_command_line(argc, argv, ¶ms) < 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 |