summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/h5ls/Dependencies0
-rw-r--r--tools/h5ls/Makefile.in55
-rw-r--r--tools/h5ls/h5ls.c2166
-rwxr-xr-xtools/h5ls/testh5ls.sh143
-rw-r--r--tools/h5toh4/Dependencies0
-rw-r--r--tools/h5toh4/Makefile.in60
-rw-r--r--tools/h5toh4/h5toh4.c2592
-rw-r--r--tools/h5toh4/h5toh4.h43
-rwxr-xr-xtools/h5toh4/testh5toh4.sh299
9 files changed, 5358 insertions, 0 deletions
diff --git a/tools/h5ls/Dependencies b/tools/h5ls/Dependencies
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/h5ls/Dependencies
diff --git a/tools/h5ls/Makefile.in b/tools/h5ls/Makefile.in
new file mode 100644
index 0000000..ba75fcd
--- /dev/null
+++ b/tools/h5ls/Makefile.in
@@ -0,0 +1,55 @@
+## HDF5 Library Makefile(.in)
+##
+## Copyright (C) 2001 National Center for Supercomputing Applications.
+## All rights reserved.
+##
+##
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+SUBDIRS=
+@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=$(srcdir)/testh5ls.sh
+
+## These are our main targets: library and tools.
+##
+LIBTOOLS=../lib/libh5tools.la
+LIBHDF5=$(top_builddir)/src/libhdf5.la
+PUB_PROGS=h5ls
+PROGS=$(PUB_PROGS) $(TEST_PROGS)
+
+## Source and object files for the library; do not install
+LIB_SRC=
+LIB_OBJ=$(LIB_SRC:.c=.lo)
+PUB_LIB=
+
+## Source and object files for programs...
+PROG_SRC=h5ls.c
+PROG_OBJ=$(PROG_SRC:.c=.lo)
+PRIVATE_HDR=
+
+## Source and object files for the tests
+TEST_SRC=
+TEST_OBJ=$(TEST_SRC:.c=.lo)
+
+## 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)
+
+h5ls: h5ls.lo
+ @$(LT_LINK_EXE) $(CFLAGS) -o $@ h5ls.lo $(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS)
+
+@CONCLUDE@
diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c
new file mode 100644
index 0000000..7a6ff39
--- /dev/null
+++ b/tools/h5ls/h5ls.c
@@ -0,0 +1,2166 @@
+/*
+ * Copyright (C) 1998 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Monday, March 23, 1998
+ */
+
+
+/*
+ * We include the private header file so we can get to the uniform
+ * programming environment it declares. Other than that, h5ls only calls
+ * HDF5 API functions (except for H5G_basename())
+ */
+#include <H5private.h>
+#include <h5tools.h>
+
+/*
+ * If defined then include the file name as part of the object name when
+ * printing full object names. Otherwise leave the file name off.
+ */
+#define H5LS_PREPEND_FILENAME
+
+/* Command-line switches */
+static int verbose_g = 0; /*lots of extra output */
+static int width_g = 80; /*output width in characters */
+static hbool_t address_g = FALSE; /*print raw data addresses */
+static hbool_t data_g = FALSE; /*display dataset values? */
+static hbool_t label_g = FALSE; /*label compound values? */
+static hbool_t string_g = FALSE; /*print 1-byte numbers as ASCII? */
+static hbool_t fullname_g = FALSE; /*print full path names */
+static hbool_t recursive_g = FALSE; /*recursive descent listing */
+static hbool_t grp_literal_g = FALSE; /*list group, not contents */
+static hbool_t hexdump_g = FALSE; /*show data as raw hexadecimal */
+static hbool_t show_errors_g = FALSE; /*print HDF5 error messages */
+static hbool_t simple_output_g = FALSE; /*make output more machine-readable */
+
+/* Info to pass to the iteration functions */
+typedef struct iter_t {
+ const char *container; /*full name of the container object */
+} iter_t;
+
+/* Table containing object id and object name */
+static struct {
+ int nalloc; /*number of slots allocated */
+ int nobjs; /*number of objects */
+ struct {
+ unsigned long id[2]; /*object number */
+ char *name; /*full object name */
+ } *obj;
+} idtab_g;
+
+/* Information about how to display each type of object */
+static struct dispatch_t {
+ const char *name;
+ hid_t (*open)(hid_t loc, const char *name);
+ herr_t (*close)(hid_t obj);
+ herr_t (*list1)(hid_t obj);
+ herr_t (*list2)(hid_t obj, const char *name);
+} dispatch_g[H5G_NTYPES];
+
+#define DISPATCH(TYPE,NAME,OPEN,CLOSE,LIST1,LIST2) { \
+ dispatch_g[TYPE].name = (NAME); \
+ dispatch_g[TYPE].open = (OPEN); \
+ dispatch_g[TYPE].close = (CLOSE); \
+ dispatch_g[TYPE].list1 = (LIST1); \
+ dispatch_g[TYPE].list2 = (LIST2); \
+}
+
+static herr_t list (hid_t group, const char *name, void *cd);
+static void display_type(hid_t type, int ind);
+static char *fix_name(const char *path, const char *base);
+
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ * Purpose: Prints a usage message on stderr and then returns.
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Thursday, July 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage (const char *progname)
+{
+ fprintf(stderr, "\
+usage: %s [OPTIONS] [OBJECTS...]\n\
+ OPTIONS\n\
+ -h, -?, --help Print a usage message and exit\n\
+ -a, --address Print addresses for raw data\n\
+ -d, --data Print the values of datasets\n\
+ -e, --errors Show all HDF5 error reporting\n\
+ -f, --full Print full path names instead of base names\n\
+ -g, --group Show information about a group, not its contents\n\
+ -l, --label Label members of compound datasets\n\
+ -r, --recursive List all groups recursively, avoiding cycles\n\
+ -s, --string Print 1-byte integer datasets as ASCII\n\
+ -S, --simple Use a machine-readable output format\n\
+ -wN, --width=N Set the number of columns of output\n\
+ -v, --verbose Generate more verbose output\n\
+ -V, --version Print version number and exit\n\
+ -x, --hexdump Show raw data in hexadecimal format\n\
+\n\
+ OBJECTS\n\
+ Each object consists of an HDF5 file name optionally followed by a\n\
+ slash and an object name within the file (if no object is specified\n\
+ within the file then the contents of the root group are displayed).\n\
+ The file name may include a printf(3C) integer format such as\n\
+ \"%%05d\" to open a file family.\n",
+ progname);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: sym_insert
+ *
+ * Purpose: Add a symbol to the table.
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Thursday, January 21, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+sym_insert(H5G_stat_t *sb, const char *name)
+{
+ int n;
+
+ /*
+ * Don't add it if the link count is 1 because such an object can only
+ * have one name.
+ */
+ if (sb->nlink<2) return;
+
+ /* Extend the table */
+ if (idtab_g.nobjs>=idtab_g.nalloc) {
+ idtab_g.nalloc = MAX(256, 2*idtab_g.nalloc);
+ idtab_g.obj = realloc(idtab_g.obj,
+ idtab_g.nalloc*sizeof(idtab_g.obj[0]));
+ }
+
+ /* Insert the entry */
+ n = idtab_g.nobjs++;
+ idtab_g.obj[n].id[0] = sb->objno[0];
+ idtab_g.obj[n].id[1] = sb->objno[1];
+ idtab_g.obj[n].name = malloc(strlen(name)+1);
+ strcpy(idtab_g.obj[n].name, name);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: sym_lookup
+ *
+ * Purpose: Find another name for the specified object.
+ *
+ * Return: Success: Ptr to another name.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, January 21, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static char *
+sym_lookup(H5G_stat_t *sb)
+{
+ int n;
+
+ if (sb->nlink<2) return NULL; /*only one name possible*/
+ for (n=0; n<idtab_g.nobjs; n++) {
+ if (idtab_g.obj[n].id[0]==sb->objno[0] &&
+ idtab_g.obj[n].id[1]==sb->objno[1]) {
+ return idtab_g.obj[n].name;
+ }
+ }
+ return NULL;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_string
+ *
+ * Purpose: Print a string value by escaping unusual characters. If
+ * STREAM is null then we only count how large the output would
+ * be.
+ *
+ * Return: Number of characters printed.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+display_string(FILE *stream, const char *s, hbool_t escape_spaces)
+{
+ int nprint=0;
+
+ for (/*void*/; s && *s; s++) {
+ switch (*s) {
+ case '"':
+ if (stream) fprintf(stream, "\\\"");
+ nprint += 2;
+ break;
+ case '\\':
+ if (stream) fprintf(stream, "\\\\");
+ nprint += 2;
+ break;
+ case '\b':
+ if (stream) fprintf(stream, "\\b");
+ nprint += 2;
+ break;
+ case '\f':
+ if (stream) fprintf(stream, "\\f");
+ nprint += 2;
+ break;
+ case '\n':
+ if (stream) fprintf(stream, "\\n");
+ nprint += 2;
+ break;
+ case '\r':
+ if (stream) fprintf(stream, "\\r");
+ nprint += 2;
+ break;
+ case '\t':
+ if (stream) fprintf(stream, "\\t");
+ nprint += 2;
+ break;
+ case ' ':
+ if (escape_spaces) {
+ if (stream) fprintf(stream, "\\ ");
+ nprint += 2;
+ } else {
+ if (stream) fprintf(stream, " ");
+ nprint++;
+ }
+ break;
+ default:
+ if (isprint((int)*s)) {
+ if (stream) putc(*s, stream);
+ nprint++;
+ } else {
+ if (stream) {
+ fprintf(stream, "\\%03o", *((const unsigned char*)s));
+ }
+ nprint += 4;
+ }
+ break;
+ }
+ }
+ return nprint;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_native_type
+ *
+ * Purpose: Prints the name of a native C data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ * Robb Matzke, 1999-06-11
+ * Added the C9x types, but we still prefer to display the types
+ * from the C language itself (like `int' vs. `int32_t').
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+display_native_type(hid_t type, int UNUSED ind)
+{
+ if (H5Tequal(type, H5T_NATIVE_SCHAR)) {
+ printf("native signed char");
+ } else if (H5Tequal(type, H5T_NATIVE_UCHAR)) {
+ printf("native unsigned char");
+ } else if (H5Tequal(type, H5T_NATIVE_INT)) {
+ printf("native int");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT)) {
+ printf("native unsigned int");
+ } else if (H5Tequal(type, H5T_NATIVE_SHORT)) {
+ printf("native short");
+ } else if (H5Tequal(type, H5T_NATIVE_USHORT)) {
+ printf("native unsigned short");
+ } else if (H5Tequal(type, H5T_NATIVE_LONG)) {
+ printf("native long");
+ } else if (H5Tequal(type, H5T_NATIVE_ULONG)) {
+ printf("native unsigned long");
+ } else if (H5Tequal(type, H5T_NATIVE_LLONG)) {
+ printf("native long long");
+ } else if (H5Tequal(type, H5T_NATIVE_ULLONG)) {
+ printf("native unsigned long long");
+ } else if (H5Tequal(type, H5T_NATIVE_FLOAT)) {
+ printf("native float");
+ } else if (H5Tequal(type, H5T_NATIVE_DOUBLE)) {
+ printf("native double");
+ } else if (H5Tequal(type, H5T_NATIVE_LDOUBLE)) {
+ printf("native long double");
+ } else if (H5Tequal(type, H5T_NATIVE_INT8)) {
+ printf("native int8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT8)) {
+ printf("native uint8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT16)) {
+ printf("native int16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT16)) {
+ printf("native uint16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT32)) {
+ printf("native int32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT32)) {
+ printf("native uint32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT64)) {
+ printf("native int64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT64)) {
+ printf("native uint64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST8)) {
+ printf("native int_least8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST8)) {
+ printf("native uint_least8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST16)) {
+ printf("native int_least16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST16)) {
+ printf("native uint_least16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST32)) {
+ printf("native int_least32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST32)) {
+ printf("native uint_least32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_LEAST64)) {
+ printf("native int_least64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_LEAST64)) {
+ printf("native uint_least64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST8)) {
+ printf("native int_fast8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST8)) {
+ printf("native uint_fast8_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST16)) {
+ printf("native int_fast16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST16)) {
+ printf("native uint_fast16_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST32)) {
+ printf("native int_fast32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST32)) {
+ printf("native uint_fast32_t");
+ } else if (H5Tequal(type, H5T_NATIVE_INT_FAST64)) {
+ printf("native int_fast64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_UINT_FAST64)) {
+ printf("native uint_fast64_t");
+ } else if (H5Tequal(type, H5T_NATIVE_B8)) {
+ printf("native 8-bit field");
+ } else if (H5Tequal(type, H5T_NATIVE_B16)) {
+ printf("native 16-bit field");
+ } else if (H5Tequal(type, H5T_NATIVE_B32)) {
+ printf("native 32-bit field");
+ } else if (H5Tequal(type, H5T_NATIVE_B64)) {
+ printf("native 64-bit field");
+ } else if (H5Tequal(type, H5T_NATIVE_HSIZE)) {
+ printf("native hsize_t");
+ } else if (H5Tequal(type, H5T_NATIVE_HSSIZE)) {
+ printf("native hssize_t");
+ } else if (H5Tequal(type, H5T_NATIVE_HERR)) {
+ printf("native herr_t");
+ } else if (H5Tequal(type, H5T_NATIVE_HBOOL)) {
+ printf("native hbool_t");
+ } else {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_ieee_type
+ *
+ * Purpose: Print the name of an IEEE floating-point data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+display_ieee_type(hid_t type, int UNUSED ind)
+{
+ if (H5Tequal(type, H5T_IEEE_F32BE)) {
+ printf("IEEE 32-bit big-endian float");
+ } else if (H5Tequal(type, H5T_IEEE_F32LE)) {
+ printf("IEEE 32-bit little-endian float");
+ } else if (H5Tequal(type, H5T_IEEE_F64BE)) {
+ printf("IEEE 64-bit big-endian float");
+ } else if (H5Tequal(type, H5T_IEEE_F64LE)) {
+ printf("IEEE 64-bit little-endian float");
+ } else {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_precision
+ *
+ * Purpose: Prints information on the next line about precision and
+ * padding if the precision is less than the total data type
+ * size.
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+display_precision(hid_t type, int ind)
+{
+ size_t prec; /*precision */
+ H5T_pad_t plsb, pmsb; /*lsb and msb padding */
+ const char *plsb_s=NULL; /*lsb padding string */
+ const char *pmsb_s=NULL; /*msb padding string */
+ size_t nbits; /*number of bits */
+
+ /*
+ * If the precision is less than the total size then show the precision
+ * and offset on the following line. Also display the padding
+ * information.
+ */
+ if (8*H5Tget_size(type)!=(prec=H5Tget_precision(type))) {
+ printf("\n%*s(%lu bit%s of precision beginning at bit %lu)",
+ ind, "", (unsigned long)prec, 1==prec?"":"s",
+ (unsigned long)H5Tget_offset(type));
+
+ H5Tget_pad(type, &plsb, &pmsb);
+ if (H5Tget_offset(type)>0) {
+ switch (plsb) {
+ case H5T_PAD_ZERO:
+ plsb_s = "zero";
+ break;
+ case H5T_PAD_ONE:
+ plsb_s = "one";
+ break;
+ case H5T_PAD_BACKGROUND:
+ plsb_s = "bkg";
+ break;
+ case H5T_PAD_ERROR:
+ case H5T_NPAD:
+ plsb_s = "unknown";
+ break;
+ }
+ }
+ if (H5Tget_offset(type)+prec<8*H5Tget_size(type)) {
+ switch (pmsb) {
+ case H5T_PAD_ZERO:
+ pmsb_s = "zero";
+ break;
+ case H5T_PAD_ONE:
+ pmsb_s = "one";
+ break;
+ case H5T_PAD_BACKGROUND:
+ pmsb_s = "bkg";
+ break;
+ case H5T_PAD_ERROR:
+ case H5T_NPAD:
+ pmsb_s = "unknown";
+ break;
+ }
+ }
+ if (plsb_s || pmsb_s) {
+ printf("\n%*s(", ind, "");
+ if (plsb_s) {
+ nbits = H5Tget_offset(type);
+ printf("%lu %s bit%s at bit 0",
+ (unsigned long)nbits, plsb_s, 1==nbits?"":"s");
+ }
+ if (plsb_s && pmsb_s) printf(", ");
+ if (pmsb_s) {
+ nbits = 8*H5Tget_size(type)-(H5Tget_offset(type)+prec);
+ printf("%lu %s bit%s at bit %lu",
+ (unsigned long)nbits, pmsb_s, 1==nbits?"":"s",
+ (unsigned long)(8*H5Tget_size(type)-nbits));
+ }
+ printf(")");
+ }
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_int_type
+ *
+ * Purpose: Print the name of an integer data type. Common information
+ * like number of bits, byte order, and sign scheme appear on
+ * the first line. Additional information might appear in
+ * parentheses on the following lines.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+display_int_type(hid_t type, int ind)
+{
+ H5T_order_t order; /*byte order value */
+ const char *order_s=NULL; /*byte order string */
+ H5T_sign_t sign; /*sign scheme value */
+ const char *sign_s=NULL; /*sign scheme string */
+
+ if (H5T_INTEGER!=H5Tget_class(type)) return FALSE;
+
+ /* Byte order */
+ if (H5Tget_size(type)>1) {
+ order = H5Tget_order(type);
+ if (H5T_ORDER_LE==order) {
+ order_s = " little-endian";
+ } else if (H5T_ORDER_BE==order) {
+ order_s = " big-endian";
+ } else if (H5T_ORDER_VAX==order) {
+ order_s = " mixed-endian";
+ } else {
+ order_s = " unknown-byte-order";
+ }
+ } else {
+ order_s = "";
+ }
+
+ /* Sign */
+ if ((sign=H5Tget_sign(type))>=0) {
+ if (H5T_SGN_NONE==sign) {
+ sign_s = " unsigned";
+ } else if (H5T_SGN_2==sign) {
+ sign_s = "";
+ } else {
+ sign_s = " unknown-sign";
+ }
+ } else {
+ sign_s = " unknown-sign";
+ }
+
+ /*
+ * Print size, order, and sign on first line, precision and padding
+ * information on the subsequent lines
+ */
+ printf("%lu-bit%s%s integer",
+ (unsigned long)(8*H5Tget_size(type)), order_s, sign_s);
+ display_precision(type, ind);
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_float_type
+ *
+ * Purpose: Print info about a floating point data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+display_float_type(hid_t type, int ind)
+{
+ H5T_order_t order; /*byte order value */
+ const char *order_s=NULL; /*byte order string */
+ size_t spos; /*sign bit position */
+ size_t esize, epos; /*exponent size and position */
+ size_t msize, mpos; /*significand size and position */
+ size_t ebias; /*exponent bias */
+ H5T_norm_t norm; /*significand normalization */
+ const char *norm_s=NULL; /*normalization string */
+ H5T_pad_t pad; /*internal padding value */
+ const char *pad_s=NULL; /*internal padding string */
+
+ if (H5T_FLOAT!=H5Tget_class(type)) return FALSE;
+
+ /* Byte order */
+ if (H5Tget_size(type)>1) {
+ order = H5Tget_order(type);
+ if (H5T_ORDER_LE==order) {
+ order_s = " little-endian";
+ } else if (H5T_ORDER_BE==order) {
+ order_s = " big-endian";
+ } else if (H5T_ORDER_VAX==order) {
+ order_s = " mixed-endian";
+ } else {
+ order_s = " unknown-byte-order";
+ }
+ } else {
+ order_s = "";
+ }
+
+ /*
+ * Print size and byte order on first line, precision and padding on
+ * subsequent lines.
+ */
+ printf("%lu-bit%s floating-point",
+ (unsigned long)(8*H5Tget_size(type)), order_s);
+ display_precision(type, ind);
+
+ /* Print sizes, locations, and other information about each field */
+ H5Tget_fields (type, &spos, &epos, &esize, &mpos, &msize);
+ ebias = H5Tget_ebias(type);
+ norm = H5Tget_norm(type);
+ switch (norm) {
+ case H5T_NORM_IMPLIED:
+ norm_s = ", msb implied";
+ break;
+ case H5T_NORM_MSBSET:
+ norm_s = ", msb always set";
+ break;
+ case H5T_NORM_NONE:
+ norm_s = ", no normalization";
+ break;
+ case H5T_NORM_ERROR:
+ norm_s = ", unknown normalization";
+ break;
+ }
+ printf("\n%*s(significant for %lu bit%s at bit %lu%s)", ind, "",
+ (unsigned long)msize, 1==msize?"":"s", (unsigned long)mpos,
+ norm_s);
+ printf("\n%*s(exponent for %lu bit%s at bit %lu, bias is 0x%lx)",
+ ind, "", (unsigned long)esize, 1==esize?"":"s",
+ (unsigned long)epos, (unsigned long)ebias);
+ printf("\n%*s(sign bit at %lu)", ind, "", (unsigned long)spos);
+
+ /* Display internal padding */
+ if (1+esize+msize<H5Tget_precision(type)) {
+ pad = H5Tget_inpad(type);
+ switch (pad) {
+ case H5T_PAD_ZERO:
+ pad_s = "zero";
+ break;
+ case H5T_PAD_ONE:
+ pad_s = "one";
+ break;
+ case H5T_PAD_BACKGROUND:
+ pad_s = "bkg";
+ break;
+ case H5T_PAD_ERROR:
+ case H5T_NPAD:
+ pad_s = "unknown";
+ break;
+ }
+ printf("\n%*s(internal padding bits are %s)", ind, "", pad_s);
+ }
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_cmpd_type
+ *
+ * Purpose: Print info about a compound data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+display_cmpd_type(hid_t type, int ind)
+{
+ char *name=NULL; /*member name */
+ int ndims; /*dimensionality */
+ hsize_t dims[H5S_MAX_RANK]; /*dimensions */
+ size_t size; /*total size of type in bytes */
+ int perm[H5S_MAX_RANK]; /*index permutation */
+ hid_t subtype; /*member data type */
+ int i, j, n; /*miscellaneous counters */
+
+
+ if (H5T_COMPOUND!=H5Tget_class(type)) return FALSE;
+ printf("struct {");
+ for (i=0; i<H5Tget_nmembers(type); i++) {
+
+ /* Name and offset */
+ name = H5Tget_member_name(type, i);
+ printf("\n%*s\"", ind+4, "");
+ n = display_string(stdout, name, FALSE);
+ printf("\"%*s +%-4lu ", MAX(0, 16-n), "",
+ (unsigned long)H5Tget_member_offset(type, i));
+ free(name);
+
+ /* Grab member's type */
+ subtype = H5Tget_member_type(type, i);
+
+ /* Dimensions and permutation */
+ if(H5Tget_class(subtype)==H5T_ARRAY) {
+ ndims = H5Tget_array_ndims(subtype);
+ H5Tget_array_dims(subtype, dims, perm);
+ } /* end if */
+ else
+ ndims=0;
+
+ if (ndims>0) {
+ printf("[");
+ for (j=0; j<ndims; j++)
+ printf("%s%lu", j?",":"", (unsigned long)(dims[j]));
+ printf("]");
+
+ for (j=0; j<ndims; j++)
+ if (perm[j]!=j)
+ break;
+
+ if (j<ndims) {
+ printf("x[");
+ for (j=0; j<ndims; j++)
+ printf("%s%d", j?",":"", perm[j]);
+ printf("]");
+ }
+ printf(" ");
+ }
+
+ /* Data type */
+ display_type(subtype, ind+4);
+ H5Tclose(subtype);
+ }
+ size = H5Tget_size(type);
+ printf("\n%*s} %lu byte%s",
+ ind, "", (unsigned long)size, 1==size?"":"s");
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_enum_type
+ *
+ * Purpose: Print info about an enumeration data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, December 23, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+display_enum_type(hid_t type, int ind)
+{
+ char **name=NULL; /*member names */
+ unsigned char *value=NULL; /*value array */
+ int nmembs; /*number of members */
+ int nchars; /*number of output characters */
+ hid_t super; /*enum base integer type */
+ hid_t native=-1; /*native integer data type */
+ size_t dst_size; /*destination value type size */
+ int i; /*miscellaneous counters */
+ size_t j;
+
+ if (H5T_ENUM!=H5Tget_class(type)) return FALSE;
+ nmembs = H5Tget_nmembers(type);
+ super = H5Tget_super(type);
+ printf("enum ");
+ display_type(super, ind+4);
+ printf(" {");
+
+ /*
+ * Determine what data type to use for the native values. To simplify
+ * things we entertain three possibilities:
+ * 1. long_long -- the largest native signed integer
+ * 2. unsigned long_long -- the largest native unsigned integer
+ * 3. raw format
+ */
+ if (H5Tget_size(type)<=sizeof(long_long)) {
+ dst_size = sizeof(long_long);
+ if (H5T_SGN_NONE==H5Tget_sign(type)) {
+ native = H5T_NATIVE_ULLONG;
+ } else {
+ native = H5T_NATIVE_LLONG;
+ }
+ } else {
+ dst_size = H5Tget_size(type);
+ }
+
+ /* Get the names and raw values of all members */
+ assert(nmembs>0);
+ name = calloc((size_t)nmembs, sizeof(char*));
+ value = calloc((size_t)nmembs, MAX(H5Tget_size(type), dst_size));
+ for (i=0; i<nmembs; i++) {
+ name[i] = H5Tget_member_name(type, i);
+ H5Tget_member_value(type, i, value+i*H5Tget_size(type));
+ }
+
+ /* Convert values to native data type */
+ if (native>0) H5Tconvert(super, native, (hsize_t)nmembs, value, NULL, H5P_DEFAULT);
+
+ /* Sort members by increasing value */
+ /*not implemented yet*/
+
+ /* Print members */
+ for (i=0; i<nmembs; i++) {
+ printf("\n%*s", ind+4, "");
+ nchars = display_string(stdout, name[i], TRUE);
+ printf("%*s = ", MAX(0, 16-nchars), "");
+
+ if (native<0) {
+ printf("0x");
+ for (j=0; j<dst_size; j++) {
+ printf("%02x", value[i*dst_size+j]);
+ }
+ } else if (H5T_SGN_NONE==H5Tget_sign(native)) {
+ printf("%"PRINTF_LL_WIDTH"u",
+ *((unsigned long_long*)((void*)(value+i*dst_size))));
+ } else {
+ printf("%"PRINTF_LL_WIDTH"d",
+ *((long_long*)((void*)(value+i*dst_size))));
+ }
+ }
+
+ /* Release resources */
+ for (i=0; i<nmembs; i++) free(name[i]);
+ free(name);
+ free(value);
+ H5Tclose(super);
+
+ if (0==nmembs) printf("\n%*s <empty>", ind+4, "");
+ printf("\n%*s}", ind, "");
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_string_type
+ *
+ * Purpose: Print information about a string data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+display_string_type(hid_t type, int UNUSED ind)
+{
+ H5T_str_t pad;
+ const char *pad_s=NULL;
+ H5T_cset_t cset;
+ const char *cset_s=NULL;
+
+ if (H5T_STRING!=H5Tget_class(type)) return FALSE;
+
+ /* Padding */
+ pad = H5Tget_strpad(type);
+ switch (pad) {
+ case H5T_STR_NULLTERM:
+ pad_s = "null-terminated";
+ break;
+ case H5T_STR_NULLPAD:
+ pad_s = "null-padded";
+ break;
+ case H5T_STR_SPACEPAD:
+ pad_s = "space-padded";
+ break;
+ case H5T_STR_RESERVED_3:
+ case H5T_STR_RESERVED_4:
+ case H5T_STR_RESERVED_5:
+ case H5T_STR_RESERVED_6:
+ case H5T_STR_RESERVED_7:
+ case H5T_STR_RESERVED_8:
+ case H5T_STR_RESERVED_9:
+ case H5T_STR_RESERVED_10:
+ case H5T_STR_RESERVED_11:
+ case H5T_STR_RESERVED_12:
+ case H5T_STR_RESERVED_13:
+ case H5T_STR_RESERVED_14:
+ case H5T_STR_RESERVED_15:
+ case H5T_STR_ERROR:
+ pad_s = "unknown-format";
+ break;
+ }
+
+ /* Character set */
+ cset = H5Tget_cset(type);
+ switch (cset) {
+ case H5T_CSET_ASCII:
+ cset_s = "ASCII";
+ break;
+ case H5T_CSET_RESERVED_1:
+ case H5T_CSET_RESERVED_2:
+ case H5T_CSET_RESERVED_3:
+ case H5T_CSET_RESERVED_4:
+ case H5T_CSET_RESERVED_5:
+ case H5T_CSET_RESERVED_6:
+ case H5T_CSET_RESERVED_7:
+ case H5T_CSET_RESERVED_8:
+ case H5T_CSET_RESERVED_9:
+ case H5T_CSET_RESERVED_10:
+ case H5T_CSET_RESERVED_11:
+ case H5T_CSET_RESERVED_12:
+ case H5T_CSET_RESERVED_13:
+ case H5T_CSET_RESERVED_14:
+ case H5T_CSET_RESERVED_15:
+ case H5T_CSET_ERROR:
+ cset_s = "unknown-character-set";
+ break;
+ }
+
+ printf("%lu-byte %s %s string",
+ (unsigned long)H5Tget_size(type), pad_s, cset_s);
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_reference_type
+ *
+ * Purpose: Prints information about a reference data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ * Robb Matzke, 1999-06-04
+ * Knows about object and dataset region references.
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+display_reference_type(hid_t type, int UNUSED ind)
+{
+ if (H5T_REFERENCE!=H5Tget_class(type)) return FALSE;
+
+ if (H5Tequal(type, H5T_STD_REF_OBJ)) {
+ printf("object reference");
+ } else if (H5Tequal(type, H5T_STD_REF_DSETREG)) {
+ printf("dataset region reference");
+ } else {
+ printf("%lu-byte unknown reference",
+ (unsigned long)H5Tget_size(type));
+ }
+
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_opaque_type
+ *
+ * Purpose: Prints information about an opaque data type.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Robb Matzke
+ * Monday, June 7, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+display_opaque_type(hid_t type, int ind)
+{
+ char *tag;
+ size_t size;
+
+ if (H5T_OPAQUE!=H5Tget_class(type)) return FALSE;
+
+ size = H5Tget_size(type);
+ printf("%lu-byte opaque type", (unsigned long)size);
+ if ((tag=H5Tget_tag(type))) {
+ printf("\n%*s(tag = \"", ind, "");
+ display_string(stdout, tag, FALSE);
+ printf("\")");
+ free(tag);
+ }
+ return TRUE;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: display_vlen_type
+ *
+ * Purpose: Print information about a variable-length type
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE
+ *
+ * Programmer: Robb Matzke
+ * Friday, December 1, 2000
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+display_vlen_type(hid_t type, int ind)
+{
+ hid_t super;
+
+ if (H5T_VLEN!=H5Tget_class(type)) return FALSE;
+
+ printf("variable length of\n%*s", ind+4, "");
+ super = H5Tget_super(type);
+ display_type(super, ind+4);
+ H5Tclose(super);
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: display_type
+ *
+ * Purpose: Prints a data type definition. The definition is printed
+ * without any leading space or trailing line-feed (although
+ * there might be line-feeds inside the type definition). The
+ * first line is assumed to have IND characters before it on
+ * the same line (printed by the caller).
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ * Robb Matzke, 1999-06-11
+ * Prints the OID of shared data types.
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+display_type(hid_t type, int ind)
+{
+ H5T_class_t data_class = H5Tget_class(type);
+ H5G_stat_t sb;
+
+ /* Bad data type */
+ if (type<0) {
+ printf("<ERROR>");
+ return;
+ }
+
+ /* Shared? If so then print the type's OID */
+ if (H5Tcommitted(type)) {
+ if (H5Gget_objinfo(type, ".", FALSE, &sb)>=0) {
+ printf("shared-%lu:%lu:%lu:%lu ",
+ sb.fileno[1], sb.fileno[0],
+ sb.objno[1], sb.objno[0]);
+ } else {
+ printf("shared ");
+ }
+ }
+
+ /* Print the type */
+ if (display_native_type(type, ind) ||
+ display_ieee_type(type, ind) ||
+ display_int_type(type, ind) ||
+ display_float_type(type, ind) ||
+ display_cmpd_type(type, ind) ||
+ display_enum_type(type, ind) ||
+ display_string_type(type, ind) ||
+ display_reference_type(type, ind) ||
+ display_vlen_type(type, ind) ||
+ display_opaque_type(type, ind)) {
+ return;
+ }
+
+ /* Unknown type */
+ printf("%lu-byte class-%u unknown",
+ (unsigned long)H5Tget_size(type),
+ (unsigned)data_class);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dump_dataset_values
+ *
+ * Purpose: Prints all values of a dataset.
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, July 21, 1998
+ *
+ * Modifications:
+ * Robb Matzke, 1999-09-27
+ * Understands the simple_output_g switch which causes data to
+ * be displayed in a more machine-readable format.
+ *-------------------------------------------------------------------------
+ */
+static void
+dump_dataset_values(hid_t dset)
+{
+ hid_t f_type = H5Dget_type(dset);
+ size_t size = H5Tget_size(f_type);
+ h5dump_t info;
+ char string_prefix[64];
+ static char fmt_double[16], fmt_float[16];
+
+ /* Set to all default values and then override */
+ memset(&info, 0, sizeof info);
+
+ if (simple_output_g) {
+ info.idx_fmt = "";
+ info.line_ncols = 65535; /*something big*/
+ info.line_per_line = 1;
+ info.line_multi_new = 0;
+ info.line_pre = " ";
+ info.line_cont = " ";
+
+ info.arr_pre = "";
+ info.arr_suf = "";
+ info.arr_sep = " ";
+
+ info.cmpd_pre = "";
+ info.cmpd_suf = "";
+ info.cmpd_sep = " ";
+
+ if (label_g) info.cmpd_name = "%s=";
+
+ info.elmt_suf1 = " ";
+ info.str_locale = ESCAPE_HTML;
+
+ } else {
+ info.idx_fmt = "(%s)";
+ info.line_ncols = width_g;
+ info.line_multi_new = 1;
+ if (label_g) info.cmpd_name = "%s=";
+ info.line_pre = " %s ";
+ info.line_cont = " %s ";
+ info.str_repeat = 8;
+ }
+
+ /* Floating point types should display full precision */
+ sprintf(fmt_float, "%%1.%dg", FLT_DIG);
+ info.fmt_float = fmt_float;
+ sprintf(fmt_double, "%%1.%dg", DBL_DIG);
+ info.fmt_double = fmt_double;
+
+ info.dset_format = "DSET-%lu:%lu:%lu:%lu-";
+ info.dset_hidefileno = 0;
+
+ info.obj_format = "-%lu:%lu:%lu:%lu";
+ info.obj_hidefileno = 0;
+
+ info.dset_blockformat_pre = "%sBlk%lu: ";
+ info.dset_ptformat_pre = "%sPt%lu: ";
+
+ info.line_indent = "";
+
+ if (hexdump_g) {
+ /*
+ * Print all data in hexadecimal format if the `-x' or `--hexdump'
+ * command line switch was given.
+ */
+ info.raw = TRUE;
+ } else if (string_g && 1==size && H5T_INTEGER==H5Tget_class(f_type)) {
+ /*
+ * Print 1-byte integer data as an ASCI character string instead of
+ * integers if the `-s' or `--string' command-line option was given.
+ */
+ info.ascii = TRUE;
+ info.elmt_suf1 = "";
+ info.elmt_suf2 = "";
+ strcpy(string_prefix, info.line_pre);
+ strcat(string_prefix, "\"");
+ info.line_pre = string_prefix;
+ info.line_suf = "\"";
+ }
+
+ /*
+ * Print all the values.
+ */
+ printf(" Data:\n");
+ if (h5dump_dset(stdout, &info, dset, -1, -1)<0) {
+ printf(" Unable to print data.\n");
+ }
+
+ H5Tclose(f_type);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: list_attr
+ *
+ * Purpose: Prints information about attributes.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Friday, June 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+list_attr (hid_t obj, const char *attr_name, void UNUSED *op_data)
+{
+ hid_t attr, space, type, p_type;
+ hsize_t size[64], nelmts=1;
+ int ndims, i, n;
+ size_t need;
+ void *buf;
+ h5dump_t info;
+
+ printf(" Attribute: ");
+ n = display_string(stdout, attr_name, TRUE);
+ printf("%*s", MAX(0, 9-n), "");
+ if ((attr = H5Aopen_name(obj, attr_name))) {
+ space = H5Aget_space(attr);
+ type = H5Aget_type(attr);
+
+ /* Data space */
+ ndims = H5Sget_simple_extent_dims(space, size, NULL);
+ if (0==ndims) {
+ puts(" scalar");
+ } else {
+ printf(" {");
+ for (i=0; i<ndims; i++) {
+ HDfprintf(stdout, "%s%Hu", i?", ":"", size[i]);
+ nelmts *= size[i];
+ }
+ puts("}");
+ }
+
+ /* Data type */
+ printf(" Type: ");
+ display_type(type, 15);
+ putchar('\n');
+
+ /* Data */
+ memset(&info, 0, sizeof info);
+ info.line_multi_new = 1;
+ if (nelmts<5) {
+ info.idx_fmt = "";
+ info.line_1st = " Data: ";
+ info.line_pre = " ";
+ info.line_cont = " ";
+ info.str_repeat = 8;
+
+ } else {
+ printf(" Data:\n");
+ info.idx_fmt = "(%s)";
+ info.line_pre = " %s ";
+ info.line_cont = " %s ";
+ info.str_repeat = 8;
+ }
+ info.line_ncols = width_g;
+ if (label_g) info.cmpd_name = "%s=";
+ if (string_g && 1==H5Tget_size(type) &&
+ H5T_INTEGER==H5Tget_class(type)) {
+ info.ascii = TRUE;
+ info.elmt_suf1 = "";
+ info.elmt_suf2 = "";
+ info.idx_fmt = "(%s)";
+ info.line_pre = " %s \"";
+ info.line_suf = "\"";
+ }
+ if (hexdump_g) {
+ p_type = H5Tcopy(type);
+ } else {
+ p_type = h5dump_fixtype(type);
+ }
+ if (p_type>=0) {
+ need = nelmts * MAX(H5Tget_size(type), H5Tget_size(p_type));
+ buf = malloc(need);
+ assert(buf);
+ if (H5Aread(attr, p_type, buf)>=0) {
+ h5dump_mem(stdout, &info, attr, p_type, space, buf,-1);
+ }
+ free(buf);
+ H5Tclose(p_type);
+ }
+
+ H5Sclose(space);
+ H5Tclose(type);
+ H5Aclose(attr);
+ } else {
+ putchar('\n');
+ }
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dataset_list1
+ *
+ * Purpose: List information about a dataset which should appear on the
+ * same line as the dataset name. This information will precede
+ * information which is applicable to all objects which will be
+ * printed by the caller.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, August 27, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+dataset_list1(hid_t dset)
+{
+ hsize_t cur_size[64]; /*current dataset dimensions */
+ hsize_t max_size[64]; /*maximum dataset dimensions */
+ hid_t space; /*data space */
+ int ndims; /*dimensionality */
+ int i;
+
+ /*
+ * Information that goes on the same row as the name. The name has
+ * already been printed.
+ */
+ space = H5Dget_space(dset);
+ ndims = H5Sget_simple_extent_dims(space, cur_size, max_size);
+ printf (" {");
+ for (i=0; i<ndims; i++) {
+ HDfprintf (stdout, "%s%Hu", i?", ":"", cur_size[i]);
+ if (max_size[i]==H5S_UNLIMITED) {
+ HDfprintf (stdout, "/%s", "Inf");
+ } else if (max_size[i]!=cur_size[i] || verbose_g>0) {
+ HDfprintf(stdout, "/%Hu", max_size[i]);
+ }
+ }
+ if (0==ndims) printf("SCALAR");
+ putchar('}');
+ H5Sclose (space);
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dataset_list2
+ *
+ * Purpose: List information about a dataset which should appear after
+ * information which is general to all objects.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, August 27, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+dataset_list2(hid_t dset, const char UNUSED *name)
+{
+ hid_t dcpl; /*dataset creation property list*/
+ hid_t type; /*data type of dataset */
+ hid_t space; /*data space of dataset */
+ int nf; /*number of filters */
+ unsigned filt_flags; /*filter flags */
+ H5Z_filter_t filt_id; /*filter identification number */
+ unsigned cd_values[20]; /*filter client data values */
+ size_t cd_nelmts; /*filter client number of values*/
+ size_t cd_num; /*filter client data counter */
+ char f_name[256]; /*filter/file name */
+ char s[64]; /*temporary string buffer */
+ off_t f_offset; /*offset in external file */
+ hsize_t f_size; /*bytes used in external file */
+ hsize_t total, used; /*total size or offset */
+ hsize_t chsize[64]; /*chunk size in elements */
+ int ndims; /*dimensionality */
+ int n, max_len; /*max extern file name length */
+ double utilization; /*percent utilization of storage*/
+ int i;
+
+ if (verbose_g>0) {
+ dcpl = H5Dget_create_plist(dset);
+ space = H5Dget_space(dset);
+ type = H5Dget_type(dset);
+
+ /* Print information about chunked storage */
+ if (H5D_CHUNKED==H5Pget_layout(dcpl)) {
+ ndims = H5Pget_chunk(dcpl, NELMTS(chsize), chsize/*out*/);
+ printf(" %-10s {", "Chunks:");
+ total = H5Tget_size(type);
+ for (i=0; i<ndims; i++) {
+ printf("%s%lu", i?", ":"", (unsigned long)(chsize[i]));
+ total *= chsize[i];
+ }
+ printf("} %lu bytes\n", (unsigned long)total);
+ }
+
+ /* Print total raw storage size */
+ used = H5Sget_simple_extent_npoints(space) * H5Tget_size(type);
+ total = H5Dget_storage_size(dset);
+ printf(" %-10s ", "Storage:");
+ printf("%lu logical byte%s, %lu allocated byte%s",
+ (unsigned long)used, 1==used?"":"s",
+ (unsigned long)total, 1==total?"":"s");
+ if (total>0) {
+#ifdef WIN32
+ hsize_t mask = (hsize_t)1 << (8*sizeof(hsize_t)-1);
+ if ((used & mask) || (total & mask)) {
+ total = 0; /*prevent utilization printing*/
+ } else {
+ utilization = (hssize_t)used*100.0 /(hssize_t)total;
+ }
+#else
+ utilization = (used*100.0)/total;
+#endif
+ printf(", %1.2f%% utilization", utilization/*(used*100.0)/total*/);
+ }
+ putchar('\n');
+
+ /* Print information about external strorage */
+ if ((nf = H5Pget_external_count(dcpl))>0) {
+ for (i=0, max_len=0; i<nf; i++) {
+ H5Pget_external(dcpl, i, sizeof(f_name), f_name, NULL, NULL);
+ n = display_string(NULL, f_name, TRUE);
+ max_len = MAX(max_len, n);
+ }
+ printf(" %-10s %d external file%s\n",
+ "Extern:", nf, 1==nf?"":"s");
+ printf(" %4s %10s %10s %10s %s\n",
+ "ID", "DSet-Addr", "File-Addr", "Bytes", "File");
+ printf(" %4s %10s %10s %10s ",
+ "----", "----------", "----------", "----------");
+ for (i=0; i<max_len; i++) putchar('-');
+ putchar('\n');
+ for (i=0, total=0; i<nf; i++) {
+ if (H5Pget_external(dcpl, i, sizeof(f_name), f_name, &f_offset,
+ &f_size)<0) {
+ HDfprintf(stdout,
+ " #%03d %10Hu %10s %10s ***ERROR*** %s\n",
+ i, total, "", "",
+ i+1<nf?"Following addresses are incorrect":"");
+ } else if (H5S_UNLIMITED==f_size) {
+ HDfprintf(stdout, " #%03d %10Hu %10Hu %10s ",
+ i, total, (hsize_t)f_offset, "INF");
+ display_string(stdout, f_name, TRUE);
+ } else {
+ HDfprintf(stdout, " #%03d %10Hu %10Hu %10Hu ",
+ i, total, (hsize_t)f_offset, f_size);
+ display_string(stdout, f_name, TRUE);
+ }
+ putchar('\n');
+ total += f_size;
+ }
+ printf(" %4s %10s %10s %10s ",
+ "----", "----------", "----------", "----------");
+ for (i=0; i<max_len; i++) putchar('-');
+ putchar('\n');
+ }
+
+ /* Print information about raw data filters */
+ if ((nf = H5Pget_nfilters(dcpl))>0) {
+ for (i=0; i<nf; i++) {
+ cd_nelmts = NELMTS(cd_values);
+ filt_id = H5Pget_filter(dcpl, i, &filt_flags, &cd_nelmts,
+ cd_values, sizeof(f_name), f_name);
+ f_name[sizeof(f_name)-1] = '\0';
+ sprintf(s, "Filter-%d:", i);
+ printf(" %-10s %s-%u %s {", s,
+ f_name[0]?f_name:"method",
+ (unsigned)filt_id,
+ filt_flags & H5Z_FLAG_OPTIONAL?"OPT":"");
+ for (cd_num=0; cd_num<cd_nelmts; cd_num++) {
+ printf("%s%u", cd_num?", ":"", cd_values[cd_num]);
+ }
+ printf("}\n");
+ }
+ }
+
+ /* Print data type */
+ printf(" %-10s ", "Type:");
+ display_type(type, 15);
+ printf("\n");
+
+ /* Print address information */
+ if (address_g) H5Ddebug(dset, 0);
+
+ /* Close stuff */
+ H5Tclose(type);
+ H5Sclose(space);
+ H5Pclose(dcpl);
+ }
+
+ if (data_g) dump_dataset_values(dset);
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: group_list2
+ *
+ * Purpose: List information about a group which should appear after
+ * information which is general to all objects.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, January 21, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+group_list2(hid_t grp, const char *name)
+{
+ iter_t iter;
+
+ if (recursive_g) {
+ iter.container = name;
+ H5Giterate(grp, ".", NULL, list, &iter);
+ }
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: datatype_list2
+ *
+ * Purpose: List information about a data type which should appear after
+ * information which is general to all objects.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+datatype_list2(hid_t type, const char UNUSED *name)
+{
+ if (verbose_g>0) {
+ printf(" %-10s ", "Type:");
+ display_type(type, 15);
+ printf("\n");
+ }
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: link_open
+ *
+ * Purpose: This gets called to open a symbolic link. Since symbolic
+ * links don't correspond to actual objects we simply print the
+ * link information and return failure.
+ *
+ * Return: Success: 0 - an invalid object but successful return
+ * of this function.
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, August 27, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+link_open(hid_t location, const char *name)
+{
+ char buf[64];
+
+ if (H5Gget_linkval (location, name, sizeof(buf), buf)<0) return -1;
+ if (NULL==HDmemchr(buf, 0, sizeof(buf))) {
+ strcpy(buf+sizeof(buf)-4, "...");
+ }
+ fputs(buf, stdout);
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: list
+ *
+ * Purpose: Prints the group member name.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Monday, March 23, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+list (hid_t group, const char *name, void *_iter)
+{
+ hid_t obj=-1;
+ char buf[512], comment[50], *fullname=NULL, *s=NULL;
+ H5G_stat_t sb;
+ struct tm *tm;
+ herr_t status;
+ iter_t *iter = (iter_t*)_iter;
+ int n;
+
+ /* Print the object name, either full name or base name */
+ fullname = fix_name(iter->container, name);
+ if (fullname_g) {
+ n = display_string(stdout, fullname, TRUE);
+ printf("%*s ", MAX(0, 24-n), "");
+ } else {
+ n = display_string(stdout, name, TRUE);
+ printf("%*s ", MAX(0, 24-n), "");
+ }
+
+ /* Get object information */
+ H5E_BEGIN_TRY {
+ status = H5Gget_objinfo(group, name, FALSE, &sb);
+ } H5E_END_TRY;
+ if (status<0) {
+ puts("**NOT FOUND**");
+ return 0;
+ } else if (sb.type<0 || sb.type>=H5G_NTYPES) {
+ printf("Unknown type(%d)", sb.type);
+ sb.type = -1;
+ }
+ if (sb.type>=0 && dispatch_g[sb.type].name) {
+ fputs(dispatch_g[sb.type].name, stdout);
+ }
+
+ /*
+ * If the object has already been printed then just show the object ID
+ * and return.
+ */
+ if ((s=sym_lookup(&sb))) {
+ printf(", same as ");
+ display_string(stdout, s, TRUE);
+ printf("\n");
+ goto done;
+ } else {
+ sym_insert(&sb, fullname);
+ }
+
+ /*
+ * Open the object. Not all objects can be opened. If this is the case
+ * then return right away.
+ */
+ if (sb.type>=0 &&
+ (NULL==dispatch_g[sb.type].open ||
+ (obj=(dispatch_g[sb.type].open)(group, name))<0)) {
+ printf(" *ERROR*\n");
+ goto done;
+ }
+
+ /*
+ * List the first line of information for the object.
+ */
+ if (sb.type>=0 && dispatch_g[sb.type].list1) {
+ (dispatch_g[sb.type].list1)(obj);
+ }
+ putchar('\n');
+
+ /*
+ * Show detailed information about the object, beginning with information
+ * which is common to all objects.
+ */
+ if (verbose_g>0 && H5G_LINK!=sb.type) {
+ if (sb.type>=0) H5Aiterate(obj, NULL, list_attr, NULL);
+ printf(" %-10s %lu:%lu:%lu:%lu\n", "Location:",
+ sb.fileno[1], sb.fileno[0], sb.objno[1], sb.objno[0]);
+ printf(" %-10s %u\n", "Links:", sb.nlink);
+ if (sb.mtime>0 && NULL!=(tm=localtime(&(sb.mtime)))) {
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm);
+ printf(" %-10s %s\n", "Modified:", buf);
+ }
+ comment[0] = '\0';
+ H5Gget_comment(group, name, sizeof(comment), comment);
+ strcpy(comment+sizeof(comment)-4, "...");
+ if (comment[0]) {
+ printf(" %-10s \"", "Comment:");
+ display_string(stdout, comment, FALSE);
+ puts("\"");
+ }
+ }
+ if (sb.type>=0 && dispatch_g[sb.type].list2) {
+ (dispatch_g[sb.type].list2)(obj, fullname);
+ }
+
+ /*
+ * Close the object.
+ */
+ done:
+ if (sb.type>=0 && obj>=0 && dispatch_g[sb.type].close) {
+ (dispatch_g[sb.type].close)(obj);
+ }
+ if (fullname) free(fullname);
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: fix_name
+ *
+ * Purpose: Returns a malloc'd buffer that contains the PATH and BASE
+ * names separated by a single slash. It also removes duplicate
+ * and trailing slashes.
+ *
+ * Return: Success: Ptr to fixed name from malloc()
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, January 21, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static char *
+fix_name(const char *path, const char *base)
+{
+ size_t n = (path?strlen(path):0) + (base?strlen(base):0) + 3;
+ char *s = malloc(n), prev='\0';
+ int len=0;
+
+ if (path) {
+ /* Path, followed by slash */
+#ifdef H5LS_PREPEND_FILENAME
+ if ('/'!=*path) s[len++] = '/';
+#endif
+ for (/*void*/; *path; path++) {
+ if ('/'!=*path || '/'!=prev) prev = s[len++] = *path;
+ }
+ if ('/'!=prev) prev = s[len++] = '/';
+ }
+
+ if (base) {
+ /* Base name w/o trailing slashes */
+ const char *end = base + strlen(base);
+ while (end>base && '/'==end[-1]) --end;
+ for (/*void*/; base<end; base++) {
+ if ('/'!=*base || '/'!=prev) prev = s[len++] = *base;
+ }
+ }
+
+ s[len] = '\0';
+ return s;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: get_width
+ *
+ * Purpose: Figure out how wide the screen is. This is highly
+ * unportable, but the user can always override the width we
+ * detect by giving a command-line option. These code snippets
+ * were borrowed from the GNU less(1).
+ *
+ * Return: Success: Number of columns.
+ *
+ * Failure: Some default number of columms.
+ *
+ * Programmer: Robb Matzke
+ * Friday, November 6, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+get_width(void)
+{
+ int width = 80; /*the default */
+ char *s;
+
+ /*
+ * Try to get it from the COLUMNS environment variable first since it's
+ * value is sometimes wrong.
+ */
+ if ((s=getenv("COLUMNS")) && *s && isdigit((int)*s)) {
+ width = (int)strtol(s, NULL, 0);
+ }
+
+#if defined(H5_HAVE_STRUCT_VIDEOCONFIG) && defined(H5_HAVE__GETVIDEOCONFIG)
+ {
+ /* Microsoft C */
+ struct videoconfig w;
+ _getvideoconfig(&w);
+ width = w.numtextcols;
+ }
+#elif defined(H5_HAVE_STRUCT_TEXT_INFO) && defined(H5_HAVE_GETTEXTINFO)
+ {
+ /* Borland C or DJGPPC */
+ struct text_info w;
+ gettextinfo(&w);
+ width = w.screenwidth;
+ }
+#elif defined(H5_HAVE_GETCONSOLESCREENBUFFERINFO)
+ {
+ /* Win32 C */
+ CONSOLE_SCREEN_BUFFER_INFO scr;
+ GetConsoleScreenBufferInfo(con_out, &scr);
+ width = scr.srWindow.Right - scr.srWindow.Left + 1;
+ }
+#elif defined(H5_HAVE__SCRSIZE)
+ {
+ /* OS/2 */
+ int w[2];
+ _scrsize(w);
+ width = w[0];
+ }
+#elif defined(H5_HAVE_TIOCGWINSZ) && defined(H5_HAVE_IOCTL)
+#ifndef __PUMAGON__
+/* the ioctl() call coredump on TFLOPS. Turn it off for now. */
+ {
+ /* Unix with ioctl(TIOCGWINSZ) */
+ struct winsize w;
+ if (ioctl(2, TIOCGWINSZ, &w)>=0 && w.ws_col>0) {
+ width = w.ws_col;
+ }
+ }
+#endif
+#elif defined(H5_HAVE_TIOCGETD) && defined(H5_HAVE_IOCTL)
+ {
+ /* Unix with ioctl(TIOCGETD) */
+ struct uwdata w;
+ if (ioctl(2, WIOCGETD, &w)>=0 && w.uw_width>0) {
+ width = w.uw_width / w.uw_hs;
+ }
+ }
+#endif
+
+ /* Set to at least 1 */
+ if (width<1) width = 1;
+ return width;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Opens a file and lists the specified group
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Robb Matzke
+ * Monday, March 23, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main (int argc, char *argv[])
+{
+ hid_t file=-1, root=-1;
+ char *fname=NULL, *oname=NULL, *x;
+ const char *progname="h5ls";
+ const char *s = NULL;
+ char *rest, *container=NULL;
+ int argno;
+ H5G_stat_t sb;
+ iter_t iter;
+ static char root_name[] = "/";
+ char drivername[50];
+
+ /* Initialize h5tools lib */
+ h5tools_init();
+
+ /* Build display table */
+ DISPATCH(H5G_DATASET, "Dataset", H5Dopen, H5Dclose,
+ dataset_list1, dataset_list2);
+ DISPATCH(H5G_GROUP, "Group", H5Gopen, H5Gclose,
+ NULL, group_list2);
+ DISPATCH(H5G_TYPE, "Type", H5Topen, H5Tclose,
+ NULL, datatype_list2);
+ DISPATCH(H5G_LINK, "-> ", link_open, NULL,
+ NULL, NULL);
+
+#if 0
+ /* Name of this program without the path */
+ if ((progname=strrchr(argv[0], '/'))) progname++;
+ else progname = argv[0];
+#endif
+
+ /* Default output width */
+ width_g = get_width();
+
+ /* Switches come before non-switch arguments */
+ for (argno=1; argno<argc && '-'==argv[argno][0]; argno++) {
+ if (!strcmp(argv[argno], "--")) {
+ /* Last switch */
+ argno++;
+ break;
+ } else if (!strcmp(argv[argno], "--help")) {
+ usage(progname);
+ exit(0);
+ } else if (!strcmp(argv[argno], "--address")) {
+ address_g = TRUE;
+ } else if (!strcmp(argv[argno], "--data")) {
+ data_g = TRUE;
+ } else if (!strcmp(argv[argno], "--errors")) {
+ show_errors_g = TRUE;
+ } else if (!strcmp(argv[argno], "--full")) {
+ fullname_g = TRUE;
+ } else if (!strcmp(argv[argno], "--group")) {
+ grp_literal_g = TRUE;
+ } else if (!strcmp(argv[argno], "--label")) {
+ label_g = TRUE;
+ } else if (!strcmp(argv[argno], "--recursive")) {
+ recursive_g = TRUE;
+ fullname_g = TRUE;
+ } else if (!strcmp(argv[argno], "--simple")) {
+ simple_output_g = TRUE;
+ } else if (!strcmp(argv[argno], "--string")) {
+ string_g = TRUE;
+ } else if (!strncmp(argv[argno], "--width=", 8)) {
+ width_g = (int)strtol(argv[argno]+8, &rest, 0);
+ if (width_g<=0 || *rest) {
+ usage(progname);
+ exit(1);
+ }
+ } else if (!strcmp(argv[argno], "--width")) {
+ if (argno+1>=argc) {
+ usage(progname);
+ exit(1);
+ } else {
+ s = argv[++argno];
+ }
+ width_g = (int)strtol(s, &rest, 0);
+ if (width_g<=0 || *rest) {
+ usage(progname);
+ exit(1);
+ }
+ } else if (!strcmp(argv[argno], "--verbose")) {
+ verbose_g++;
+ } else if (!strcmp(argv[argno], "--version")) {
+ print_version(progname);
+ exit(0);
+ } else if (!strcmp(argv[argno], "--hexdump")) {
+ hexdump_g = TRUE;
+ } else if (!strncmp(argv[argno], "-w", 2)) {
+ if (argv[argno][2]) {
+ s = argv[argno]+2;
+ } else if (argno+1>=argc) {
+ usage(progname);
+ exit(1);
+ } else {
+ s = argv[++argno];
+ }
+ width_g = (int)strtol(s, &rest, 0);
+ if (width_g<=0 || *rest) {
+ usage(progname);
+ exit(1);
+ }
+ } else if ('-'!=argv[argno][1]) {
+ /* Single-letter switches */
+ for (s=argv[argno]+1; *s; s++) {
+ switch (*s) {
+ case '?':
+ case 'h': /* --help */
+ usage(progname);
+ exit(0);
+ case 'a': /* --address */
+ address_g = TRUE;
+ break;
+ case 'd': /* --data */
+ data_g = TRUE;
+ break;
+ case 'e': /* --errors */
+ show_errors_g = TRUE;
+ break;
+ case 'f': /* --full */
+ fullname_g = TRUE;
+ break;
+ case 'g': /* --group */
+ grp_literal_g = TRUE;
+ break;
+ case 'l': /* --label */
+ label_g = TRUE;
+ break;
+ case 'r': /* --recursive */
+ recursive_g = TRUE;
+ fullname_g = TRUE;
+ break;
+ case 'S': /* --simple */
+ simple_output_g = TRUE;
+ break;
+ case 's': /* --string */
+ string_g = TRUE;
+ break;
+ case 'v': /* --verbose */
+ verbose_g++;
+ break;
+ case 'V': /* --version */
+ print_version(progname);
+ exit(0);
+ case 'x': /* --hexdump */
+ hexdump_g = TRUE;
+ break;
+ default:
+ usage(progname);
+ exit(1);
+ }
+ }
+ } else {
+ usage(progname);
+ exit(1);
+ }
+ }
+
+ /*
+ * If no arguments remain then print a usage message (instead of doing
+ * absolutely nothing ;-)
+ */
+ if (argno>=argc) {
+ usage(progname);
+ exit(1);
+ }
+
+ /* Turn off HDF5's automatic error printing unless you're debugging h5ls */
+ if (!show_errors_g) H5Eset_auto(NULL, NULL);
+
+
+ /*
+ * Each remaining argument is an hdf5 file followed by an optional slash
+ * and object name.
+ *
+ * Example: ../dir1/foo/bar/baz
+ * \_________/\______/
+ * file obj
+ *
+ * The dichotomy is determined by calling H5Fopen() repeatedly until it
+ * succeeds. The first call uses the entire name and each subsequent call
+ * chops off the last component. If we reach the beginning of the name
+ * then there must have been something wrong with the file (perhaps it
+ * doesn't exist).
+ */
+ while (argno<argc) {
+ fname = argv[argno++];
+ oname = NULL;
+ file = -1;
+
+ while (fname && *fname) {
+ file = h5dump_fopen(fname, drivername, sizeof drivername);
+ if (file>=0) {
+ if (verbose_g) {
+ printf("Opened \"%s\" with %s driver.\n",
+ fname, drivername);
+ }
+ break; /*success*/
+ }
+
+ /* Shorten the file name; lengthen the object name */
+ x = oname;
+ oname = strrchr(fname, '/');
+ if (x) *x = '/';
+ if (!oname) break;
+ *oname = '\0';
+ }
+ if (file<0) {
+ fprintf(stderr, "%s: unable to open file\n", argv[argno-1]);
+ continue;
+ }
+ if (oname) oname++;
+ if (!oname || !*oname) oname = root_name;
+
+ /* Open the object and display it's information */
+ if (H5Gget_objinfo(file, oname, TRUE, &sb)>=0 &&
+ H5G_GROUP==sb.type && !grp_literal_g) {
+ /*
+ * Specified name is a group. List the complete contents of the
+ * group.
+ */
+ sym_insert(&sb, oname);
+#ifdef H5LS_PREPEND_FILENAME
+ iter.container = container = fix_name(fname, oname);
+#else
+ iter.container = container = fix_name("", oname);
+#endif
+ H5Giterate(file, oname, NULL, list, &iter);
+ free(container);
+
+ } else if ((root=H5Gopen(file, "/"))<0) {
+ exit(1); /*major problem!*/
+
+ } else {
+ /*
+ * Specified name is a non-group object -- list that object. The
+ * container for the object is everything up to the base name.
+ */
+#ifdef H5LS_PREPEND_FILENAME
+ iter.container = fname;
+#else
+ iter.container = "/";
+#endif
+ list(root, oname, &iter);
+ if (H5Gclose(root)<0) exit(1);
+ }
+ H5Fclose(file);
+ }
+ h5tools_close();
+
+ return 0;
+}
diff --git a/tools/h5ls/testh5ls.sh b/tools/h5ls/testh5ls.sh
new file mode 100755
index 0000000..cb3f99f
--- /dev/null
+++ b/tools/h5ls/testh5ls.sh
@@ -0,0 +1,143 @@
+#! /bin/sh
+#
+# Copyright (C) 2001 National Center for Supercomputing Applications
+# All rights reserved.
+#
+# Tests for the h5ls tool
+
+H5LS=h5ls # The tool name
+H5LS_BIN=`pwd`/$H5LS # The path of the tool binary
+
+CMP='cmp -s'
+DIFF='diff -c'
+NLINES=20 # Max. lines of output to display if test fails
+
+nerrors=0
+verbose=yes
+
+# 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'
+}
+
+# Run a test and print PASS or *FAIL*. For now, if h5ls can complete
+# with exit status 0, consider it pass. If a test fails then increment
+# the `nerrors' global variable and (if $verbose is set) display up to $NLINS
+# lines of the actual output from the tool test. The actual output is not
+# removed if $HDF5_NOCLEANUP has a non-zero value.
+# Arguemnts:
+# $1 -- actual output filename to use
+# $2 and on -- argument for the h5ls tool
+TOOLTEST() {
+ expect="$srcdir/../testfiles/$1"
+ actual="../testfiles/`basename $1 .ls`.out"
+ shift
+
+ # Run test.
+ # Stderr is included in stdout so that the diff can detect
+ # any unexpected output from that stream too.
+ TESTING $H5LS $@
+ (
+ echo "#############################"
+ echo " output for '$H5LS $@'"
+ echo "#############################"
+ cd $srcdir/../testfiles
+ $RUNSERIAL $H5LS_BIN "$@"
+ ) >$actual 2>&1
+
+ exitcode=$?
+ if [ $exitcode -ne 0 ]; then
+ echo "*FAILED*"
+ nerrors="`expr $nerrors + 1`"
+ if [ yes = "$verbose" ]; then
+ echo "test returned with exit code $exitcode"
+ echo "test output: (up to $NLINES lines)"
+ head -$NLINES $actual
+ echo "***end of test output***"
+ echo ""
+ fi
+ elif [ ! -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 differs from actual result"
+ nerrors="`expr $nerrors + 1`"
+ test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /'
+ fi
+
+ # Clean up output file
+ if test -z "$HDF5_NOCLEANUP"; then
+ rm -f $actual
+ fi
+}
+
+##############################################################################
+##############################################################################
+### T H E T E S T S ###
+##############################################################################
+##############################################################################
+
+# Toss in a bunch of tests. Not sure if they are the right kinds.
+# test the help syntax
+TOOLTEST help-1.ls -w80 -h
+TOOLTEST help-2.ls -w80 -help
+TOOLTEST help-3.ls -w80 -?
+
+# test simple command
+TOOLTEST tall-1.ls -w80 tall.h5
+TOOLTEST tall-2.ls -w80 -r -d tall.h5
+TOOLTEST tgroup.ls -w80 tgroup.h5
+
+# test for displaying groups
+TOOLTEST tgroup-1.ls -w80 -r -g tgroup.h5
+
+# test for displaying simple space datasets
+TOOLTEST tdset-1.ls -w80 -r -d tdset.h5
+
+# test for displaying soft links
+TOOLTEST tslink-1.ls -w80 -r tslink.h5
+
+# tests for hard links
+TOOLTEST thlink-1.ls -w80 thlink.h5
+
+# tests for compound data types
+TOOLTEST tcomp-1.ls -w80 -r -d tcompound.h5
+
+#test for the nested compound type
+TOOLTEST tnestcomp-1.ls -w80 -r -d tnestedcomp.h5
+
+# test for loop detection
+TOOLTEST tloop-1.ls -w80 -r -d tloop.h5
+
+# test for string
+TOOLTEST tstr-1.ls -w80 -r -d tstr.h5
+
+# test test file created from lib SAF team
+TOOLTEST tsaf.ls -w80 -r -d tsaf.h5
+
+# test for variable length data types
+TOOLTEST tvldtypes1.ls -w80 -r -d tvldtypes1.h5
+
+# test for array data types
+TOOLTEST tarray1.ls -w80 -r -d tarray1.h5
+
+# test for empty data
+TOOLTEST tempty.ls -w80 -d tempty.h5
+
+if test $nerrors -eq 0 ; then
+ echo "All h5ls tests passed."
+fi
+
+exit $nerrors
diff --git a/tools/h5toh4/Dependencies b/tools/h5toh4/Dependencies
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/h5toh4/Dependencies
diff --git a/tools/h5toh4/Makefile.in b/tools/h5toh4/Makefile.in
new file mode 100644
index 0000000..4c529d6
--- /dev/null
+++ b/tools/h5toh4/Makefile.in
@@ -0,0 +1,60 @@
+## HDF5 Library Makefile(.in)
+##
+## Copyright (C) 2001 National Center for Supercomputing Applications.
+## All rights reserved.
+##
+##
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+SUBDIRS=
+@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=@TESTH5TOH4@
+
+## These are our main targets: library and tools.
+##
+LIBTOOLS=../lib/libh5tools.la
+LIBHDF5=$(top_builddir)/src/libhdf5.la
+PUB_PROGS=@H5TOH4@
+PROGS=$(PUB_PROGS) $(TEST_PROGS)
+
+## Source and object files for the library; do not install
+##
+LIB_SRC=
+LIB_OBJ=$(LIB_SRC:.c=.lo)
+PUB_LIB=
+
+## Source and object files for programs...
+##
+PROG_SRC=h5toh4.c
+PROG_OBJ=$(PROG_SRC:.c=.lo)
+PRIVATE_HDR=h5toh4.h
+
+## Source and object files for the tests
+##
+TEST_SRC=
+TEST_OBJ=$(TEST_SRC:.c=.lo)
+
+## 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)
+
+h5toh4: h5toh4.lo
+ @$(LT_LINK_EXE) $(CFLAGS) -o $@ h5toh4.lo $(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS)
+
+@CONCLUDE@
diff --git a/tools/h5toh4/h5toh4.c b/tools/h5toh4/h5toh4.c
new file mode 100644
index 0000000..30b381c
--- /dev/null
+++ b/tools/h5toh4/h5toh4.c
@@ -0,0 +1,2592 @@
+/******************************************************************************
+
+ Description: This file contains routines to translate H5 files to H4 files.
+
+ Author: Paul Harten for the University of Illinois, NCSA
+
+ Creation Date: 04 October 1998
+
+ History:
+
+
+*****************************************************************************/
+
+#include "h5toh4.h"
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <h5tools.h>
+
+
+#ifdef WIN32
+typedef unsigned int mode_t;
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(mode) (((mode)&0xF000) == S_IFDIR)
+#endif
+extern void PrintOptions_h5toh4(void);
+extern char *BuildFilename(char *h5_filename, char *h4_extension);
+extern int test_file(char *filename, int oflag, mode_t mode);
+extern int test_dir(char *);
+extern int h5toh4(char *, char *);
+
+extern herr_t convert_group(hid_t, char *, op_data_t *);
+extern herr_t convert_dataset(hid_t, char *, op_data_t *);
+extern herr_t convert_all(hid_t, char *, op_data_t *);
+extern herr_t convert_attr(hid_t, char *, op_data_t *);
+extern herr_t convert_shared_dataset(hid_t, int, op_data_t *);
+extern herr_t convert_shared_group(hid_t, int, op_data_t *);
+extern herr_t convert_dataset_string(hid_t, char *, op_data_t *);
+extern int32 h5type_to_h4type(hid_t);
+extern hid_t h4type_to_memtype(int32);
+
+extern void free_table(table_t **temp);
+extern void dump_tables(char* name, table_t* table);
+extern int get_table_idx(table_t*, unsigned long *);
+extern int get_tableflag(table_t*, int);
+extern int set_tableflag(table_t*, int);
+extern char* get_objectname(table_t*, int);
+
+typedef herr_t (*H5G_operator_t)(hid_t, const char*, void*);
+
+static int prefix_len = 1024;
+static char *prefix;
+static table_t *group_table, *dset_table, *type_table;
+
+static herr_t h5atomic_type_to_h4type(const hid_t h5type, hid_t* h5memtype, size_t* h5memsize, int32* h4type);
+
+
+/*****************************************************************************
+
+ Routine: main()
+
+ Description: This routine check out arguments sent, makes sure everything is
+ ok, chooses between the acceptable argument formats and then
+ calls h5toh4().
+
+ Input: arg - the number of arguments from the call + 1;
+ argv - a pointer to an array of strings which are the arguments.
+ This includes the routine name as the first string.
+
+ Output: function return - error status
+
+*****************************************************************************/
+
+int
+main(int argc, char *argv[])
+{
+ char *h5_filename=NULL;
+ char *h4_filename=NULL;
+ char *h4_extension;
+ int status = 0;
+ int status2 = 0;
+
+
+ argc--;
+ argv++;
+
+ if (argc == 0) {
+ fprintf(stderr,"\nError: Invalid Arguments\n");
+ PrintOptions_h5toh4();
+ return -1;
+ }
+
+ /* take care -h (help) option first */
+ { int i;
+ for (i=0; i < argc; i++)
+ if ( HDstrcmp(argv[i],"-h") == 0 ) {
+ PrintOptions_h5toh4();
+ return 0;
+ }
+ }
+
+ /*fargv = argv; */
+
+ /* Change -m with 1 filename to as 1 filename case */
+ if (argc == 2 && HDstrcmp(argv[0],"-m") == 0) {
+ argv++;
+ argc--;
+ }
+
+ switch(argc) {
+
+ case 0:
+
+ PrintOptions_h5toh4();
+ break;
+
+ case 1: /* h5toh4 file1 */
+ h5_filename = argv[0];
+
+ if (HDstrcmp(h5_filename,"-m") == 0) {
+ fprintf(stderr,"\nError: Invalid Arguments\n");
+ PrintOptions_h5toh4();
+ status = -1;
+ break;
+ }
+#ifndef WIN32
+ if (test_file(h5_filename,O_EXCL,(mode_t)(S_IRUSR|S_IRGRP|S_IROTH)) != 0 ) { /* 292 Decimal - 0444 Octal, a+r */
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status = -1;
+ break;
+ }
+ if (test_dir(h5_filename) != 0 ) {
+ fprintf(stderr,"%s: Is a directory\n",h5_filename);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status = -1;
+ break;
+ }
+#endif
+ h4_extension = HDstrdup("hdf");
+
+ h4_filename = BuildFilename(h5_filename,h4_extension);
+ if (h4_filename == NULL) {
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status = -1;
+ break;
+ }
+#ifndef WIN32
+ if (test_file(h4_filename,O_CREAT|O_EXCL,(mode_t)(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH)) != 0) { /* 436 Decimal - 0664 Octal, ug+rw,o+r */
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status = -1;
+ break;
+ }
+#endif
+ status = h5toh4(h5_filename, h4_filename);
+ if ( status != 0 ) {
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ }
+ if (h4_filename != NULL) {
+ HDfree(h4_filename);
+ }
+
+ break;
+
+ case 2: /* h5toh4 file_in file_out */
+ h5_filename = argv[0];
+ h4_filename = argv[1];
+
+ if (HDstrcmp(h4_filename,"-m") == 0) {
+ fprintf(stderr,"\nError: Invalid Arguments\n");
+ PrintOptions_h5toh4();
+ status = -1;
+ break;
+ }
+#ifndef WIN32
+ if (test_file(h5_filename,O_EXCL,292) != 0 ) { /* 292 Decimal - 0444 Octal, a+r */
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status = -1;
+ break;
+ }
+ if (test_dir(h5_filename) != 0 ) {
+ fprintf(stderr,"%s: Is a directory\n",h5_filename);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status = -1;
+ break;
+ }
+ if (test_file(h4_filename,O_CREAT|O_RDWR,436) != 0) { /* 436 Decimal - 0664 Octal, ug+rw,o+r */
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status = -1;
+ break;
+ }
+ if (test_dir(h4_filename) != 0 ) {
+ fprintf(stderr,"%s: Is a directory\n",h4_filename);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status = -1;
+ break;
+ }
+#endif
+ status = h5toh4(h5_filename, h4_filename);
+ if ( status != 0 ) {
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ }
+ break;
+
+ default: /* h5toh4 -m file1 file2 file3 ... */
+ if (HDstrcmp(argv[0],"-m") != 0) {
+ fprintf(stderr,"\nError: Invalid Arguments\n");
+ PrintOptions_h5toh4();
+ status = -1;
+ break;
+ }
+ argv++;
+ argc--;
+
+ while ( argc > 0 ) {
+ h5_filename = argv[0];
+ argv++;
+ argc--;
+
+ if (HDstrcmp(h5_filename,"-m") == 0) {
+ fprintf(stderr,"\nError: Invalid Arguments\n");
+ PrintOptions_h5toh4();
+ status2 = -1;
+ break;
+ }
+#ifndef WIN32
+ if (test_file(h5_filename,O_EXCL,292) != 0 ) { /* 292 Decimal - 0444 Octal, a+r */
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status2 = -1;
+ continue;
+ }
+ if (test_dir(h5_filename) != 0 ) {
+ fprintf(stderr,"%s: Is a directory\n",h5_filename);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status2 = -1;
+ continue;
+ }
+#endif
+ h4_extension = HDstrdup("hdf");
+
+ h4_filename = BuildFilename(h5_filename,h4_extension);
+ if (h4_filename == NULL) {
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status2 = -1;
+ continue;
+ }
+#ifndef WIN32
+ if (test_file(h4_filename,O_CREAT|O_EXCL,436) != 0) { /* 436 Decimal - 0664 Octal, ug+rw,o+r */
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status2 = -1;
+ continue;
+ }
+#endif
+ status = h5toh4(h5_filename, h4_filename);
+ if ( status != 0 ) {
+ fprintf(stderr,"Error: Problem with %s\n",h5_filename);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "main", __FILE__, __LINE__);
+ status2 = status;
+ }
+ if (h4_filename != NULL) {
+ HDfree(h4_filename);
+ }
+
+ }
+ status = status2;
+ break;
+ }
+
+ return status;
+
+}
+
+
+/*****************************************************************************
+
+ Routine: PrintOptions_h5toh4()
+
+ Description: This routine prints the acceptable argument formats out to stderr.
+
+ Input: None
+
+ Output: output to stderr
+
+*****************************************************************************/
+
+void PrintOptions_h5toh4(void)
+{
+ fprintf(stderr,"\nh5toh4 -h (gives this print-out)\n");
+ fprintf(stderr,"h5toh4 file.h5 file.hdf\n");
+ fprintf(stderr,"h5toh4 file.h5\n");
+ fprintf(stderr,"h5toh4 -m file1.h5 file2.h5 ...\n\n");
+}
+
+
+/*****************************************************************************
+
+ Routine: h5toh4()
+
+ Description: This routine translates information from a HDF5 file into a
+ HDF4 file.
+
+ Input: h5_filename - filename of HDF5 file,
+ h4_filename - filename of HDF4 file
+
+ Output: function return - error status
+
+*****************************************************************************/
+
+int h5toh4(char *h5_filename, char *h4_filename)
+{
+
+ hid_t fid, gid;
+ hid_t plist=H5P_DEFAULT;
+ int status = 0;
+ int32 hfile_id;
+ int32 sd_id;
+ op_data_t op_data;
+ void *edata;
+ hid_t (*func)(void*);
+
+
+ find_objs_t *info = malloc(sizeof(find_objs_t));
+
+
+
+ /* open hdf5 file */
+ if ((fid = H5Fopen (h5_filename, H5F_ACC_RDONLY, plist)) <= 0) {
+ fprintf(stderr,"Error: Unable to open file %s\n",h5_filename);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ return (fid);
+ }
+
+ /* open root group */
+ if ((gid = H5Gopen (fid, "/")) <= 0 ) {
+ fprintf(stderr,"Error: Unable to open root group\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ return (gid);
+ } else {
+
+ /* open hdf4 file */
+ if ((hfile_id = Hopen(h4_filename, DFACC_CREATE, 0)) <= 0) {
+ fprintf(stderr,"Error: Unable to open file %s\n", h4_filename);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ return (hfile_id);
+ } else {
+
+ if ((sd_id = SDstart(h4_filename, DFACC_RDWR)) <= 0) {
+ fprintf(stderr,"Error: Unable to open file %s, using SDstart\n", h4_filename);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ return (sd_id);
+ } else {
+
+ /* Initialize Vgroup interface */
+ if ((status = Vstart(hfile_id)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to initialize Vgroup interface\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ status = FAIL;
+ }
+
+ /* allocate and initialize internal data structure */
+ init_table(&group_table);
+ init_table(&type_table);
+ init_table(&dset_table);
+ init_prefix(&prefix, prefix_len);
+
+ /* init the find_objs_t*/
+ info->threshold = 0;
+ info->prefix_len = prefix_len;
+ info->prefix = prefix;
+ info->group_table = group_table;
+ info->type_table = type_table;
+ info->dset_table = dset_table;
+ info->status = status;
+
+
+
+ /* Disable error reporting */
+ H5Eget_auto (&func, &edata);
+ H5Eset_auto (NULL, NULL);
+
+ /* find all objects one time */
+ if ((status = H5Giterate(fid, "/", NULL, (H5G_operator_t)find_objs, (void*)info)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to iterate over all of the groups\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ }
+
+ /* Enable error reporting */
+ H5Eset_auto (func, edata);
+
+#ifdef H5DUMP_DEBUG
+ dump_tables();
+#endif
+
+ if (status != SUCCEED) {
+ fprintf(stderr,"Error: internal error! \n");
+ goto done;
+ }
+
+ op_data.hfile_id = hfile_id;
+ op_data.sd_id = sd_id;
+ op_data.vgroup_id = 0;
+
+ /* start at root group */
+ if (( status = convert_group (gid, HDstrdup("/"), &op_data)) != SUCCEED) {
+ fprintf(stderr,"Error: convert_group did not work for %s\n","/");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ status = FAIL;
+ }
+
+ /* Terminate access to Vgroup interface */
+ if ((status = Vend(hfile_id)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to terminate Vgroup interface\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ status = FAIL;
+ }
+ }
+
+ /* close hdf4 SDS */
+ if ((status = SDend(sd_id)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to close file %s, from SDstart\n", h4_filename);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ status = FAIL;
+ }
+
+ }
+
+ /* close hdf4 file */
+ if ((status = Hclose(hfile_id)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to close file %s\n", h4_filename);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ status = FAIL;
+ }
+
+ }
+
+ if ((status = H5Gclose (gid)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to close root group\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ status = FAIL;
+ }
+
+ if ((status = H5Fclose (fid)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to close file %s\n", h5_filename);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5toh4", __FILE__, __LINE__);
+ status = FAIL;
+ }
+
+done:
+ free_table(&group_table);
+ free_table(&dset_table);
+ free_table(&type_table);
+
+ return status;
+
+}
+
+/*-------------------------------------------------------------------------
+ * Function: convert_group
+ *
+ * Purpose: Dump everything within the specified group
+ *
+ * Return: status
+ *
+ * Programmer: Paul Harten
+ *
+ * Modifications:
+ *
+ *-----------------------------------------------------------------------*/
+herr_t
+convert_group (hid_t gid, char *name, op_data_t *op_data) {
+H5G_stat_t statbuf;
+
+ int32 hfile_id;
+ int32 vgroup_id;
+ int32 obj_idx;
+ int32 status;
+ int idx, flag;
+
+ hfile_id = op_data->hfile_id;
+
+ if ((vgroup_id = Vattach(hfile_id, -1, "w")) <= 0 ) {
+ fprintf(stderr,"Error: Unable to create new vgroup\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ return(vgroup_id);
+ }
+
+ if ((status = Vsetname(vgroup_id, name)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to set name on new vgroup\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ return(status);
+ }
+
+ if ((status = Vsetclass(vgroup_id, "HDF5")) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to set class on new vgroup\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ return(status);
+ }
+
+ if (op_data->vgroup_id == 0) {
+ obj_idx = -1; /* Indexes assigned below start from 0 */
+ } else {
+ if ((obj_idx = Vinsert(op_data->vgroup_id, vgroup_id)) < 0) {
+ fprintf(stderr,"Error: Index %d of the new vgroup is illegal\n",(int)obj_idx);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ return(obj_idx);
+ }
+ }
+ op_data->vgroup_id = vgroup_id;
+ op_data->sds_id = 0;
+ op_data->vdata_id = 0;
+ op_data->obj_idx = obj_idx;
+
+
+ /* hard link */
+ if ((status = H5Gget_objinfo(gid, ".", TRUE, &statbuf)) != SUCCEED ) {
+ fprintf(stderr,"Error: H5Gget_objinfo() did not work\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ return (status);
+ }
+
+ if (HDstrcmp(name,"/") == 0) { /* this is the root group, just iterate */
+
+ if ((status = H5Aiterate(gid, NULL, (H5A_operator_t)convert_attr, op_data)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to iterate over all of the attributes\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ return(status);
+ }
+
+ if ((status = H5Giterate(gid, ".", NULL, (H5G_operator_t)convert_all, op_data)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to iterate over all of the groups\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ return(status);
+ }
+
+ } else {
+
+ if ((idx = get_table_idx(group_table, statbuf.objno)) < 0 ) {
+
+ fprintf(stderr,"Error: object not found, %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ status = FAIL;
+
+ } else if((flag = get_tableflag(group_table,idx)) < 0 ) {
+
+ fprintf(stderr,"Error: get_tableflag() should never return < 0\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ status = FAIL;
+
+ } else if(flag == TRUE ) { /* this has already been converted, don't convert the attributes again */
+
+ if ((status = H5Giterate(gid, ".", NULL, (H5G_operator_t)convert_all, op_data)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to iterate over all of the groups\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ return(status);
+ }
+
+ } else { /* flag == FALSE */
+
+ /* this is now being converted */
+ if ((status = set_tableflag(group_table,idx)) < 0 ) {
+ fprintf(stderr,"Error: set_tableflag should never return < 0\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ return(status);
+ }
+
+ if ((status = H5Aiterate(gid, NULL, (H5A_operator_t)convert_attr, op_data)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to iterate over all of the attributes\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ return(status);
+ }
+
+ if ((status = H5Giterate(gid, ".", NULL, (H5G_operator_t)convert_all, op_data)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to iterate over all of the groups\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ return(status);
+ }
+
+ }
+
+ }
+
+
+ if ((status = Vdetach(vgroup_id)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to detach the new Vgroup\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_group", __FILE__, __LINE__);
+ status = FAIL;
+ }
+
+ return status;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: convert_dataset
+ *
+ * Purpose: Convert the specified data set
+ *
+ * Return: status
+ *
+ * Programmer: Paul Harten
+ *
+ * Modifications:
+ *
+ *-----------------------------------------------------------------------*/
+herr_t
+convert_dataset (hid_t did, char *name, op_data_t *op_data) {
+hid_t type, space, class, mem_type, type2;
+/* H5G_stat_t statbuf; */
+size_t typesize;
+int i, idx;
+int32 dim_sizes[32], start[32], edges[32];
+int ndims;
+int ndimf;
+hsize_t dims[32], maxdims[32];
+hsize_t dimf[4];
+int permf[4];
+int32 hfile_id;
+int32 sd_id;
+int32 sds_id;
+int32 vdata_id;
+int32 vgroup_id;
+int32 n_values;
+int32 status;
+int32 h4_type;
+int32 recsize;
+int32 n_records, num_of_recs, record_pos;
+intn nmembers;
+char *buffer=NULL; /* read/write buffer*/
+char fieldname_list[4096] = "\0";
+char *fieldname=NULL;
+hid_t fieldtype;
+int32 order;
+off_t offset;
+off_t offset_array[512];
+hid_t h4type_array[512], memtype_array[512];
+int32 order_array[512];
+
+
+ /* hard link */
+/*
+ if ((status = H5Gget_objinfo(did, ".", TRUE, &statbuf)) != SUCCEED ) {
+ fprintf(stderr,"Error: H5Gget_objinfo() did not work\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return (status);
+ }
+*/
+
+ if ((type = H5Dget_type(did)) <= 0) {
+ fprintf(stderr, "Error: H5Dget_type() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((space = H5Dget_space(did)) <= 0) {
+ fprintf(stderr, "Error: H5Dget_space() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((n_values = H5Sget_simple_extent_npoints(space)) <= 0) {
+ fprintf(stderr, "Error: H5Sget_simple_extent_npoints() returned inappropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((ndims = H5Sget_simple_extent_dims(space,dims,maxdims)) < 0 ) {
+ fprintf(stderr, "Error: Problems getting ndims, dims, and maxdims of dataset\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = ndims;
+ return status;
+ }
+
+ if ((class = H5Tget_class(type)) < 0 ) {
+ fprintf(stderr,"Error: problem with getting class\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = class;
+ return status;
+ }
+
+ switch (class) {
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ sd_id = op_data->sd_id;
+#define NEWWAY
+#ifdef NEWWAY
+ if (FAIL==h5atomic_type_to_h4type(type, &mem_type, &typesize, &h4_type)){
+ fprintf(stderr, "Error: Problems translating h5 type to h4 type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+#else
+ if ((h4_type = h5type_to_h4type(type)) == FAIL ) {
+ fprintf(stderr, "Error: Problems translating h5 type to h4 type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+ if ((mem_type = h4type_to_memtype(h4_type)) == FAIL ) {
+ fprintf(stderr, "Error: Problems translating h4 type to mem type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+ if ((typesize = H5Tget_size(mem_type)) <= 0) {
+ fprintf(stderr, "Error: H5Tget_size() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+#endif
+ if ((buffer = HDmalloc(n_values*typesize)) == NULL) {
+ fprintf(stderr, "Error: Problems with HDmalloc of memory space\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+ if ((status = H5Dread(did, mem_type, space, space, H5P_DEFAULT, buffer)) != SUCCEED) {
+ fprintf(stderr, "Error: Problems with H5Dread\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+ for (i=0;i<ndims;i++) {
+ if (maxdims[i] == H5S_UNLIMITED) {
+ if ( i == 0 ) {
+ dim_sizes[0] = 0; /* this is how HDF4 communicates unlimited dimension */
+ } else {
+ dim_sizes[i] = (int32)dims[i];
+ }
+ } else {
+ dim_sizes[i] = (int32)maxdims[i];
+ }
+ start[i] = 0;
+ edges[i] = (int32)dims[i];
+ }
+ if ((sds_id = SDcreate(sd_id, name, h4_type, ndims, dim_sizes)) <= 0 ) {
+ fprintf(stderr, "Error: Unable to create SDS %s.\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+ op_data->sds_id = sds_id;
+ if ((status = SDwritedata(sds_id, start, NULL, edges, buffer)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to write SDS %s.\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ }
+ if ((status = H5Aiterate(did, NULL, (H5A_operator_t)convert_attr, op_data)) < 0 ) {
+ fprintf(stderr,"Error: iterate over attributes\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ }
+ if ((status = SDendaccess(sds_id)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to end access to SDS %s.\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ }
+ break;
+ case H5T_TIME:
+ fprintf(stderr,"Warning: H5T_TIME not yet implemented.\n");
+ break;
+ case H5T_STRING:
+ if (ndims==1) {
+ convert_dataset_string(did, name, op_data);
+ } else {
+ fprintf(stderr,"Warning: HDF5 datasets of H5T_STRING type with ndims > 1 are not converted.\n");
+ }
+ break;
+ case H5T_BITFIELD:
+ fprintf(stderr,"Warning: H5T_BITFIELD not yet implemented.\n");
+ break;
+ case H5T_OPAQUE:
+ fprintf(stderr,"Warning: H5T_OPAQUE not yet implemented.\n");
+ break;
+ case H5T_ARRAY:
+ fprintf(stderr,"Warning: H5T_OPAQUE not yet implemented.\n");
+ break;
+ case H5T_COMPOUND:
+ if (ndims==1) {
+ if ((nmembers = H5Tget_nmembers(type)) <= 0 ) {
+ fprintf(stderr, "Error: Unable to get information about compound datatype %d\n",nmembers);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+
+ offset = 0;
+ for (idx=0;idx<nmembers;idx++) {
+ if ((fieldtype = H5Tget_member_type(type, idx)) < 0 ) {
+ fprintf(stderr,"Error: H5 datasets of H5T_COMPOUND type with fieldtype %d, idx %d.\n",fieldtype,idx);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+ /* Special case for array fields */
+ if(H5Tget_class(fieldtype)==H5T_ARRAY) {
+ hid_t arr_base_type;
+
+ /* Get the number of dimensions */
+ if ((ndimf = H5Tget_array_ndims(fieldtype)) < 0 || ndimf > H5S_MAX_RANK ) {
+ fprintf(stderr, "Error: rank of members of compound type should not be %d\n",ndimf);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+ /* Get the dimensions and dimension permutations */
+ if (H5Tget_array_dims(fieldtype,dimf,permf) < 0) {
+ fprintf(stderr, "Error: cannot retrieve dimensions for array\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+ /* Get the 'real' field type */
+ if ((arr_base_type=H5Tget_super(fieldtype)) < 0) {
+ fprintf(stderr, "Error: cannot retrieve base type for array\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+ if (H5Tclose(fieldtype) < 0 ) {
+ fprintf(stderr,"Error: closing type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+
+ /* Assign the array's base type as the field type for future use */
+ fieldtype=arr_base_type;
+ } /* end if */
+ else
+ ndimf=0;
+#ifdef NEWWAY
+ if (FAIL==h5atomic_type_to_h4type(fieldtype, &mem_type, &typesize, &h4_type)){
+ fprintf(stderr, "Error: Problems translating h5 type to h4 type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+#else
+ if ((h4_type = h5type_to_h4type(fieldtype)) < 0 ) {
+ fprintf(stderr, "Error: Problems translating h5 type to h4 type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+ if ((mem_type = h4type_to_memtype(h4_type)) == FAIL ) {
+ fprintf(stderr, "Error: Problems translating h4 type to mem type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+ if ((typesize = H5Tget_size(mem_type)) <= 0) {
+ fprintf(stderr, "Error: H5Tget_size() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+#endif
+ order = 1;
+ if (ndimf > 0) {
+ order *= dimf[permf[0]];
+ if (ndimf > 1) {
+ order *= dimf[permf[1]];
+ if (ndimf > 2) {
+ order *= dimf[permf[2]];
+ if (ndimf > 3) {
+ order *= dimf[permf[3]];
+ }
+ }
+ }
+ }
+ h4type_array[idx] = h4_type; /* used for VSfdefine */
+ memtype_array[idx] = mem_type; /* used during the build of the memory compound type */
+ offset_array[idx] = offset; /* used during the build of the memory compound type */
+ order_array[idx] = order; /* used for VSfdefine */
+
+ offset += order * typesize; /* calculating packed size of memory compound type */
+ }
+ hfile_id = op_data->hfile_id;
+ vgroup_id = op_data->vgroup_id;
+ if ((vdata_id = VSattach(hfile_id, -1, "w")) <= 0 ) {
+ fprintf(stderr, "Error: Unable to create vdata %s.\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+/*
+ * This step is done during the convert_shared_dataset() call instead of here.
+ *
+ if ((idx = Vinsert(vgroup_id, vdata_id)) < 0 ) {
+ fprintf(stderr, "Error: Unable to insert vdata %s.\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+*/
+ op_data->vdata_id = vdata_id;
+ if ((status = VSsetname(vdata_id, name)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set vdata name %s.\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+ if ((status = VSsetclass(vdata_id, "HDF5")) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set class on vdata %s\n", name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+ if ((type2 = H5Tcreate(H5T_COMPOUND, (size_t)offset)) <= 0 ) {
+ fprintf(stderr, "Error: unable to execute H5Tcreate()\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+ for (idx=0;idx<nmembers;idx++) {
+ /* Special case for array fields */
+ if(H5Tget_member_class(type,idx)==H5T_ARRAY) {
+ hid_t arr_type;
+
+ if ((arr_type = H5Tget_member_type(type, idx)) < 0 ) {
+ fprintf(stderr,"Error: H5 datasets of H5T_COMPOUND type with fieldtype %d, idx %d.\n",arr_type,idx);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+ /* Get the number of dimensions */
+ if ((ndimf = H5Tget_array_ndims(arr_type)) < 0 || ndimf > H5S_MAX_RANK ) {
+ fprintf(stderr, "Error: rank of members of compound type should not be %d\n",ndimf);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+ /* Get the dimensions and dimension permutations */
+ if (H5Tget_array_dims(arr_type,dimf,permf) < 0) {
+ fprintf(stderr, "Error: cannot retrieve dimensions for array\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+ if (H5Tclose(arr_type) < 0 ) {
+ fprintf(stderr,"Error: closing type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+ } /* end if */
+ else
+ ndimf=0;
+
+ if ((fieldname = H5Tget_member_name(type, idx)) == NULL ) {
+ fprintf(stderr, "Error: Unable to get fieldname for compound type %d, idx %d\n", type, idx);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+ if ((offset = H5Tget_offset(memtype_array[idx])) < 0 || offset >= 128 ) {
+ fprintf(stderr, "Error: H5Tget_offset() is returning a bad value %d\n",(int)offset);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+ if (ndimf == 0 ) {
+ if ((status = H5Tinsert(type2,fieldname,offset_array[idx]+offset,memtype_array[idx])) != SUCCEED ) {
+ fprintf(stderr, "Error: Problems inserting field into compound datatype\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+ } else {
+ hid_t arr_type;
+
+ /* Create the array datatype */
+ if ((arr_type = H5Tarray_create(memtype_array[idx], ndimf, dimf, permf)) < 0 ) {
+ fprintf(stderr,"Error: cannot create array datatype\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+
+ if ((status = H5Tinsert(type2,fieldname,offset_array[idx]+offset,arr_type)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problems inserting field into compound datatype\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+
+ if (H5Tclose(arr_type) < 0 ) {
+ fprintf(stderr,"Error: closing type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ return FAIL;
+ }
+ }
+ if ((status = VSfdefine(vdata_id, fieldname, h4type_array[idx], order_array[idx])) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set field %d\n", idx);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+ strcat(fieldname_list,fieldname);
+ if (idx<nmembers-1) {
+ strcat(fieldname_list,", ");
+ }
+
+ if (fieldname != NULL) {
+ HDfree(fieldname);
+ }
+ }
+ if ((status = VSsetfields(vdata_id, fieldname_list)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set fieldname list %s\n", name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+ if ((status = VSsetinterlace(vdata_id, FULL_INTERLACE)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set FULL_INTERLACE mode, status %d\n", (int)status);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+ if ((recsize = H5Tget_size(type2)) <= 0 ) {
+ fprintf(stderr, "Error: Unable to get record size %d\n", (int)recsize);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+/*
+ Since the space is rank 1, n_records does not depend on maxdims.
+*/
+ n_records = n_values;
+ if ((buffer = HDmalloc(n_records*recsize)) == NULL) {
+ fprintf(stderr, "Error: Problems with HDmalloc of memory space\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+ if ((status = H5Dread(did, type2, space, space, H5P_DEFAULT, buffer)) != SUCCEED) {
+ fprintf(stderr, "Error: Problems with H5Dread\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+ if ((status = H5Tclose(type2)) < 0 ) {
+ fprintf(stderr,"Error: closing type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+
+ if ((record_pos = VSseek(vdata_id, 0)) != 0 ) {
+ fprintf(stderr, "Error: Could not seek the beginning of the Vdata, %d\n", (int)record_pos);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = record_pos;
+ break;
+ }
+ if ((num_of_recs = VSwrite(vdata_id, (void *)buffer, n_records, FULL_INTERLACE)) != n_records ) {
+ fprintf(stderr, "Error: Only able to write %d of %d records\n", (int)num_of_recs, (int)n_records);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = num_of_recs;
+ break;
+ }
+
+ /* there are only vdata attributes, no field attributes */
+ if ((status = H5Aiterate(did, NULL, (H5A_operator_t)convert_attr, op_data)) < 0 ) {
+ fprintf(stderr,"Error: iterate over attributes\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+ if ((status = VSdetach(vdata_id)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to detach to vdata %s.\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ break;
+ }
+
+ } else {
+
+ fprintf(stderr,"Warning: HDF5 datasets of H5T_COMPOUND type with ndims > 1 are not converted.\n");
+
+ }
+ break;
+ default:
+ fprintf(stderr,"Error: %d class not found\n",class);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ }
+
+ if ((status = H5Tclose(type)) < 0 ) {
+ fprintf(stderr,"Error: closing type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ }
+
+ if ((status = H5Sclose(space)) < 0 ) {
+ fprintf(stderr,"Error: closing space\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ }
+
+ if (buffer != NULL) {
+ HDfree(buffer);
+ }
+
+ return status;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: convert_attr
+ *
+ * Purpose: dump the attribute
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Paul Harten
+ *
+ * Modifications:
+ *
+ *-----------------------------------------------------------------------*/
+
+herr_t
+convert_attr (hid_t attr, char *attr_name, op_data_t *op_data)
+{
+hid_t attr_id, type, space, mem_type, class;
+size_t typesize;
+char *attr_values=NULL;
+int32 status;
+int32 h4_type;
+int32 sds_id;
+int32 vdata_id;
+int32 vgroup_id;
+int32 n_values;
+int32 order;
+hid_t fxdlenstr;
+size_t lenstr;
+H5T_cset_t cset;
+H5T_str_t strpad;
+
+ sds_id = op_data->sds_id;
+ vdata_id = op_data->vdata_id;
+ vgroup_id = op_data->vgroup_id;
+
+ if ((attr_id = H5Aopen_name (attr, attr_name))>= 0) {
+
+ if ((type = H5Aget_type(attr_id)) <= 0) {
+ fprintf(stderr, "Error: H5Aget_type() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((class = H5Tget_class(type)) < 0 ) {
+ fprintf(stderr,"Error: problem with getting class\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = class;
+ return status;
+ }
+
+ switch (class) {
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+
+
+ if ((space = H5Aget_space(attr_id)) <= 0) {
+ fprintf(stderr, "Error: H5Dget_space() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((n_values = H5Sget_simple_extent_npoints(space)) <= 0) {
+ fprintf(stderr, "Error: H5sget_simple_extent_npoints() didn't return correct value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+#ifdef NEWWAY
+ if (FAIL==h5atomic_type_to_h4type(type, &mem_type, &typesize, &h4_type)){
+ fprintf(stderr, "Error: Problems translating h5 type to h4 type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+#else
+ if ((h4_type = h5type_to_h4type(type)) == FAIL ) {
+ fprintf(stderr, "Error: Problems translating h5 type to h4 type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((mem_type = h4type_to_memtype(h4_type)) == FAIL ) {
+ fprintf(stderr, "Error: Problems translating h4 type to mem type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((typesize = H5Tget_size(mem_type)) <= 0) {
+ fprintf(stderr, "Error: H5Tget_size() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+#endif
+
+ if ((attr_values = HDmalloc(n_values*typesize)) == NULL) {
+ fprintf(stderr, "Error: Problems with HDmalloc of memory space\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((status = H5Aread(attr_id, mem_type, attr_values)) != SUCCEED) {
+ fprintf(stderr, "Error: Problems with H5Aread\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if (sds_id != 0) {
+ if ((status = SDsetattr(sds_id, attr_name, h4_type, n_values, attr_values)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+ } else if (vdata_id != 0) {
+ if ((status = VSsetattr(vdata_id, -1, attr_name, h4_type, n_values, attr_values)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+ } else {
+ if ((status = Vsetattr(vgroup_id, attr_name, h4_type, n_values, attr_values)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+ }
+
+ if ((status = H5Sclose(space)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problems closing H5Sclose\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+ if ((status = H5Aclose(attr_id)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problems closing H5Aclose\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if (attr_values != NULL) {
+ HDfree(attr_values);
+ }
+
+ status = SUCCEED;
+ break;
+
+ case H5T_TIME:
+ fprintf(stderr,"Warning: H5T_TIME attribute not yet implemented.\n");
+ break;
+ case H5T_STRING:
+
+ fxdlenstr = type;
+ h4_type = DFNT_CHAR;
+
+ if ((space = H5Aget_space(attr_id)) <= 0) {
+ fprintf(stderr, "Error: H5Dget_space() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((n_values = H5Sget_simple_extent_npoints(space)) <= 0) {
+ fprintf(stderr, "Error: H5sget_simple_extent_npoints() didn't return correct value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((mem_type = H5Tcopy(H5T_C_S1)) == FAIL ) {
+ fprintf(stderr, "Error: Problems translating h4 type to mem type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = mem_type;
+ return status;
+ }
+ if ((lenstr = H5Tget_size(fxdlenstr)) <= 0 ) {
+ fprintf(stderr, "Error: size of fixed length string type should not be %d\n",(int)lenstr);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ return lenstr;
+ }
+ if ((status = H5Tset_size(mem_type,lenstr)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problem with H5Tset_size()\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ return status;
+ }
+
+ strpad = H5Tget_strpad(fxdlenstr);
+ if ((strpad != H5T_STR_NULLTERM) && (strpad != H5T_STR_NULLPAD) && (strpad != H5T_STR_SPACEPAD)) {
+ fprintf(stderr, "Error: Invalid string padding value, %d\n",(int)strpad);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ return strpad;
+ }
+ if ((status = H5Tset_strpad(mem_type, H5T_STR_SPACEPAD)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problem with H5Tset_strpad()\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ return status;
+ }
+
+ if ((cset = H5Tget_cset(fxdlenstr)) != H5T_CSET_ASCII ) {
+ fprintf(stderr, "Error: cset value != %d\n",(int)H5T_CSET_ASCII);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ return cset;
+ }
+ if ((status = H5Tset_cset(mem_type,cset)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problem with H5Tset_cset()\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ return status;
+ }
+
+ order = n_values * lenstr;
+ if ((attr_values = HDmalloc(order)) == NULL) {
+ fprintf(stderr, "Error: Problems with HDmalloc of memory space\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((status = H5Aread(attr_id, mem_type, attr_values)) != SUCCEED) {
+ fprintf(stderr, "Error: Problems with H5Aread\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if (sds_id != 0) {
+ if ((status = SDsetattr(sds_id, attr_name, h4_type, order, attr_values)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+ } else if (vdata_id != 0) {
+ if ((status = VSsetattr(vdata_id, -1, attr_name, h4_type, order, attr_values)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+ } else {
+ if ((status = Vsetattr(vgroup_id, attr_name, h4_type, order, attr_values)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set %s attribute.\n",attr_name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+ }
+
+ if ((status = H5Sclose(space)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problems closing H5Sclose\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+ if ((status = H5Aclose(attr_id)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problems closing H5Aclose\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if (attr_values != NULL) {
+ HDfree(attr_values);
+ }
+
+ status = SUCCEED;
+ break;
+ case H5T_BITFIELD:
+ fprintf(stderr,"Warning: H5T_BITFIELD attribute not yet implemented.\n");
+ break;
+ case H5T_OPAQUE:
+ fprintf(stderr,"Warning: H5T_OPAQUE attribute not yet implemented.\n");
+ break;
+ case H5T_COMPOUND:
+ fprintf(stderr,"Warning: H5T_COMPOUND attribute not implemented.\n");
+ break;
+ default:
+ fprintf(stderr,"Error: %d class not found\n",class);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ }
+
+ if ((status = H5Tclose(type)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problems closing H5Tclose\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_attr", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ } else {
+
+ status = FAIL;
+
+ }
+
+ return status;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: convert_all
+ *
+ * Purpose: Dump everything in the specified object
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Paul Harten
+ *
+ * Modifications:
+ *
+ *-----------------------------------------------------------------------*/
+herr_t
+convert_all (hid_t group, char *name, op_data_t *op_data)
+{
+ hid_t obj;
+ H5G_stat_t statbuf, statbuf2;
+ int status;
+ op_data_t op_data_save;
+ int32 vgroup_id;
+ int32 sd_id;
+ int32 sds_id;
+ int idx, flag;
+ void *edata;
+ hid_t (*func)(void*);
+
+ op_data_save = *op_data;
+
+ vgroup_id = op_data->vgroup_id;
+ sd_id = op_data->sd_id;
+ sds_id = op_data->sds_id;
+
+ if ((status = H5Gget_objinfo(group, name, FALSE, &statbuf)) != SUCCEED ) {
+ fprintf(stderr,"Error: H5Gget_objinfo() did not work\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ return (status);
+ }
+ statbuf2 = statbuf;
+
+ switch (statbuf.type) {
+
+ case H5G_LINK: /* this is a soft link only */
+
+
+ /* Disable error reporting */
+ H5Eget_auto (&func, &edata);
+ H5Eset_auto (NULL, NULL);
+
+ /* test to see if object exists */
+ if ((status = H5Gget_objinfo(group, name, TRUE, NULL)) != SUCCEED ) {
+ fprintf(stderr,"Warning: the object pointed to by the symbolic link \"%s\" does not exist.\n",name);
+ }
+
+ /* Enable error reporting */
+ H5Eset_auto (func, edata);
+
+ if (status != SUCCEED) {
+ break;
+ }
+
+ /* follow link for type */
+ if ((status = H5Gget_objinfo(group, name, TRUE, &statbuf)) != SUCCEED ) {
+ fprintf(stderr,"Error: H5Gget_objinfo() did not work\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ return (status);
+ }
+
+ if (statbuf.type==H5G_DATASET ) {
+
+ if ((idx = get_table_idx(dset_table, statbuf.objno)) < 0 ) {
+
+ fprintf(stderr,"Error: object not found\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+
+ } else if((flag = get_tableflag(dset_table,idx)) < 0 ) {
+
+ fprintf(stderr,"Error: get_tableflag() should never return < 0\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+
+ } else if(flag == TRUE ) { /* this has already been converted, add as a tag/ref */
+
+ if ((obj = H5Dopen (group, name)) <= 0 ) {
+ fprintf(stderr,"Error: Unable to open H5 dataset\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ return (obj);
+ } else {
+ if ((status = convert_shared_dataset(obj, idx, op_data)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to convert to tag/ref\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ }
+ }
+ if ((status = H5Dclose(obj)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to close H5 dataset %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+
+ } else { /* flag == FALSE */
+
+ if ((obj = H5Dopen (group, name)) <= 0 ) {
+ fprintf(stderr,"Error: Unable to open H5 dataset\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ return (obj);
+ } else {
+ if (( status = convert_dataset (obj, name, op_data)) != SUCCEED) {
+ fprintf(stderr,"Error: convert_dataset did not work for %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+ if ((status = convert_shared_dataset(obj, idx, op_data)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to convert to tag/ref\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ }
+ if(( status = set_tableflag(dset_table,idx)) != SUCCEED ) {
+ fprintf(stderr,"Error: set_tableflag() did not work for %s\n", name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ break;
+ }
+ }
+ if ((status = H5Dclose(obj)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to close H5 dataset %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+
+ }
+
+ } else if (statbuf.type==H5G_GROUP ) {
+
+ if ((idx = get_table_idx(group_table, statbuf.objno)) < 0 ) {
+
+ fprintf(stderr,"Error: object not found\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+
+ } else if((flag = get_tableflag(group_table,idx)) < 0 ) {
+
+ fprintf(stderr,"Error: get_tableflag() should never return < 0\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+
+ } else if(flag == TRUE ) {
+
+ if (( status = convert_shared_group (group, idx, op_data)) != SUCCEED) {
+ fprintf(stderr,"Error: convert_group did not work for %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+
+ } else { /* flag == FALSE */
+
+ if ((obj = H5Gopen (group, name)) <= 0 ) {
+ fprintf(stderr,"Error: Unable to open group\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ return (obj);
+ } else {
+ if (( status = convert_group (obj, name, op_data)) != SUCCEED) {
+ fprintf(stderr,"Error: convert_group did not work for %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+ }
+ if ((status = H5Gclose(obj)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to close group %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+
+ }
+
+ }
+
+ break;
+
+ case H5G_GROUP:
+
+ if ((idx = get_table_idx(group_table, statbuf.objno)) < 0 ) {
+
+ fprintf(stderr,"Error: object not found\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+
+ } else if((flag = get_tableflag(group_table,idx)) < 0 ) {
+
+ fprintf(stderr,"Error: get_tableflag() should never return < 0\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+
+ } else if(flag == TRUE ) {
+
+ if (( status = convert_shared_group (group, idx, op_data)) != SUCCEED) {
+ fprintf(stderr,"Error: convert_group did not work for %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+
+ } else { /* flag == FALSE */
+
+ if ((obj = H5Gopen (group, name)) <= 0 ) {
+ fprintf(stderr,"Error: Unable to open group\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ return (obj);
+ } else {
+ if (( status = convert_group (obj, name, op_data)) != SUCCEED) {
+ fprintf(stderr,"Error: convert_group did not work for %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+ }
+ if ((status = H5Gclose(obj)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to close group %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+
+ }
+
+ break;
+
+ case H5G_DATASET:
+
+ if ((idx = get_table_idx(dset_table, statbuf.objno)) < 0 ) {
+
+ fprintf(stderr,"Error: object not found\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+
+ } else if((flag = get_tableflag(dset_table,idx)) < 0 ) {
+
+ fprintf(stderr,"Error: get_tableflag() should never return < 0\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+
+ } else if(flag == TRUE ) { /* this has already been converted, add as a tag/ref */
+
+ if ((obj = H5Dopen (group, name)) <= 0 ) {
+ fprintf(stderr,"Error: Unable to open H5 dataset\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ return (obj);
+ } else {
+ if ((status = convert_shared_dataset(obj, idx, op_data)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to convert to tag/ref\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ }
+ }
+ if ((status = H5Dclose(obj)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to close H5 dataset %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+
+ } else { /* flag == FALSE */
+
+ if ((obj = H5Dopen (group, name)) <= 0 ) {
+ fprintf(stderr,"Error: Unable to open H5 dataset\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ return (obj);
+ } else {
+ if (( status = convert_dataset (obj, name, op_data)) != SUCCEED) {
+ fprintf(stderr,"Error: convert_dataset did not work for %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+ if ((status = convert_shared_dataset(obj, idx, op_data)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to convert to tag/ref\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ }
+ if(( status = set_tableflag(dset_table,idx)) != SUCCEED ) {
+ fprintf(stderr,"Error: set_tableflag() did not work for %s\n", name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ break;
+ }
+ }
+ if ((status = H5Dclose(obj)) != SUCCEED) {
+ fprintf(stderr,"Error: Unable to close H5 dataset %s\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_all", __FILE__, __LINE__);
+ status = FAIL;
+ break;
+ }
+
+ }
+
+ break;
+
+ case H5G_TYPE:
+ /* object is ignored */
+ break;
+
+ default:
+ fprintf (stderr,"Unknown Object %s\n", name);
+ status = FAIL;
+ break;
+
+ }
+
+ *op_data = op_data_save;
+
+ return SUCCEED;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: convert_shared_dataset
+ *
+ * Purpose: Handle a shared dataset which has already been converted.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Paul Harten
+ *
+ * Modifications:
+ *
+ *-----------------------------------------------------------------------*/
+herr_t
+convert_shared_dataset(hid_t did, int idx, op_data_t *op_data)
+{
+ int status=SUCCEED;
+ int32 vgroup_id;
+ char *dataset_name=NULL;
+ char *dataset_name2=NULL;
+ int32 hfile_id;
+ int32 sd_id;
+ int32 sds_id;
+ int32 sds_ref;
+ int32 vdata_ref;
+ int32 sds_index;
+ int32 numtagref;
+ hid_t type, space, class;
+ hsize_t dims[32], maxdims[32];
+ int n_values, ndims;
+
+ vgroup_id = op_data->vgroup_id;
+
+ if ((dataset_name = get_objectname(dset_table, idx)) == NULL ) {
+ fprintf(stderr,"Error: get_objectname() did not work\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ return (status);
+ }
+
+ if ((dataset_name2 = strrchr(dataset_name,'/')) == NULL) { /* find last "/" in dataset_name */
+ dataset_name2 = dataset_name; /* no "/"s were found */
+ } else {
+ dataset_name2 = dataset_name2 + sizeof(char); /* 1 character past last "/" */
+ }
+
+ if ((type = H5Dget_type(did)) <= 0) {
+ fprintf(stderr, "Error: H5Dget_type() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((space = H5Dget_space(did)) <= 0) {
+ fprintf(stderr, "Error: H5Dget_space() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((n_values = H5Sget_simple_extent_npoints(space)) <= 0) {
+ fprintf(stderr, "Error: H5Sget_simple_extent_npoints() returned inappropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((ndims = H5Sget_simple_extent_dims(space,dims,maxdims)) < 0 ) {
+ fprintf(stderr, "Error: Problems getting ndims, dims, and maxdims of dataset\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ status = ndims;
+ return status;
+ }
+
+ if ((class = H5Tget_class(type)) < 0 ) {
+ fprintf(stderr,"Error: problem with getting class\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ status = class;
+ return status;
+ }
+
+ switch (class) {
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ sd_id = op_data->sd_id;
+ if ((sds_index = SDnametoindex(sd_id, dataset_name2)) < 0 ) {
+ fprintf (stderr,"Error: Problem with SDnametoindex().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ return (sds_index);
+ }
+ if ((sds_id = SDselect(sd_id, sds_index)) < 0 ) {
+ fprintf (stderr,"Error: Problem with SDselect().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ return (sds_id);
+ }
+ if ((sds_ref = SDidtoref(sds_id)) < 0 ) {
+ fprintf (stderr,"Error: Problem with SDidtoref().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ return (sds_ref);
+ }
+ if ((numtagref = Vaddtagref(vgroup_id, DFTAG_NDG, sds_ref)) < 0 ) {
+ fprintf (stderr,"Error: Problem with Vaddtagref().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ return (numtagref);
+ }
+ break;
+ case H5T_TIME:
+ fprintf(stderr,"Error: H5T_TIME not yet implemented.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ break;
+ case H5T_STRING:
+ hfile_id = op_data->hfile_id;
+ if (ndims==1) {
+ if ((vdata_ref = VSfind(hfile_id,dataset_name2)) <= 0 ) {
+ fprintf (stderr,"Error: Problem with VSfind().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ return (vdata_ref);
+ }
+ if ((numtagref = Vaddtagref(vgroup_id, DFTAG_VH, vdata_ref)) < 0 ) {
+ fprintf (stderr,"Error: Problem with Vaddtagref().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ return (numtagref);
+ }
+ }
+ break;
+ case H5T_BITFIELD:
+ fprintf(stderr,"Error: H5T_BITFIELD not yet implemented.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ break;
+ case H5T_OPAQUE:
+ fprintf(stderr,"Error: H5T_OPAQUE not yet implemented.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ break;
+ case H5T_COMPOUND:
+ hfile_id = op_data->hfile_id;
+ if (ndims==1) {
+ if ((vdata_ref = VSfind(hfile_id,dataset_name2)) <= 0 ) {
+ fprintf (stderr,"Error: Problem with VSfind().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ return (vdata_ref);
+ }
+ if ((numtagref = Vaddtagref(vgroup_id, DFTAG_VH, vdata_ref)) < 0 ) {
+ fprintf (stderr,"Error: Problem with Vaddtagref().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ return (numtagref);
+ }
+ }
+ break;
+ default:
+ fprintf(stderr,"Error: %d class not found\n",class);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ }
+
+ if ((status = H5Tclose(type)) < 0 ) {
+ fprintf(stderr,"Error: closing type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset", __FILE__, __LINE__);
+ status = FAIL;
+ }
+
+ if (dataset_name != NULL) {
+ HDfree (dataset_name);
+ }
+
+ return status;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: convert_shared_group
+ *
+ * Purpose: Handle a shared group which has already been converted.
+ *
+ * Return: status
+ *
+ * Programmer: Paul Harten
+ *
+ * Modifications:
+ *
+ *-----------------------------------------------------------------------*/
+herr_t
+convert_shared_group (hid_t group, int idx, op_data_t *op_data) {
+
+ int32 hfile_id;
+ int32 vgroup_id;
+ int32 vgroup_ref;
+ int32 numtagref;
+ int32 status = SUCCEED;
+ hid_t group2;
+ char *group_name=NULL;
+ char *group_name2=NULL;
+ char vgroup_name[VGNAMELENMAX];
+
+ group2 = group;
+ hfile_id = op_data->hfile_id;
+
+ if ((group_name = get_objectname(group_table, idx)) == NULL ) {
+ fprintf(stderr,"Error: get_objectname() did not work\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__);
+ status = FAIL;
+ return (status);
+ }
+
+ if ((group_name2 = strrchr(group_name,'/')) == NULL) { /* find last "/" in group_name */
+ group_name2 = group_name; /* no "/"s were found */
+ } else {
+ group_name2 = group_name2 + sizeof(char); /* 1 character past last "/" */
+ }
+
+ if ((status = Vgetname(op_data->vgroup_id,vgroup_name)) < 0 ) {
+ fprintf (stderr,"Error: Problem with Vfind().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__);
+ return (status);
+ }
+
+ if ((vgroup_ref = Vfind(hfile_id,vgroup_name)) <= 0 ) {
+ fprintf (stderr,"Error: Problem with Vfind().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__);
+ return (vgroup_ref);
+ }
+
+ if ((vgroup_id = Vattach(hfile_id, vgroup_ref, "w")) <= 0 ) {
+ fprintf(stderr,"Error: Unable to create new vgroup\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__);
+ return(vgroup_id);
+ }
+
+ if ((vgroup_ref = Vfind(hfile_id,group_name2)) <= 0 ) {
+ fprintf (stderr,"Error: Problem with Vfind().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__);
+ return (vgroup_ref);
+ }
+
+ if ((numtagref = Vaddtagref(vgroup_id, DFTAG_VG, vgroup_ref)) < 0 ) {
+ fprintf (stderr,"Error: Problem with Vaddtagref().\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__);
+ return (numtagref);
+ }
+
+ if ((status = Vdetach(vgroup_id)) != SUCCEED ) {
+ fprintf(stderr,"Error: Unable to detach the new Vgroup\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_group", __FILE__, __LINE__);
+ status = FAIL;
+ }
+
+ if (group_name != NULL) {
+ HDfree(group_name);
+ }
+
+ return status;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: convert_dataset_string
+ *
+ * Purpose: convert a dataset with string elements.
+ *
+ * Return: status
+ *
+ * Programmer: Paul Harten
+ *
+ * Modifications:
+ *
+ *-----------------------------------------------------------------------*/
+herr_t
+convert_dataset_string (hid_t did, char *name, op_data_t *op_data) {
+
+ int32 hfile_id;
+ int32 vgroup_id;
+ int32 vdata_id;
+hid_t fxdlenstr, space, class, mem_type;
+const char* fieldname = {"string"};
+const char* fieldname_list = fieldname;
+char *buffer;
+int32 status;
+int32 h4_type;
+int32 recsize, n_records, n_values, num_of_recs, record_pos;
+size_t lenstr;
+H5T_cset_t cset;
+H5T_str_t strpad;
+
+ if ((fxdlenstr = H5Dget_type(did)) <= 0) {
+ fprintf(stderr, "Error: H5Dget_type() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((class = H5Tget_class(fxdlenstr)) != H5T_STRING ) {
+ fprintf(stderr,"Error: problem with getting class\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_shared_dataset", __FILE__, __LINE__);
+ status = class;
+ return status;
+ }
+
+ if ((space = H5Dget_space(did)) <= 0) {
+ fprintf(stderr, "Error: H5Dget_space() didn't return appropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ if ((n_values = H5Sget_simple_extent_npoints(space)) <= 0) {
+ fprintf(stderr, "Error: H5Sget_simple_extent_npoints() returned inappropriate value.\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ h4_type = DFNT_CHAR;
+ if ((mem_type = H5Tcopy(H5T_C_S1)) == FAIL ) {
+ fprintf(stderr, "Error: Problems translating h4 type to mem type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ status = mem_type;
+ return status;
+ }
+ if ((lenstr = H5Tget_size(fxdlenstr)) <= 0 ) {
+ fprintf(stderr, "Error: size of fixed length string type should not be %d\n",(int)lenstr);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return lenstr;
+ }
+ if ((status = H5Tset_size(mem_type,lenstr)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problem with H5Tset_size()\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return status;
+ }
+
+ strpad = H5Tget_strpad(fxdlenstr);
+ if ((strpad != H5T_STR_NULLTERM) && (strpad != H5T_STR_NULLPAD) && (strpad != H5T_STR_SPACEPAD)) {
+ fprintf(stderr, "Error: Invalid string padding value, %d\n",(int)strpad);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return strpad;
+ }
+ if ((status = H5Tset_strpad(mem_type, strpad)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problem with H5Tset_strpad()\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return status;
+ }
+
+ if ((cset = H5Tget_cset(fxdlenstr)) != H5T_CSET_ASCII ) {
+ fprintf(stderr, "Error: cset value != %d\n",(int)H5T_CSET_ASCII);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return cset;
+ }
+ if ((status = H5Tset_cset(mem_type,cset)) != SUCCEED ) {
+ fprintf(stderr, "Error: Problem with H5Tset_cset()\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return status;
+ }
+
+ hfile_id = op_data->hfile_id;
+ vgroup_id = op_data->vgroup_id;
+ if ((vdata_id = VSattach(hfile_id, -1, "w")) <= 0 ) {
+ fprintf(stderr, "Error: Unable to create vdata %s.\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+
+ op_data->vdata_id = vdata_id;
+ if ((status = VSsetname(vdata_id, name)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set vdata name %s.\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return status;
+ }
+ if ((status = VSsetclass(vdata_id, "HDF5")) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set class on vdata %s\n", name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return status;
+ }
+
+ if ((status = VSfdefine(vdata_id, fieldname, h4_type, lenstr)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to VSfdefine() field\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return status;
+ }
+
+ if ((status = VSsetfields(vdata_id, fieldname_list)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set fieldname list %s\n", fieldname_list);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return status;
+ }
+ if ((status = VSsetinterlace(vdata_id, FULL_INTERLACE)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to set FULL_INTERLACE mode, status %d\n", (int)status);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return status;
+ }
+ if ((recsize = H5Tget_size(mem_type)) <= 0 ) {
+ fprintf(stderr, "Error: Unable to get record size %d\n", (int)recsize);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ status = recsize;
+ return status;
+ }
+/*
+ Since the space is rank 1, n_records does not depend on maxdims.
+*/
+ n_records = n_values;
+ if ((buffer = HDmalloc(n_records*recsize)) == NULL) {
+ fprintf(stderr, "Error: Problems with HDmalloc of memory space\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ status = FAIL;
+ return status;
+ }
+ if ((status = H5Dread(did, mem_type, space, space, H5P_DEFAULT, buffer)) != SUCCEED) {
+ fprintf(stderr, "Error: Problems with H5Dread\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return status;
+ }
+
+ if ((record_pos = VSseek(vdata_id, 0)) != 0 ) {
+ fprintf(stderr, "Error: Could not seek the beginning of the Vdata, %d\n", (int)record_pos);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ status = record_pos;
+ return status;
+ }
+ if ((num_of_recs = VSwrite(vdata_id, (void *)buffer, n_records, FULL_INTERLACE)) != n_records ) {
+ fprintf(stderr, "Error: Only able to write %d of %d records\n", (int)num_of_recs, (int)n_records);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ status = num_of_recs;
+ return status;
+ }
+
+ /* there are only vdata attributes, no field attributes */
+ if ((status = H5Aiterate(did, NULL, (H5A_operator_t)convert_attr, op_data)) < 0 ) {
+ fprintf(stderr,"Error: iterate over attributes\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return status;
+ }
+ if ((status = VSdetach(vdata_id)) != SUCCEED ) {
+ fprintf(stderr, "Error: Unable to detach to vdata %s.\n",name);
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "convert_dataset_string", __FILE__, __LINE__);
+ return status;
+ }
+
+ if (buffer != NULL) {
+ HDfree(buffer);
+ }
+
+ return status;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: h5atomic_type_to_h4type
+ *
+ * Purpose: Match an H5 atomic type to an appropriate H4 type.
+ * Assign an appropirate H5 memory type that matches the H4 type.
+ * Return the H5 memory type, H4 type and sizeof H4 via pointers.
+ *
+ * Return: SUCCEED on suceed, FAIL on failure.
+ * When fail, pointer values of h5memtype, h5memsize and h4_type
+ * may have changed and are undefined.
+ *
+ * Programmer: Albert Cheng, March 2000
+ *
+ * Modifications:
+ *
+ *-----------------------------------------------------------------------*/
+static herr_t h5atomic_type_to_h4type(const hid_t h5type, hid_t* h5memtype, size_t* h5memsize, int32* h4type)
+{
+ H5T_class_t class;
+ size_t h5typesize, h4typesize;
+ H5T_sign_t sign;
+ hid_t mem_datatype = FAIL;
+
+ if ((class = H5Tget_class(h5type)) < 0 ) {
+ fprintf(stderr,"Error: problem with getting type class\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__);
+ return FAIL;
+ }
+
+ switch(class){
+ case H5T_INTEGER:
+ if ((h5typesize = H5Tget_size(h5type)) == 0 ) {
+ fprintf(stderr,"Error: problem with getting type size\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__);
+ return FAIL;
+ }
+ if ((sign = H5Tget_sign(h5type)) == H5T_SGN_ERROR) {
+ fprintf(stderr,"Error: problem with getting type sign\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__);
+ return FAIL;
+ }
+ /* deduce the proper HDF4 integer type to use according to the size of the HDF5 type. */
+ /* Current HDF4 types can be 8, 16, 32 bits (1, 2, 4 bytes). */
+ switch(h5typesize){
+ case 1:
+ *h4type = (sign == H5T_SGN_2 ? DFNT_INT8 : DFNT_UINT8);
+ h4typesize = sizeof(int8);
+ if (h4typesize == H5Tget_size(H5T_NATIVE_CHAR)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SCHAR : H5T_NATIVE_UCHAR);
+ }else if (h4typesize == H5Tget_size(H5T_NATIVE_SHORT)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SHORT : H5T_NATIVE_USHORT);
+ }else if (h4typesize == H5Tget_size(H5T_NATIVE_INT)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_INT : H5T_NATIVE_UINT);
+ }else if (h4typesize == H5Tget_size(H5T_NATIVE_LONG)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_LONG : H5T_NATIVE_ULONG);
+ }else
+ return(FAIL);
+ break;
+ case 2:
+ *h4type = (sign == H5T_SGN_2 ? DFNT_INT16 : DFNT_UINT16);
+ h4typesize = sizeof(int16);
+ if (h4typesize == H5Tget_size(H5T_NATIVE_CHAR)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SCHAR : H5T_NATIVE_UCHAR);
+ }else if (h4typesize == H5Tget_size(H5T_NATIVE_SHORT)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SHORT : H5T_NATIVE_USHORT);
+ }else if (h4typesize == H5Tget_size(H5T_NATIVE_INT)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_INT : H5T_NATIVE_UINT);
+ }else if (h4typesize == H5Tget_size(H5T_NATIVE_LONG)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_LONG : H5T_NATIVE_ULONG);
+ }else
+ return(FAIL);
+ break;
+ case 4:
+ *h4type = (sign == H5T_SGN_2 ? DFNT_INT32 : DFNT_UINT32);
+ h4typesize = sizeof(int32);
+ if (h4typesize == H5Tget_size(H5T_NATIVE_CHAR)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SCHAR : H5T_NATIVE_UCHAR);
+ }else if (h4typesize == H5Tget_size(H5T_NATIVE_SHORT)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_SHORT : H5T_NATIVE_USHORT);
+ }else if (h4typesize == H5Tget_size(H5T_NATIVE_INT)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_INT : H5T_NATIVE_UINT);
+ }else if (h4typesize == H5Tget_size(H5T_NATIVE_LONG)){
+ mem_datatype = (sign == H5T_SGN_2 ? H5T_NATIVE_LONG : H5T_NATIVE_ULONG);
+ }else
+ return(FAIL);
+ break;
+ default:
+ fprintf(stderr,"Error: unmatchable integer type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__);
+ return FAIL;
+ }
+ break;
+ /* end of case H5T_INTEGER */
+
+ case H5T_FLOAT:
+ if ((h5typesize = H5Tget_size(h5type)) == 0 ) {
+ fprintf(stderr,"Error: problem with getting type size\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__);
+ return FAIL;
+ }
+ /* deduce the proper HDF4 floating point type to use according to the size of the HDF5 type. */
+ /* Current HDF4 types can be 32 or 64 bits (4 or 8 bytes). */
+ switch(h5typesize){
+ case 4:
+ *h4type = DFNT_FLOAT32;
+ h4typesize = sizeof(float32);
+ if (h4typesize == H5Tget_size(H5T_NATIVE_FLOAT)){
+ mem_datatype = H5T_NATIVE_FLOAT;
+ }else if (h4typesize == H5Tget_size(H5T_NATIVE_DOUBLE)){
+ mem_datatype = H5T_NATIVE_DOUBLE;
+ }else
+ return(FAIL);
+ break;
+ case 8:
+ *h4type = DFNT_FLOAT64;
+ h4typesize = sizeof(float64);
+ if (h4typesize == H5Tget_size(H5T_NATIVE_FLOAT)){
+ mem_datatype = H5T_NATIVE_FLOAT;
+ }else if (h4typesize == H5Tget_size(H5T_NATIVE_DOUBLE)){
+ mem_datatype = H5T_NATIVE_DOUBLE;
+ }else
+ return(FAIL);
+ break;
+ default:
+ fprintf(stderr,"Error: unmatchable H5 float type\n");
+ DEBUG_PRINT("Error detected in %s() [%s line %d]\n", "h5atomic_type_to_h4type", __FILE__, __LINE__);
+ return FAIL;
+ }
+ break;
+ /* end of case H5T_FLOAT */
+
+ default:
+ return FAIL;
+ }
+
+ *h5memsize = h4typesize;
+ *h5memtype = mem_datatype;
+ return(SUCCEED);
+}
+#ifndef NEWWAY
+/*****************************************************************************
+
+ Routine: h5type_to_h4type(h5type)
+
+ Description: Translate h5 datatype into h4 datatype
+
+ Input: h5 datatype
+
+ Output: function return, h4 datatype
+
+*****************************************************************************/
+
+int32 h5type_to_h4type(hid_t h5_datatype)
+{
+ int32 h4_datatype;
+
+ if (H5Tequal(h5_datatype,H5T_STD_I8BE)) {
+ h4_datatype = DFNT_INT8;
+ } else if (H5Tequal(h5_datatype,H5T_STD_I16BE)) {
+ h4_datatype = DFNT_INT16;
+ } else if (H5Tequal(h5_datatype,H5T_STD_I32BE)) {
+ h4_datatype = DFNT_INT32;
+/*
+ * This is not supported by HDF4
+ *
+ } else if (H5Tequal(h5_datatype,H5T_STD_I64BE)) {
+ h4_datatype = DFNT_INT64;
+*/
+ } else if (H5Tequal(h5_datatype,H5T_STD_U8BE)) {
+ h4_datatype = DFNT_UINT8;
+ } else if (H5Tequal(h5_datatype,H5T_STD_U16BE)) {
+ h4_datatype = DFNT_UINT16;
+ } else if (H5Tequal(h5_datatype,H5T_STD_U32BE)) {
+ h4_datatype = DFNT_UINT32;
+ } else if (H5Tequal(h5_datatype,H5T_STD_U64BE)) {
+ h4_datatype = DFNT_UINT64;
+ } else if (H5Tequal(h5_datatype,H5T_IEEE_F32BE)) {
+ h4_datatype = DFNT_FLOAT32;
+ } else if (H5Tequal(h5_datatype,H5T_IEEE_F64BE)) {
+ h4_datatype = DFNT_FLOAT64;
+ } else if (H5Tequal(h5_datatype,H5T_STD_I8LE)) {
+ h4_datatype = DFNT_INT8;
+ } else if (H5Tequal(h5_datatype,H5T_STD_I16LE)) {
+ h4_datatype = DFNT_INT16;
+ } else if (H5Tequal(h5_datatype,H5T_STD_I32LE)) {
+ h4_datatype = DFNT_INT32;
+/*
+ * This is not supported by HDF4
+ *
+ } else if (H5Tequal(h5_datatype,H5T_STD_I64LE)) {
+ h4_datatype = DFNT_INT64;
+*/
+ } else if (H5Tequal(h5_datatype,H5T_STD_U8LE)) {
+ h4_datatype = DFNT_UINT8;
+ } else if (H5Tequal(h5_datatype,H5T_STD_U16LE)) {
+ h4_datatype = DFNT_UINT16;
+ } else if (H5Tequal(h5_datatype,H5T_STD_U32LE)) {
+ h4_datatype = DFNT_UINT32;
+ } else if (H5Tequal(h5_datatype,H5T_STD_U64LE)) {
+ h4_datatype = DFNT_UINT64;
+ } else if (H5Tequal(h5_datatype,H5T_IEEE_F32LE)) {
+ h4_datatype = DFNT_FLOAT32;
+ } else if (H5Tequal(h5_datatype,H5T_IEEE_F64LE)) {
+ h4_datatype = DFNT_FLOAT64;
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_SCHAR)) {
+ h4_datatype = DFNT_INT8;
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_UCHAR)) {
+ h4_datatype = DFNT_UINT8;
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_SHORT)) {
+ h4_datatype = DFNT_INT16;
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_USHORT)) {
+ h4_datatype = DFNT_UINT16;
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_INT)) {
+ h4_datatype = DFNT_INT32;
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_UINT)) {
+ h4_datatype = DFNT_UINT32;
+/*
+ * This is not supported by HDF4
+ *
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_LONG)) {
+ h4_datatype = DFNT_INT64;
+*/
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_ULONG)) {
+ h4_datatype = DFNT_UINT64;
+/*
+ * This is not supported by HDF4
+ *
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_LLONG)) {
+ h4_datatype = DFNT_INT128;
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_ULLONG)) {
+ h4_datatype = DFNT_UINT128;
+*/
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_FLOAT)) {
+ h4_datatype = DFNT_FLOAT32;
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_DOUBLE)) {
+ h4_datatype = DFNT_FLOAT64;
+/*
+ * This is not supported by HDF4
+ *
+ } else if (H5Tequal(h5_datatype,H5T_NATIVE_LDOUBLE)) {
+ h4_datatype = DFNT_FLOAT128;
+*/
+ } else {
+ h4_datatype = FAIL;
+ }
+
+ return h4_datatype;
+
+}
+
+
+/*****************************************************************************
+
+ Routine: h4type_to_memtype(h4type)
+
+ Description: Translate h4 datatype into mem datatype
+
+ Input: h4 datatype
+
+ Output: function return, mem datatype
+
+*****************************************************************************/
+
+hid_t h4type_to_memtype(int32 h4_datatype)
+{
+ hid_t mem_datatype;
+
+ switch (h4_datatype) {
+ case DFNT_INT8:
+ case DFNT_NINT8:
+ case DFNT_LINT8:
+ mem_datatype = H5T_NATIVE_SCHAR; break;
+ case DFNT_UINT8:
+ case DFNT_NUINT8:
+ case DFNT_LUINT8:
+ mem_datatype = H5T_NATIVE_UCHAR; break;
+ case DFNT_INT16:
+ case DFNT_NINT16:
+ case DFNT_LINT16:
+ mem_datatype = H5T_NATIVE_SHORT; break;
+ case DFNT_UINT16:
+ case DFNT_NUINT16:
+ case DFNT_LUINT16:
+ mem_datatype = H5T_NATIVE_USHORT; break;
+ case DFNT_INT32:
+ case DFNT_NINT32:
+ case DFNT_LINT32:
+ mem_datatype = H5T_NATIVE_INT; break;
+ case DFNT_UINT32:
+ case DFNT_NUINT32:
+ case DFNT_LUINT32:
+ mem_datatype = H5T_NATIVE_UINT; break;
+ case DFNT_INT64:
+ case DFNT_NINT64:
+ case DFNT_LINT64:
+ mem_datatype = H5T_NATIVE_LONG; break;
+ case DFNT_UINT64:
+ case DFNT_NUINT64:
+ case DFNT_LUINT64:
+ mem_datatype = H5T_NATIVE_ULONG; break;
+ case DFNT_INT128:
+ case DFNT_NINT128:
+ case DFNT_LINT128:
+ mem_datatype = H5T_NATIVE_LLONG; break;
+ case DFNT_UINT128:
+ case DFNT_NUINT128:
+ case DFNT_LUINT128:
+ mem_datatype = H5T_NATIVE_ULLONG; break;
+ case DFNT_FLOAT32:
+ case DFNT_NFLOAT32:
+ case DFNT_LFLOAT32:
+ mem_datatype = H5T_NATIVE_FLOAT; break;
+ case DFNT_FLOAT64:
+ case DFNT_NFLOAT64:
+ case DFNT_LFLOAT64:
+ mem_datatype = H5T_NATIVE_DOUBLE; break;
+ case DFNT_FLOAT128:
+ case DFNT_NFLOAT128:
+ case DFNT_LFLOAT128:
+ mem_datatype = H5T_NATIVE_LDOUBLE; break;
+ default:
+ mem_datatype = FAIL;
+ }
+
+ return mem_datatype;
+
+}
+#endif
+
+
+/*****************************************************************************
+
+ Routine: test_file
+
+ Description: Test a file for read/write - ability.
+
+ Input: filename - Unix filename
+
+ Output: function return, global variable - errno
+
+*****************************************************************************/
+
+int test_file(char *filename,int oflag,mode_t mode)
+{
+ int fid;
+
+ errno = 0;
+
+ fid = open(filename, oflag, mode);
+ if (fid < 0) {
+ perror(filename);
+ }
+ close(fid);
+
+ return errno;
+
+}
+
+
+/*****************************************************************************
+
+ Routine: test_dir
+
+ Description: Test pathway to determine if it is a directory
+
+ Input: path - pathname given
+
+ Output: function return TRUE/FALSE
+
+*****************************************************************************/
+
+int test_dir(char *path)
+{
+
+ struct stat buf;
+ struct stat *buf_ptr;
+ int idir;
+
+ buf_ptr = &buf;
+
+ idir = stat(path, buf_ptr);
+ if (idir < 0) {
+ if (errno == 2) {
+ return 0;
+ } else {
+ perror(path);
+ }
+ }
+
+ return S_ISDIR(buf_ptr->st_mode);
+}
+
+/*****************************************************************************
+
+ Routine: BuildFilename()
+
+ Description: Build a filename with new extension
+
+ Input: filename - present filename
+ ext - extension to root of filename
+
+ Output: (filename:r).ext
+
+*****************************************************************************/
+
+char *BuildFilename(char *filename, char *ext)
+{
+ /* build outgoing filename */
+
+ char *filename_out;
+ char *lastper_ptr, *lastdir_ptr;
+ int root_len;
+
+ lastper_ptr = strrchr(filename,'.');
+ lastdir_ptr = strrchr(filename,'/');
+
+ if ( lastper_ptr <= lastdir_ptr ) { /* no extension */
+ root_len = strlen(filename);
+ } else { /* existing extension */
+ root_len = (int)(lastper_ptr - filename);
+ }
+
+ filename_out = (char *)HDmalloc(root_len + strlen(ext) + 2);
+ filename_out = strncpy(filename_out, filename, (size_t)root_len);
+ filename_out[root_len] = '\0';
+ filename_out = strcat(filename_out,".");
+ filename_out = strcat(filename_out,ext);
+
+ return filename_out;
+}
+
diff --git a/tools/h5toh4/h5toh4.h b/tools/h5toh4/h5toh4.h
new file mode 100644
index 0000000..d268060
--- /dev/null
+++ b/tools/h5toh4/h5toh4.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 1998 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Paul Harten <pharten@ncsa.uiuc.edu>
+ * Friday, October 16th, 1998
+ *
+ * Purpose: Convert H5 files to H4 files.
+ */
+
+#ifndef _H5TOH4_H
+#define _H5TOH4_H
+
+#include "hdf.h"
+#include "mfhdf.h"
+#include "hdf5.h"
+
+#ifdef H5_HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+typedef struct op_data_t {
+ /*
+ * information being carried between iterations.
+ *
+ */
+
+ int32 hfile_id;
+ int32 vgroup_id;
+ int32 sd_id;
+ int32 sds_id;
+ int32 vdata_id;
+ int32 obj_idx;
+
+} op_data_t;
+
+#ifdef H5TOH4_DEBUG
+#define DEBUG_PRINT(s1,s2,s3,n1) ( fprintf(stderr,s1,s2,s3,n1) )
+#else
+#define DEBUG_PRINT(s1,s2,s3,n1) ( fprintf(stderr," ") )
+#endif
+
+#endif
diff --git a/tools/h5toh4/testh5toh4.sh b/tools/h5toh4/testh5toh4.sh
new file mode 100755
index 0000000..986a6a2
--- /dev/null
+++ b/tools/h5toh4/testh5toh4.sh
@@ -0,0 +1,299 @@
+#! /bin/sh
+#
+# Copyright (C) 1997-2001 National Center for Supercomputing Applications.
+# All rights reserved.
+#
+
+H5TOH4=h5toh4 # a relative name
+H5TOH4_BIN=`pwd`/$H5TOH4 # an absolute command path
+
+cmp='cmp -s'
+diff='diff -c'
+
+RM='rm -f'
+SED='sed '
+H4DUMP='hdp'
+
+# Verify if $H4DUMP is a valid command.
+tmpfile=/tmp/testh5toh4.$$
+$H4DUMP -H > $tmpfile
+if test -s "$tmpfile"; then
+ # Find out which version of hdp is being used. Over simplified
+ # algorithm but will do the job for now.
+ if ( grep -s 'NCSA HDF Version 4.1 Release [3-9]' $tmpfile > /dev/null )
+ then
+ H4DUMPVER=413
+ else
+ H4DUMPVER=0
+ echo " Some tests maybe skipped because your version of $H4DUMP does"
+ echo " not handle loops in Vgroups correctly. You need version"
+ echo " 4.1 Release 3 or later. Visit http://hdf.ncsa.uiuc.edu"
+ echo " or email hdfhelp@ncsa.uiuc.edu for more information."
+ fi
+else
+ echo " Could not run the '$H4DUMP' command. The test can still proceed"
+ echo " but it may fail if '$H4DUMP' is needed to verify the output."
+ echo " You can make sure '$H4DUMP' is among your shell PATH and run"
+ echo " the test again. You may also visit http://hdf.ncsa.uiuc.edu"
+ echo " or email hdfhelp@ncsa.uiuc.edu for more information."
+ H4DUMP=:
+ H4DUMPVER=0
+fi
+$RM $tmpfile
+
+# The build (current) directory might be different than the source directory.
+if test -z "$srcdir"; then
+ srcdir=.
+fi
+mkdir ../testfiles >/dev/null 2>&1
+
+SRCDIR="$srcdir/../testfiles"
+OUTDIR="../testfiles/Results"
+
+test -d $OUTDIR || mkdir $OUTDIR
+
+nerrors=0
+verbose=yes
+
+# 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'
+}
+
+# Run a test and print PASS or *FAIL*. If a test fails then increment
+# the `nerrors' global variable and (if $verbose is set) display the
+# difference between the actual and the expected hdf4 files. The
+# expected hdf4 files are in testfiles/Expected directory.
+# The actual hdf4 file is not removed if $HDF5_NOCLEANUP is to a non-null
+# value.
+CONVERT() {
+ # Run h5toh4 convert.
+ TESTING $H5TOH4 $@
+
+ #
+ # Set up arguments to run the conversion test.
+ # The converter assumes all hdf5 files has the .h5 suffix as in the form
+ # of foo.h5. It creates the corresponding hdf4 files with the .hdf suffix
+ # as in the form of foo.hdf. One exception is that if exactly two file
+ # names are given, it treats the first argument as an hdf5 file and creates
+ # the corresponding hdf4 file with the name as the second argument, WITOUT
+ # any consideration of the suffix. (For this test script, in order to
+ # match the output hdf4 file with the expected hdf4 file, it expects the
+ # second file of the two-files tests has the .hdf suffix too.)
+ #
+ # If SRCDIR != OUTDIR, need to copy the input hdf5 files from the SRCDIR
+ # to the OUTDIR and transform the input file pathname because of the suffix
+ # convention mentioned above. This way, the hdf4 files are always created
+ # in the OUTDIR directory.
+ #
+
+ INFILES=""
+ OUTFILES=""
+ MULTIRUN=""
+
+ case "$1" in
+ "-m") # multiple files conversion
+ MULTIRUN="-m"
+ shift
+ for f in $*
+ do
+ if test "$SRCDIR" != "$OUTDIR"; then
+ cp $SRCDIR/$f $OUTDIR/$f
+ fi
+ INFILES="$INFILES $f"
+ OUTFILES="$OUTFILES `basename $f .h5`.hdf"
+ shift
+ done
+ ;;
+ * ) # Single file conversion
+ case $# in
+ 1) if test "$SRCDIR" != "$OUTDIR"; then
+ cp $SRCDIR/$1 $OUTDIR/$1
+ fi
+ INFILES="$1"
+ OUTFILES="`basename $1 .h5`.hdf"
+ ;;
+ 2) # hdf4 file specified
+ if test "$SRCDIR" != "$OUTDIR"; then
+ cp $SRCDIR/$1 $OUTDIR/$1
+ fi
+ INFILES="$1"
+ OUTFILES="$2"
+ ;;
+ *) # Illegal
+ echo "Illegal arguments"
+ exit 1
+ ;;
+ esac
+ ;;
+ esac
+
+ # run the conversion and remove input files that have been copied over
+ (
+ cd $OUTDIR
+ $H5TOH4_BIN $MULTIRUN $INFILES 2>/dev/null
+ if test "$SRCDIR" != "$OUTDIR"; then
+ $RM $INFILES
+ fi
+ )
+
+ # Verify results
+ result="passed"
+ for f in $OUTFILES
+ do
+ if $cmp $SRCDIR/Expected/$f $OUTDIR/$f
+ then
+ :
+ else
+ # Use hdp to dump the files and verify the output.
+ # Filter out the output of "reference = ..." because
+ # reference numbers are immaterial in general.
+ outfile=`basename $f .hdf`
+ expect_out=$outfile.expect
+ actual_out=$outfile.actual
+
+ if [ $outfile = "tloop" -a $H4DUMPVER -lt 413 ]
+ then
+ echo " -SKIP-"
+ result="skipped"
+ touch $expect_out $actual_out # fake them
+ else
+ (cd $SRCDIR/Expected
+ $H4DUMP dumpvg $outfile.hdf
+ $H4DUMP dumpvd $outfile.hdf
+ $H4DUMP dumpsds $outfile.hdf ) |
+ sed -e 's/reference = [0-9]*;//' > $expect_out
+ (cd $OUTDIR
+ $H4DUMP dumpvg $outfile.hdf
+ $H4DUMP dumpvd $outfile.hdf
+ $H4DUMP dumpsds $outfile.hdf ) |
+ sed -e 's/reference = [0-9]*;//' > $actual_out
+ fi
+
+ if [ "passed" = $result -a ! -s $actual_out ] ; then
+ echo "*FAILED*"
+ nerrors="`expr $nerrors + 1`"
+ result=failed
+ test yes = "$verbose" &&
+ echo " H4DUMP failed to produce valid output"
+ elif $cmp $expect_out $actual_out; then
+ :
+ else
+ if test "passed" = $result; then
+ echo "*FAILED*"
+ nerrors="`expr $nerrors + 1`"
+ result=failed
+ fi
+ test yes = "$verbose" &&
+ echo " Actual result (*.actual) differs from expected result (*.expect)" &&
+ $diff $expect_out $actual_out |sed 's/^/ /'
+ fi
+ fi
+
+ # Clean up output file
+ if test -z "$HDF5_NOCLEANUP"; then
+ $RM $expect_out $actual_out
+ $RM $OUTDIR/$f
+ fi
+ done
+ if test "passed" = "$result"; then
+ echo " PASSED"
+ fi
+}
+
+
+
+##############################################################################
+##############################################################################
+### T H E T E S T S ###
+##############################################################################
+##############################################################################
+
+$RM $OUTDIR/*.hdf $OUTDIR/*.tmp
+
+#
+# The HDF4 filenames are created based upon the HDF5 filenames
+# without the extension.
+#
+
+# test for converting H5 groups to H4 Vgroups.
+CONVERT tgroup.h5
+
+# test for converting H5 datasets to H4 SDS's.
+CONVERT tdset.h5
+
+# test for converting H5 attributes to H4 attributes.
+CONVERT tattr.h5
+
+# test for converting H5 soft links.
+CONVERT tslink.h5
+
+# test for converting H5 hard links.
+CONVERT thlink.h5
+
+# test for converting H5 compound data type to H4 Vdata.
+CONVERT tcompound.h5
+
+# test for converting all H5 objects at in same file.
+CONVERT tall.h5
+
+# tests for converting H5 objects with loops.
+CONVERT tloop.h5
+
+# test for converting extendable H5 datasets to H4 SDS's.
+CONVERT tdset2.h5
+
+# test for converting extendable H5 datasets with compound data type to H4 Vdata.
+CONVERT tcompound2.h5
+
+# tests for converting H5 objects from many different pathways.
+CONVERT tmany.h5
+
+# tests for converting H5 string objects.
+CONVERT tstr.h5
+
+# tests for converting more H5 string objects.
+CONVERT tstr2.h5
+
+#
+# The test for conversion are the same as above with the only difference
+# being that the HDF4 filenames are given explicitly.
+#
+
+$RM $OUTDIR/*.tmp
+CONVERT tgroup.h5 tgroup.hdf
+CONVERT tdset.h5 tdset.hdf
+CONVERT tattr.h5 tattr.hdf
+CONVERT tslink.h5 tslink.hdf
+CONVERT thlink.h5 thlink.hdf
+CONVERT tcompound.h5 tcompound.hdf
+CONVERT tall.h5 tall.hdf
+CONVERT tloop.h5 tloop.hdf
+CONVERT tdset2.h5 tdset2.hdf
+CONVERT tcompound2.h5 tcompound2.hdf
+CONVERT tmany.h5 tmany.hdf
+CONVERT tstr.h5 tstr.hdf
+CONVERT tstr2.h5 tstr2.hdf
+
+#
+# Again, the test for conversion are the same as the first set of test.
+# Here, multiple conversion are done on HDF5 files at one time.
+#
+
+$RM $OUTDIR/*.hdf $OUTDIR/*.tmp
+CONVERT -m tgroup.h5 tdset.h5 tattr.h5 tslink.h5 thlink.h5
+CONVERT -m tcompound.h5 tall.h5
+CONVERT -m tloop.h5
+CONVERT -m tdset2.h5 tcompound2.h5 tmany.h5
+CONVERT -m tstr.h5 tstr2.h5
+
+if test $nerrors -eq 0 ; then
+ echo "All h5toh4 tests passed."
+fi
+
+if test -z "$HDF5_NOCLEANUP"; then
+ $RM -r $OUTDIR
+fi
+exit $nerrors