summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/h5ls.c66
-rw-r--r--tools/h5tools.c191
-rw-r--r--tools/h5tools.h22
3 files changed, 220 insertions, 59 deletions
diff --git a/tools/h5ls.c b/tools/h5ls.c
index 93a756a..0ae0c21 100644
--- a/tools/h5ls.c
+++ b/tools/h5ls.c
@@ -78,9 +78,9 @@ usage: %s [OPTIONS] FILE [GROUP]\n\
static void
dump_dataset_values(hid_t dset)
{
- hid_t f_type, m_type=-1;
+ hid_t f_type = H5Dget_type(dset);
+ size_t size = H5Tget_size(f_type);
h5dump_t info;
- size_t size;
/* Set to all default values and then override */
memset(&info, 0, sizeof info);
@@ -88,62 +88,26 @@ dump_dataset_values(hid_t dset)
info.line_ncols = width_g;
/*
- * Decide which data type to use for printing the values and make any
- * necessary adjustments to the way the values will be formatted.
+ * If the dataset is a 1-byte integer type then format it as an ASCI
+ * character string instead of integers.
*/
- f_type = H5Dget_type(dset);
- size = H5Tget_size(f_type);
- switch (H5Tget_class(f_type)) {
- case H5T_INTEGER:
- if (1==size) {
- /*
- * Assume that the dataset is being used to hold character values
- * and print the values as strings.
- */
- info.elmt_suf1 = "";
- info.elmt_suf2 = "";
- info.idx_fmt = " (%s) \"";
- info.line_suf = "\"";
- }
-
- /*
- * For printing use an integer which is the same width and sign as
- * the file but in native byte order.
- */
- m_type = H5Tcopy(H5T_NATIVE_INT);
- H5Tset_offset(m_type, 0);
- H5Tset_precision(m_type, size*8);
- H5Tset_size(m_type, size);
- H5Tset_sign(m_type, H5Tget_sign(f_type));
- break;
-
- case H5T_FLOAT:
- if (size==sizeof(float)) {
- m_type = H5Tcopy(H5T_NATIVE_FLOAT);
- } else {
- m_type = H5Tcopy(H5T_NATIVE_DOUBLE);
- }
- break;
-
- case H5T_COMPOUND:
- printf(" Data: printing of compound data types is not implemented "
- "yet\n");
- break;
-
- default:
- /*unable to print*/
- printf(" Data: [unable to print]\n");
- break;
+ if (1==size && H5T_INTEGER==H5Tget_class(f_type)) {
+ info.elmt_suf1 = "";
+ info.elmt_suf2 = "";
+ info.idx_fmt = " (%s) \"";
+ info.line_suf = "\"";
}
- H5Tclose(f_type);
- if (m_type<0) return; /*not printable*/
+
/*
* Print all the values.
*/
printf(" Data:\n");
- h5dump(stdout, &info, dset, m_type);
- H5Tclose(m_type);
+ if (h5dump(stdout, &info, dset, -1)<0) {
+ printf(" Unable to print data.\n");
+ }
+
+ H5Tclose(f_type);
}
diff --git a/tools/h5tools.c b/tools/h5tools.c
index ef1e954..7941377 100644
--- a/tools/h5tools.c
+++ b/tools/h5tools.c
@@ -27,6 +27,7 @@
#define OPT(X,S) ((X)?(X):(S))
#define MIN(X,Y) ((X)<(Y)?(X):(Y))
#define NELMTS(X) (sizeof(X)/sizeof(*X))
+#define ALIGN(A,Z) ((((A)+(Z)-1)/(Z))*(Z))
/*-------------------------------------------------------------------------
@@ -102,8 +103,10 @@ h5dump_prefix(char *s/*out*/, const h5dump_t *info, hsize_t elmtno, int ndims,
static void
h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp)
{
- size_t i, n;
- char temp[1024];
+ size_t i, n, offset;
+ char temp[1024], *name;
+ hid_t memb;
+ int nmembs, j;
if (H5Tequal(type, H5T_NATIVE_DOUBLE)) {
sprintf(temp, "%g", *((double*)vp));
@@ -111,9 +114,30 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp)
sprintf(temp, "%g", *((float*)vp));
} else if (H5Tequal(type, H5T_NATIVE_CHAR) ||
H5Tequal(type, H5T_NATIVE_UCHAR)) {
- if ('\\'==*((char*)vp)) strcpy(temp, "\\\\");
- else if (isprint(*((char*)vp))) sprintf(temp, "%c", *((char*)vp));
- else sprintf(temp, "\\%03o", *((unsigned char*)vp));
+ switch (*((char*)vp)) {
+ case '\\':
+ strcpy(temp, "\\\\");
+ break;
+ case '\b':
+ strcpy(temp, "\\b");
+ break;
+ case '\f':
+ strcpy(temp, "\\f");
+ break;
+ case '\n':
+ strcpy(temp, "\\n");
+ break;
+ case '\r':
+ strcpy(temp, "\\r");
+ break;
+ case '\t':
+ strcpy(temp, "\\t");
+ break;
+ default:
+ if (isprint(*((char*)vp))) sprintf(temp, "%c", *((char*)vp));
+ else sprintf(temp, "\\%03o", *((unsigned char*)vp));
+ break;
+ }
} else if (H5Tequal(type, H5T_NATIVE_SHORT)) {
sprintf(temp, "%d", *((short*)vp));
} else if (H5Tequal(type, H5T_NATIVE_USHORT)) {
@@ -126,6 +150,24 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp)
sprintf(temp, "%ld", *((long*)vp));
} else if (H5Tequal(type, H5T_NATIVE_ULONG)) {
sprintf(temp, "%lu", *((unsigned long*)vp));
+ } else if (H5T_COMPOUND==H5Tget_class(type)) {
+ nmembs = H5Tget_nmembers(type);
+ strcpy(temp, OPT(info->cmpd_pre, "{"));
+ for (j=0; j<nmembs; j++) {
+ if (j) strcat(temp, OPT(info->cmpd_sep, ","));
+
+ /* The name */
+ name = H5Tget_member_name(type, j);
+ sprintf(temp+strlen(temp), OPT(info->cmpd_name, ""), name);
+ free(name);
+
+ /* The value */
+ offset = H5Tget_member_offset(type, j);
+ memb = H5Tget_member_type(type, j);
+ h5dump_sprint(temp+strlen(temp), info, memb, (char*)vp+offset);
+ H5Tclose(memb);
+ }
+ strcat(temp, OPT(info->cmpd_suf, "}"));
} else {
strcpy(temp, "0x");
n = H5Tget_size(type);
@@ -243,7 +285,7 @@ h5dump_simple(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type)
for (i=0; i<hs_nelmts; i++) {
/* Render the element */
h5dump_sprint(p_buf, info, p_type, sm_buf+i*p_type_nbytes);
- if (i+1<hs_nelmts) {
+ if (elmtno+i+1<p_nelmts) {
strcat(p_buf, OPT(info->elmt_suf1, ","));
}
@@ -297,6 +339,121 @@ h5dump_simple(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type)
/*-------------------------------------------------------------------------
+ * Function: h5dump_fixtype
+ *
+ * Purpose: Given a file data type choose a memory data type which is
+ * appropriate for printing the data.
+ *
+ * Return: Success: Memory data type
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, July 23, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+h5dump_fixtype(hid_t f_type)
+{
+ hid_t m_type=-1, f_memb;
+ hid_t *memb=NULL;
+ char **name=NULL;
+ int nmembs, i;
+ size_t size;
+
+ size = H5Tget_size(f_type);
+ switch (H5Tget_class(f_type)) {
+
+ case H5T_INTEGER:
+ /*
+ * Use the smallest native integer type of the same sign as the file
+ * such that the memory type is at least as large as the file type.
+ * If there is no memory type large enough then use the largest
+ * memory type available.
+ */
+ if (size<=sizeof(char)) {
+ m_type = H5Tcopy(H5T_NATIVE_CHAR);
+ } else if (size<=sizeof(short)) {
+ m_type = H5Tcopy(H5T_NATIVE_SHORT);
+ } else if (size<=sizeof(int)) {
+ m_type = H5Tcopy(H5T_NATIVE_INT);
+ } else if (size<=sizeof(long)) {
+ m_type = H5Tcopy(H5T_NATIVE_LONG);
+ } else {
+ m_type = H5Tcopy(H5T_NATIVE_LLONG);
+ }
+ H5Tset_sign(m_type, H5Tget_size(f_type));
+ break;
+
+ case H5T_FLOAT:
+ /*
+ * Use the smallest native floating point type available such that
+ * its size is at least as large as the file type. If there is not
+ * native type large enough then use the largest native type.
+ */
+ if (size<=sizeof(float)) {
+ m_type = H5Tcopy(H5T_NATIVE_FLOAT);
+ } else if (size<=sizeof(double)) {
+ m_type = H5Tcopy(H5T_NATIVE_DOUBLE);
+ } else {
+ m_type = H5Tcopy(H5T_NATIVE_LDOUBLE);
+ }
+ break;
+
+ case H5T_COMPOUND:
+ nmembs = H5Tget_nmembers(f_type);
+ memb = calloc(nmembs, sizeof(hid_t));
+ name = calloc(nmembs, sizeof(char*));
+
+ for (i=0, size=0; i<nmembs; i++) {
+ f_memb = H5Tget_member_type(f_type, i);
+ memb[i] = h5dump_fixtype(f_memb);
+ size = ALIGN(size, H5Tget_size(memb[i])) + H5Tget_size(memb[i]);
+ H5Tclose(f_memb);
+ name[i] = H5Tget_member_name(f_type, i);
+ if (memb[i]<0 || NULL==name[i]) goto done;
+ }
+
+ m_type = H5Tcreate(H5T_COMPOUND, size);
+ for (i=0, size=0; i<nmembs; i++) {
+ H5Tinsert(m_type, name[i], size, memb[i]);
+ size = ALIGN(size, H5Tget_size(memb[i])) + H5Tget_size(memb[i]);
+ }
+ break;
+
+ case H5T_TIME:
+ case H5T_STRING:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ /*
+ * These type classes are not implemented yet.
+ */
+ break;
+
+ default:
+ /* What the heck? */
+ break;
+ }
+
+ done:
+ /* Clean up temp buffers */
+ if (memb && name) {
+ for (i=0; i<nmembs; i++) {
+ if (memb[i]>=0) H5Tclose(memb[i]);
+ if (name[i]) free(name[i]);
+ }
+ free(memb);
+ free(name);
+ }
+
+ return m_type;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: h5dump
*
* Purpose: Print some values from a dataset. The values to print are
@@ -315,13 +472,31 @@ h5dump_simple(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type)
*-------------------------------------------------------------------------
*/
int
-h5dump(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type)
+h5dump(FILE *stream, const h5dump_t *info, hid_t dset, hid_t _p_type)
{
hid_t f_space;
+ hid_t p_type = _p_type;
+ hid_t f_type;
+ int status;
+ /* Check the data space */
f_space = H5Dget_space(dset);
if (H5Sis_simple(f_space)<=0) return -1;
H5Sclose(f_space);
- return h5dump_simple(stream, info, dset, p_type);
+ /*
+ * Check the data type. If the caller didn't supply a data type then
+ * use an appropriate native data type.
+ */
+ if (p_type<0) {
+ f_type = H5Dget_type(dset);
+ p_type = h5dump_fixtype(f_type);
+ H5Tclose(f_type);
+ if (p_type<0) return -1;
+ }
+
+ /* Print the data */
+ status = h5dump_simple(stream, info, dset, p_type);
+ if (p_type!=_p_type) H5Tclose(p_type);
+ return status;
}
diff --git a/tools/h5tools.h b/tools/h5tools.h
index 966eaff..3b9b231 100644
--- a/tools/h5tools.h
+++ b/tools/h5tools.h
@@ -18,6 +18,28 @@
*/
typedef struct h5dump_t {
/*
+ * Fields associated with compound data types.
+ *
+ * name: How the name of the struct member is printed in the
+ * values. By default the name is not printed, but a
+ * reasonable setting might be "%s=" which prints the name
+ * followed by an equal sign and then the value.
+ *
+ * sep: A string that separates one member from another. The
+ * default is a comma.
+ *
+ * pre: A string to print at the beginning of a compound type.
+ * The default is a left curly brace.
+ *
+ * suf: A string to print at the end of each compound type. The
+ * default is a right curly brace.
+ */
+ const char *cmpd_name;
+ const char *cmpd_sep;
+ const char *cmpd_pre;
+ const char *cmpd_suf;
+
+ /*
* Fields associated with the individual elements.
*
* fmt: A printf(3c) format to use to print the value string