summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/h5ls.c39
-rw-r--r--tools/h5tools.c98
-rw-r--r--tools/h5tools.h16
3 files changed, 115 insertions, 38 deletions
diff --git a/tools/h5ls.c b/tools/h5ls.c
index 0ae0c21..c79c8d1 100644
--- a/tools/h5ls.c
+++ b/tools/h5ls.c
@@ -86,6 +86,7 @@ dump_dataset_values(hid_t dset)
memset(&info, 0, sizeof info);
info.idx_fmt = " (%s) ";
info.line_ncols = width_g;
+ if (verbose_g) info.cmpd_name = "%s=";
/*
* If the dataset is a 1-byte integer type then format it as an ASCI
@@ -177,6 +178,7 @@ list (hid_t group, const char *name, void __unused__ *op_data)
int i;
char buf[512], comment[50];
H5G_stat_t statbuf;
+ struct tm *tm;
/* Disable error reporting */
H5Eget_auto (&func, &edata);
@@ -185,13 +187,6 @@ list (hid_t group, const char *name, void __unused__ *op_data)
/* Print info about each name */
printf ("%-25s ", name);
- if (H5Gstat (group, name, TRUE, &statbuf)>=0) {
- sprintf (buf, "%lu:%lu:%lu:%lu",
- statbuf.fileno[1], statbuf.fileno[0],
- statbuf.objno[1], statbuf.objno[0]);
- printf ("%-20s ", buf);
- }
-
if ((obj=H5Dopen (group, name))>=0) {
hsize_t size[64];
hsize_t maxsize[64];
@@ -209,7 +204,6 @@ list (hid_t group, const char *name, void __unused__ *op_data)
printf ("}\n");
H5Dclose (space);
H5Aiterate (obj, NULL, list_attr, NULL);
- if (dump_g) dump_dataset_values(obj);
H5Dclose (obj);
} else if ((obj=H5Gopen (group, name))>=0) {
printf ("Group\n");
@@ -228,11 +222,30 @@ list (hid_t group, const char *name, void __unused__ *op_data)
printf ("Unknown Type\n");
}
- /* Display the comment if the object has one */
- comment[0] = '\0';
- H5Gget_comment(group, name, sizeof(comment), comment);
- strcpy(comment+sizeof(comment)-4, "...");
- if (comment[0]) printf("%26s%s\n", "", comment);
+ if (verbose_g>0) {
+ if (H5Gstat(group, name, TRUE, &statbuf)>=0) {
+ printf(" %-10s %lu:%lu:%lu:%lu\n",
+ "Location:", statbuf.fileno[1], statbuf.fileno[0],
+ statbuf.objno[1], statbuf.objno[0]);
+ if (statbuf.mtime>0 && NULL!=(tm = localtime(&(statbuf.mtime)))) {
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm);
+ printf(" %-10s %s\n", "Modtime:", buf);
+ }
+ }
+
+ /* Display the comment if the object has one */
+ comment[0] = '\0';
+ H5Gget_comment(group, name, sizeof(comment), comment);
+ strcpy(comment+sizeof(comment)-4, "...");
+ if (comment[0]) printf(" %-10s %s\n", "Comment:", comment);
+ }
+
+ if (dump_g && (obj=H5Dopen(group, name))) {
+ /* Turn on error reporting before dumping the data */
+ H5Eset_auto(func, edata);
+ dump_dataset_values(obj);
+ H5Dclose(obj);
+ }
/* Restore error reporting */
H5Eset_auto (func, edata);
diff --git a/tools/h5tools.c b/tools/h5tools.c
index 7941377..fae2251 100644
--- a/tools/h5tools.c
+++ b/tools/h5tools.c
@@ -22,7 +22,7 @@
* size of that temporary buffer in bytes. For efficiency's sake, choose the
* largest value suitable for your machine (for testing use a small value).
*/
-#define H5DUMP_BUFSIZE 1024
+#define H5DUMP_BUFSIZE (1024*1024)
#define OPT(X,S) ((X)?(X):(S))
#define MIN(X,Y) ((X)<(Y)?(X):(Y))
@@ -103,10 +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, offset;
+ size_t i, n, offset, size, dims[4], nelmts;
char temp[1024], *name;
hid_t memb;
- int nmembs, j;
+ int nmembs, j, k, ndims;
if (H5Tequal(type, H5T_NATIVE_DOUBLE)) {
sprintf(temp, "%g", *((double*)vp));
@@ -115,6 +115,9 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp)
} else if (H5Tequal(type, H5T_NATIVE_CHAR) ||
H5Tequal(type, H5T_NATIVE_UCHAR)) {
switch (*((char*)vp)) {
+ case '"':
+ strcpy(temp, "\\\"");
+ break;
case '\\':
strcpy(temp, "\\\\");
break;
@@ -164,7 +167,18 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp)
/* The value */
offset = H5Tget_member_offset(type, j);
memb = H5Tget_member_type(type, j);
- h5dump_sprint(temp+strlen(temp), info, memb, (char*)vp+offset);
+ size = H5Tget_size(memb);
+ ndims = H5Tget_member_dims(type, j, dims, NULL);
+ assert(ndims>=0 && ndims<=4);
+ for (k=0, nelmts=1; k<ndims; k++) nelmts *= dims[k];
+
+ if (nelmts>1) strcat(temp, OPT(info->arr_pre, "["));
+ for (i=0; i<nelmts; i++) {
+ if (i) strcat(temp, OPT(info->arr_sep, ","));
+ h5dump_sprint(temp+strlen(temp), info, memb,
+ (char*)vp+offset+i*size);
+ }
+ if (nelmts>1) strcat(temp, OPT(info->arr_suf, "]"));
H5Tclose(memb);
}
strcat(temp, OPT(info->cmpd_suf, "}"));
@@ -361,8 +375,8 @@ 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;
+ int nmembs, i, j, *ndims=NULL;
+ size_t size, offset, *dims=NULL, nelmts;
size = H5Tget_size(f_type);
switch (H5Tget_class(f_type)) {
@@ -385,7 +399,7 @@ h5dump_fixtype(hid_t f_type)
} else {
m_type = H5Tcopy(H5T_NATIVE_LLONG);
}
- H5Tset_sign(m_type, H5Tget_size(f_type));
+ H5Tset_sign(m_type, H5Tget_sign(f_type));
break;
case H5T_FLOAT:
@@ -404,23 +418,51 @@ h5dump_fixtype(hid_t f_type)
break;
case H5T_COMPOUND:
+ /*
+ * We have to do this in two steps. The first step scans the file
+ * type and converts the members to native types and remembers all
+ * their names and sizes, computing the size of the memory compound
+ * type at the same time. Then we create the memory compound type
+ * and add the members.
+ */
nmembs = H5Tget_nmembers(f_type);
memb = calloc(nmembs, sizeof(hid_t));
name = calloc(nmembs, sizeof(char*));
+ ndims = calloc(nmembs, sizeof(int));
+ dims = calloc(nmembs*4, sizeof(size_t));
for (i=0, size=0; i<nmembs; i++) {
+
+ /* Get the member type and fix it */
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);
+ if (memb[i]<0) goto done;
+
+ /* Get the member dimensions */
+ ndims[i] = H5Tget_member_dims(f_type, i, dims+i*4, NULL);
+ assert(ndims[i]>=0 && ndims[i]<=4);
+ for (j=0, nelmts=1; j<ndims[i]; j++) nelmts *= dims[i*4+j];
+
+ /* Get the member name */
name[i] = H5Tget_member_name(f_type, i);
- if (memb[i]<0 || NULL==name[i]) goto done;
+ if (NULL==name[i]) goto done;
+
+ /*
+ * Compute the new offset so each member is aligned on a byte
+ * boundary which is the same as the member size.
+ */
+ size = ALIGN(size, H5Tget_size(memb[i])) +
+ nelmts * H5Tget_size(memb[i]);
}
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]);
+ for (i=0, offset=0; i<nmembs; i++) {
+ H5Tinsert_array(m_type, name[i], offset, ndims[i], dims+i*4,
+ NULL, memb[i]);
+ for (j=0, nelmts=1; j<ndims[i]; j++) nelmts *= dims[i*4+j];
+ offset = ALIGN(offset, H5Tget_size(memb[i])) +
+ nelmts * H5Tget_size(memb[i]);
}
break;
@@ -440,13 +482,15 @@ h5dump_fixtype(hid_t f_type)
done:
/* Clean up temp buffers */
- if (memb && name) {
+ if (memb && name && ndims && dims) {
for (i=0; i<nmembs; i++) {
if (memb[i]>=0) H5Tclose(memb[i]);
if (name[i]) free(name[i]);
}
free(memb);
free(name);
+ free(ndims);
+ free(dims);
}
return m_type;
@@ -456,9 +500,10 @@ h5dump_fixtype(hid_t f_type)
/*-------------------------------------------------------------------------
* Function: h5dump
*
- * Purpose: Print some values from a dataset. The values to print are
- * determined by the P_SPACE argument and the format to use to
- * print them is determined by the P_TYPE argument.
+ * Purpose: Print some values from a dataset DSET to the file STREAM
+ * after converting all types to P_TYPE (which should be a
+ * native type). If P_TYPE is a negative value then it will be
+ * computed from the dataset type using only native types.
*
* Return: Success: 0
*
@@ -478,16 +523,14 @@ h5dump(FILE *stream, const h5dump_t *info, hid_t dset, hid_t _p_type)
hid_t p_type = _p_type;
hid_t f_type;
int status;
+ h5dump_t info_dflt;
- /* Check the data space */
- f_space = H5Dget_space(dset);
- if (H5Sis_simple(f_space)<=0) return -1;
- H5Sclose(f_space);
-
- /*
- * Check the data type. If the caller didn't supply a data type then
- * use an appropriate native data type.
- */
+ /* Use default values */
+ if (!stream) stream = stdout;
+ if (!info) {
+ memset(&info_dflt, 0, sizeof info_dflt);
+ info = &info_dflt;
+ }
if (p_type<0) {
f_type = H5Dget_type(dset);
p_type = h5dump_fixtype(f_type);
@@ -495,6 +538,11 @@ h5dump(FILE *stream, const h5dump_t *info, hid_t dset, hid_t _p_type)
if (p_type<0) return -1;
}
+ /* Check the data space */
+ f_space = H5Dget_space(dset);
+ if (H5Sis_simple(f_space)<=0) return -1;
+ H5Sclose(f_space);
+
/* Print the data */
status = h5dump_simple(stream, info, dset, p_type);
if (p_type!=_p_type) H5Tclose(p_type);
diff --git a/tools/h5tools.h b/tools/h5tools.h
index 3b9b231..374bb71 100644
--- a/tools/h5tools.h
+++ b/tools/h5tools.h
@@ -18,6 +18,22 @@
*/
typedef struct h5dump_t {
/*
+ * Fields associated with compound array members.
+ *
+ * pre: A string to print at the beginning of each array. The
+ * default value is the left square bracket `['.
+ *
+ * sep: A string to print between array values. The default
+ * value is a comma.
+ *
+ * suf: A strint to print at the end of each array. The default
+ * value is a right square bracket `]'.
+ */
+ const char *arr_pre;
+ const char *arr_sep;
+ const char *arr_suf;
+
+ /*
* Fields associated with compound data types.
*
* name: How the name of the struct member is printed in the