summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1999-01-21 18:33:39 (GMT)
committerRobb Matzke <matzke@llnl.gov>1999-01-21 18:33:39 (GMT)
commita2b8da49db95737d1962bbf7969cbc86a0b0233d (patch)
treedca97737d4bdf7ee2cdae8040fe5a9b9d6ee0b0f /tools
parentbb776bacbf1dd3e80c7ade0f8afc91c2544977b5 (diff)
downloadhdf5-a2b8da49db95737d1962bbf7969cbc86a0b0233d.zip
hdf5-a2b8da49db95737d1962bbf7969cbc86a0b0233d.tar.gz
hdf5-a2b8da49db95737d1962bbf7969cbc86a0b0233d.tar.bz2
[svn-r1032] Changes since 19990118
---------------------- ./tools/h5tools.c Strings are not converted to null-padding before being printed; they are printed with whatever byte values appear in the file. ./tools/h5ls.c Now able to display attribute data type and data. Added a `-f' or `--full' switch which causes the full name of each object to be displayed instead of just the base name. Added a `-r' or `--recursive' switch that recursively prints the contents of groups, avoiding cycles. More bulletproofing for non-printable characters in things like object names, attribute names, and comment strings. We don't want listing a file to send termal escape sequences because it's sometimes possible to execute commands that way. Since h5ls doesn't usually use quotes around object names we must sometimes escape space characters. External files are listed in a table to make the output less confusing. ./tools/h5tools.c ./tools/h5tools.h Changed h5dump() to h5dump_dset() and added h5dump_mem(). Also make h5dump_fixtype() public. ./test/dtypes.c Wrote some data to an attribute to test h5ls attribute printing. ./src/H5ACprivate.h ./src/H5Apublic.h ./src/H5Dprivate.h ./src/H5Dpublic.h ./src/H5Epublic.h ./src/H5Fprivate.h ./src/H5Fpublic.h ./src/H5Gprivate.h ./src/H5HLprivate.h ./src/H5Oprivate.h ./src/H5Ppublic.h ./src/H5RApublic.h ./src/H5Rpublic.h ./src/H5Spublic.h ./src/H5Tpkg.h ./src/H5Tpublic.h ./src/H5Vprivate.h ./src/H5Zpublic.h ./src/H5private.h ./src/H5public.h Reindented function prototypes after `HDF5API' was added. Also rewrapped long lines. ./src/H5Flow.c Added an `#ifdef WIN32' around an unused variable. ./src/H5api_adpt.h Removed extra carriage returns inserted by "broken" operating system. ./src/H5Dprivate.h ./src/H5Oprivate.h ./src/H5Vprivate.h ./src/H5private.h Removed extraneous inclusion of H5api_adpt.h since it's included in H5public.h which is included by everything. ./src/Makefile.in Added H5api_adpt.h to the list of public header files to fix broken `make install'.
Diffstat (limited to 'tools')
-rw-r--r--tools/h5ls.c425
-rw-r--r--tools/h5tools.c150
-rw-r--r--tools/h5tools.h5
3 files changed, 510 insertions, 70 deletions
diff --git a/tools/h5ls.c b/tools/h5ls.c
index 918712c..9a386f0 100644
--- a/tools/h5ls.c
+++ b/tools/h5ls.c
@@ -10,7 +10,7 @@
/*
* 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.
+ * HDF5 API functions (except for H5G_basename())
*/
#include <H5private.h>
#include <h5tools.h>
@@ -21,6 +21,23 @@ static int width_g = 80; /*output width in characters */
static hbool_t dump_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 */
+
+/* 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 {
@@ -28,7 +45,7 @@ static struct dispatch_t {
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);
+ herr_t (*list2)(hid_t obj, const char *name);
} dispatch_g[H5G_NTYPES];
#define DISPATCH(TYPE,NAME,OPEN,CLOSE,LIST1,LIST2) { \
@@ -41,6 +58,7 @@ static struct dispatch_t {
static herr_t list (hid_t group, const char *name, void *cd);
static void display_type(hid_t type, int indent);
+static char *fix_name(const char *path, const char *base);
/*-------------------------------------------------------------------------
@@ -65,7 +83,9 @@ usage: %s [OPTIONS] FILE [OBJECTS...]\n\
OPTIONS\n\
-h, -?, --help Print a usage message and exit\n\
-d, --dump Print the values of datasets\n\
+ -f, --full Print full path names instead of base names\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\
-wN, --width=N Set the number of columns of output\n\
-v, --verbose Generate more verbose output\n\
@@ -83,9 +103,84 @@ usage: %s [OPTIONS] FILE [OBJECTS...]\n\
/*-------------------------------------------------------------------------
+ * 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.
+ * 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.
*
@@ -97,46 +192,57 @@ usage: %s [OPTIONS] FILE [OBJECTS...]\n\
*-------------------------------------------------------------------------
*/
static int
-display_string(const char *s)
+display_string(FILE *stream, const char *s, hbool_t escape_spaces)
{
int nprint=0;
for (/*void*/; s && *s; s++) {
switch (*s) {
case '"':
- printf("\\\"");
+ if (stream) fprintf(stream, "\\\"");
nprint += 2;
break;
case '\\':
- printf("\\\\");
+ if (stream) fprintf(stream, "\\\\");
nprint += 2;
break;
case '\b':
- printf("\\b");
+ if (stream) fprintf(stream, "\\b");
nprint += 2;
break;
case '\f':
- printf("\\f");
+ if (stream) fprintf(stream, "\\f");
nprint += 2;
break;
case '\n':
- printf("\\n");
+ if (stream) fprintf(stream, "\\n");
nprint += 2;
break;
case '\r':
- printf("\\r");
+ if (stream) fprintf(stream, "\\r");
nprint += 2;
break;
case '\t':
- printf("\\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(*s)) {
- putchar(*s);
+ if (stream) putc(*s, stream);
nprint++;
} else {
- printf("\\%03o", *((const unsigned char*)s));
+ if (stream) {
+ fprintf(stream, "\\%03o", *((const unsigned char*)s));
+ }
nprint += 4;
}
break;
@@ -548,7 +654,7 @@ display_cmpd_type(hid_t type, int indent)
/* Name and offset */
name = H5Tget_member_name(type, i);
printf("\n%*s\"", indent+4, "");
- n = display_string(name);
+ n = display_string(stdout, name, FALSE);
printf("\"%*s +%-4lu ", MAX(0, 16-n), "",
(unsigned long)H5Tget_member_offset(type, i));
free(name);
@@ -655,7 +761,7 @@ display_enum_type(hid_t type, int indent)
/* Print members */
for (i=0; i<nmembs; i++) {
printf("\n%*s", indent+4, "");
- nchars = display_string(name[i]);
+ nchars = display_string(stdout, name[i], TRUE);
printf("%*s = ", MAX(0, 16-nchars), "");
if (native<0) {
@@ -685,7 +791,7 @@ display_enum_type(hid_t type, int indent)
/*-------------------------------------------------------------------------
- * Function: display_string
+ * Function: display_string_type
*
* Purpose: Print information about a string data type.
*
@@ -895,7 +1001,7 @@ dump_dataset_values(hid_t dset)
* Print all the values.
*/
printf(" Data:\n");
- if (h5dump(stdout, &info, dset, -1)<0) {
+ if (h5dump_dset(stdout, &info, dset, -1)<0) {
printf(" Unable to print data.\n");
}
@@ -922,24 +1028,65 @@ dump_dataset_values(hid_t dset)
static herr_t
list_attr (hid_t obj, const char *attr_name, void __unused__ *op_data)
{
- hid_t attr;
- int i;
-
- printf(" %-10s %-10s", "Attribute:", attr_name);
- if ((attr = H5Aopen_name (obj, attr_name))) {
- hid_t space = H5Aget_space (attr);
- hsize_t size[64];
- int ndims = H5Sget_simple_extent_dims (space, size, NULL);
- H5Sclose (space);
- printf (" {");
+ 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, 10-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);
+ printf(" {");
for (i=0; i<ndims; i++) {
- HDfprintf (stdout, "%s%Hu", i?", ":"", size[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.idx_fmt = " (%s) ";
+ 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_suf = "\"";
+ }
+ if ((p_type=h5dump_fixtype(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, p_type, space, buf);
+ }
+ free(buf);
+ H5Tclose(p_type);
}
- putchar ('}');
- H5Aclose (attr);
+
+ H5Sclose(space);
+ H5Tclose(type);
+ H5Aclose(attr);
+ } else {
+ putchar('\n');
}
- putchar ('\n');
return 0;
}
@@ -1013,7 +1160,7 @@ dataset_list1(hid_t dset)
*-------------------------------------------------------------------------
*/
static herr_t
-dataset_list2(hid_t dset)
+dataset_list2(hid_t dset, const char __unused__ *name)
{
hid_t dcpl; /*dataset creation property list*/
hid_t type; /*data type of dataset */
@@ -1031,6 +1178,7 @@ dataset_list2(hid_t dset)
hsize_t total; /*total size or offset */
hsize_t chsize[64]; /*chunk size in elements */
int ndims; /*dimensionality */
+ int n, max_len; /*max extern file name length */
int i;
if (verbose_g>0) {
@@ -1052,8 +1200,19 @@ dataset_list2(hid_t dset)
/* Print information about external strorage */
if ((nf = H5Pget_external_count(dcpl))>0) {
- printf(" %-10s %d external file%s (num/addr/offset/length)\n",
+ 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) {
@@ -1062,17 +1221,21 @@ dataset_list2(hid_t dset)
i, total, "", "",
i+1<nf?"Following addresses are incorrect":"");
} else if (H5S_UNLIMITED==f_size) {
- HDfprintf(stdout, " #%03d %10Hu %10Hu %10s \"",
+ HDfprintf(stdout, " #%03d %10Hu %10Hu %10s ",
i, total, (hsize_t)f_offset, "INF");
- display_string(f_name);
+ display_string(stdout, f_name, TRUE);
} else {
- HDfprintf(stdout, " #%03d %10Hu %10Hu %10Hu \"",
+ HDfprintf(stdout, " #%03d %10Hu %10Hu %10Hu ",
i, total, (hsize_t)f_offset, f_size);
- display_string(f_name);
+ display_string(stdout, f_name, TRUE);
}
- printf("\"\n");
+ 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 */
@@ -1111,6 +1274,36 @@ dataset_list2(hid_t dset)
/*-------------------------------------------------------------------------
+ * 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
@@ -1128,7 +1321,7 @@ dataset_list2(hid_t dset)
*-------------------------------------------------------------------------
*/
static herr_t
-datatype_list2(hid_t type)
+datatype_list2(hid_t type, const char __unused__ *name)
{
printf(" %-10s ", "Type:");
display_type(type, 15);
@@ -1155,7 +1348,7 @@ datatype_list2(hid_t type)
*-------------------------------------------------------------------------
*/
static herr_t
-ragged_list2(hid_t __unused__ ra)
+ragged_list2(hid_t __unused__ ra, const char __unused__ *name)
{
if (dump_g) {
puts(" Data: Not implemented yet (see values of member");
@@ -1215,17 +1408,26 @@ link_open(hid_t location, const char *name)
*-------------------------------------------------------------------------
*/
static herr_t
-list (hid_t group, const char *name, void __unused__ *cd)
+list (hid_t group, const char *name, void *_iter)
{
- hid_t obj;
- char buf[512], comment[50];
+ 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 */
- printf("%-25s ", name);
-
+ /* 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, 25-n), "");
+ } else {
+ n = display_string(stdout, name, TRUE);
+ printf("%*s", MAX(0, 25-n), "");
+ }
+
/* Get object information */
H5E_BEGIN_TRY {
status = H5Gget_objinfo(group, name, FALSE, &sb);
@@ -1242,13 +1444,29 @@ list (hid_t group, const char *name, void __unused__ *cd)
}
/*
+ * 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)) return 0;
-
+ (obj=(dispatch_g[sb.type].open)(group, name))<0)) {
+ printf(" *ERROR*\n");
+ goto done;
+ }
+
/*
* List the first line of information for the object.
*/
@@ -1273,21 +1491,76 @@ list (hid_t group, const char *name, void __unused__ *cd)
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 (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);
+ (dispatch_g[sb.type].list2)(obj, fullname);
}
/*
* Close the object.
*/
- if (sb.type>0) (dispatch_g[sb.type].close)(obj);
+ done:
+ if (sb.type>0 && obj>=0) (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 and insures that the name begins with a
+ * slash.
+ *
+ * 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) {
+ /* Slash, followed by path, followed by slash */
+ if ('/'!=*path) prev = s[len++] = '/';
+ 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
@@ -1395,14 +1668,15 @@ main (int argc, char *argv[])
const char *fname = NULL;
const char *progname;
const char *s;
- char *rest;
+ char *rest, *container=NULL;
int argno;
H5G_stat_t sb;
+ iter_t iter;
DISPATCH(H5G_DATASET, "Dataset", H5Dopen, H5Dclose,
dataset_list1, dataset_list2);
DISPATCH(H5G_GROUP, "Group", H5Gopen, H5Gclose,
- NULL, NULL);
+ NULL, group_list2);
DISPATCH(H5G_TYPE, "Type", H5Topen, H5Tclose,
NULL, datatype_list2);
DISPATCH(H5G_LINK, "-> ", link_open, NULL,
@@ -1411,7 +1685,7 @@ main (int argc, char *argv[])
NULL, ragged_list2);
/* Name of this program without the path */
- if ((progname=strrchr (argv[0], '/'))) progname++;
+ if ((progname=strrchr(argv[0], '/'))) progname++;
else progname = argv[0];
/* Default output width */
@@ -1428,8 +1702,13 @@ main (int argc, char *argv[])
exit(0);
} else if (!strcmp(argv[argno], "--dump")) {
dump_g = TRUE;
+ } else if (!strcmp(argv[argno], "--full")) {
+ fullname_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], "--string")) {
string_g = TRUE;
} else if (!strncmp(argv[argno], "--width=", 8)) {
@@ -1469,9 +1748,16 @@ main (int argc, char *argv[])
case 'd': /* --dump */
dump_g++;
break;
+ case 'f': /* --full */
+ fullname_g = TRUE;
+ break;
case 'l': /* --label */
label_g = TRUE;
break;
+ case 'r': /* --recursive */
+ recursive_g = TRUE;
+ fullname_g = TRUE;
+ break;
case 's': /* --string */
string_g = TRUE;
break;
@@ -1504,27 +1790,42 @@ main (int argc, char *argv[])
usage(progname);
exit(1);
}
- if (strchr (fname, '%')) {
- plist = H5Pcreate (H5P_FILE_ACCESS);
- H5Pset_family (plist, 0, H5P_DEFAULT);
+ if (strchr(fname, '%')) {
+ plist = H5Pcreate(H5P_FILE_ACCESS);
+ H5Pset_family(plist, 0, H5P_DEFAULT);
}
- if ((file = H5Fopen (fname, H5F_ACC_RDONLY, plist))<0) exit (1);
+ if ((file = H5Fopen(fname, H5F_ACC_RDONLY, plist))<0) exit (1);
/*
* The remaining optional arguments are the names of the objects to list.
* If there are no arguments then list `/'.
*/
if (argno>=argc) {
- H5Giterate(file, "/", NULL, list, NULL);
+ iter.container = "/";
+ H5Giterate(file, "/", NULL, list, &iter);
} else {
for (/*void*/; argno<argc; argno++) {
if (H5Gget_objinfo(file, argv[argno], TRUE, &sb)>=0 &&
+ /*
+ * Specified name is a group. List the complete contents of
+ * the group.
+ */
H5G_GROUP==sb.type) {
- H5Giterate(file, argv[argno], NULL, list, NULL);
+ iter.container = container = fix_name("", argv[argno]);
+ H5Giterate(file, argv[argno], NULL, list, &iter);
+ free(container);
+
} else if ((root=H5Gopen(file, "/"))<0) {
- exit(1);
+ exit(1); /*major problem!*/
+
} else {
- list(root, argv[argno], NULL);
+ /*
+ * Specified name is a non-group object -- list that object.
+ * The container for the object is everything up to the base
+ * name.
+ */
+ iter.container = "/";
+ list(root, argv[argno], &iter);
if (H5Gclose(root)<0) exit(1);
}
}
diff --git a/tools/h5tools.c b/tools/h5tools.c
index c1f889c..d69a280 100644
--- a/tools/h5tools.c
+++ b/tools/h5tools.c
@@ -331,10 +331,10 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp)
/*-------------------------------------------------------------------------
- * Function: h5dump_simple
+ * Function: h5dump_simple_dset
*
* Purpose: Print some values from a dataset with a simple data space.
- * This is a special case of h5dump().
+ * This is a special case of h5dump_dset().
*
* Return: Success: 0
*
@@ -348,7 +348,8 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp)
*-------------------------------------------------------------------------
*/
static int
-h5dump_simple(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type)
+h5dump_simple_dset(FILE *stream, const h5dump_t *info, hid_t dset,
+ hid_t p_type)
{
hid_t f_space; /*file data space */
int ndims; /*dimensionality */
@@ -499,6 +500,104 @@ h5dump_simple(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type)
/*-------------------------------------------------------------------------
+ * Function: h5dump_simple_mem
+ *
+ * Purpose: Print some values from memory with a simple data space.
+ * This is a special case of h5dump_mem().
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, July 23, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+h5dump_simple_mem(FILE *stream, const h5dump_t *info, hid_t type,
+ hid_t space, void *_mem)
+{
+ unsigned char *mem = (unsigned char*)_mem;
+ int ndims; /*dimensionality */
+ hsize_t i; /*counters */
+ int need_prefix=1; /*indices need printing */
+
+ /* Print info */
+ hsize_t p_min_idx[H5S_MAX_RANK];/*min selected index */
+ hsize_t p_max_idx[H5S_MAX_RANK];/*max selected index */
+ size_t p_type_nbytes; /*size of memory type */
+ hsize_t p_nelmts; /*total selected elmts */
+ char p_buf[8192]; /*output string */
+ size_t p_column=0; /*output column */
+ size_t p_ncolumns=80; /*default num columns */
+ char p_prefix[1024]; /*line prefix string */
+
+ /*
+ * Check that everything looks okay. The dimensionality must not be too
+ * great and the dimensionality of the items selected for printing must
+ * match the dimensionality of the dataset.
+ */
+ ndims = H5Sget_simple_extent_ndims(space);
+ if ((size_t)ndims>NELMTS(p_min_idx)) return -1;
+
+ /* Assume entire data space to be printed */
+ for (i=0; i<(hsize_t)ndims; i++) p_min_idx[i] = 0;
+ H5Sget_simple_extent_dims(space, p_max_idx, NULL);
+ for (i=0, p_nelmts=1; i<(hsize_t)ndims; i++) {
+ p_nelmts *= p_max_idx[i]-p_min_idx[i];
+ }
+ if (0==p_nelmts) return 0; /*nothing to print*/
+ p_type_nbytes = H5Tget_size(type);
+
+ /* Local things */
+ if (info->line_ncols>0) p_ncolumns = info->line_ncols;
+
+ for (i=0; i<p_nelmts; i++) {
+ /* Render the element */
+ h5dump_sprint(p_buf, info, type, mem+i*p_type_nbytes);
+ if (i+1<p_nelmts) {
+ strcat(p_buf, OPT(info->elmt_suf1, ","));
+ }
+
+ /* Print the prefix */
+ if ((p_column +
+ strlen(p_buf) +
+ strlen(OPT(info->elmt_suf2, " ")) +
+ strlen(OPT(info->line_suf, ""))) > p_ncolumns) {
+ need_prefix = 1;
+ }
+ if (need_prefix) {
+ h5dump_prefix(p_prefix, info, i, ndims, p_min_idx, p_max_idx);
+ if (p_column) {
+ fputs(OPT(info->line_suf, ""), stream);
+ putc('\n', stream);
+ fputs(OPT(info->line_sep, ""), stream);
+ }
+ fputs(p_prefix, stream);
+ p_column = strlen(p_prefix);
+ need_prefix = 0;
+ } else {
+ fputs(OPT(info->elmt_suf2, " "), stream);
+ p_column += strlen(OPT(info->elmt_suf2, " "));
+ }
+
+ fputs(p_buf, stream);
+ p_column += strlen(p_buf);
+ }
+
+ if (p_column) {
+ fputs(OPT(info->line_suf, ""), stream);
+ putc('\n', stream);
+ fputs(OPT(info->line_sep, ""), stream);
+ }
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: h5dump_fixtype
*
* Purpose: Given a file data type choose a memory data type which is
@@ -515,7 +614,7 @@ h5dump_simple(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type)
*
*-------------------------------------------------------------------------
*/
-static hid_t
+hid_t
h5dump_fixtype(hid_t f_type)
{
hid_t m_type=-1, f_memb;
@@ -652,7 +751,7 @@ h5dump_fixtype(hid_t f_type)
/*-------------------------------------------------------------------------
- * Function: h5dump
+ * Function: h5dump_dset
*
* Purpose: Print some values from a dataset DSET to the file STREAM
* after converting all types to P_TYPE (which should be a
@@ -671,7 +770,7 @@ h5dump_fixtype(hid_t f_type)
*-------------------------------------------------------------------------
*/
int
-h5dump(FILE *stream, const h5dump_t *info, hid_t dset, hid_t _p_type)
+h5dump_dset(FILE *stream, const h5dump_t *info, hid_t dset, hid_t _p_type)
{
hid_t f_space;
hid_t p_type = _p_type;
@@ -698,7 +797,44 @@ h5dump(FILE *stream, const h5dump_t *info, hid_t dset, hid_t _p_type)
H5Sclose(f_space);
/* Print the data */
- status = h5dump_simple(stream, info, dset, p_type);
+ status = h5dump_simple_dset(stream, info, dset, p_type);
if (p_type!=_p_type) H5Tclose(p_type);
return status;
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: h5dump_mem
+ *
+ * Purpose: Displays the data contained in MEM. MEM must have the
+ * specified data TYPE and SPACE. Currently only simple data
+ * spaces are allowed and only the `all' selection.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 20, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+h5dump_mem(FILE *stream, const h5dump_t *info, hid_t type, hid_t space,
+ void *mem)
+{
+ h5dump_t info_dflt;
+
+ /* Use default values */
+ if (!stream) stream = stdout;
+ if (!info) {
+ memset(&info_dflt, 0, sizeof info_dflt);
+ info = &info_dflt;
+ }
+
+ /* Check the data space */
+ if (H5Sis_simple(space)<=0) return -1;
+ return h5dump_simple_mem(stream, info, type, space, mem);
+}
diff --git a/tools/h5tools.h b/tools/h5tools.h
index 54017aa..8b5cbfe 100644
--- a/tools/h5tools.h
+++ b/tools/h5tools.h
@@ -122,6 +122,9 @@ typedef struct h5dump_t {
} h5dump_t;
-int h5dump(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type);
+hid_t h5dump_fixtype(hid_t f_type);
+int h5dump_dset(FILE *stream, const h5dump_t *info, hid_t dset, hid_t p_type);
+int h5dump_mem(FILE *stream, const h5dump_t *info, hid_t type, hid_t space,
+ void *mem);
#endif