summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorRobert E. McGrath <mcgrath@ncsa.uiuc.edu>2004-08-05 15:10:39 (GMT)
committerRobert E. McGrath <mcgrath@ncsa.uiuc.edu>2004-08-05 15:10:39 (GMT)
commitf53299c0b33a767f58c9e4fb50b4d7b3f2f0c5c2 (patch)
tree6f904201828a301e670785bada08ad2ea19ad687 /tools
parent5390a63a77772ef0f91a0fd286128be9d5a84e8c (diff)
downloadhdf5-f53299c0b33a767f58c9e4fb50b4d7b3f2f0c5c2.zip
hdf5-f53299c0b33a767f58c9e4fb50b4d7b3f2f0c5c2.tar.gz
hdf5-f53299c0b33a767f58c9e4fb50b4d7b3f2f0c5c2.tar.bz2
[svn-r9019] Purpose:
Adding new 'jam' utility Description: New utility, plus changes to makefiles Solution: See http://hdf.ncsa.uiuc.edu/RFC/Jam Platforms tested: verbena (fortran,C++), arabica, hirdls (SGI Irix64) Misc. update: Manifest will be done in next checkin.
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile.in2
-rw-r--r--tools/h5jam/Dependencies0
-rw-r--r--tools/h5jam/Makefile.in96
-rw-r--r--tools/h5jam/getub.c167
-rw-r--r--tools/h5jam/h5jam.c534
-rw-r--r--tools/h5jam/h5jamgentest.c639
-rw-r--r--tools/h5jam/h5unjam.c314
-rw-r--r--tools/h5jam/tellub.c186
-rw-r--r--tools/h5jam/testh5jam.sh.in527
9 files changed, 2464 insertions, 1 deletions
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 037a107..27b503c 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -20,7 +20,7 @@ srcdir=@srcdir@
## All subdirectories except for the ``lib'' subdirectory.
##
-SUBDIRS=h5dump h5diff h5ls misc gifconv h5import h5repack
+SUBDIRS=h5dump h5diff h5ls misc gifconv h5import h5repack h5jam
## Add include directory to the C preprocessor flags, add -lh5tools and
## -lhdf5 to the list of libraries.
diff --git a/tools/h5jam/Dependencies b/tools/h5jam/Dependencies
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/h5jam/Dependencies
diff --git a/tools/h5jam/Makefile.in b/tools/h5jam/Makefile.in
new file mode 100644
index 0000000..ccb2018
--- /dev/null
+++ b/tools/h5jam/Makefile.in
@@ -0,0 +1,96 @@
+## HDF5 Library Makefile(.in)
+##
+## 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have
+## access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu.
+##
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+@COMMENCE@
+
+## Add include directory to the C preprocessor flags, add -lh5tools and
+## -lhdf5 to the list of libraries.
+##
+CPPFLAGS=-I. -I$(srcdir) -I$(top_builddir)/src -I$(top_srcdir)/src \
+ -I$(top_srcdir)/tools/lib @CPPFLAGS@
+
+## Test programs and scripts.
+##
+TEST_PROGS=
+TEST_SCRIPTS=./testh5jam.sh
+
+OTHER_PROGS=tellub h5jamgentest getub
+## These are our main targets: library and tools.
+##
+LIBTOOLS=../lib/libh5tools.la
+LIBHDF5=$(top_builddir)/src/libhdf5.la
+
+PUB_PROGS=h5jam h5unjam
+
+PROGS=$(PUB_PROGS) $(TEST_PROGS) $(OTHER_PROGS)
+
+## Source and object files for the library; do not install
+##
+LIB_SRC=
+LIB_OBJ=$(LIB_SRC:.c=.lo)
+PUB_LIB=
+
+## Temporary files. *.h5 are generated by jamgentest. They should
+## copied to the testfiles/ directory if update is required.
+MOSTLYCLEAN=*.h5 *.txt
+CLEAN=
+DISTCLEAN=testh5jam.sh
+
+#### FIX AFTER HERE
+
+## Source and object files for programs...
+##
+PROG_SRC=h5jam.c h5unjam.c
+PROG_OBJ=$(PROG_SRC:.c=.lo)
+
+PRIVATE_HDR=
+
+OTHER_SRC=tellub.c h5jamgentest.c getub.c
+OTHER_OBJ=$(OTHER_SRC:.c=.lo)
+
+## Source and object files for the tests (to be cleaned up)
+##
+TEST_SRC=
+TEST_OBJ=$(TEST_SRC:.c=.lo) $(OTHER_OBJ)
+
+## Programs have to be built before they can be tested!
+##
+check test _test: $(PROGS)
+
+## How to build the programs...They all depend on the hdf5 library and
+## the tools library compiled in this directory.
+##
+$(PROGS): $(LIBTOOLS) $(LIBHDF5)
+
+h5jam: h5jam.lo
+ @$(LT_LINK_EXE) $(CFLAGS) -o $@ h5jam.lo $(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS)
+
+h5unjam: h5unjam.lo
+ @$(LT_LINK_EXE) $(CFLAGS) -o $@ h5unjam.lo $(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS)
+
+h5jamgentest: h5jamgentest.lo
+ @$(LT_LINK_EXE) $(CFLAGS) -o $@ h5jamgentest.lo $(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS)
+
+tellub: tellub.lo
+ @$(LT_LINK_EXE) $(CFLAGS) -o $@ tellub.lo $(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS)
+
+getub: getub.lo
+ @$(LT_LINK_EXE) $(CFLAGS) -o $@ getub.lo $(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS)
+
+check-all: check
+
+@CONCLUDE@
diff --git a/tools/h5jam/getub.c b/tools/h5jam/getub.c
new file mode 100644
index 0000000..e2aec5c
--- /dev/null
+++ b/tools/h5jam/getub.c
@@ -0,0 +1,167 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "h5tools_utils.h"
+
+void parse_command_line (int argc, const char *argv[]);
+
+#define TRUE 1
+#define FALSE 0
+
+static char *progname="getub";
+char *nbytes = NULL;
+
+static const char *s_opts = "c:"; /* add more later ? */
+static struct long_options l_opts[] = {
+ {"c", require_arg, 'c'}, /* input file */
+ {NULL, 0, '\0'}
+};
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Print the usage message
+ *
+ * Return: void
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage (const char *prog)
+{
+ fflush (stdout);
+ fprintf (stdout, "usage: %s -c nb file] \n", prog);
+ fprintf (stdout, " print first 'nb' byts of file to stdoug.\n");
+}
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: Parse the command line for the h5dumper.
+ *
+ * Return: Success:
+ *
+ * Failure: Exits program with EXIT_FAILURE value.
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+parse_command_line (int argc, const char *argv[])
+{
+ int opt = FALSE;
+
+ /* parse command line options */
+ while ((opt = get_option (argc, argv, s_opts, l_opts)) != EOF)
+ {
+ switch ((char) opt)
+ {
+ case 'c':
+ nbytes = strdup (opt_arg);
+ break;
+ case '?':
+ default:
+ usage (progname);
+ exit (EXIT_FAILURE);
+ }
+ }
+
+ if (argc <= opt_ind)
+ {
+ error_msg (progname, "missing file name\n");
+ usage (progname);
+ exit (EXIT_FAILURE);
+ }
+}
+
+int
+main (int argc, const char *argv[])
+{
+ int fd;
+ unsigned int size;
+ char *filename;
+ long res;
+ char *buf;
+
+ parse_command_line (argc, argv);
+
+ if (nbytes == NULL)
+ {
+ /* missing arg */
+ error_msg (progname, "missing size\n");
+ usage (progname);
+ exit (EXIT_FAILURE);
+ }
+ if (argc <= (opt_ind))
+ {
+ error_msg (progname, "missing file name\n");
+ usage (progname);
+ exit (EXIT_FAILURE);
+ }
+ filename = strdup (argv[opt_ind]);
+
+ size = 0;
+ res = sscanf (nbytes, "%u", &size);
+ if (res == EOF)
+ {
+ /* fail */
+ error_msg (progname, "missing file name\n");
+ usage (progname);
+ exit (EXIT_FAILURE);
+ }
+
+ fd = open (filename, O_RDONLY);
+ if (fd < 0)
+ {
+ error_msg (progname, "can't open file %s\n", filename);
+ exit (EXIT_FAILURE);
+ }
+
+ buf = malloc ((unsigned)(size + 1));
+ if (buf == NULL)
+ {
+ close (fd);
+ exit (EXIT_FAILURE);
+ }
+
+ res = read (fd, buf, (unsigned)size);
+
+ if (res < size)
+ {
+ if (buf)
+ free (buf);
+ close (fd);
+ exit (EXIT_FAILURE);
+ }
+
+ write (1, buf, (unsigned)size);
+
+ if (buf)
+ free (buf);
+ close (fd);
+ return (EXIT_SUCCESS);
+}
diff --git a/tools/h5jam/h5jam.c b/tools/h5jam/h5jam.c
new file mode 100644
index 0000000..9528b0a
--- /dev/null
+++ b/tools/h5jam/h5jam.c
@@ -0,0 +1,534 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "hdf5.h"
+#include "h5tools_utils.h"
+
+#define TRUE 1
+#define FALSE 0
+
+hsize_t write_pad (int, hsize_t);
+hsize_t compute_user_block_size (hsize_t);
+hsize_t copy_some_to_file (int, int, hsize_t, hsize_t, ssize_t);
+void parse_command_line (int, const char *[]);
+
+const char *progname = "jam";
+int d_status = EXIT_SUCCESS;
+int do_clobber = FALSE;
+char *output_file = NULL;
+char *input_file = NULL;
+char *ub_file = NULL;
+
+/*
+ * Command-line options: The user can specify short or long-named
+ * parameters. The long-named ones can be partially spelled. When
+ * adding more, make sure that they don't clash with each other.
+ */
+static const char *s_opts = "hi:u:o:c"; /* add more later ? */
+static struct long_options l_opts[] = {
+ {"help", no_arg, 'h'},
+ {"hel", no_arg, 'h'},
+ {"i", require_arg, 'i'}, /* input file */
+ {"u", require_arg, 'u'}, /* user block file */
+ {"o", require_arg, 'o'}, /* output file */
+ {"clobber", no_arg, 'c'}, /* clobber existing UB */
+ {"clobbe", no_arg, 'c'},
+ {"clobb", no_arg, 'c'},
+ {"clob", no_arg, 'c'},
+ {"clo", no_arg, 'c'},
+ {"cl", no_arg, 'c'},
+ {NULL, 0, '\0'}
+};
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Print the usage message
+ *
+ * Return: void
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage (const char *prog)
+{
+ fflush (stdout);
+ fprintf (stdout,
+ "usage: %s -u user_block_file -i h5_file [-o ofile | --clobber] \n",
+ prog);
+ fprintf (stdout, " Add 'user_block_file' to front of \n");
+ fprintf (stdout,
+ " 'h5_file', pad so 'h5_file' starts on proper\n");
+ fprintf (stdout, " byte.\n");
+ fprintf (stdout, "\n");
+ fprintf (stdout, " %s -h \n", prog);
+ fprintf (stdout, " Print a usage message and exit\n");
+}
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: Parse the command line for the h5dumper.
+ *
+ * Return: Success:
+ *
+ * Failure: Exits program with EXIT_FAILURE value.
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+parse_command_line (int argc, const char *argv[])
+{
+ int opt = FALSE;
+
+ /* parse command line options */
+ while ((opt = get_option (argc, argv, s_opts, l_opts)) != EOF)
+ {
+ switch ((char) opt)
+ {
+ case 'o':
+ output_file = strdup (opt_arg);
+ break;
+ case 'i':
+ input_file = strdup (opt_arg);
+ break;
+ case 'u':
+ ub_file = strdup (opt_arg);
+ break;
+ case 'c':
+ do_clobber = TRUE;
+ break;
+ case 'h':
+ usage (progname);
+ exit (EXIT_SUCCESS);
+ case '?':
+ default:
+ usage (progname);
+ exit (EXIT_FAILURE);
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: HDF5 user block jammer
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main (int argc, const char *argv[])
+{
+ int ufid;
+ int h5fid;
+ int ofid;
+ void *edata;
+ hid_t (*func) (void *);
+ hid_t ifile;
+ hid_t plist;
+ herr_t status;
+ htri_t testval;
+ hsize_t usize;
+ hsize_t h5fsize;
+ hsize_t startub;
+ hsize_t where;
+ hsize_t newubsize;
+ off_t fsize;
+ struct stat sbuf;
+ struct stat sbuf2;
+ int res;
+
+ /* Disable error reporting */
+ H5Eget_auto (H5E_DEFAULT, &func, &edata);
+ H5Eset_auto (H5E_DEFAULT, NULL, NULL);
+
+ parse_command_line (argc, argv);
+
+ if (ub_file == NULL)
+ {
+ /* no user block */
+ error_msg (progname, "no user block file name\n");
+ usage (progname);
+ exit (EXIT_FAILURE);
+ }
+
+ if (input_file == NULL)
+ {
+ /* no user block */
+ error_msg (progname, "no HDF5 file\n");
+ usage (progname);
+ exit (EXIT_FAILURE);
+ }
+
+ testval = H5Fis_hdf5 (input_file);
+
+ if (testval <= 0)
+ {
+ error_msg (progname, "Input HDF5 file is not HDF \"%s\"\n", input_file);
+ exit (EXIT_FAILURE);
+ }
+
+ ifile = H5Fopen (input_file, H5F_ACC_RDONLY, H5P_DEFAULT);
+
+ if (ifile < 0)
+ {
+ error_msg (progname, "Can't open input HDF5 file \"%s\"\n", input_file);
+ exit (EXIT_FAILURE);
+ }
+
+ plist = H5Fget_create_plist (ifile);
+ if (plist < 0)
+ {
+ error_msg (progname, "Can't get file creation plist for file \"%s\"\n",
+ input_file);
+ exit (EXIT_FAILURE);
+ }
+
+ status = H5Pget_userblock (plist, &usize);
+ if (status < 0)
+ {
+ error_msg (progname, "Can't get user block for file \"%s\"\n",
+ input_file);
+ exit (EXIT_FAILURE);
+ }
+
+ H5Pclose (plist);
+ H5Fclose (ifile);
+
+ ufid = open (ub_file, O_RDONLY);
+
+ if (ufid < 0)
+ {
+ error_msg (progname, "unable to open user block file \"%s\"\n",
+ ub_file);
+ exit (EXIT_FAILURE);
+ }
+
+ res = stat (ub_file, &sbuf);
+
+ if (res < 0)
+ {
+ error_msg (progname, "Can't stat file \"%s\"\n", ub_file);
+ exit (EXIT_FAILURE);
+ }
+
+ fsize = sbuf.st_size;
+
+ h5fid = open (input_file, O_RDONLY);
+
+ if (h5fid < 0)
+ {
+ error_msg (progname, "unable to open HDF5 file for read \"%s\"\n",
+ input_file);
+ exit (EXIT_FAILURE);
+ }
+
+ res = stat (input_file, &sbuf2);
+
+ if (res < 0)
+ {
+ error_msg (progname, "Can't stat file \"%s\"\n", input_file);
+ exit (EXIT_FAILURE);
+ }
+
+ h5fsize = sbuf2.st_size;
+
+ if (output_file == NULL)
+ {
+ ofid = open (input_file, O_WRONLY);
+
+ if (ofid < 0)
+ {
+ error_msg (progname, "unable to open output file \"%s\"\n",
+ output_file);
+ exit (EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ ofid = open (output_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+
+ if (ofid < 0)
+ {
+ error_msg (progname, "unable to create output file \"%s\"\n",
+ output_file);
+ exit (EXIT_FAILURE);
+ }
+ }
+
+ newubsize = compute_user_block_size ((hsize_t) fsize);
+
+ startub = usize;
+
+ if (usize > 0)
+ {
+ if (do_clobber == TRUE)
+ {
+ /* where is max of the current size or the new UB */
+ if (usize > newubsize)
+ {
+ newubsize = usize;
+ }
+ startub = 0; /*blast the old */
+ }
+ else
+ {
+ /* add new ub to current ublock, pad to new offset */
+ newubsize += usize;
+ newubsize = compute_user_block_size ((hsize_t) newubsize);
+ }
+ }
+
+ /* copy the HDF5 from starting at usize to starting at newubsize:
+ * makes room at 'from' for new ub */
+ /* if no current ub, usize is 0 */
+ copy_some_to_file (h5fid, ofid, usize, newubsize,
+ (ssize_t) (h5fsize - usize));
+
+ /* copy the old ub to the beginning of the new file */
+ if (!do_clobber)
+ {
+ where =
+ copy_some_to_file (h5fid, ofid, (hsize_t) 0, (hsize_t) 0,
+ (ssize_t) usize);
+ }
+
+ /* copy the new ub to the end of the ub */
+ where = copy_some_to_file (ufid, ofid, (hsize_t) 0, startub, (ssize_t) - 1);
+
+ /* pad the ub */
+ where = write_pad (ofid, where);
+
+
+ close (ufid);
+ close (h5fid);
+ close (ofid);
+
+ return d_status;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: copy_some_to_file
+ *
+ * Purpose: Copy part of the input file to output.
+ * infid: fd of file to read
+ * outfid: fd of file to write
+ * startin: offset of where to read from infid
+ * startout: offset of where to write to outfid
+ * limit: bytes to read/write
+ *
+ * If limit is < 0, the entire input file is copied.
+ *
+ * Note: this routine can be used to copy within
+ * the same file, i.e., infid and outfid can be the
+ * same file.
+ *
+ * Return: Success: last byte written in the output.
+ * Failure: Exits program with EXIT_FAILURE value.
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t
+copy_some_to_file (int infid, int outfid, hsize_t startin, hsize_t startout,
+ ssize_t limit)
+{
+ char buf[1024];
+ struct stat sbuf;
+ int res;
+ ssize_t tot = 0;
+ ssize_t howmuch = 0;
+ ssize_t nchars = -1;
+/* used in assertion check
+ ssize_t ncw = -1;
+*/
+ ssize_t to;
+ ssize_t from;
+ ssize_t toend;
+ ssize_t fromend;
+
+ if (startin > startout)
+ {
+ /* this case is prohibited */
+ error_msg (progname, "copy_some_to_file: panic: startin > startout?\n");
+ exit (EXIT_FAILURE);
+ }
+
+ if (limit < 0)
+ {
+ res = fstat (infid, &sbuf);
+
+ if (res < 0)
+ {
+ error_msg (progname, "Can't stat file \n");
+ exit (EXIT_FAILURE);
+ }
+
+ howmuch = sbuf.st_size;
+ }
+ else
+ {
+ howmuch = limit;
+ }
+
+ if (howmuch == 0)
+ {
+ return 0;
+ }
+
+ /* assert (howmuch > 0) */
+
+ toend = (ssize_t) startout + howmuch;
+ fromend = (ssize_t) startin + howmuch;
+
+ if (howmuch > 512)
+ {
+ to = toend - 512;
+ from = fromend - 512;
+ }
+ else
+ {
+ to = toend - howmuch;
+ from = fromend - howmuch;
+ }
+
+ while (howmuch > 0)
+ {
+ lseek (outfid, (off_t) to, SEEK_SET);
+ lseek (infid, (off_t) from, SEEK_SET);
+
+ if (howmuch > 512)
+ {
+ nchars = read (infid, buf, (unsigned) 512);
+ }
+ else
+ {
+ nchars = read (infid, buf, howmuch);
+ }
+ if (nchars <= 0)
+ {
+ printf ("huh? \n");
+ exit (1);
+ }
+ /*ncw = */ write (outfid, buf, (unsigned) nchars);
+
+ /* assert (ncw == nchars) */
+
+ tot += nchars;
+ howmuch -= nchars;
+ if (howmuch > 512)
+ {
+ to -= nchars;
+ from -= nchars;
+ }
+ else
+ {
+ to -= howmuch;
+ from -= howmuch;
+ }
+ }
+
+ /* assert howmuch == 0 */
+ /* assert tot == limit */
+
+ return ((hsize_t) tot + (hsize_t) startout);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: compute_user_block_size
+ *
+ * Purpose: Find the offset of the HDF5 header after the user block:
+ * align at 0, 512, 1024, etc.
+ * ublock_size: the size of the user block (bytes).
+ *
+ * Return: Success: the location of the header == the size of the
+ * padded user block.
+ * Failure: none
+ *
+ * Return: Success: last byte written in the output.
+ * Failure: Exits program with EXIT_FAILURE value.
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t
+compute_user_block_size (hsize_t ublock_size)
+{
+ ssize_t where = 512;
+
+ if (ublock_size == 0)
+ return 0;
+
+ while (where < ublock_size)
+ {
+ where *= 2;
+ }
+
+ return (where);
+}
+
+/*
+ * Write zeroes to fill the file from 'where' to 512, 1024, etc. bytes.
+ *
+ * Returns the size of the padded file.
+ */
+hsize_t
+write_pad (int ofile, hsize_t where)
+{
+ unsigned int i;
+ char buf[1];
+ hsize_t psize;
+
+ buf[0] = '\0';
+
+ lseek (ofile, (off_t) where, SEEK_SET);
+
+ psize = compute_user_block_size (where);
+ psize -= where;
+
+ for (i = 0; i < psize; i++)
+ {
+ write (ofile, buf, 1);
+ }
+ return (where + psize); /* the new size of the file. */
+}
diff --git a/tools/h5jam/h5jamgentest.c b/tools/h5jam/h5jamgentest.c
new file mode 100644
index 0000000..e3bf10f
--- /dev/null
+++ b/tools/h5jam/h5jamgentest.c
@@ -0,0 +1,639 @@
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Generate the binary hdf5 files and user block data for the jam/unjam tests.
+ * Usage: just execute the program without any arguments will
+ * generate all the files in the local directory.
+ *
+ * If you regenerate the test files (e.g., changing some code,
+ * trying it on a new platform, ...), you need to verify the correctness
+ * of the expected output and update the corresponding *.ddl files.
+ */
+#include <limits.h>
+
+#include "hdf5.h"
+#include "H5private.h"
+
+#define UBTXT1 "u0.txt"
+#define UBTXT2 "u10.txt"
+#define UBTXT3 "u511.txt"
+#define UBTXT4 "u512.txt"
+#define UBTXT5 "u513.txt"
+/* not used yet
+#define UBTXT6 "u1023.txt"
+#define UBTXT7 "u1024.txt"
+#define UBTXT8 "u1025.txt"
+#define UBTXT9 "u2047.txt"
+#define UBTXT10 "u2048.txt"
+#define UBTXT11 "u2049.txt"
+#define UBBIN1 "u0.dat"
+#define UBBIN2 "u10.dat"
+#define UBBIN3 "u511.dat"
+#define UBBIN4 "u512.dat"
+#define UBBIN5 "u513.dat"
+*/
+
+/* not used yet
+#define FILE1 "tnull.h5"
+#define FILE2 "tnullwithub.h5"
+*/
+/* tall is same as dumper test */
+#define FILE7 "tall.h5"
+#define FILE8 "twithub.h5"
+#define FILE9 "twithub513.h5"
+
+/*
+ * This pattern is used to fill text files
+ */
+char pattern[11] = "abcdefghij";
+
+/*-------------------------------------------------------------------------
+ * prototypes
+ *-------------------------------------------------------------------------
+ */
+
+
+#define LENSTR 50
+#define LENSTR2 11
+
+#define SPACE2_RANK 2
+#define SPACE2_DIM1 10
+#define SPACE2_DIM2 10
+
+#define SPACE1_RANK 1
+#define SPACE1_DIM1 4
+
+#define DIM1 20
+#define DIM2 10
+#define CDIM1 DIM1/2
+#define CDIM2 DIM2/2
+#define RANK 2
+
+/* Element selection information */
+#define POINT1_NPOINTS 10
+
+typedef enum{
+ RED,
+ GREEN,
+ BLUE,
+ WHITE,
+ BLACK
+} enumtype;
+
+/* Compound datatype */
+typedef struct s1_t {
+ unsigned int a;
+ unsigned int b;
+ float c;
+} s1_t;
+
+
+/* 1-D array datatype */
+#define ARRAY1_RANK 1
+#define ARRAY1_DIM1 4
+
+/* 3-D array datatype */
+#define ARRAY2_RANK 3
+#define ARRAY2_DIM1 3
+#define ARRAY2_DIM2 4
+#define ARRAY2_DIM3 5
+
+/* 2-D array datatype */
+#define ARRAY3_RANK 2
+#define ARRAY3_DIM1 6
+#define ARRAY3_DIM2 3
+
+/* VL string datatype name */
+#define VLSTR_TYPE "vl_string_type"
+
+
+/*
+
+/ : g1 g2 attr1 attr2
+g1 : g1.1 g1.2
+g1.1 : dset1.1.1(attr1, attr2) dset1.1.2
+g1.2 : g1.2.1
+g1.2.1 : slink
+g2 : dset2.1 dset2.2
+
+*/
+
+
+static void gent_all(void) {
+hid_t fid, group, attr, dataset, space;
+hsize_t dims[2];
+int data[2][2], dset1[10][10], dset2[20];
+char buf[60];
+int i, j;
+float dset2_1[10], dset2_2[3][5];
+
+ fid = H5Fcreate(FILE7, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+
+ /* create groups */
+ group = H5Gcreate (fid, "/g1", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g2", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g1/g1.1", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g1/g1.2", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g1/g1.2/g1.2.1", 0);
+ H5Gclose(group);
+
+ /* root attributes */
+ group = H5Gopen (fid, "/");
+
+ dims[0] = 10;
+ space = H5Screate_simple(1, dims, NULL);
+ attr = H5Acreate (group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT);
+ sprintf(buf, "abcdefghi");
+ H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ dims[0] = 2; dims[1] = 2;
+ space = H5Screate_simple(2, dims, NULL);
+ attr = H5Acreate (group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT);
+ data[0][0] = 0; data[0][1] = 1; data[1][0] = 2; data[1][1] = 3;
+ H5Awrite(attr, H5T_NATIVE_INT, data);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ H5Gclose(group);
+
+ group = H5Gopen (fid, "/g1/g1.1");
+
+ /* dset1.1.1 */
+ dims[0] = 10; dims[1] = 10;
+ space = H5Screate_simple(2, dims, NULL);
+ dataset = H5Dcreate(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 10; j++)
+ dset1[i][j] = j*i;
+ H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1);
+ H5Sclose(space);
+
+ /* attributes of dset1.1.1 */
+ dims[0] = 27;
+ space = H5Screate_simple(1, dims, NULL);
+ attr = H5Acreate (dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT);
+ sprintf(buf, "1st attribute of dset1.1.1");
+ H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ dims[0] = 27;
+ space = H5Screate_simple(1, dims, NULL);
+ attr = H5Acreate (dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT);
+ sprintf(buf, "2nd attribute of dset1.1.1");
+ H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ H5Dclose(dataset);
+
+ /* dset1.1.2 */
+ dims[0] = 20;
+ space = H5Screate_simple(1, dims, NULL);
+ dataset = H5Dcreate(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 20; i++)
+ dset2[i] = i;
+ H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2);
+ H5Sclose(space);
+ H5Dclose(dataset);
+
+ H5Gclose(group);
+
+ /* soft link */
+ group = H5Gopen (fid, "/g1/g1.2/g1.2.1");
+ H5Glink (group, H5G_LINK_SOFT, "somevalue", "slink");
+ H5Gclose(group);
+
+ group = H5Gopen (fid, "/g2");
+
+ /* dset2.1 */
+ dims[0] = 10;
+ space = H5Screate_simple(1, dims, NULL);
+ dataset = H5Dcreate(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 10; i++)
+ dset2_1[i] = (float)(i*0.1+1);
+ H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1);
+ H5Sclose(space);
+ H5Dclose(dataset);
+
+ /* dset2.2 */
+ dims[0] = 3; dims[1] = 5;
+ space = H5Screate_simple(2, dims, NULL);
+ dataset = H5Dcreate(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 5; j++)
+ dset2_2[i][j] = (float)((i+1)*j*0.1);
+ H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2);
+ H5Sclose(space);
+ H5Dclose(dataset);
+
+ H5Gclose(group);
+
+ H5Fclose(fid);
+
+}
+
+static void gent_withub(void) {
+hid_t fid, group, attr, dataset, space;
+hid_t create_plist;
+hsize_t dims[2];
+int data[2][2], dset1[10][10], dset2[20];
+char buf[512];
+int i, j;
+float dset2_1[10], dset2_2[3][5];
+int fd;
+char *bp;
+
+ create_plist = H5Pcreate(H5P_FILE_CREATE);
+ H5Pset_userblock(create_plist,512);
+ fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT);
+
+ /* create groups */
+ group = H5Gcreate (fid, "/g1", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g2", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g1/g1.1", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g1/g1.2", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g1/g1.2/g1.2.1", 0);
+ H5Gclose(group);
+
+ /* root attributes */
+ group = H5Gopen (fid, "/");
+
+ dims[0] = 10;
+ space = H5Screate_simple(1, dims, NULL);
+ attr = H5Acreate (group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT);
+ sprintf(buf, "abcdefghi");
+ H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ dims[0] = 2; dims[1] = 2;
+ space = H5Screate_simple(2, dims, NULL);
+ attr = H5Acreate (group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT);
+ data[0][0] = 0; data[0][1] = 1; data[1][0] = 2; data[1][1] = 3;
+ H5Awrite(attr, H5T_NATIVE_INT, data);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ H5Gclose(group);
+
+ group = H5Gopen (fid, "/g1/g1.1");
+
+ /* dset1.1.1 */
+ dims[0] = 10; dims[1] = 10;
+ space = H5Screate_simple(2, dims, NULL);
+ dataset = H5Dcreate(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 10; j++)
+ dset1[i][j] = j*i;
+ H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1);
+ H5Sclose(space);
+
+ /* attributes of dset1.1.1 */
+ dims[0] = 27;
+ space = H5Screate_simple(1, dims, NULL);
+ attr = H5Acreate (dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT);
+ sprintf(buf, "1st attribute of dset1.1.1");
+ H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ dims[0] = 27;
+ space = H5Screate_simple(1, dims, NULL);
+ attr = H5Acreate (dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT);
+ sprintf(buf, "2nd attribute of dset1.1.1");
+ H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ H5Dclose(dataset);
+
+ /* dset1.1.2 */
+ dims[0] = 20;
+ space = H5Screate_simple(1, dims, NULL);
+ dataset = H5Dcreate(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 20; i++)
+ dset2[i] = i;
+ H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2);
+ H5Sclose(space);
+ H5Dclose(dataset);
+
+ H5Gclose(group);
+
+ /* soft link */
+ group = H5Gopen (fid, "/g1/g1.2/g1.2.1");
+ H5Glink (group, H5G_LINK_SOFT, "somevalue", "slink");
+ H5Gclose(group);
+
+ group = H5Gopen (fid, "/g2");
+
+ /* dset2.1 */
+ dims[0] = 10;
+ space = H5Screate_simple(1, dims, NULL);
+ dataset = H5Dcreate(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 10; i++)
+ dset2_1[i] = (float)(i*0.1+1);
+ H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1);
+ H5Sclose(space);
+ H5Dclose(dataset);
+
+ /* dset2.2 */
+ dims[0] = 3; dims[1] = 5;
+ space = H5Screate_simple(2, dims, NULL);
+ dataset = H5Dcreate(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 5; j++)
+ dset2_2[i][j] = (float)((i+1)*j*0.1);
+ H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2);
+ H5Sclose(space);
+ H5Dclose(dataset);
+
+ H5Gclose(group);
+
+ H5Fclose(fid);
+
+
+ fd = open(FILE8,O_RDWR);
+ if (fd < 0) {
+ /* panic */
+ }
+ /* fill buf with pattern */
+ memset(buf,'\0',512);
+ bp = buf;
+ for (i = 0; i < strlen(pattern); i++) {
+ *bp++ = pattern[i%10];
+ }
+
+ write(fd,buf,512);
+
+ close(fd);
+}
+
+static void gent_withub513(void) {
+hid_t fid, group, attr, dataset, space;
+hid_t create_plist;
+hsize_t dims[2];
+int data[2][2], dset1[10][10], dset2[20];
+char buf[1023];
+int i, j;
+float dset2_1[10], dset2_2[3][5];
+int fd;
+char *bp;
+
+ create_plist = H5Pcreate(H5P_FILE_CREATE);
+ H5Pset_userblock(create_plist,1024);
+ fid = H5Fcreate(FILE9, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT);
+
+ /* create groups */
+ group = H5Gcreate (fid, "/g1", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g2", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g1/g1.1", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g1/g1.2", 0);
+ H5Gclose(group);
+
+ group = H5Gcreate (fid, "/g1/g1.2/g1.2.1", 0);
+ H5Gclose(group);
+
+ /* root attributes */
+ group = H5Gopen (fid, "/");
+
+ dims[0] = 10;
+ space = H5Screate_simple(1, dims, NULL);
+ attr = H5Acreate (group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT);
+ sprintf(buf, "abcdefghi");
+ H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ dims[0] = 2; dims[1] = 2;
+ space = H5Screate_simple(2, dims, NULL);
+ attr = H5Acreate (group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT);
+ data[0][0] = 0; data[0][1] = 1; data[1][0] = 2; data[1][1] = 3;
+ H5Awrite(attr, H5T_NATIVE_INT, data);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ H5Gclose(group);
+
+ group = H5Gopen (fid, "/g1/g1.1");
+
+ /* dset1.1.1 */
+ dims[0] = 10; dims[1] = 10;
+ space = H5Screate_simple(2, dims, NULL);
+ dataset = H5Dcreate(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 10; j++)
+ dset1[i][j] = j*i;
+ H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1);
+ H5Sclose(space);
+
+ /* attributes of dset1.1.1 */
+ dims[0] = 27;
+ space = H5Screate_simple(1, dims, NULL);
+ attr = H5Acreate (dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT);
+ sprintf(buf, "1st attribute of dset1.1.1");
+ H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ dims[0] = 27;
+ space = H5Screate_simple(1, dims, NULL);
+ attr = H5Acreate (dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT);
+ sprintf(buf, "2nd attribute of dset1.1.1");
+ H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
+ H5Sclose(space);
+ H5Aclose(attr);
+
+ H5Dclose(dataset);
+
+ /* dset1.1.2 */
+ dims[0] = 20;
+ space = H5Screate_simple(1, dims, NULL);
+ dataset = H5Dcreate(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 20; i++)
+ dset2[i] = i;
+ H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2);
+ H5Sclose(space);
+ H5Dclose(dataset);
+
+ H5Gclose(group);
+
+ /* soft link */
+ group = H5Gopen (fid, "/g1/g1.2/g1.2.1");
+ H5Glink (group, H5G_LINK_SOFT, "somevalue", "slink");
+ H5Gclose(group);
+
+ group = H5Gopen (fid, "/g2");
+
+ /* dset2.1 */
+ dims[0] = 10;
+ space = H5Screate_simple(1, dims, NULL);
+ dataset = H5Dcreate(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 10; i++)
+ dset2_1[i] = (float)(i*0.1+1);
+ H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1);
+ H5Sclose(space);
+ H5Dclose(dataset);
+
+ /* dset2.2 */
+ dims[0] = 3; dims[1] = 5;
+ space = H5Screate_simple(2, dims, NULL);
+ dataset = H5Dcreate(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT);
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 5; j++)
+ dset2_2[i][j] = (float)((i+1)*j*0.1);
+ H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2);
+ H5Sclose(space);
+ H5Dclose(dataset);
+
+ H5Gclose(group);
+
+ H5Fclose(fid);
+
+
+ fd = open(FILE9,O_RDWR);
+ if (fd < 0) {
+ /* panic */
+ }
+ /* fill buf with pattern */
+ memset(buf,'\0',1024);
+ bp = buf;
+ for (i = 0; i < 513; i++) {
+ *bp++ = pattern[i%10];
+ }
+
+ write(fd,buf,1024);
+
+ close(fd);
+}
+
+void
+create_textfile(char *name, off_t size) {
+char *buf;
+int fd;
+int i;
+char *bp;
+
+ fd = creat(name,0777);
+ if (fd < 0) {
+ /* panic */
+ }
+ buf = calloc(size,1);
+ if (buf == NULL) {
+ /* panic */
+ }
+ /* fill buf with pattern */
+ bp = buf;
+ for (i = 0; i < size; i++) {
+ *bp++ = pattern[i%10];
+ }
+
+
+ write(fd,buf,size);
+
+ close(fd);
+}
+
+#ifdef notdef
+/* not used yet */
+void
+create_binfile(char *name, off_t size) {
+char *buf;
+int fd;
+int i;
+char *bp;
+
+ fd = creat(name,0777);
+ if (fd < 0) {
+ /* panic */
+ }
+ buf = calloc(size,1);
+ if (buf == NULL) {
+ /* panic */
+ }
+ /* fill buf with pattern */
+ bp = buf;
+ for (i = 0; i < size; i++) {
+ *bp++ = (char) i & 0xff;
+ }
+
+ write(fd,buf,size);
+
+ close(fd);
+}
+#endif
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ *-------------------------------------------------------------------------
+ */
+
+
+int main(void)
+{
+
+/*
+create_textfile(UBTXT1,0);
+*/
+create_textfile(UBTXT2,10);
+create_textfile(UBTXT3,511);
+create_textfile(UBTXT4,512);
+create_textfile(UBTXT5,513);
+/*
+create_textfile(UBTXT6,1023);
+create_textfile(UBTXT7,1024);
+create_textfile(UBTXT8,1025);
+create_textfile(UBTXT9,2047);
+create_textfile(UBTXT10,2048);
+create_textfile(UBTXT11,2049);
+
+create_binfile(UBBIN1,0);
+create_binfile(UBBIN2,10);
+create_binfile(UBBIN3,511);
+create_binfile(UBBIN4,512);
+create_binfile(UBBIN5,513);
+
+*/
+ gent_all();
+ gent_withub();
+ gent_withub513();
+
+ return 0;
+}
diff --git a/tools/h5jam/h5unjam.c b/tools/h5jam/h5unjam.c
new file mode 100644
index 0000000..22c190a
--- /dev/null
+++ b/tools/h5jam/h5unjam.c
@@ -0,0 +1,314 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "hdf5.h"
+#include "h5tools_utils.h"
+
+#define TRUE 1
+#define FALSE 0
+
+hsize_t write_pad( int , hsize_t );
+hsize_t compute_pad( hsize_t );
+hsize_t copy_to_file( int , int , ssize_t, ssize_t );
+
+const char *progname = "unjam";
+int d_status = EXIT_SUCCESS;
+int do_delete = FALSE;
+char *output_file = NULL;
+char *input_file = NULL;
+char *ub_file = NULL;
+
+/*
+ * Command-line options: The user can specify short or long-named
+ * parameters. The long-named ones can be partially spelled. When
+ * adding more, make sure that they don't clash with each other.
+ */
+static const char *s_opts = "hu:i:o:d";
+static struct long_options l_opts[] = {
+ { "help", no_arg, 'h' },
+ { "hel", no_arg, 'h' },
+ {"i", require_arg, 'i'}, /* input file */
+ {"u", require_arg, 'u'}, /* user block file */
+ {"o", require_arg, 'o'}, /* output file */
+ {"delete", no_arg, 'd'}, /* delete ub */
+ {"delet", no_arg, 'd'},
+ {"dele", no_arg, 'd'},
+ {"del", no_arg, 'd'},
+ {"de", no_arg, 'd'},
+ { NULL, 0, '\0' }
+};
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Print the usage message
+ *
+ * Return: void
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage(const char *prog)
+{
+ fflush(stdout);
+ fprintf(stdout, "usage: %s -i h5_file -o user_block_file_out -o h5_file_out [-d | --delete]\n", prog);
+ fprintf(stdout, " Extract user block from 'h5_file' into 'user_block_file'\n");
+ fprintf(stdout, " and HDF5 file into 'h5_file_out'\n");
+
+ fprintf(stdout, " %s -h\n",prog);
+ fprintf(stdout, " Print a usage message and exit\n");
+}
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: Parse the command line for the h5dumper.
+ *
+ * Return: Success:
+ *
+ * Failure: Exits program with EXIT_FAILURE value.
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+parse_command_line(int argc, const char *argv[])
+{
+ int opt = FALSE;
+
+ /* parse command line options */
+ while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) {
+ switch ((char)opt) {
+ case 'o':
+ output_file = strdup (opt_arg);
+ break;
+ case 'i':
+ input_file = strdup (opt_arg);
+ break;
+ case 'u':
+ ub_file = strdup (opt_arg);
+ break;
+ case 'd':
+ do_delete = TRUE;
+ break;
+ case 'h':
+ usage(progname);
+ exit(EXIT_SUCCESS);
+ case '?':
+ default:
+ usage(progname);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* check for file name to be processed */
+/*
+ if (argc <= opt_ind+2) {
+ error_msg(progname, "missing file name\n");
+ usage(progname);
+ exit(EXIT_FAILURE);
+ }
+*/
+}
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: HDF5 user block unjammer
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, const char *argv[])
+{
+ int ifid;
+ int ufid;
+ int h5fid;
+ void *edata;
+ hid_t (*func)(void*);
+ hid_t ifile;
+ off_t fsize;
+ hsize_t usize;
+ htri_t testval;
+ herr_t status;
+ hid_t plist;
+ int res;
+ struct stat sbuf;
+
+ /* Disable error reporting */
+ H5Eget_auto(H5E_DEFAULT, &func, &edata);
+ H5Eset_auto(H5E_DEFAULT, NULL, NULL);
+
+ parse_command_line(argc, argv);
+
+ testval = H5Fis_hdf5(input_file);
+
+ if (testval <= 0) {
+ error_msg(progname, "Input HDF5 file is not HDF \"%s\"\n", input_file);
+ exit(EXIT_FAILURE);
+ }
+
+ ifile = H5Fopen(input_file, H5F_ACC_RDONLY , H5P_DEFAULT);
+
+ if (ifile < 0) {
+ error_msg(progname, "Can't open input HDF5 file \"%s\"\n", input_file);
+ exit(EXIT_FAILURE);
+ }
+
+ plist = H5Fget_create_plist(ifile);
+ if (plist < 0) {
+ error_msg(progname, "Can't get file creation plist for file \"%s\"\n", input_file);
+ exit(EXIT_FAILURE);
+ }
+
+ status = H5Pget_userblock(plist, & usize );
+ if (status < 0) {
+ error_msg(progname, "Can't get user block for file \"%s\"\n", input_file);
+ exit(EXIT_FAILURE);
+ }
+
+ if (usize == 0) {
+ /* no user block to remove: message? */
+ error_msg(progname, "\"%s\" has no user block: no change to file\n", input_file);
+ exit(EXIT_SUCCESS);
+
+ }
+
+ res = stat(input_file, &sbuf);
+
+ if (res < 0) {
+ error_msg(progname, "Can't stat file \"%s\"\n", input_file);
+ exit(EXIT_FAILURE);
+ }
+
+ fsize = sbuf.st_size;
+
+ ifid = open(input_file,O_RDONLY);
+
+ if (ifid < 0) {
+ error_msg(progname, "unable to open input HDF5 file \"%s\"\n", input_file);
+ exit(EXIT_FAILURE);
+ }
+
+ if (do_delete && (ub_file != NULL)) {
+ error_msg(progname, "??\"%s\"\n", ub_file);
+ exit(EXIT_FAILURE);
+ }
+
+ if (ub_file == NULL) {
+ /* write to sdtout */
+ ufid = dup(1);
+ } else {
+ ufid = open(ub_file,O_WRONLY|O_CREAT|O_TRUNC, 0644 );
+
+ if (ufid < 0) {
+ error_msg(progname, "unable to open user block file for output\"%s\"\n", ub_file);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (output_file == NULL) {
+ h5fid = open(input_file,O_WRONLY);
+
+ if (h5fid < 0) {
+ error_msg(progname, "unable to open output HDF5 file \"%s\"\n", input_file);
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ h5fid = open(output_file,O_WRONLY|O_CREAT|O_TRUNC, 0644 );
+
+ if (h5fid < 0) {
+ error_msg(progname, "unable to open output HDF5 file \"%s\"\n", output_file);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+
+ /* copy from 0 to 'usize - 1' into ufid */
+ if (!do_delete) {
+ copy_to_file( ifid, ufid, 0, (ssize_t) usize);
+ }
+
+ /* copy from usize to end of file into h5fid,
+ * starting at end of user block if present
+ */
+ copy_to_file( ifid, h5fid, (ssize_t) usize, (fsize - (ssize_t)usize) );
+
+
+ close(ufid);
+ close(h5fid);
+ close(ifid);
+
+ return d_status;
+}
+
+/*
+ * Copy 'how_much' bytes from the input file to the output file,
+ * starting at byte 'where' in the input file.
+ *
+ * Returns the size of the output file.
+ */
+hsize_t
+copy_to_file( int infid, int ofid, ssize_t where, ssize_t how_much ) {
+ char buf[1024];
+ off_t to;
+ off_t from;
+ ssize_t nchars = -1;
+
+
+ if (how_much <= 0) {
+ /* nothing to copy */
+ return(where);
+ }
+ from = where;
+ to = 0;
+
+ while( how_much > 0) {
+ lseek(infid,from,SEEK_SET);
+ if (how_much > 512) {
+ nchars = read(infid,buf,(unsigned)512);
+ } else {
+ nchars = read(infid,buf,(unsigned)how_much);
+ }
+ lseek(ofid,to,SEEK_SET);
+ write(ofid,buf,(unsigned)nchars);
+ how_much -= nchars;
+ from += nchars;
+ to += nchars;
+ }
+
+ return (where+how_much);
+}
diff --git a/tools/h5jam/tellub.c b/tools/h5jam/tellub.c
new file mode 100644
index 0000000..23d5693
--- /dev/null
+++ b/tools/h5jam/tellub.c
@@ -0,0 +1,186 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "hdf5.h"
+#include "h5tools_utils.h"
+
+#define TRUE 1
+#define FALSE 0
+
+const char *progname = "tellub";
+
+/*
+ * Command-line options: The user can specify short or long-named
+ * parameters. The long-named ones can be partially spelled. When
+ * adding more, make sure that they don't clash with each other.
+ */
+static const char *s_opts = "h";
+static struct long_options l_opts[] = {
+ {"help", no_arg, 'h'},
+ {"hel", no_arg, 'h'},
+ {NULL, 0, '\0'}
+};
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Print the usage message
+ *
+ * Return: void
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage (const char *prog)
+{
+ fflush (stdout);
+ fprintf (stdout, "usage: %s h5_file\n", prog);
+ fprintf (stdout,
+ " Check that h5_fil is HDF5 file and print size of user block \n");
+ fprintf (stdout, " %s -h\n", prog);
+ fprintf (stdout, " Print a usage message and exit\n");
+}
+
+/*-------------------------------------------------------------------------
+ * Function: parse_command_line
+ *
+ * Purpose: Parse the command line for the h5dumper.
+ *
+ * Return: Success:
+ *
+ * Failure: Exits program with EXIT_FAILURE value.
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+parse_command_line (int argc, const char *argv[])
+{
+ int opt = FALSE;
+
+ /* parse command line options */
+ while ((opt = get_option (argc, argv, s_opts, l_opts)) != EOF)
+ {
+ switch ((char) opt)
+ {
+ case 'h':
+ usage (progname);
+ exit (EXIT_SUCCESS);
+ case '?':
+ default:
+ usage (progname);
+ exit (EXIT_FAILURE);
+ }
+ }
+
+ /* check for file name to be processed */
+ if (argc <= opt_ind)
+ {
+ error_msg (progname, "missing file name\n");
+ usage (progname);
+ exit (EXIT_FAILURE);
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: HDF5 user block unjammer
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ * Programmer:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+main (int argc, const char *argv[])
+{
+ char *ifname;
+ void *edata;
+ hid_t (*func) (void *);
+ hid_t ifile;
+ hsize_t usize;
+ htri_t testval;
+ herr_t status;
+ hid_t plist;
+
+ /* Disable error reporting */
+ H5Eget_auto (H5E_DEFAULT, &func, &edata);
+ H5Eset_auto (H5E_DEFAULT, NULL, NULL);
+
+ parse_command_line (argc, argv);
+
+ if (argc <= (opt_ind))
+ {
+ error_msg (progname, "missing file name\n");
+ usage (progname);
+ exit (EXIT_FAILURE);
+ }
+
+ ifname = strdup (argv[opt_ind]);
+
+ testval = H5Fis_hdf5 (ifname);
+
+ if (testval <= 0)
+ {
+ error_msg (progname, "Input HDF5 file is not HDF \"%s\"\n", ifname);
+ exit (EXIT_FAILURE);
+ }
+
+ ifile = H5Fopen (ifname, H5F_ACC_RDONLY, H5P_DEFAULT);
+
+ if (ifile < 0)
+ {
+ error_msg (progname, "Can't open input HDF5 file \"%s\"\n", ifname);
+ exit (EXIT_FAILURE);
+ }
+
+ plist = H5Fget_create_plist (ifile);
+ if (plist < 0)
+ {
+ error_msg (progname, "Can't get file creation plist for file \"%s\"\n",
+ ifname);
+ exit (EXIT_FAILURE);
+ }
+
+ status = H5Pget_userblock (plist, &usize);
+ if (status < 0)
+ {
+ error_msg (progname, "Can't get user block for file \"%s\"\n", ifname);
+ exit (EXIT_FAILURE);
+ }
+
+ printf ("%ld\n", (long) usize);
+
+ H5Pclose (plist);
+ H5Fclose (ifile);
+
+ exit (EXIT_SUCCESS);
+}
diff --git a/tools/h5jam/testh5jam.sh.in b/tools/h5jam/testh5jam.sh.in
new file mode 100644
index 0000000..88e9a7c
--- /dev/null
+++ b/tools/h5jam/testh5jam.sh.in
@@ -0,0 +1,527 @@
+#! /bin/sh
+#
+# 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have
+# access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu.
+#
+# Tests for the h5dump tool
+
+# Determine which filters are available
+USE_FILTER_SZIP="@USE_FILTER_SZIP@"
+USE_FILTER_DEFLATE="@USE_FILTER_DEFLATE@"
+USE_FILTER_SHUFFLE="@USE_FILTER_SHUFFLE@"
+USE_FILTER_FLETCHER32="@USE_FILTER_FLETCHER32@"
+
+DUMPER=h5dump # The dumper to use
+DUMPER_BIN=`pwd`/../$DUMPER # The path of the dumper binary
+JAM=h5jam # Tool to test
+UNJAM=h5unjam # Tool to test
+JAM_BIN=`pwd` # The path of the jam binary
+UNJAM_BIN=`pwd` # The path of the jam binary
+
+CMP='cmp -s'
+DIFF='diff -c'
+AWK='awk'
+
+nerrors=0
+verbose=yes
+
+# The build (current) directory might be different than the source directory.
+if test -z "$srcdir"; then
+ srcdir=.
+fi
+TESTFILES="$srcdir/../testfiles"
+
+#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 "Compare".
+#
+COMPARE() {
+ SPACES=" "
+ echo "Compare $* $SPACES" | cut -c1-70 | tr -d '\012'
+}
+
+# Print a "SKIP" message
+SKIP() {
+ TESTING $JAM $@
+ echo " -SKIP-"
+}
+
+#
+# COMPARE_FILES a.h5 b.h5
+# Compare two files, skipping the first line. This is used to
+# compare the output of the dumper, skipping the file name which
+# is different.
+# The result is stored in 'compval'.
+#
+cmpval=0;
+COMPARE_FILES() {
+ $AWK 'NR > 1' $1 > $1.cmp
+ $AWK 'NR > 1' $2 > $2.cmp
+ $CMP $1.cmp $2.cmp
+ cmpval=$?
+ rm -f $1.cmp $2.cmp
+}
+
+# CLEANUP files
+# Clean up named files.
+CLEANUP() {
+ if test -z "$HDF5_NOCLEANUP"; then
+ for i in $*
+ do
+ rm -f $i
+ done
+ fi
+}
+
+# SETUP file tocopy
+# Clone a standard input file in the test directory
+#
+SETUP() {
+ cp $1 $2
+}
+
+#
+# CHECKFILE orig.h5 compar.h5
+# Check that the test file is the same as an original.
+# The two files are dumped with the dumper, and the output
+# compared with COMPARE_FILES.
+# If the files are the same, the test reports " PASSED",
+# otherwise, it reports "*FAILED*"
+CHECKFILE() {
+ expected="`dirname $2`/`basename $2 .h5`.out"
+ expected_err="`dirname $2`/`basename $2 .h5`.err"
+ actual="`basename $1 .h5`.out"
+ actual_err="`basename $1 .h5`.err"
+
+ $RUNSERIAL $DUMPER_BIN/$DUMPER $1 >$expected 2>$expected_err
+ cat $expected_err >> $expected
+
+ # dump the test file
+ COMPARE $2 to $1
+ $RUNSERIAL $DUMPER_BIN/$DUMPER $2 >$actual 2>$actual_err
+ cat $actual_err >> $actual
+
+ # compare the two files (ignore line 1)
+ COMPARE_FILES $actual $expected
+ if [ "$cmpval" = 0 ] ; then
+ echo " PASSED"
+ else
+ echo "*FAILED*"
+ echo " Expected result (*.ddl) differs from actual result (*.out)"
+ nerrors="`expr $nerrors + 1`"
+ test yes = "$verbose" && $DIFF $expected $actual |sed 's/^/ /'
+ fi
+
+ # Clean up output files
+ if test -z "$HDF5_NOCLEANUP"; then
+ rm -f $actual $actual_err
+ rm -f $expected $expected_err
+ fi
+}
+
+#
+# CHECK_UB file.h5 user_block_file origfile.h5
+#
+# Check the user block in 'file.h5' is the same as
+# 'user_block' (allowing for padding).
+#
+# If the original file had a user block before the test
+# then 'compare.h5' is passed. The user block must be extracted
+# and the test file compared to:
+# cat compare_ub user_block_file.
+#
+# This test uses './getub' to extract the user block from
+# 'file.h5', which is compared to the file described above.
+#
+# The result is set in variable 'result1'.
+#
+result1=0;
+CHECK_UB_1() {
+ hfile="$1"
+ ufile="$2"
+
+ # check for third argument (the original file)
+ origfile="";
+ if [ -n "$3" ];
+ then
+ origfile="$3"
+ fi
+
+ # find the length of the user block to check
+ s1=`cat $ufile | wc -c | sed -e 's/ //g'`
+ if [ "$s1" = "0" ];
+ then
+ echo "File "$ufile" is empty"
+ result1=1;
+ fi
+
+ # Get the size of the original user block, if any.
+ if [ -n "$origfile" ];
+ then
+ # 'tellub' calls H5Fget_user_block to get the size
+ # of the user block
+ s2=`$JAM_BIN/tellub $origfile`
+ if [ "$s2" = "0" ];
+ then
+ size=$s1;
+ cmpfile=$ufile
+ else
+ cmpfile="tt2"
+ size=`expr $s2 + $s1`
+ ./getub -c $s2 $origfile > $cmpfile
+ cat $ufile >> $cmpfile
+ fi
+ else
+ # assume no user block
+ s2="0"
+ size=$s1;
+ cmpfile=$ufile
+ fi
+
+ # Extract 'size' bytes from the front of 'hfile'
+ # Compare to 'cmpfile', result is set in result1
+ tfile="tt1"
+ ./getub -c $size $hfile > $tfile
+ res=`cmp $cmpfile $tfile`
+ if [ "$?" != "0" ];
+ then
+ echo $res
+ result1=1;
+ else
+ result1=0;
+ fi
+
+ # clean up
+ rm -f $tfile
+ if [ "$s2" != "0" ] ;
+ then
+ rm -f $cmpfile
+ fi
+}
+
+
+# CHECK_NOUB file.h5
+#
+# Check that 'file.h5' has no user block.
+# Setst result2 to 1 if there is a user block (fail), 0 if none (pass)
+
+result2=0;
+
+CHECK_NOUB() {
+ hfile="$1"
+
+ # call 'ubsize' to get the size of the user block
+ ubsize=`$JAM_BIN/tellub $hfile`
+
+ if [ "$?" != "0" ];
+ then
+ # error
+ result2=1;
+ else
+ if [ "$ubsize" = "0" ];
+ then
+ # pass
+ result2=0;
+ else
+ # fail
+ result2=1;
+ fi
+ fi
+}
+
+# JAMTEST user_block file.h5 [--clobber] [ofile.h5]
+#
+# Test the 'jam' tool:
+# 1. figure out the input and output, and the comparision
+# that will be done.
+# 2. call 'jam' with the appropriate arguments
+# 3. check the user block is correct in the output (Check_UB)
+# If the user block is correct, print "PASSED", else "*FAILED*"
+JAMTEST() {
+ ufile="$1"
+ ifile="$2"
+ compare_test="" # the file to test
+ compare_orig="" # the comparison to test against
+ cleanup=""
+
+ # sort out the arguments for the test and the check
+ do_clobber="no"
+ if [ "$3" = "--clobber" ];
+ then
+ # clobber overwrites any existing user block
+ do_clobber="yes"
+ clobber="--clobber"
+ compare_orig=""
+ if [ -z "$4" ];
+ then
+ # output goes to infile, compare ubfile to infile
+ ofile=""
+ compare_test="$ifile"
+ else
+ # output goes to $4, compare ofile to ubfile
+ ofile="$4"
+ compare_test="$ofile"
+ fi
+ else
+ clobber=""
+ # add user block to existing ub, if any
+ if [ -z "$3" ];
+ then
+ # output goes to infile, compare ubfile to infile
+ ofile=""
+ compare_test="$ifile"
+ cp $ifile xxofile.h5
+ compare_orig="xxofile.h5"
+ cleanup="$cleanup $compare_orig"
+ else
+ # output goes to $4, compare ofile to ubfile
+ ofile="$3"
+ compare_test="$ofile"
+ compare_orig="$ifile"
+ fi
+ fi
+
+ # call 'jam' with the appropriate arguments
+ if [ -n "$ofile" ];
+ then
+ TESTING h5jam -u `basename $ufile` -i `basename $ifile` -o `basename $ofile` $clobber
+ $JAM_BIN/$JAM -u $ufile -i $ifile -o $ofile $clobber
+ else
+ TESTING jam -u `basename $ufile` -i `basename $ifile` $clobber
+ $JAM_BIN/$JAM -u $ufile -i $ifile $clobber
+ fi
+
+ #echo "CHECK_UB_1 $compare_test $ufile $compare_orig"
+ CHECK_UB_1 $compare_test $ufile $compare_orig
+
+ if [ "$result1" = "0" ] ;
+ then
+ echo " PASSED"
+ else
+ echo " *FAILED*"
+ nerrors="`expr $nerrors + 1`"
+ fi
+ CLEANUP $cleanup
+}
+
+# UNJAMTEST file.h5 [- | --delete] ofile
+#
+# Test the 'unjam' tool
+#
+###fix the working directory here and in jamtest
+UNJAMTEST () {
+ infile="$1"
+ ofile="$3"
+ if [ "$2" = "-" ];
+ then
+ uofile="uofile"
+ TESTING h5unjam -i `basename $infile` -o `basename $ofile` "> "`basename $uofile`
+ $JAM_BIN/$UNJAM -i $infile -o $ofile > $uofile
+ else
+ if [ "$2" = "--delete" ];
+ then
+ uofile="none"
+ TESTING h5unjam -i `basename $infile` -o `basename $ofile` --delete
+ $JAM_BIN/$UNJAM -i $infile -o $ofile --delete
+
+ else
+ uofile="$2"
+ TESTING h5unjam -i `basename $infile` -u `basename $uofile` -o `basename $ofile`
+ $JAM_BIN/$UNJAM -i $infile -u $uofile -o $ofile
+ fi
+ fi
+
+ result1=0
+ result2=0
+ cleanup=""
+ if [ "$uofile" != "none" ];
+ then
+ # sets result1
+ CHECK_UB_1 $infile $uofile
+ CLEANUP $uofile
+ fi
+
+ # sets result2
+ CHECK_NOUB $ofile
+
+ if [ "$result1" = "0" -a "$result2" = "0" ];
+ then
+ echo " PASSED"
+ else
+ echo " *FAILED*"
+ nerrors="`expr $nerrors + 1`"
+ fi
+}
+
+
+##############################################################################
+##############################################################################
+### T H E T E S T S ###
+##############################################################################
+##############################################################################
+
+JAMTEST $TESTFILES/u10.txt $TESTFILES/tall.h5 ta2.h5
+CHECKFILE $TESTFILES/tall.h5 ta2.h5
+CLEANUP ta2.h5
+JAMTEST $TESTFILES/u511.txt $TESTFILES/tall.h5 ta3.h5
+CHECKFILE $TESTFILES/tall.h5 ta3.h5
+CLEANUP ta3.h5
+JAMTEST $TESTFILES/u512.txt $TESTFILES/tall.h5 ta4.h5
+CHECKFILE $TESTFILES/tall.h5 ta4.h5
+CLEANUP ta4.h5
+JAMTEST $TESTFILES/u513.txt $TESTFILES/tall.h5 ta5.h5
+CHECKFILE $TESTFILES/tall.h5 ta5.h5
+CLEANUP ta5.h5
+
+SETUP $TESTFILES/tall.h5 ta.h5
+JAMTEST $TESTFILES/u10.txt ta.h5
+CHECKFILE $TESTFILES/tall.h5 ta.h5
+SETUP $TESTFILES/tall.h5 ta.h5
+JAMTEST $TESTFILES/u511.txt ta.h5
+CHECKFILE $TESTFILES/tall.h5 ta.h5
+SETUP $TESTFILES/tall.h5 ta.h5
+JAMTEST $TESTFILES/u512.txt ta.h5
+CHECKFILE $TESTFILES/tall.h5 ta.h5
+SETUP $TESTFILES/tall.h5 ta.h5
+JAMTEST $TESTFILES/u513.txt ta.h5
+CHECKFILE $TESTFILES/tall.h5 ta.h5
+CLEANUP ta.h5
+
+JAMTEST $TESTFILES/u10.txt $TESTFILES/twithub.h5 tax2.h5
+CHECKFILE $TESTFILES/tall.h5 tax2.h5
+CLEANUP tax2.h5
+JAMTEST $TESTFILES/u511.txt $TESTFILES/twithub.h5 tax3.h5
+CHECKFILE $TESTFILES/tall.h5 tax3.h5
+CLEANUP tax3.h5
+JAMTEST $TESTFILES/u512.txt $TESTFILES/twithub.h5 tax4.h5
+CHECKFILE $TESTFILES/tall.h5 tax4.h5
+CLEANUP tax4.h5
+JAMTEST $TESTFILES/u513.txt $TESTFILES/twithub.h5 tax5.h5
+CHECKFILE $TESTFILES/tall.h5 tax5.h5
+CLEANUP tax5.h5
+
+JAMTEST $TESTFILES/u10.txt $TESTFILES/twithub513.h5 tax6.h5
+CHECKFILE $TESTFILES/tall.h5 tax6.h5
+CLEANUP tax6.h5
+JAMTEST $TESTFILES/u511.txt $TESTFILES/twithub513.h5 tax7.h5
+CHECKFILE $TESTFILES/tall.h5 tax7.h5
+CLEANUP tax7.h5
+JAMTEST $TESTFILES/u512.txt $TESTFILES/twithub513.h5 tax8.h5
+CHECKFILE $TESTFILES/tall.h5 tax8.h5
+CLEANUP tax8.h5
+JAMTEST $TESTFILES/u513.txt $TESTFILES/twithub513.h5 tax9.h5
+CHECKFILE $TESTFILES/tall.h5 tax9.h5
+CLEANUP tax9.h5
+
+JAMTEST $TESTFILES/u10.txt $TESTFILES/twithub.h5 --clobber taz2.h5
+CHECKFILE $TESTFILES/tall.h5 taz2.h5
+CLEANUP taz2.h5
+JAMTEST $TESTFILES/u511.txt $TESTFILES/twithub.h5 --clobber taz3.h5
+CHECKFILE $TESTFILES/tall.h5 taz3.h5
+CLEANUP taz3.h5
+JAMTEST $TESTFILES/u512.txt $TESTFILES/twithub.h5 --clobber taz4.h5
+CHECKFILE $TESTFILES/tall.h5 taz4.h5
+CLEANUP taz4.h5
+JAMTEST $TESTFILES/u513.txt $TESTFILES/twithub.h5 --clobber taz5.h5
+CHECKFILE $TESTFILES/tall.h5 taz5.h5
+CLEANUP taz5.h5
+
+JAMTEST $TESTFILES/u10.txt $TESTFILES/twithub513.h5 --clobber taz6.h5
+CHECKFILE $TESTFILES/tall.h5 taz6.h5
+CLEANUP taz6.h5
+JAMTEST $TESTFILES/u511.txt $TESTFILES/twithub513.h5 --clobber taz7.h5
+CHECKFILE $TESTFILES/tall.h5 taz7.h5
+CLEANUP taz7.h5
+JAMTEST $TESTFILES/u512.txt $TESTFILES/twithub513.h5 --clobber taz8.h5
+CHECKFILE $TESTFILES/tall.h5 taz8.h5
+CLEANUP taz8.h5
+JAMTEST $TESTFILES/u513.txt $TESTFILES/twithub513.h5 --clobber taz9.h5
+CHECKFILE $TESTFILES/tall.h5 taz9.h5
+CLEANUP taz9.h5
+
+SETUP $TESTFILES/twithub.h5 tay2.h5
+JAMTEST $TESTFILES/u10.txt tay2.h5 --clobber
+CHECKFILE $TESTFILES/tall.h5 tay2.h5
+CLEANUP tay2.h5
+SETUP $TESTFILES/twithub.h5 tay3.h5
+JAMTEST $TESTFILES/u511.txt tay3.h5 --clobber
+CHECKFILE $TESTFILES/tall.h5 tay3.h5
+CLEANUP tay3.h5
+SETUP $TESTFILES/twithub.h5 tay4.h5
+JAMTEST $TESTFILES/u512.txt tay4.h5 --clobber
+CHECKFILE $TESTFILES/tall.h5 tay4.h5
+CLEANUP tay4.h5
+SETUP $TESTFILES/twithub.h5 tay5.h5
+JAMTEST $TESTFILES/u513.txt tay5.h5 --clobber
+CHECKFILE $TESTFILES/tall.h5 tay5.h5
+CLEANUP tay5.h5
+
+SETUP $TESTFILES/twithub513.h5 tay6.h5
+JAMTEST $TESTFILES/u10.txt tay6.h5 --clobber
+CHECKFILE $TESTFILES/tall.h5 tay6.h5
+CLEANUP tay6.h5
+SETUP $TESTFILES/twithub513.h5 tay7.h5
+JAMTEST $TESTFILES/u511.txt tay7.h5 --clobber
+CHECKFILE $TESTFILES/tall.h5 tay7.h5
+CLEANUP tay7.h5
+SETUP $TESTFILES/twithub513.h5 tay8.h5
+JAMTEST $TESTFILES/u512.txt tay8.h5 --clobber
+CHECKFILE $TESTFILES/tall.h5 tay8.h5
+CLEANUP tay8.h5
+SETUP $TESTFILES/twithub513.h5 tay9.h5
+JAMTEST $TESTFILES/u513.txt tay9.h5 --clobber
+CHECKFILE $TESTFILES/tall.h5 tay9.h5
+CLEANUP tay9.h5
+
+SETUP $TESTFILES/twithub.h5 tai1.h5
+UNJAMTEST tai1.h5 o10.txt taa1.h5
+CHECKFILE $TESTFILES/tall.h5 taa1.h5
+CLEANUP taa1.h5 tai1.h5 o10.txt
+SETUP $TESTFILES/twithub513.h5 tai2.h5
+UNJAMTEST tai2.h5 o512.txt taa2.h5
+CHECKFILE $TESTFILES/tall.h5 taa2.h5
+CLEANUP taa2.h5 tai2.h5 o512.txt
+
+SETUP $TESTFILES/twithub.h5 tai3.h5
+UNJAMTEST tai3.h5 - taa3.h5
+CHECKFILE $TESTFILES/tall.h5 taa3.h5
+CLEANUP taa3.h5 tai3.h5
+SETUP $TESTFILES/twithub513.h5 tai4.h5
+UNJAMTEST tai4.h5 - taa4.h5
+CHECKFILE $TESTFILES/tall.h5 taa4.h5
+CLEANUP taa4.h5 tai4.h5
+
+SETUP $TESTFILES/twithub.h5 taj2.h5
+UNJAMTEST taj2.h5 --delete tac2.h5
+CHECKFILE $TESTFILES/tall.h5 tac2.h5
+CLEANUP tac2.h5 taj2.h5
+SETUP $TESTFILES/twithub513.h5 taj3.h5
+UNJAMTEST taj3.h5 --delete tac3.h5
+CHECKFILE $TESTFILES/tall.h5 tac3.h5
+CLEANUP tac3.h5 taj3.h5
+
+
+
+if test $nerrors -eq 0 ; then
+ echo "All $JAM tests passed."
+fi
+
+exit $nerrors