summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/h5copy/h5copy.c4
-rw-r--r--tools/h5dump/h5dump.c10
-rw-r--r--tools/h5ls/h5ls.c524
-rwxr-xr-xtools/h5ls/testh5ls.sh1
-rw-r--r--tools/h5stat/h5stat.c327
-rw-r--r--tools/h5stat/testfiles/h5stat_filters-file.ddl1
-rw-r--r--tools/h5stat/testfiles/h5stat_filters.ddl1
-rw-r--r--tools/h5stat/testfiles/h5stat_newgrat.ddl1
-rw-r--r--tools/h5stat/testfiles/h5stat_tsohm.ddl1
-rw-r--r--tools/lib/h5tools_ref.c192
-rw-r--r--tools/lib/h5tools_utils.c186
-rw-r--r--tools/lib/h5tools_utils.h2
-rw-r--r--tools/lib/h5trav.c276
-rw-r--r--tools/lib/h5trav.h14
-rw-r--r--tools/testfiles/h5copytst.out.ls3
-rw-r--r--tools/testfiles/h5mkgrp_nested.ls3
-rw-r--r--tools/testfiles/h5mkgrp_nested_latest.ls4
-rw-r--r--tools/testfiles/h5mkgrp_nested_mult.ls3
-rw-r--r--tools/testfiles/h5mkgrp_nested_mult_latest.ls4
-rw-r--r--tools/testfiles/h5mkgrp_several.ls3
-rw-r--r--tools/testfiles/h5mkgrp_several_latest.ls4
-rw-r--r--tools/testfiles/h5mkgrp_single.ls3
-rw-r--r--tools/testfiles/h5mkgrp_single_latest.ls4
-rw-r--r--tools/testfiles/tall-2.ls1
-rw-r--r--tools/testfiles/tarray1.ls1
-rw-r--r--tools/testfiles/tattr2.ls143
-rw-r--r--tools/testfiles/tcomp-1.ls1
-rw-r--r--tools/testfiles/tdset-1.ls1
-rw-r--r--tools/testfiles/textlink-1.ls1
-rw-r--r--tools/testfiles/tgroup-1.ls40
-rw-r--r--tools/testfiles/tgroup-2.ls4
-rw-r--r--tools/testfiles/tloop-1.ls1
-rw-r--r--tools/testfiles/tnestcomp-1.ls1
-rw-r--r--tools/testfiles/tsaf.ls1
-rw-r--r--tools/testfiles/tslink-1.ls1
-rw-r--r--tools/testfiles/tstr-1.ls1
-rw-r--r--tools/testfiles/tudlink-1.ls1
-rw-r--r--tools/testfiles/tvldtypes1.ls1
38 files changed, 662 insertions, 1108 deletions
diff --git a/tools/h5copy/h5copy.c b/tools/h5copy/h5copy.c
index cadb0d0..216b2bb 100644
--- a/tools/h5copy/h5copy.c
+++ b/tools/h5copy/h5copy.c
@@ -199,8 +199,8 @@ main (int argc, const char *argv[])
unsigned flag=0;
unsigned verbose=0;
unsigned parents=0;
- hid_t ocpl_id; /* Object copy property list */
- hid_t lcpl_id; /* Link creation property list */
+ hid_t ocpl_id = (-1); /* Object copy property list */
+ hid_t lcpl_id = (-1); /* Link creation property list */
char str_flag[20];
int opt;
diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c
index c69c5d70..28534bf 100644
--- a/tools/h5dump/h5dump.c
+++ b/tools/h5dump/h5dump.c
@@ -3952,7 +3952,7 @@ main(int argc, const char *argv[])
/* allocate and initialize internal data structure */
init_prefix(&prefix, prefix_len);
- /* find all objects that might be targets of a reference */
+ /* Prepare to find objects that might be targets of a reference */
fill_ref_path_table(fid);
if(doxml) {
@@ -4094,7 +4094,6 @@ done:
free_table(type_table);
HDfree(prefix);
- HDfree(info.prefix);
HDfree(fname);
/* To Do: clean up XML table */
@@ -5342,8 +5341,7 @@ xml_dump_group(hid_t gid, const char *name)
if(HDstrcmp(name, "/") == 0) {
isRoot = 1;
- tmp = HDmalloc(2);
- HDstrcpy(tmp, "/");
+ tmp = HDstrdup("/");
} else {
tmp = HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2);
HDstrcpy(tmp, prefix);
@@ -5401,8 +5399,8 @@ xml_dump_group(hid_t gid, const char *name)
ptrstr = malloc(100);
t_objname = xml_escape_the_name(found_obj->objname);
par_name = xml_escape_the_name(par);
- xml_name_to_XID(par,parentxid,100,1);
- xml_name_to_XID(found_obj->objname,ptrstr,100,1);
+ xml_name_to_XID(found_obj->objname, ptrstr, 100, 1);
+ xml_name_to_XID(par, parentxid, 100, 1);
printf("<%sGroupPtr OBJ-XID=\"%s\" H5Path=\"%s\" "
"Parents=\"%s\" H5ParentPaths=\"%s\" />\n",
xmlnsprefix,
diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c
index 2c56cb5..80b45d8 100644
--- a/tools/h5ls/h5ls.c
+++ b/tools/h5ls/h5ls.c
@@ -27,6 +27,15 @@
#include "H5private.h"
#include "h5tools.h"
#include "h5tools_utils.h"
+#include "h5trav.h"
+
+#define NAME_BUF_SIZE 2048
+
+/* Struct to pass through to visitors */
+typedef struct {
+ hid_t fid; /* File ID */
+ const char *fname; /* Filename */
+}iter_t;
/* Command-line switches */
static int verbose_g = 0; /* lots of extra output */
@@ -43,21 +52,7 @@ static hbool_t show_errors_g = FALSE; /* print HDF5 error messages */
static hbool_t simple_output_g = FALSE; /* make output more machine-readable */
static hbool_t show_file_name_g = FALSE; /* show file name for full names */
static hbool_t no_line_wrap_g = FALSE; /* show data content without line wrap */
-
-/* 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 {
- haddr_t id; /* object number */
- char *name; /* full object name */
- } *obj;
-} idtab_g;
+static hbool_t display_root_g = FALSE; /* show root group in output? */
/* Information about how to display each type of object */
static struct dispatch_t {
@@ -68,17 +63,13 @@ static struct dispatch_t {
herr_t (*list2)(hid_t obj, const char *name);
} dispatch_g[H5O_TYPE_NTYPES];
-#define DISPATCH(TYPE, NAME, OPEN, CLOSE, LIST1, LIST2) { \
+#define DISPATCH(TYPE, NAME, 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, const H5L_info_t *linfo, void *cd);
static void display_type(hid_t type, int ind);
-static char *fix_name(const char *path, const char *base);
const char *progname="h5ls";
int d_status;
@@ -131,76 +122,6 @@ usage: %s [OPTIONS] [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(const H5O_info_t *oi, 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(oi->rc < 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]));
- } /* end if */
-
- /* Insert the entry */
- n = idtab_g.nobjs++;
- idtab_g.obj[n].id = oi->addr;
- idtab_g.obj[n].name = HDstrdup(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(const H5O_info_t *oi)
-{
- int n;
-
- /*only one name possible*/
- if(oi->rc < 2)
- return NULL;
-
- for(n = 0; n < idtab_g.nobjs; n++)
- if(idtab_g.obj[n].id == oi->addr)
- return idtab_g.obj[n].name;
-
- return NULL;
-}
-
-
-/*-------------------------------------------------------------------------
* Function: display_string
*
* Purpose: Print a string value by escaping unusual characters. If
@@ -278,6 +199,55 @@ display_string(FILE *stream, const char *s, hbool_t escape_spaces)
/*-------------------------------------------------------------------------
+ * Function: display_obj_name
+ *
+ * Purpose: Print an object name and another string.
+ *
+ * Return: Success: TRUE
+ *
+ * Failure: FALSE, nothing printed
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, November 6, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+display_obj_name(FILE *stream, const iter_t *iter, const char *oname,
+ const char *s)
+{
+ static char fullname[NAME_BUF_SIZE]; /* Buffer for file and/or object name */
+ const char *name = fullname; /* Pointer to buffer for printing */
+ int n;
+
+ if(show_file_name_g)
+ sprintf(fullname, "%s/%s", iter->fname, oname);
+ else
+ name = oname;
+
+ /* Print the object name, either full name or base name */
+ if(fullname_g)
+ n = display_string(stream, name, TRUE);
+ else {
+ const char *last_sep; /* The location of the last group separator */
+
+ /* Find the last component of the path name */
+ if(NULL == (last_sep = HDstrrchr(name, '/')))
+ last_sep = name;
+ else {
+ last_sep++;
+ } /* end else */
+ n = display_string(stream, last_sep, TRUE);
+ } /* end else */
+ printf("%*s ", MAX(0, (24 - n)), s);
+
+ return TRUE;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: display_native_type
*
* Purpose: Prints the name of a native C data type.
@@ -1326,7 +1296,7 @@ list_attr(hid_t obj, const char *attr_name, const H5A_info_t UNUSED *ainfo,
void UNUSED *op_data)
{
hid_t attr, space, type, p_type;
- hsize_t size[64], nelmts = 1;
+ hsize_t size[H5S_MAX_RANK], nelmts = 1;
int ndims, i, n;
size_t need;
hsize_t temp_need;
@@ -1460,8 +1430,8 @@ list_attr(hid_t obj, const char *attr_name, const H5A_info_t UNUSED *ainfo,
static herr_t
dataset_list1(hid_t dset)
{
- hsize_t cur_size[64]; /* current dataset dimensions */
- hsize_t max_size[64]; /* maximum dataset dimensions */
+ hsize_t cur_size[H5S_MAX_RANK]; /* current dataset dimensions */
+ hsize_t max_size[H5S_MAX_RANK]; /* maximum dataset dimensions */
hid_t space; /* data space */
int ndims; /* dimensionality */
H5S_class_t space_type; /* type of dataspace */
@@ -1524,7 +1494,6 @@ dataset_list2(hid_t dset, const char UNUSED *name)
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 */
@@ -1537,6 +1506,8 @@ dataset_list2(hid_t dset, const char UNUSED *name)
/* Print information about chunked storage */
if (H5D_CHUNKED==H5Pget_layout(dcpl)) {
+ hsize_t chsize[64]; /* chunk size in elements */
+
ndims = H5Pget_chunk(dcpl, NELMTS(chsize), chsize/*out*/);
printf(" %-10s {", "Chunks:");
total = H5Tget_size(type);
@@ -1645,39 +1616,9 @@ dataset_list2(hid_t dset, const char UNUSED *name)
/*-------------------------------------------------------------------------
- * 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;
- H5Literate(grp, H5_INDEX_NAME, H5_ITER_INC, NULL, list, &iter);
- }
- return 0;
-}
-
-
-/*-------------------------------------------------------------------------
* Function: datatype_list2
*
- * Purpose: List information about a data type which should appear after
+ * Purpose: List information about a datatype which should appear after
* information which is general to all objects.
*
* Return: Success: 0
@@ -1704,80 +1645,56 @@ datatype_list2(hid_t type, const char UNUSED *name)
/*-------------------------------------------------------------------------
- * Function: list
+ * Function: list_obj
*
- * Purpose: Prints the group member name.
+ * Purpose: Prints information about an object
*
* Return: Success: 0
*
* Failure: -1
*
- * Programmer: Robb Matzke
- * Monday, March 23, 1998
+ * Programmer: Quincey Koziol
+ * Tuesday, November 6, 2007
*
- * Modifications:
- * Robb Matzke, LLNL, 2003-06-06
- * If simple_output_g (set by `--simple') is turned on then
- * the modification time is printed as UTC instead of the
- * local timezone.
*-------------------------------------------------------------------------
*/
static herr_t
-list(hid_t group, const char *name, const H5L_info_t *linfo, void *_iter)
+list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void *_iter)
{
+ H5O_type_t obj_type = oinfo->type; /* Type of the object */
iter_t *iter = (iter_t*)_iter;
- char *fullname = NULL;
- 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);
- else
- n = display_string(stdout, name, TRUE);
- printf("%*s ", MAX(0, (24 - n)), "");
-
- /* Actions on objects */
- if(linfo->type == H5L_TYPE_HARD) {
- H5O_info_t oi;
- char *s;
- hid_t obj;
-
- /* Get object information */
- if(H5Oget_info_by_name(group, name, &oi, H5P_DEFAULT) < 0) {
- puts("**NOT FOUND**");
- return 0;
- } else if(oi.type < 0 || oi.type >= H5O_TYPE_NTYPES) {
- printf("Unknown type(%d)", (int)oi.type);
- oi.type = H5O_TYPE_UNKNOWN;
- }
- if(oi.type >= 0 && dispatch_g[oi.type].name)
- fputs(dispatch_g[oi.type].name, stdout);
-
- /* If the object has already been printed then just show the object ID
- * and return. */
- if((s = sym_lookup(&oi))) {
- printf(", same as ");
- display_string(stdout, s, TRUE);
- printf("\n");
- goto done;
- } /* end if */
- else
- sym_insert(&oi, fullname);
+ /* Print the link's name, either full name or base name */
+ display_obj_name(stdout, iter, name, "");
+
+ /* Check object information */
+ if(oinfo->type < 0 || oinfo->type >= H5O_TYPE_NTYPES) {
+ printf("Unknown type(%d)", (int)oinfo->type);
+ obj_type = H5O_TYPE_UNKNOWN;
+ }
+ if(obj_type >= 0 && dispatch_g[obj_type].name)
+ fputs(dispatch_g[obj_type].name, stdout);
+
+ /* Check if we've seen this object before */
+ if(first_seen) {
+ printf(", same as ");
+ display_string(stdout, first_seen, TRUE);
+ printf("\n");
+ } /* end if */
+ else {
+ hid_t obj = (-1); /* ID of object opened */
/* Open the object. Not all objects can be opened. If this is the case
* then return right away.
*/
- if(oi.type >= 0 &&
- (NULL == dispatch_g[oi.type].open ||
- (obj = (dispatch_g[oi.type].open)(group, name, H5P_DEFAULT)) < 0)) {
+ if(obj_type >= 0 && (obj = H5Oopen(iter->fid, name, H5P_DEFAULT)) < 0) {
printf(" *ERROR*\n");
goto done;
} /* end if */
/* List the first line of information for the object. */
- if(oi.type >= 0 && dispatch_g[oi.type].list1)
- (dispatch_g[oi.type].list1)(obj);
+ if(obj_type >= 0 && dispatch_g[obj_type].list1)
+ (dispatch_g[obj_type].list1)(obj);
putchar('\n');
/* Show detailed information about the object, beginning with information
@@ -1786,22 +1703,22 @@ list(hid_t group, const char *name, const H5L_info_t *linfo, void *_iter)
char comment[50];
/* Display attributes */
- if(oi.type >= 0)
+ if(obj_type >= 0)
H5Aiterate2(obj, H5_INDEX_NAME, H5_ITER_INC, NULL, list_attr, NULL);
/* Object location & reference count */
- printf(" %-10s %lu:"H5_PRINTF_HADDR_FMT"\n", "Location:", oi.fileno, oi.addr);
- printf(" %-10s %u\n", "Links:", (unsigned)oi.rc);
+ printf(" %-10s %lu:"H5_PRINTF_HADDR_FMT"\n", "Location:", oinfo->fileno, oinfo->addr);
+ printf(" %-10s %u\n", "Links:", (unsigned)oinfo->rc);
/* Modification time */
- if(oi.mtime > 0) {
+ if(oinfo->mtime > 0) {
char buf[256];
struct tm *tm;
if(simple_output_g)
- tm = HDgmtime(&(oi.mtime));
+ tm = HDgmtime(&(oinfo->mtime));
else
- tm = HDlocaltime(&(oi.mtime));
+ tm = HDlocaltime(&(oinfo->mtime));
if(tm) {
HDstrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm);
printf(" %-10s %s\n", "Modified:", buf);
@@ -1810,7 +1727,7 @@ list(hid_t group, const char *name, const H5L_info_t *linfo, void *_iter)
/* Object comment */
comment[0] = '\0';
- H5Oget_comment_by_name(group, name, comment, sizeof(comment), H5P_DEFAULT);
+ H5Oget_comment(obj, comment, sizeof(comment));
HDstrcpy(comment + sizeof(comment) - 4, "...");
if(comment[0]) {
printf(" %-10s \"", "Comment:");
@@ -1820,118 +1737,91 @@ list(hid_t group, const char *name, const H5L_info_t *linfo, void *_iter)
} /* end if */
/* Detailed list for object */
- if(oi.type >= 0 && dispatch_g[oi.type].list2)
- (dispatch_g[oi.type].list2)(obj, fullname);
+ if(obj_type >= 0 && dispatch_g[obj_type].list2)
+ (dispatch_g[obj_type].list2)(obj, name);
/* Close the object. */
- if(oi.type >= 0 && dispatch_g[oi.type].close)
- (dispatch_g[oi.type].close)(obj);
- } /* end if */
- /* Actions on links */
- else {
- char *buf;
-
- HDfputs("-> ", stdout);
- switch(linfo->type) {
- case H5L_TYPE_SOFT:
- if((buf = HDmalloc(linfo->u.val_size)) == NULL)
- goto done;
-
- if(H5Lget_val(group, name, buf, linfo->u.val_size, H5P_DEFAULT) < 0) {
- HDfree(buf);
- goto done;
- } /* end if */
-
- HDfputs(buf, stdout);
- HDfree(buf);
- break;
-
- case H5L_TYPE_EXTERNAL:
- {
- const char *filename;
- const char *path;
-
- if((buf = HDmalloc(linfo->u.val_size)) == NULL)
- goto done;
-
- if(H5Lget_val(group, name, buf, linfo->u.val_size, H5P_DEFAULT) < 0) {
- HDfree(buf);
- goto done;
- } /* end if */
- if(H5Lunpack_elink_val(buf, linfo->u.val_size, NULL, &filename, &path) < 0) {
- HDfree(buf);
- goto done;
- } /* end if */
-
- HDfputs("file: ", stdout);
- HDfputs(filename, stdout);
- HDfputs(" path: ", stdout);
- HDfputs(path, stdout);
- }
- break;
-
- default:
- HDfputs("cannot follow UD links", stdout);
- break;
- } /* end switch */
- HDfputc('\n', stdout);
+ if(obj_type >= 0)
+ H5Oclose(obj);
} /* end else */
done:
- if(fullname)
- free(fullname);
return 0;
-} /* end list() */
+} /* end list_obj() */
/*-------------------------------------------------------------------------
- * Function: fix_name
+ * Function: list_lnk
*
- * 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.
+ * Purpose: Prints information about a link
*
- * Return: Success: Ptr to fixed name from malloc()
- *
- * Failure: NULL
+ * Return: Success: 0
*
- * Programmer: Robb Matzke
- * Thursday, January 21, 1999
+ * Failure: -1
*
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Thursday, November 8, 2007
*
*-------------------------------------------------------------------------
*/
-static char *
-fix_name(const char *path, const char *base)
+static herr_t
+list_lnk(const char *name, const H5L_info_t *linfo, void *_iter)
{
- size_t n = (path ? HDstrlen(path) : 0) + (base ? HDstrlen(base) : 0) + 3;
- char *s = HDmalloc(n), prev='\0';
- size_t len = 0;
-
- if (path) {
- /* Path, followed by slash */
- for (/*void*/; *path; path++)
- if ('/'!=*path || '/'!=prev)
- prev = s[len++] = *path;
- if ('/' != prev)
- prev = s[len++] = '/';
- }
+ char *buf;
+ iter_t *iter = (iter_t*)_iter;
- if (base) {
- /* Base name w/o trailing slashes */
- const char *end = base + HDstrlen(base);
- while (end > base && '/' == end[-1])
- --end;
+ /* Print the link's name, either full name or base name */
+ display_obj_name(stdout, iter, name, "");
- for (/*void*/; base < end; base++)
- if ('/' != *base || '/' != prev)
- prev = s[len++] = *base;
- }
+ HDfputs("-> ", stdout);
+ switch(linfo->type) {
+ case H5L_TYPE_SOFT:
+ if((buf = HDmalloc(linfo->u.val_size)) == NULL)
+ goto done;
- s[len] = '\0';
- return s;
-}
+ if(H5Lget_val(iter->fid, name, buf, linfo->u.val_size, H5P_DEFAULT) < 0) {
+ HDfree(buf);
+ goto done;
+ } /* end if */
+
+ HDfputs(buf, stdout);
+ HDfree(buf);
+ break;
+
+ case H5L_TYPE_EXTERNAL:
+ {
+ const char *filename;
+ const char *path;
+
+ if((buf = HDmalloc(linfo->u.val_size)) == NULL)
+ goto done;
+
+ if(H5Lget_val(iter->fid, name, buf, linfo->u.val_size, H5P_DEFAULT) < 0) {
+ HDfree(buf);
+ goto done;
+ } /* end if */
+ if(H5Lunpack_elink_val(buf, linfo->u.val_size, NULL, &filename, &path) < 0) {
+ HDfree(buf);
+ goto done;
+ } /* end if */
+
+ HDfputs("file: ", stdout);
+ HDfputs(filename, stdout);
+ HDfputs(" path: ", stdout);
+ HDfputs(path, stdout);
+ HDfree(buf);
+ }
+ break;
+
+ default:
+ HDfputs("cannot follow UD links", stdout);
+ break;
+ } /* end switch */
+ HDfputc('\n', stdout);
+
+done:
+ return 0;
+} /* end list_lnk() */
/*-------------------------------------------------------------------------
@@ -2059,10 +1949,10 @@ leave(int ret)
int
main(int argc, const char *argv[])
{
- hid_t file = -1, root = -1;
+ hid_t file = -1;
char *fname = NULL, *oname = NULL, *x;
const char *s = NULL;
- char *rest, *container = NULL;
+ char *rest;
int argno;
static char root_name[] = "/";
char drivername[50];
@@ -2072,9 +1962,9 @@ main(int argc, const char *argv[])
h5tools_init();
/* Build object display table */
- DISPATCH(H5O_TYPE_GROUP, "Group", H5Gopen2, H5Gclose, NULL, group_list2);
- DISPATCH(H5O_TYPE_DATASET, "Dataset", H5Dopen2, H5Dclose, dataset_list1, dataset_list2);
- DISPATCH(H5O_TYPE_NAMED_DATATYPE, "Type", H5Topen2, H5Tclose, NULL, datatype_list2);
+ DISPATCH(H5O_TYPE_GROUP, "Group", NULL, NULL);
+ DISPATCH(H5O_TYPE_DATASET, "Dataset", dataset_list1, dataset_list2);
+ DISPATCH(H5O_TYPE_NAMED_DATATYPE, "Type", NULL, datatype_list2);
/* Default output width */
width_g = get_width();
@@ -2230,6 +2120,13 @@ main(int argc, const char *argv[])
leave(1);
} /* end if */
+ /* Check for conflicting arguments */
+ if(recursive_g && grp_literal_g) {
+ fprintf(stderr, "Error: 'recursive' option not compatible with 'group info' option!\n\n");
+ usage();
+ leave(1);
+ } /* end if */
+
/* Turn off HDF5's automatic error printing unless you're debugging h5ls */
if(!show_errors_g)
H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
@@ -2249,7 +2146,6 @@ main(int argc, const char *argv[])
* doesn't exist). */
show_file_name_g = (argc-argno > 1); /*show file names if more than one*/
while(argno < argc) {
- H5O_info_t oi;
H5L_info_t li;
iter_t iter;
@@ -2281,24 +2177,21 @@ main(int argc, const char *argv[])
} /* end if */
if(oname)
oname++;
- if(!oname || !*oname)
+ if(!oname || !*oname) {
oname = root_name;
+ if(recursive_g)
+ display_root_g = TRUE;
+ } /* end if */
+
+ /* Remember the file information for later */
+ iter.fname = fname;
+ iter.fid = file;
/* Check for root group as object name */
if(HDstrcmp(oname, root_name)) {
/* Check the type of link given */
if(H5Lget_info(file, oname, &li, H5P_DEFAULT) < 0) {
- char *fullname = NULL;
- int n;
-
- fullname = fix_name(oname, "/");
- if(fullname_g)
- n = display_string(stdout, fullname, TRUE);
- else
- n = display_string(stdout, oname, TRUE);
- printf("%*s \n", MAX(0, (24 - n)), "**NOT FOUND**");
-
- HDfree(fullname);
+ display_obj_name(stdout, &iter, oname, "**NOT FOUND**");
leave(1);
} /* end if */
} /* end if */
@@ -2306,34 +2199,25 @@ main(int argc, const char *argv[])
li.type = H5L_TYPE_HARD;
/* Open the object and display it's information */
- if(li.type == H5L_TYPE_HARD && H5Oget_info_by_name(file, oname, &oi, H5P_DEFAULT) >= 0 && H5O_TYPE_GROUP == oi.type && !grp_literal_g) {
- /* Specified name is a group. List the complete contents of the group. */
- sym_insert(&oi, oname);
- iter.container = container = fix_name((show_file_name_g ? fname : ""), oname);
-
- /* list root attributes */
- if(verbose_g > 0) {
- if((root = H5Gopen2(file, "/", H5P_DEFAULT)) < 0)
- leave(1);
- H5Aiterate2(root, H5_INDEX_NAME, H5_ITER_INC, NULL, list_attr, NULL);
- if(H5Gclose(root) < 0)
- leave(1);
- } /* end if */
+ if(li.type == H5L_TYPE_HARD) {
+ H5O_info_t oi; /* Information for object */
- /* list */
- H5Literate_by_name(file, oname, H5_INDEX_NAME, H5_ITER_INC, NULL, list, &iter, H5P_DEFAULT);
- free(container);
- } else if((root = H5Gopen2(file, "/", H5P_DEFAULT)) < 0) {
- leave(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.
- */
- iter.container = show_file_name_g ? fname : "/";
- list(root, oname, &li, &iter);
- if(H5Gclose(root) < 0)
+ /* Retrieve info for object to list */
+ if(H5Oget_info_by_name(file, oname, &oi, H5P_DEFAULT) < 0) {
+ display_obj_name(stdout, &iter, oname, "**NOT FOUND**");
leave(1);
- }
+ } /* end if */
+
+ /* Check for group iteration */
+ if(H5O_TYPE_GROUP == oi.type && !grp_literal_g)
+ /* Specified name is a group. List the complete contents of the group. */
+ h5trav_visit(file, oname, display_root_g, recursive_g, list_obj, list_lnk, &iter);
+ else
+ /* Specified name is a non-group object -- list that object */
+ list_obj(oname, &oi, NULL, &iter);
+ } else
+ /* Specified name is not for object -- list that link */
+ list_lnk(oname, &li, &iter);
H5Fclose(file);
free(fname);
} /* end while */
diff --git a/tools/h5ls/testh5ls.sh b/tools/h5ls/testh5ls.sh
index ab36eb4..f25db4e 100755
--- a/tools/h5ls/testh5ls.sh
+++ b/tools/h5ls/testh5ls.sh
@@ -112,6 +112,7 @@ TOOLTEST tgroup.ls -w80 tgroup.h5
# test for displaying groups
TOOLTEST tgroup-1.ls -w80 -r -g tgroup.h5
+TOOLTEST tgroup-2.ls -w80 -g tgroup.h5/g1
# test for displaying simple space datasets
TOOLTEST tdset-1.ls -w80 -r -d tdset.h5
diff --git a/tools/h5stat/h5stat.c b/tools/h5stat/h5stat.c
index c69d801..f03efd7 100644
--- a/tools/h5stat/h5stat.c
+++ b/tools/h5stat/h5stat.c
@@ -47,8 +47,7 @@ typedef struct ohdr_info_t {
/* Info to pass to the iteration functions */
typedef struct iter_t {
- const char *container; /* Full name of the container object */
- unsigned long curr_depth; /* Current depth of hierarchy */
+ hid_t fid; /* File ID */
unsigned long uniq_groups; /* Number of unique groups */
unsigned long uniq_dsets; /* Number of unique datasets */
@@ -56,7 +55,6 @@ typedef struct iter_t {
unsigned long uniq_links; /* Number of unique links */
unsigned long uniq_others; /* Number of other unique objects */
- unsigned long max_depth; /* Maximum depth of hierarchy */
unsigned long max_links; /* Maximum # of links to an object */
hsize_t max_fanout; /* Maximum fanout from a group */
unsigned long num_small_groups[SIZE_SMALL_GROUPS]; /* Size of small groups tracked */
@@ -95,16 +93,6 @@ typedef struct iter_t {
} iter_t;
-/* Table containing object id and object name */
-static struct {
- int nalloc; /* number of slots allocated */
- int nobjs; /* number of objects */
- struct {
- haddr_t id; /* object number */
- char *name; /* full object name */
- } *obj;
-} idtab_g;
-
const char *progname = "h5stat";
int d_status = EXIT_SUCCESS;
static int display_all = TRUE;
@@ -260,123 +248,6 @@ ceil_log10(unsigned long x)
/*-------------------------------------------------------------------------
- * Function: sym_insert
- *
- * Purpose: Add a symbol to the table.
- *
- * Return: void
- *
- * Programmer: Robb Matzke
- * Thursday, January 21, 1999
- *
- *-------------------------------------------------------------------------
- */
-static void
-sym_insert(H5O_info_t *oi, const char *name)
-{
- /* Don't add it if the link count is 1 because such an object can only
- * have one name. */
- if(oi->rc > 1) {
- int n;
-
- /* 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]));
- } /* end if */
-
- /* Insert the entry */
- n = idtab_g.nobjs++;
- idtab_g.obj[n].id = oi->addr;
- idtab_g.obj[n].name = strdup(name);
- } /* end if */
-} /* end sym_insert() */
-
-
-/*-------------------------------------------------------------------------
- * 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(H5O_info_t *oi)
-{
- int n;
-
- /*only one name possible*/
- if(oi->rc < 2)
- return NULL;
-
- for(n = 0; n < idtab_g.nobjs; n++)
- if(idtab_g.obj[n].id == oi->addr)
- return idtab_g.obj[n].name;
-
- return NULL;
-} /* end sym_lookup() */
-
-
-/*-------------------------------------------------------------------------
- * 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';
- size_t len = 0;
-
- if (path) {
- /* Path, followed by slash */
- 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: attribute_stats
*
* Purpose: Gather statistics about attributes on an object
@@ -453,25 +324,21 @@ attribute_stats(iter_t *iter, const H5O_info_t *oi)
*-------------------------------------------------------------------------
*/
static herr_t
-group_stats(hid_t group, const char *name, const char *fullname,
- const H5O_info_t *oi, H5L_iterate_t walk, iter_t *iter)
+group_stats(iter_t *iter, const char *name, const H5O_info_t *oi)
{
- const char *last_container;
H5G_info_t ginfo; /* Group information */
unsigned bin; /* "bin" the number of objects falls in */
herr_t ret;
/* Gather statistics about this type of object */
iter->uniq_groups++;
- if(iter->curr_depth > iter->max_depth)
- iter->max_depth = iter->curr_depth;
/* Get object header information */
iter->group_ohdr_info.total_size += oi->hdr.space.total;
iter->group_ohdr_info.free_size += oi->hdr.space.free;
/* Get group information */
- ret = H5Gget_info_by_name(group, name, &ginfo, H5P_DEFAULT);
+ ret = H5Gget_info_by_name(iter->fid, name, &ginfo, H5P_DEFAULT);
assert(ret >= 0);
/* Update link stats */
@@ -506,18 +373,6 @@ group_stats(hid_t group, const char *name, const char *fullname,
ret = attribute_stats(iter, oi);
assert(ret >= 0);
- /* Update current container info */
- last_container = iter->container;
- iter->container = fullname;
- iter->curr_depth++;
-
- /* Recursively descend into current group's objects */
- H5Literate_by_name(group, name, H5_INDEX_NAME, H5_ITER_INC, NULL, walk, iter, H5P_DEFAULT);
-
- /* Revert current container info */
- iter->container = last_container;
- iter->curr_depth--;
-
return 0;
} /* end group_stats() */
@@ -549,7 +404,7 @@ group_stats(hid_t group, const char *name, const char *fullname,
*-------------------------------------------------------------------------
*/
static herr_t
-dataset_stats(hid_t group, const char *name, const H5O_info_t *oi, iter_t *iter)
+dataset_stats(iter_t *iter, const char *name, const H5O_info_t *oi)
{
unsigned bin; /* "bin" the number of objects falls in */
hid_t did; /* Dataset ID */
@@ -575,7 +430,7 @@ dataset_stats(hid_t group, const char *name, const H5O_info_t *oi, iter_t *iter)
iter->dset_ohdr_info.total_size += oi->hdr.space.total;
iter->dset_ohdr_info.free_size += oi->hdr.space.free;
- did = H5Dopen2(group, name, H5P_DEFAULT);
+ did = H5Dopen2(iter->fid, name, H5P_DEFAULT);
assert(did > 0);
/* Update dataset metadata info */
@@ -710,89 +565,90 @@ dataset_stats(hid_t group, const char *name, const H5O_info_t *oi, iter_t *iter)
/*-------------------------------------------------------------------------
- * Function: walk
+ * Function: obj_stats
*
- * Purpose: Gather statistics about the file
+ * Purpose: Gather statistics about an object
*
* Return: Success: 0
- * Failure: -1
*
- * Programmer: Quincey Koziol
- * Tuesday, August 16, 2005
+ * Failure: -1
*
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Tuesday, November 6, 2007
*
*-------------------------------------------------------------------------
*/
static herr_t
-walk(hid_t group, const char *name, const H5L_info_t *linfo, void *_iter)
+obj_stats(const char *path, const H5O_info_t *oi, const char *already_visited,
+ void *_iter)
{
iter_t *iter = (iter_t *)_iter;
- char *fullname = NULL;
- herr_t ret; /* Generic return value */
-
- if(!linfo || linfo->type == H5L_TYPE_HARD) {
- H5O_info_t oi;
- char *s;
-
- /* Get object information */
- ret = H5Oget_info_by_name(group, name, &oi, H5P_DEFAULT);
- assert(ret >= 0);
-
- /* If the object has already been printed then just show the object ID
- * and return. */
- if((s = sym_lookup(&oi))) {
- printf("%s same as %s\n", name, s);
- } else {
- /* Get the full object name */
- fullname = fix_name(iter->container, name);
- sym_insert(&oi, fullname);
-
- /* Gather some statistics about the object */
- if(oi.rc > iter->max_links)
- iter->max_links = oi.rc;
-
- switch(oi.type) {
- case H5O_TYPE_GROUP:
- group_stats(group, name, fullname, &oi, walk, iter);
- break;
-
- case H5O_TYPE_DATASET:
- dataset_stats(group, name, &oi, iter);
- break;
-
- case H5O_TYPE_NAMED_DATATYPE:
- /* Gather statistics about this type of object */
- iter->uniq_types++;
- break;
-
- default:
- /* Gather statistics about this type of object */
- iter->uniq_others++;
- break;
- } /* end switch */
- }
- } /* end if */
- else {
- switch(linfo->type) {
- case H5L_TYPE_SOFT:
- case H5L_TYPE_EXTERNAL:
- /* Gather statistics about links and UD links */
- iter->uniq_links++;
+
+ /* If the object has already been seen then just return */
+ if(NULL == already_visited) {
+ /* Gather some general statistics about the object */
+ if(oi->rc > iter->max_links)
+ iter->max_links = oi->rc;
+
+ switch(oi->type) {
+ case H5O_TYPE_GROUP:
+ group_stats(iter, path, oi);
+ break;
+
+ case H5O_TYPE_DATASET:
+ dataset_stats(iter, path, oi);
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ /* Gather statistics about this type of object */
+ iter->uniq_types++;
break;
default:
/* Gather statistics about this type of object */
iter->uniq_others++;
break;
- } /* end switch() */
- } /* end else */
+ } /* end switch */
+ } /* end if */
- if(fullname)
- free(fullname);
+ return 0;
+} /* end obj_stats() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: lnk_stats
+ *
+ * Purpose: Gather statistics about a link
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, November 6, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+lnk_stats(const char UNUSED *path, const H5L_info_t *li, void *_iter)
+{
+ iter_t *iter = (iter_t *)_iter;
+
+ switch(li->type) {
+ case H5L_TYPE_SOFT:
+ case H5L_TYPE_EXTERNAL:
+ /* Gather statistics about links and UD links */
+ iter->uniq_links++;
+ break;
+
+ default:
+ /* Gather statistics about this type of object */
+ iter->uniq_others++;
+ break;
+ } /* end switch() */
return 0;
-}
+} /* end lnk_stats() */
/*-------------------------------------------------------------------------
@@ -915,13 +771,13 @@ parse_command_line(int argc, const char *argv[])
*-------------------------------------------------------------------------
*/
static herr_t
-iter_init(iter_t *iter)
+iter_init(iter_t *iter, hid_t fid)
{
/* Clear everything to zeros */
- memset(iter, 0, sizeof(*iter));
+ HDmemset(iter, 0, sizeof(*iter));
- /* Initialize non-zero information */
- iter->container = "/";
+ /* Set the file ID for later use in callbacks */
+ iter->fid = fid;
return 0;
}
@@ -953,7 +809,6 @@ print_file_info(const iter_t *iter)
printf("\t# of unique links: %lu\n", iter->uniq_links);
printf("\t# of unique other: %lu\n", iter->uniq_others);
printf("\tMax. # of links to object: %lu\n", iter->max_links);
- printf("\tMax. depth of hierarchy: %lu\n", iter->max_depth);
HDfprintf(stdout, "\tMax. # of objects in group: %Hu\n", iter->max_fanout);
return 0;
@@ -1318,8 +1173,6 @@ main(int argc, const char *argv[])
const char *fname = NULL;
hid_t fid;
struct handler_t *hand;
- char root[] = "/";
- int i;
H5F_info_t finfo;
@@ -1329,25 +1182,23 @@ main(int argc, const char *argv[])
/* Initialize h5tools lib */
h5tools_init();
hand = parse_command_line (argc, argv);
- if (!hand) {
+ if(!hand) {
error_msg(progname, "unable to parse command line arguments \n");
leave(EXIT_FAILURE);
- }
+ } /* end if */
fname = argv[opt_ind];
- if(!display_object)
- hand[0].obj = root;
printf("Filename: %s\n", fname);
fid = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
- if (fid < 0) {
+ if(fid < 0) {
error_msg(progname, "unable to open file \"%s\"\n", fname);
leave(EXIT_FAILURE);
- }
+ } /* end if */
/* Initialize iter structure */
- iter_init(&iter);
+ iter_init(&iter, fid);
/* Get storge info for SOHM's btree/list/heap and superblock extension */
if(H5Fget_info(fid, &finfo) < 0)
@@ -1357,15 +1208,23 @@ main(int argc, const char *argv[])
iter.SM_hdr_storage_size = finfo.sohm.hdr_size;
iter.SM_index_storage_size = finfo.sohm.msgs_info.index_size;
iter.SM_heap_storage_size = finfo.sohm.msgs_info.heap_size;
- }
+ } /* end else */
/* Walk the objects or all file */
- i = 0;
- while(hand[i].obj) {
- walk(fid, hand[i].obj, NULL, &iter);
- print_statistics(hand[i].obj, &iter);
- i++;
- } /* end while */
+ if(display_object) {
+ unsigned u;
+
+ u = 0;
+ while(hand[u].obj) {
+ h5trav_visit(fid, hand[u].obj, TRUE, TRUE, obj_stats, lnk_stats, &iter);
+ print_statistics(hand[u].obj, &iter);
+ u++;
+ } /* end while */
+ } /* end if */
+ else {
+ h5trav_visit(fid, "/", TRUE, TRUE, obj_stats, lnk_stats, &iter);
+ print_statistics("/", &iter);
+ } /* end else */
free(hand);
diff --git a/tools/h5stat/testfiles/h5stat_filters-file.ddl b/tools/h5stat/testfiles/h5stat_filters-file.ddl
index c6aeef0..7b8f47f 100644
--- a/tools/h5stat/testfiles/h5stat_filters-file.ddl
+++ b/tools/h5stat/testfiles/h5stat_filters-file.ddl
@@ -9,5 +9,4 @@ File information
# of unique links: 0
# of unique other: 0
Max. # of links to object: 1
- Max. depth of hierarchy: 0
Max. # of objects in group: 16
diff --git a/tools/h5stat/testfiles/h5stat_filters.ddl b/tools/h5stat/testfiles/h5stat_filters.ddl
index 4dd6aee..df2e304 100644
--- a/tools/h5stat/testfiles/h5stat_filters.ddl
+++ b/tools/h5stat/testfiles/h5stat_filters.ddl
@@ -9,7 +9,6 @@ File information
# of unique links: 0
# of unique other: 0
Max. # of links to object: 1
- Max. depth of hierarchy: 0
Max. # of objects in group: 16
Object header size: (total/unused)
Groups: 48/8
diff --git a/tools/h5stat/testfiles/h5stat_newgrat.ddl b/tools/h5stat/testfiles/h5stat_newgrat.ddl
index 228d565..6881ca9 100644
--- a/tools/h5stat/testfiles/h5stat_newgrat.ddl
+++ b/tools/h5stat/testfiles/h5stat_newgrat.ddl
@@ -9,7 +9,6 @@ File information
# of unique links: 0
# of unique other: 0
Max. # of links to object: 1
- Max. depth of hierarchy: 1
Max. # of objects in group: 351
Object header size: (total/unused)
Groups: 51597/32292
diff --git a/tools/h5stat/testfiles/h5stat_tsohm.ddl b/tools/h5stat/testfiles/h5stat_tsohm.ddl
index 572965e..15a058e 100644
--- a/tools/h5stat/testfiles/h5stat_tsohm.ddl
+++ b/tools/h5stat/testfiles/h5stat_tsohm.ddl
@@ -9,7 +9,6 @@ File information
# of unique links: 0
# of unique other: 0
Max. # of links to object: 1
- Max. depth of hierarchy: 0
Max. # of objects in group: 2
Object header size: (total/unused)
Groups: 51/2
diff --git a/tools/lib/h5tools_ref.c b/tools/lib/h5tools_ref.c
index 123065b..de1e2c3 100644
--- a/tools/lib/h5tools_ref.c
+++ b/tools/lib/h5tools_ref.c
@@ -20,6 +20,7 @@
#include "H5SLprivate.h"
#include "h5tools.h"
#include "h5tools_utils.h"
+#include "h5trav.h"
/*
@@ -42,15 +43,12 @@ typedef struct {
} ref_path_node_t;
static H5SL_t *ref_path_table = NULL; /* the "table" (implemented with a skip list) */
-static hid_t thefile;
+static hid_t thefile = (-1);
extern char *progname;
extern int d_status;
static int ref_path_table_put(const char *, haddr_t objno);
-static hbool_t ref_path_table_find(haddr_t objno);
-static herr_t fill_ref_path_table_cb(hid_t group, const char *obj_name,
- const H5L_info_t *linfo, void *op_data);
/*-------------------------------------------------------------------------
* Function: free_ref_path_info
@@ -77,6 +75,61 @@ free_ref_path_info(void *item, void UNUSED *key, void UNUSED *operator_data/*in,
}
/*-------------------------------------------------------------------------
+ * Function: init_ref_path_cb
+ *
+ * Purpose: Called by interator to create references for
+ * all objects and enter them in the table.
+ *
+ * Return: Error status.
+ *
+ * Programmer: REMcG
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+init_ref_path_cb(const char *obj_name, const H5O_info_t *oinfo,
+ const char *already_seen, void UNUSED *_udata)
+{
+ /* Check if the object is already in the path table */
+ if(NULL == already_seen) {
+ /* Insert the object into the path table */
+ ref_path_table_put(obj_name, oinfo->addr);
+ } /* end if */
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: init_ref_path_table
+ *
+ * Purpose: Initalize the reference path table
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+init_ref_path_table(void)
+{
+ /* Sanity check */
+ HDassert(thefile > 0);
+
+ /* Create skip list to store reference path information */
+ if((ref_path_table = H5SL_create(H5SL_TYPE_HADDR, 0.5, (size_t)16))==NULL)
+ return (-1);
+
+ /* Iterate over objects in this file */
+ if(h5trav_visit(thefile, "/", TRUE, TRUE, init_ref_path_cb, NULL, NULL) < 0) {
+ error_msg(progname, "unable to construct reference path table\n");
+ d_status = EXIT_FAILURE;
+ } /* end if */
+
+ return(0);
+}
+
+/*-------------------------------------------------------------------------
* Function: term_ref_path_table
*
* Purpose: Terminate the reference path table
@@ -137,39 +190,11 @@ ref_path_table_lookup(const char *thepath)
if(H5Oget_info_by_name(thefile, thepath, &oi, H5P_DEFAULT) < 0)
return HADDR_UNDEF;
- /* All existing objects in the file had better be in the table */
- HDassert(ref_path_table_find(oi.addr));
-
/* Return OID */
return(oi.addr);
}
/*-------------------------------------------------------------------------
- * Function: ref_path_table_find
- *
- * Purpose: Looks up a table entry given a object number.
- * Used during construction of the table.
- *
- * Return: TRUE/FALSE on success, can't fail
- *
- * Programmer: Quincey Koziol
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static hbool_t
-ref_path_table_find(haddr_t objno)
-{
- HDassert(ref_path_table);
-
- if(H5SL_search(ref_path_table, &objno) == NULL)
- return FALSE;
- else
- return TRUE;
-}
-
-/*-------------------------------------------------------------------------
* Function: ref_path_table_put
*
* Purpose: Enter the 'obj' with 'path' in the table (assumes its not
@@ -200,7 +225,7 @@ ref_path_table_put(const char *path, haddr_t objno)
return(-1);
new_node->objno = objno;
- new_node->path = path;
+ new_node->path = HDstrdup(path);
return(H5SL_insert(ref_path_table, new_node, &(new_node->objno)));
}
@@ -237,17 +262,17 @@ get_fake_xid (void) {
haddr_t
ref_path_table_gen_fake(const char *path)
{
- const char *dup_path;
haddr_t fake_objno;
- if((dup_path = HDstrdup(path)) == NULL)
- return HADDR_UNDEF;
-
/* Generate fake ID for string */
fake_objno = get_fake_xid();
- /* Insert "fake" object into table (takes ownership of path) */
- ref_path_table_put(dup_path, fake_objno);
+ /* Create ref path table, if it hasn't already been created */
+ if(ref_path_table == NULL)
+ init_ref_path_table();
+
+ /* Insert "fake" object into table */
+ ref_path_table_put(path, fake_objno);
return(fake_objno);
}
@@ -271,74 +296,19 @@ lookup_ref_path(haddr_t ref)
ref_path_node_t *node;
/* Be safer for h5ls */
- if(!ref_path_table)
+ if(thefile < 0)
return(NULL);
+ /* Create ref path table, if it hasn't already been created */
+ if(ref_path_table == NULL)
+ init_ref_path_table();
+
node = H5SL_search(ref_path_table, &ref);
return(node ? node->path : NULL);
}
/*-------------------------------------------------------------------------
- * Function: fill_ref_path_table_cb
- *
- * Purpose: Called by interator to create references for
- * all objects and enter them in the table.
- *
- * Return: Error status.
- *
- * Programmer: REMcG
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-fill_ref_path_table_cb(hid_t group, const char *obj_name, const H5L_info_t *linfo,
- void *op_data)
-{
- if(linfo->type == H5L_TYPE_HARD) {
- H5O_info_t oinfo;
-
- H5Oget_info_by_name(group, obj_name, &oinfo, H5P_DEFAULT);
-
- /* Check if the object is already in the path table */
- if(!ref_path_table_find(oinfo.addr)) {
- const char *obj_prefix = (const char *)op_data;
- size_t tmp_len;
- char *thepath;
-
- /* Compute length for this object's path */
- tmp_len = HDstrlen(obj_prefix) + HDstrlen(obj_name) + 2;
-
- /* Allocate room for the path for this object */
- if((thepath = (char *)HDmalloc(tmp_len)) == NULL)
- return FAIL;
-
- /* Build the name for this object */
- HDstrcpy(thepath, obj_prefix);
- HDstrcat(thepath, "/");
- HDstrcat(thepath, obj_name);
-
- /* Insert the object into the path table (takes ownership of the path) */
- ref_path_table_put(thepath, oinfo.addr);
-
- if(oinfo.type == H5O_TYPE_GROUP) {
- /* Iterate over objects in this group, using this group's
- * name as their prefix
- */
- if(H5Literate_by_name(group, obj_name, H5_INDEX_NAME, H5_ITER_INC, NULL, fill_ref_path_table_cb, thepath, H5P_DEFAULT) < 0) {
- error_msg(progname, "unable to dump group \"%s\"\n", thepath);
- d_status = EXIT_FAILURE;
- } /* end if */
- } /* end if */
- } /* end if */
- } /* end if */
-
- return 0;
-}
-
-/*-------------------------------------------------------------------------
* Function: fill_ref_path_table
*
* Purpose: Called by interator to create references for
@@ -348,37 +318,15 @@ fill_ref_path_table_cb(hid_t group, const char *obj_name, const H5L_info_t *linf
*
* Programmer: REMcG
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
fill_ref_path_table(hid_t fid)
{
- H5O_info_t oinfo;
- char *root_path;
-
/* Set file ID for later queries (XXX: this should be fixed) */
thefile = fid;
- /* Create skip list to store reference path information */
- if((ref_path_table = H5SL_create(H5SL_TYPE_HADDR, 0.5, (size_t)16))==NULL)
- return (-1);
-
- /* Build the name for root group */
- root_path = HDstrdup("/");
-
- /* Get info for root group */
- H5Oget_info_by_name(fid, root_path, &oinfo, H5P_DEFAULT);
-
- /* Insert the root group into the path table (takes ownership of path) */
- ref_path_table_put(root_path, oinfo.addr);
-
- /* Iterate over objects in this file */
- if(H5Literate(fid, H5_INDEX_NAME, H5_ITER_INC, NULL, fill_ref_path_table_cb, (void *)"") < 0) {
- error_msg(progname, "unable to dump root group\n");
- d_status = EXIT_FAILURE;
- } /* end if */
+ /* Defer creating the ref path table until it's needed */
return 0;
}
diff --git a/tools/lib/h5tools_utils.c b/tools/lib/h5tools_utils.c
index cb38e7a..512a3fb 100644
--- a/tools/lib/h5tools_utils.c
+++ b/tools/lib/h5tools_utils.c
@@ -30,6 +30,7 @@
#include "h5tools_utils.h"
#include "H5private.h"
+#include "h5trav.h"
/* global variables */
int nCols = 80;
@@ -44,10 +45,7 @@ static void init_table(table_t **tbl);
#ifdef H5DUMP_DEBUG
static void dump_table(char* tablename, table_t *table);
#endif /* H5DUMP_DEBUG */
-static void add_obj(table_t *table, haddr_t objno, char *objname, hbool_t recorded);
-static char * build_obj_path_name(const char *prefix, const char *name);
-static herr_t find_objs_cb(hid_t group, const char *name, const H5L_info_t *info,
- void *op_data);
+static void add_obj(table_t *table, haddr_t objno, const char *objname, hbool_t recorded);
/*-------------------------------------------------------------------------
@@ -428,44 +426,15 @@ search_obj(table_t *table, haddr_t objno)
{
unsigned u;
- for (u = 0; u < table->nobjs; u++)
- if (table->objs[u].objno == objno)
- return &(table->objs[u]);
+ for(u = 0; u < table->nobjs; u++)
+ if(table->objs[u].objno == objno)
+ return &(table->objs[u]);
return NULL;
}
/*-------------------------------------------------------------------------
- * Function: build_obj_path_name
- *
- * Purpose: Allocate space & build path name from prefix & name
- *
- * Return: Success: SUCCEED
- *
- * Failure: FAIL
- *
- * Programmer: Quincey Koziol
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static char *
-build_obj_path_name(const char *prefix, const char *name)
-{
- char *path;
-
- path = HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2);
- HDstrcpy(path, prefix);
- HDstrcat(path,"/");
- HDstrcat(path,name); /* absolute name of the data set */
-
- return(path);
-} /* end build_obj_path_name() */
-
-
-/*-------------------------------------------------------------------------
* Function: find_objs_cb
*
* Purpose: Callback to find objects, committed types and store them in tables
@@ -481,90 +450,65 @@ build_obj_path_name(const char *prefix, const char *name)
*-------------------------------------------------------------------------
*/
static herr_t
-find_objs_cb(hid_t group, const char *name, const H5L_info_t UNUSED *linfo, void *op_data)
+find_objs_cb(const char *name, const H5O_info_t *oinfo, const char *already_seen,
+ void *op_data)
{
- H5O_info_t oinfo;
find_objs_t *info = (find_objs_t*)op_data;
herr_t ret_value = 0;
- if(H5Oget_info_by_name(group, name, &oinfo, H5P_DEFAULT) < 0)
- ; /* keep going */
- else {
- switch(oinfo.type) {
- char *tmp;
- size_t tmp_len;
-
- case H5O_TYPE_GROUP:
- if(search_obj(info->group_table, oinfo.addr) == NULL) {
- char *old_prefix;
+ switch(oinfo->type) {
+ case H5O_TYPE_GROUP:
+ if(NULL == already_seen)
+ add_obj(info->group_table, oinfo->addr, name, TRUE);
+ break;
- tmp = build_obj_path_name(info->prefix, name);
- add_obj(info->group_table, oinfo.addr, tmp, TRUE);
+ case H5O_TYPE_DATASET:
+ if(NULL == already_seen) {
+ hid_t dset;
- old_prefix = info->prefix;
- tmp_len = HDstrlen(tmp);
- info->prefix = HDmalloc(tmp_len+1);
- HDstrcpy(info->prefix, tmp);
+ /* Add the dataset to the list of objects */
+ add_obj(info->dset_table, oinfo->addr, name, TRUE);
- if(H5Literate_by_name(group, name, H5_INDEX_NAME, H5_ITER_INC, NULL, find_objs_cb, (void *)info, H5P_DEFAULT) < 0)
- ret_value = FAIL;
+ /* Check for a dataset that uses a named datatype */
+ if((dset = H5Dopen2(info->fid, name, H5P_DEFAULT)) >= 0) {
+ hid_t type = H5Dget_type(dset);
- info->prefix = old_prefix;
- } /* end if */
- break;
-
- case H5O_TYPE_DATASET:
- if(search_obj(info->dset_table, oinfo.addr) == NULL) {
- hid_t dset;
-
- tmp = build_obj_path_name(info->prefix, name);
- add_obj(info->dset_table, oinfo.addr, tmp, TRUE);
-
- if((dset = H5Dopen2(group, name, H5P_DEFAULT)) >= 0) {
- hid_t type;
+ if(H5Tcommitted(type) > 0) {
+ H5O_info_t type_oinfo;
- type = H5Dget_type(dset);
-
- if(H5Tcommitted(type) > 0) {
- H5Oget_info(type, &oinfo);
- if(search_obj(info->type_table, oinfo.addr) == NULL) {
- char *type_name = HDstrdup(tmp);
-
- add_obj(info->type_table, oinfo.addr, type_name, FALSE);
- } /* end if */
- } /* end if */
-
- H5Tclose(type);
- H5Dclose(dset);
+ H5Oget_info(type, &type_oinfo);
+ if(search_obj(info->type_table, type_oinfo.addr) == NULL)
+ add_obj(info->type_table, type_oinfo.addr, name, FALSE);
} /* end if */
- else
- ret_value = FAIL;
- } /* end if */
- break;
- case H5O_TYPE_NAMED_DATATYPE:
- {
- obj_t *found_obj;
-
- tmp = build_obj_path_name(info->prefix, name);
- if((found_obj = search_obj(info->type_table, oinfo.addr)) == NULL)
- add_obj(info->type_table, oinfo.addr, tmp, TRUE);
- else {
- /* Use latest version of name */
- HDfree(found_obj->objname);
- found_obj->objname = HDstrdup(tmp);
-
- /* Mark named datatype as having valid name */
- found_obj->recorded = TRUE;
- } /* end else */
- break;
- }
-
- default:
- /* Ignore links, etc. */
- break;
+ H5Tclose(type);
+ H5Dclose(dset);
+ } /* end if */
+ else
+ ret_value = FAIL;
+ } /* end if */
+ break;
+
+ case H5O_TYPE_NAMED_DATATYPE:
+ {
+ obj_t *found_obj;
+
+ if((found_obj = search_obj(info->type_table, oinfo->addr)) == NULL)
+ add_obj(info->type_table, oinfo->addr, name, TRUE);
+ else {
+ /* Use latest version of name */
+ HDfree(found_obj->objname);
+ found_obj->objname = HDstrdup(name);
+
+ /* Mark named datatype as having valid name */
+ found_obj->recorded = TRUE;
+ } /* end else */
+ break;
}
- } /* end else */
+
+ default:
+ break;
+ } /* end switch */
return ret_value;
}
@@ -589,31 +533,19 @@ herr_t
init_objs(hid_t fid, find_objs_t *info, table_t **group_table,
table_t **dset_table, table_t **type_table)
{
- H5O_info_t oinfo;
-
/* Initialize the tables */
init_table(group_table);
init_table(dset_table);
init_table(type_table);
/* Init the find_objs_t */
- info->prefix = HDcalloc(1, 1);
+ info->fid = fid;
info->group_table = *group_table;
info->type_table = *type_table;
info->dset_table = *dset_table;
- /* add the root group as an object, it may have hard links to it */
- if(H5Oget_info(fid, &oinfo) < 0)
- return FAIL;
- else {
- /* call with an empty string, it appends '/' group separator */
- char *tmp = build_obj_path_name(info->prefix, "");
-
- add_obj(info->group_table, oinfo.addr, tmp, TRUE);
- } /* end else */
-
/* Find all shared objects */
- return(H5Literate(fid, H5_INDEX_NAME, H5_ITER_INC, NULL, find_objs_cb, (void *)info));
+ return(h5trav_visit(fid, "/", TRUE, TRUE, find_objs_cb, NULL, info));
}
@@ -632,22 +564,22 @@ init_objs(hid_t fid, find_objs_t *info, table_t **group_table,
*-------------------------------------------------------------------------
*/
static void
-add_obj(table_t *table, haddr_t objno, char *objname, hbool_t record)
+add_obj(table_t *table, haddr_t objno, const char *objname, hbool_t record)
{
unsigned u;
/* See if we need to make table larger */
- if (table->nobjs == table->size) {
+ if(table->nobjs == table->size) {
table->size *= 2;
- table->objs = HDrealloc(table->objs, table->size * sizeof(obj_t));
- }
+ table->objs = HDrealloc(table->objs, table->size * sizeof(table->objs[0]));
+ } /* end if */
/* Increment number of objects in table */
u = table->nobjs++;
/* Set information about object */
table->objs[u].objno = objno;
- table->objs[u].objname = objname;
+ table->objs[u].objname = HDstrdup(objname);
table->objs[u].recorded = record;
table->objs[u].displayed = 0;
}
diff --git a/tools/lib/h5tools_utils.h b/tools/lib/h5tools_utils.h
index e604e5a..e7b175c 100644
--- a/tools/lib/h5tools_utils.h
+++ b/tools/lib/h5tools_utils.h
@@ -95,7 +95,7 @@ typedef struct table_t {
/*this struct stores the information that is passed to the find_objs function*/
typedef struct find_objs_t {
- char *prefix;
+ hid_t fid;
table_t *group_table;
table_t *type_table;
table_t *dset_table;
diff --git a/tools/lib/h5trav.c b/tools/lib/h5trav.c
index 97de021..14ced60 100644
--- a/tools/lib/h5trav.c
+++ b/tools/lib/h5trav.c
@@ -24,24 +24,25 @@
typedef struct trav_addr_t {
size_t nalloc;
size_t nused;
- haddr_t *addrs;
+ struct {
+ haddr_t addr;
+ char *path;
+ } *objs;
} trav_addr_t;
typedef struct {
- herr_t (*visit_obj)(const char *path_name, const H5O_info_t *oinfo, hbool_t already_visited, void *udata);
- herr_t (*visit_lnk)(const char *path_name, const H5L_info_t *linfo, void *udata);
+ h5trav_obj_func_t visit_obj; /* Callback for visiting objects */
+ h5trav_lnk_func_t visit_lnk; /* Callback for visiting links */
void *udata; /* User data to pass to callbacks */
} trav_visitor_t;
typedef struct {
trav_addr_t *seen; /* List of addresses seen already */
- const char *curr_path; /* Current path to parent group */
const trav_visitor_t *visitor; /* Information for visiting each link/object */
} trav_ud_traverse_t;
typedef struct {
hid_t fid; /* File ID being traversed */
- trav_table_t *table; /* Table for tracking name of objects with >1 hard link */
} trav_print_udata_t;
/*-------------------------------------------------------------------------
@@ -52,10 +53,8 @@ static void trav_table_add(trav_table_t *table,
const char *objname,
const H5O_info_t *oinfo);
-static size_t trav_table_search(const trav_table_t *table, haddr_t objno);
-
static void trav_table_addlink(trav_table_t *table,
- size_t j /* the object index */,
+ haddr_t objno,
const char *path);
/*-------------------------------------------------------------------------
@@ -78,19 +77,20 @@ static void trav_table_addlink(trav_table_t *table,
*-------------------------------------------------------------------------
*/
static void
-trav_addr_add(trav_addr_t *visited, haddr_t addr)
+trav_addr_add(trav_addr_t *visited, haddr_t addr, const char *path)
{
size_t idx; /* Index of address to use */
/* Allocate space if necessary */
if(visited->nused == visited->nalloc) {
visited->nalloc = MAX(1, visited->nalloc * 2);;
- visited->addrs = (haddr_t *)HDrealloc(visited->addrs, visited->nalloc * sizeof(haddr_t));
+ visited->objs = HDrealloc(visited->objs, visited->nalloc * sizeof(visited->objs[0]));
} /* end if */
/* Append it */
idx = visited->nused++;
- visited->addrs[idx] = addr;
+ visited->objs[idx].addr = addr;
+ visited->objs[idx].path = HDstrdup(path);
} /* end trav_addr_add() */
@@ -107,7 +107,7 @@ trav_addr_add(trav_addr_t *visited, haddr_t addr)
*
*-------------------------------------------------------------------------
*/
-static hbool_t
+static const char *
trav_addr_visited(trav_addr_t *visited, haddr_t addr)
{
size_t u; /* Local index variable */
@@ -115,11 +115,11 @@ trav_addr_visited(trav_addr_t *visited, haddr_t addr)
/* Look for address */
for(u = 0; u < visited->nused; u++)
/* Check for address already in array */
- if(visited->addrs[u] == addr)
- return(TRUE);
+ if(visited->objs[u].addr == addr)
+ return(visited->objs[u].path);
/* Didn't find address */
- return(FALSE);
+ return(NULL);
} /* end trav_addr_visited() */
@@ -135,68 +135,44 @@ trav_addr_visited(trav_addr_t *visited, haddr_t addr)
*-------------------------------------------------------------------------
*/
static herr_t
-traverse_cb(hid_t loc_id, const char *link_name, const H5L_info_t *linfo,
+traverse_cb(hid_t loc_id, const char *path, const H5L_info_t *linfo,
void *_udata)
{
trav_ud_traverse_t *udata = (trav_ud_traverse_t *)_udata; /* User data */
- hbool_t is_group = FALSE; /* If the object is a group */
- hbool_t already_visited = FALSE; /* Whether the link/object was already visited */
- char *link_path; /* Full path name of a link */
+ char *full_name;
+ const char *already_visited = NULL; /* Whether the link/object was already visited */
- /* Construct the full path name of this link */
- link_path = (char*)HDmalloc(HDstrlen(udata->curr_path) + HDstrlen(link_name) + 2);
- HDassert(link_path);
- HDstrcpy(link_path, udata->curr_path);
- HDstrcat(link_path, "/");
- HDstrcat(link_path, link_name);
+ /* Create the full path name for the link */
+ full_name = HDmalloc(HDstrlen(path) + 2);
+ *full_name = '/';
+ HDstrcpy(full_name + 1, path);
/* Perform the correct action for different types of links */
if(linfo->type == H5L_TYPE_HARD) {
H5O_info_t oinfo;
/* Get information about the object */
- if(H5Oget_info_by_name(loc_id, link_name, &oinfo, H5P_DEFAULT) < 0)
+ if(H5Oget_info_by_name(loc_id, path, &oinfo, H5P_DEFAULT) < 0)
return(H5_ITER_ERROR);
/* If the object has multiple links, add it to the list of addresses
* already visited, if it isn't there already
*/
- if(oinfo.rc > 1) {
- already_visited = trav_addr_visited(udata->seen, oinfo.addr);
- if(!already_visited)
- trav_addr_add(udata->seen, oinfo.addr);
- } /* end if */
-
- /* Check if object is a group, for later */
- is_group = (oinfo.type == H5O_TYPE_GROUP) ? TRUE : FALSE;
+ if(oinfo.rc > 1)
+ if(NULL == (already_visited = trav_addr_visited(udata->seen, oinfo.addr)))
+ trav_addr_add(udata->seen, oinfo.addr, full_name);
/* Make 'visit object' callback */
if(udata->visitor->visit_obj)
- (*udata->visitor->visit_obj)(link_path, &oinfo, already_visited, udata->visitor->udata);
+ (*udata->visitor->visit_obj)(full_name, &oinfo, already_visited, udata->visitor->udata);
} /* end if */
else {
/* Make 'visit link' callback */
if(udata->visitor->visit_lnk)
- (*udata->visitor->visit_lnk)(link_path, linfo, udata->visitor->udata);
+ (*udata->visitor->visit_lnk)(full_name, linfo, udata->visitor->udata);
} /* end else */
- /* Check for group that we haven't visited yet & recurse */
- if(is_group && !already_visited) {
- const char *prev_path = udata->curr_path; /* Previous path to link's parent group */
-
- /* Set current path to this object */
- udata->curr_path = link_path;
-
- /* Iterate over all links in group object */
- if(H5Literate_by_name(loc_id, link_name, H5_INDEX_NAME, H5_ITER_INC, NULL, traverse_cb, udata, H5P_DEFAULT) < 0)
- return(H5_ITER_ERROR);
-
- /* Restore path in udata */
- udata->curr_path = prev_path;
- } /* end if */
-
- /* Free path name for current link/object */
- HDfree(link_path);
+ HDfree(full_name);
return(H5_ITER_CONT);
} /* end traverse_cb() */
@@ -217,39 +193,58 @@ traverse_cb(hid_t loc_id, const char *link_name, const H5L_info_t *linfo,
*-------------------------------------------------------------------------
*/
static int
-traverse(hid_t file_id, const trav_visitor_t *visitor)
+traverse(hid_t file_id, const char *grp_name, hbool_t visit_start,
+ hbool_t recurse, const trav_visitor_t *visitor)
{
- H5O_info_t oinfo; /* Object info for root group */
- trav_addr_t seen; /* List of addresses seen */
- trav_ud_traverse_t udata; /* User data for iteration callback */
+ H5O_info_t oinfo; /* Object info for starting group */
- /* Get info for root group */
- if(H5Oget_info(file_id, &oinfo) < 0)
+ /* Get info for starting object */
+ if(H5Oget_info_by_name(file_id, grp_name, &oinfo, H5P_DEFAULT) < 0)
return -1;
- /* Visit the root group of the file */
- (*visitor->visit_obj)("/", &oinfo, FALSE, visitor->udata);
+ /* Visit the starting object */
+ if(visit_start && visitor->visit_obj)
+ (*visitor->visit_obj)(grp_name, &oinfo, NULL, visitor->udata);
- /* Init addresses seen */
- seen.nused = seen.nalloc = 0;
- seen.addrs = NULL;
+ /* Go visiting, if the object is a group */
+ if(oinfo.type == H5O_TYPE_GROUP) {
+ trav_addr_t seen; /* List of addresses seen */
+ trav_ud_traverse_t udata; /* User data for iteration callback */
- /* Check for multiple links to root group */
- if(oinfo.rc > 1)
- trav_addr_add(&seen, oinfo.addr);
+ /* Init addresses seen */
+ seen.nused = seen.nalloc = 0;
+ seen.objs = NULL;
- /* Set up user data structure */
- udata.seen = &seen;
- udata.curr_path = "";
- udata.visitor = visitor;
+ /* Check for multiple links to top group */
+ if(oinfo.rc > 1)
+ trav_addr_add(&seen, oinfo.addr, grp_name);
- /* Iterate over all links in root group */
- if(H5Literate(file_id, H5_INDEX_NAME, H5_ITER_INC, NULL, traverse_cb, &udata) < 0)
- return -1;
+ /* Set up user data structure */
+ udata.seen = &seen;
+ udata.visitor = visitor;
- /* Free visited addresses table */
- if(seen.addrs)
- HDfree(seen.addrs);
+ /* Check for iteration of links vs. visiting all links recursively */
+ if(recurse) {
+ /* Visit all links in group, recursively */
+ if(H5Lvisit_by_name(file_id, grp_name, H5_INDEX_NAME, H5_ITER_INC, traverse_cb, &udata, H5P_DEFAULT) < 0)
+ return -1;
+ } /* end if */
+ else {
+ /* Iterate over links in group */
+ if(H5Literate_by_name(file_id, grp_name, H5_INDEX_NAME, H5_ITER_INC, NULL, traverse_cb, &udata, H5P_DEFAULT) < 0)
+ return -1;
+ } /* end else */
+
+ /* Free visited addresses table */
+ if(seen.objs) {
+ size_t u; /* Local index variable */
+
+ /* Free paths to objects */
+ for(u = 0; u < seen.nused; u++)
+ HDfree(seen.objs[u].path);
+ HDfree(seen.objs);
+ } /* end if */
+ } /* end if */
return 0;
}
@@ -301,7 +296,7 @@ trav_info_add(trav_info_t *info, const char *path, h5trav_type_t obj_type)
*/
static int
trav_info_visit_obj(const char *path, const H5O_info_t *oinfo,
- hbool_t UNUSED already_visited, void *udata)
+ const char UNUSED *already_visited, void *udata)
{
/* Add the object to the 'info' struct */
/* (object types map directly to "traversal" types) */
@@ -359,7 +354,7 @@ h5trav_getinfo(hid_t file_id, trav_info_t *info)
info_visitor.udata = info;
/* Traverse all objects in the file, visiting each object & link */
- if(traverse(file_id, &info_visitor) < 0)
+ if(traverse(file_id, "/", TRUE, TRUE, &info_visitor) < 0)
return -1;
return 0;
@@ -470,24 +465,17 @@ trav_info_free(trav_info_t *info)
*/
static int
trav_table_visit_obj(const char *path, const H5O_info_t *oinfo,
- hbool_t already_visited, void *udata)
+ const char *already_visited, void *udata)
{
trav_table_t *table = (trav_table_t *)udata;
/* Check if we've already seen this object */
- if(!already_visited)
+ if(NULL == already_visited)
/* add object to table */
trav_table_add(table, path, oinfo);
- else {
- size_t found; /* Index of original object seen */
-
- /* Look for object in existing table */
- found = trav_table_search(table, oinfo->addr);
- HDassert(found < table->nobjs);
-
+ else
/* Add alias for object to table */
- trav_table_addlink(table, found, path);
- } /* end else */
+ trav_table_addlink(table, oinfo->addr, path);
return(0);
} /* end trav_table_visit_obj() */
@@ -541,7 +529,7 @@ h5trav_gettable(hid_t fid, trav_table_t *table)
table_visitor.udata = table;
/* Traverse all objects in the file, visiting each object & link */
- if(traverse(fid, &table_visitor) < 0)
+ if(traverse(fid, "/", TRUE, TRUE, &table_visitor) < 0)
return -1;
return 0;
}
@@ -670,25 +658,33 @@ trav_table_add(trav_table_t *table,
*/
static void
-trav_table_addlink(trav_table_t *table,
- size_t j /* the object index */,
- const char *path)
+trav_table_addlink(trav_table_t *table, haddr_t objno, const char *path)
{
- size_t new;
+ size_t i; /* Local index variable */
- /* already inserted */
- if(HDstrcmp(table->objs[j].name, path) == 0)
- return;
+ for(i = 0; i < table->nobjs; i++) {
+ if(table->objs[i].objno == objno) {
+ size_t n;
- /* allocate space if necessary */
- if(table->objs[j].nlinks == (unsigned)table->objs[j].sizelinks) {
- table->objs[j].sizelinks = MAX(1, table->objs[j].sizelinks * 2);
- table->objs[j].links = (trav_link_t*)HDrealloc(table->objs[j].links, table->objs[j].sizelinks * sizeof(trav_link_t));
- } /* end if */
+ /* already inserted? */
+ if(HDstrcmp(table->objs[i].name, path) == 0)
+ return;
+
+ /* allocate space if necessary */
+ if(table->objs[i].nlinks == (unsigned)table->objs[i].sizelinks) {
+ table->objs[i].sizelinks = MAX(1, table->objs[i].sizelinks * 2);
+ table->objs[i].links = (trav_link_t*)HDrealloc(table->objs[i].links, table->objs[i].sizelinks * sizeof(trav_link_t));
+ } /* end if */
- /* insert it */
- new = table->objs[j].nlinks++;
- table->objs[j].links[new].new_name = (char *)HDstrdup(path);
+ /* insert it */
+ n = table->objs[i].nlinks++;
+ table->objs[i].links[n].new_name = (char *)HDstrdup(path);
+
+ return;
+ } /* end for */
+ } /* end for */
+
+ HDassert(0 && "object not in table?!?");
}
@@ -809,10 +805,8 @@ void trav_table_free( trav_table_t *table )
*/
static int
trav_print_visit_obj(const char *path, const H5O_info_t *oinfo,
- hbool_t already_visited, void *udata)
+ const char *already_visited, void UNUSED *udata)
{
- trav_print_udata_t *print_udata = (trav_print_udata_t *)udata;
-
/* Print the name of the object */
/* (no new-line, so that objects that we've encountered before can print
* the name of the original object)
@@ -836,26 +830,12 @@ trav_print_visit_obj(const char *path, const H5O_info_t *oinfo,
} /* end switch */
/* Check if we've already seen this object */
- if(!already_visited) {
+ if(NULL == already_visited)
/* Finish printing line about object */
printf("\n");
-
- /* Check if we will encounter another hard link to this object */
- if(oinfo->rc > 1) {
- /* Add object to table */
- trav_table_add(print_udata->table, path, oinfo);
- } /* end if */
- } /* end if */
- else {
- size_t found; /* Index of original object seen */
-
- /* Locate object in table */
- found = trav_table_search(print_udata->table, oinfo->addr);
- HDassert(found < print_udata->table->nobjs);
-
- /* Print the link's destination */
- printf(" -> %s\n", print_udata->table->objs[found].name);
- } /* end else */
+ else
+ /* Print the link's original name */
+ printf(" -> %s\n", already_visited);
return(0);
} /* end trav_print_visit_obj() */
@@ -938,16 +918,11 @@ trav_print_visit_lnk(const char *path, const H5L_info_t *linfo, void *udata)
int
h5trav_print(hid_t fid)
{
- trav_table_t *table = NULL; /* Table for objects w/multiple hard links */
trav_print_udata_t print_udata; /* User data for traversal */
trav_visitor_t print_visitor; /* Visitor structure for printing objects */
- /* Initialize the table */
- trav_table_init(&table);
-
/* Init user data for printing */
print_udata.fid = fid;
- print_udata.table = table;
/* Init visitor structure */
print_visitor.visit_obj = trav_print_visit_obj;
@@ -955,11 +930,42 @@ h5trav_print(hid_t fid)
print_visitor.udata = &print_udata;
/* Traverse all objects in the file, visiting each object & link */
- if(traverse(fid, &print_visitor) < 0)
+ if(traverse(fid, "/", TRUE, TRUE, &print_visitor) < 0)
return -1;
- /* Free table */
- trav_table_free(table);
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: h5trav_visit
+ *
+ * Purpose: Generic traversal routine for visiting objects and links
+ *
+ * Return: 0, -1 on error
+ *
+ * Programmer: Quincey Koziol, koziol@hdfgroup.org
+ *
+ * Date: November 6, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int
+h5trav_visit(hid_t fid, const char *grp_name, hbool_t visit_start,
+ hbool_t recurse, h5trav_obj_func_t visit_obj, h5trav_lnk_func_t visit_lnk,
+ void *udata)
+{
+ trav_visitor_t visitor; /* Visitor structure for objects */
+
+ /* Init visitor structure */
+ visitor.visit_obj = visit_obj;
+ visitor.visit_lnk = visit_lnk;
+ visitor.udata = udata;
+
+ /* Traverse all objects in the file, visiting each object & link */
+ if(traverse(fid, grp_name, visit_start, recurse, &visitor) < 0)
+ return -1;
return 0;
}
diff --git a/tools/lib/h5trav.h b/tools/lib/h5trav.h
index 05bc3cb..5c07331 100644
--- a/tools/lib/h5trav.h
+++ b/tools/lib/h5trav.h
@@ -18,6 +18,12 @@
#include "hdf5.h"
+/* Typedefs for visiting objects */
+typedef herr_t (*h5trav_obj_func_t)(const char *path_name, const H5O_info_t *oinfo,
+ const char *first_seen, void *udata);
+typedef herr_t (*h5trav_lnk_func_t)(const char *path_name, const H5L_info_t *linfo,
+ void *udata);
+
/*-------------------------------------------------------------------------
* public enum to specify type of an object
* the TYPE can be:
@@ -101,6 +107,14 @@ extern "C" {
#endif
/*-------------------------------------------------------------------------
+ * "h5trav general" public functions
+ *-------------------------------------------------------------------------
+ */
+int h5trav_visit(hid_t file_id, const char *grp_name, hbool_t visit_start,
+ hbool_t recurse, h5trav_obj_func_t visit_obj, h5trav_lnk_func_t visit_lnk,
+ void *udata);
+
+/*-------------------------------------------------------------------------
* "h5trav info" public functions
*-------------------------------------------------------------------------
*/
diff --git a/tools/testfiles/h5copytst.out.ls b/tools/testfiles/h5copytst.out.ls
index c4d1778..785c3f0 100644
--- a/tools/testfiles/h5copytst.out.ls
+++ b/tools/testfiles/h5copytst.out.ls
@@ -2,6 +2,9 @@
Expected output for 'h5ls ../testfiles/h5copytst.out.h5'
#############################
Opened "../testfiles/h5copytst.out.h5" with sec2 driver.
+/ Group
+ Location: 1:96
+ Links: 1
/A Group
Location: 1:90344
Links: 1
diff --git a/tools/testfiles/h5mkgrp_nested.ls b/tools/testfiles/h5mkgrp_nested.ls
index 2b9fb25..472656d 100644
--- a/tools/testfiles/h5mkgrp_nested.ls
+++ b/tools/testfiles/h5mkgrp_nested.ls
@@ -2,6 +2,9 @@
Expected output for 'h5ls ../testfiles/h5mkgrp_nested.h5'
#############################
Opened "../testfiles/h5mkgrp_nested.h5" with sec2 driver.
+/ Group
+ Location: 1:96
+ Links: 1
/one Group
Location: 1:800
Links: 1
diff --git a/tools/testfiles/h5mkgrp_nested_latest.ls b/tools/testfiles/h5mkgrp_nested_latest.ls
index f0bab6f..c00292d 100644
--- a/tools/testfiles/h5mkgrp_nested_latest.ls
+++ b/tools/testfiles/h5mkgrp_nested_latest.ls
@@ -2,6 +2,10 @@
Expected output for 'h5ls ../testfiles/h5mkgrp_nested_latest.h5'
#############################
Opened "../testfiles/h5mkgrp_nested_latest.h5" with sec2 driver.
+/ Group
+ Location: 1:48
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
/one Group
Location: 1:195
Links: 1
diff --git a/tools/testfiles/h5mkgrp_nested_mult.ls b/tools/testfiles/h5mkgrp_nested_mult.ls
index 4fccd83..6a22ffd 100644
--- a/tools/testfiles/h5mkgrp_nested_mult.ls
+++ b/tools/testfiles/h5mkgrp_nested_mult.ls
@@ -2,6 +2,9 @@
Expected output for 'h5ls ../testfiles/h5mkgrp_nested_mult.h5'
#############################
Opened "../testfiles/h5mkgrp_nested_mult.h5" with sec2 driver.
+/ Group
+ Location: 1:96
+ Links: 1
/one Group
Location: 1:800
Links: 1
diff --git a/tools/testfiles/h5mkgrp_nested_mult_latest.ls b/tools/testfiles/h5mkgrp_nested_mult_latest.ls
index 7835050..0b19ff9 100644
--- a/tools/testfiles/h5mkgrp_nested_mult_latest.ls
+++ b/tools/testfiles/h5mkgrp_nested_mult_latest.ls
@@ -2,6 +2,10 @@
Expected output for 'h5ls ../testfiles/h5mkgrp_nested_mult_latest.h5'
#############################
Opened "../testfiles/h5mkgrp_nested_mult_latest.h5" with sec2 driver.
+/ Group
+ Location: 1:48
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
/one Group
Location: 1:195
Links: 1
diff --git a/tools/testfiles/h5mkgrp_several.ls b/tools/testfiles/h5mkgrp_several.ls
index dcbe3eb..bbf5c92 100644
--- a/tools/testfiles/h5mkgrp_several.ls
+++ b/tools/testfiles/h5mkgrp_several.ls
@@ -2,6 +2,9 @@
Expected output for 'h5ls ../testfiles/h5mkgrp_several.h5'
#############################
Opened "../testfiles/h5mkgrp_several.h5" with sec2 driver.
+/ Group
+ Location: 1:96
+ Links: 1
/one Group
Location: 1:800
Links: 1
diff --git a/tools/testfiles/h5mkgrp_several_latest.ls b/tools/testfiles/h5mkgrp_several_latest.ls
index c59107e..a3b5224 100644
--- a/tools/testfiles/h5mkgrp_several_latest.ls
+++ b/tools/testfiles/h5mkgrp_several_latest.ls
@@ -2,6 +2,10 @@
Expected output for 'h5ls ../testfiles/h5mkgrp_several_latest.h5'
#############################
Opened "../testfiles/h5mkgrp_several_latest.h5" with sec2 driver.
+/ Group
+ Location: 1:48
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
/one Group
Location: 1:195
Links: 1
diff --git a/tools/testfiles/h5mkgrp_single.ls b/tools/testfiles/h5mkgrp_single.ls
index 1f7e828..e9932f7 100644
--- a/tools/testfiles/h5mkgrp_single.ls
+++ b/tools/testfiles/h5mkgrp_single.ls
@@ -2,6 +2,9 @@
Expected output for 'h5ls ../testfiles/h5mkgrp_single.h5'
#############################
Opened "../testfiles/h5mkgrp_single.h5" with sec2 driver.
+/ Group
+ Location: 1:96
+ Links: 1
/single Group
Location: 1:800
Links: 1
diff --git a/tools/testfiles/h5mkgrp_single_latest.ls b/tools/testfiles/h5mkgrp_single_latest.ls
index 7f5ee72..b6e6ea4 100644
--- a/tools/testfiles/h5mkgrp_single_latest.ls
+++ b/tools/testfiles/h5mkgrp_single_latest.ls
@@ -2,6 +2,10 @@
Expected output for 'h5ls ../testfiles/h5mkgrp_single_latest.h5'
#############################
Opened "../testfiles/h5mkgrp_single_latest.h5" with sec2 driver.
+/ Group
+ Location: 1:48
+ Links: 1
+ Modified: XXXX-XX-XX XX:XX:XX XXX
/latest Group
Location: 1:195
Links: 1
diff --git a/tools/testfiles/tall-2.ls b/tools/testfiles/tall-2.ls
index 5513214..2e4cd37 100644
--- a/tools/testfiles/tall-2.ls
+++ b/tools/testfiles/tall-2.ls
@@ -1,6 +1,7 @@
#############################
output for 'h5ls -w80 -r -d tall.h5'
#############################
+/ Group
/g1 Group
/g1/g1.1 Group
/g1/g1.1/dset1.1.1 Dataset {10, 10}
diff --git a/tools/testfiles/tarray1.ls b/tools/testfiles/tarray1.ls
index 83a51a8..60c002d 100644
--- a/tools/testfiles/tarray1.ls
+++ b/tools/testfiles/tarray1.ls
@@ -1,6 +1,7 @@
#############################
output for 'h5ls -w80 -r -d tarray1.h5'
#############################
+/ Group
/Dataset1 Dataset {4}
Data:
(0) [0,1,2,3], [10,11,12,13], [20,21,22,23], [30,31,32,33]
diff --git a/tools/testfiles/tattr2.ls b/tools/testfiles/tattr2.ls
index 88b24cd..0448868 100644
--- a/tools/testfiles/tattr2.ls
+++ b/tools/testfiles/tattr2.ls
@@ -2,149 +2,6 @@
output for 'h5ls -w80 -v -S tattr2.h5'
#############################
Opened "tattr2.h5" with sec2 driver.
- Attribute: array {2}
- Type: [3] 32-bit little-endian integer
- Data: [1,2,3], [4,5,6]
- Attribute: array2D {3, 2}
- Type: [3] 32-bit little-endian integer
- Data:
- (0,0) [1,2,3], [4,5,6], [7,8,9], [10,11,12], [13,14,15], [16,17,18]
- Attribute: array3D {4, 3, 2}
- Type: [3] 32-bit little-endian integer
- Data:
- (0,0,0) [1,2,3], [4,5,6], [7,8,9], [10,11,12], [13,14,15],
- (0,2,1) [16,17,18], [19,20,21], [22,23,24], [25,26,27], [28,29,30],
- (1,2,0) [31,32,33], [34,35,36], [37,38,39], [40,41,42], [43,44,45],
- (2,1,1) [46,47,48], [49,50,51], [52,53,54], [55,56,57], [58,59,60],
- (3,1,0) [61,62,63], [64,65,66], [67,68,69], [70,71,72]
- Attribute: bitfield {2}
- Type: 8-bit bitfield
- Data: 0x01, 0x02
- Attribute: bitfield2D {3, 2}
- Type: 8-bit bitfield
- Data:
- (0,0) 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
- Attribute: bitfield3D {4, 3, 2}
- Type: 8-bit bitfield
- Data:
- (0,0,0) 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
- (1,2,0) 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
- (3,1,0) 0x15, 0x16, 0x17, 0x18
- Attribute: compound {2}
- Type: struct {
- "a" +0 8-bit integer
- "b" +4 IEEE 64-bit little-endian float
- } 12 bytes
- Data: {1, 2}, {3, 4}
- Attribute: compound2D {3, 2}
- Type: struct {
- "a" +0 8-bit integer
- "b" +4 IEEE 64-bit little-endian float
- } 12 bytes
- Data:
- (0,0) {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}
- Attribute: compound3D {4, 3, 2}
- Type: struct {
- "a" +0 8-bit integer
- "b" +4 IEEE 64-bit little-endian float
- } 12 bytes
- Data:
- (0,0,0) {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13,
- (1,0,0) 14}, {15, 16}, {17, 18}, {19, 20}, {21, 22}, {23, 24},
- (2,0,0) {25, 26}, {27, 28}, {29, 30}, {31, 32}, {33, 34}, {35, 36},
- (3,0,0) {37, 38}, {39, 40}, {41, 42}, {43, 44}, {45, 46}, {47, 48}
- Attribute: enum {2}
- Type: enum 32-bit little-endian integer {
- RED = 0
- GREEN = 1
- }
- Data: RED, RED
- Attribute: enum2D {3, 2}
- Type: enum 32-bit little-endian integer {
- RED = 0
- GREEN = 1
- }
- Data:
- (0,0) RED, RED, RED, RED, RED, RED
- Attribute: enum3D {4, 3, 2}
- Type: enum 32-bit little-endian integer {
- RED = 0
- GREEN = 1
- }
- Data:
- (0,0,0) RED, RED, RED, RED, RED, RED, RED, RED, RED, RED, RED, RED,
- (2,0,0) RED, RED, RED, RED, RED, RED, RED, RED, RED, RED, RED, RED
- Attribute: float {2}
- Type: IEEE 32-bit little-endian float
- Data: 1, 2
- Attribute: float2D {3, 2}
- Type: IEEE 32-bit little-endian float
- Data:
- (0,0) 1, 2, 3, 4, 5, 6
- Attribute: float3D {4, 3, 2}
- Type: IEEE 32-bit little-endian float
- Data:
- (0,0,0) 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- (2,2,1) 18, 19, 20, 21, 22, 23, 24
- Attribute: integer {2}
- Type: 32-bit little-endian integer
- Data: 1, 2
- Attribute: integer2D {3, 2}
- Type: 32-bit little-endian integer
- Data:
- (0,0) 1, 2, 3, 4, 5, 6
- Attribute: integer3D {4, 3, 2}
- Type: 32-bit little-endian integer
- Data:
- (0,0,0) 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- (2,2,1) 18, 19, 20, 21, 22, 23, 24
- Attribute: opaque {2}
- Type: 1-byte opaque type
- (tag = "1-byte opaque type")
- Data: 0x01, 0x02
- Attribute: opaque2D {3, 2}
- Type: 1-byte opaque type
- (tag = "1-byte opaque type")
- Data:
- (0,0) 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
- Attribute: opaque3D {4, 3, 2}
- Type: 1-byte opaque type
- (tag = "1-byte opaque type")
- Data:
- (0,0,0) 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
- (1,2,0) 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
- (3,1,0) 0x15, 0x16, 0x17, 0x18
- Attribute: string {2}
- Type: 2-byte null-terminated ASCII string
- Data: "ab", "de"
- Attribute: string2D {3, 2}
- Type: 2-byte null-terminated ASCII string
- Data:
- (0,0) "ab", "cd", "ef", "gh", "ij", "kl"
- Attribute: string3D {4, 3, 2}
- Type: 2-byte null-terminated ASCII string
- Data:
- (0,0,0) "ab", "cd", "ef", "gh", "ij", "kl", "mn", "pq", "rs", "tu",
- (1,2,0) "vw", "xz", "AB", "CD", "EF", "GH", "IJ", "KL", "MN", "PQ",
- (3,1,0) "RS", "TU", "VW", "XZ"
- Attribute: vlen {2}
- Type: variable length of
- 32-bit little-endian integer
- Data: (1), (2,3)
- Attribute: vlen2D {3, 2}
- Type: variable length of
- 32-bit little-endian integer
- Data:
- (0,0) (0), (1), (2,3), (4,5), (6,7,8), (9,10,11)
- Attribute: vlen3D {4, 3, 2}
- Type: variable length of
- 32-bit little-endian integer
- Data:
- (0,0,0) (0), (1), (2), (3), (4), (5), (6,7), (8,9), (10,11),
- (1,1,1) (12,13), (14,15), (16,17), (18,19,20), (21,22,23),
- (2,1,0) (24,25,26), (27,28,29), (30,31,32), (33,34,35),
- (3,0,0) (36,37,38,39), (40,41,42,43), (44,45,46,47), (48,49,50,51),
- (3,2,0) (52,53,54,55), (56,57,58,59)
dset Dataset {2/2}
Attribute: array {2}
Type: [3] 32-bit little-endian integer
diff --git a/tools/testfiles/tcomp-1.ls b/tools/testfiles/tcomp-1.ls
index 599fe68..9cfb47d 100644
--- a/tools/testfiles/tcomp-1.ls
+++ b/tools/testfiles/tcomp-1.ls
@@ -1,6 +1,7 @@
#############################
output for 'h5ls -w80 -r -d tcompound.h5'
#############################
+/ Group
/dset1 Dataset {5}
Data:
(0) {0, 0, 1}, {1, 1, 0.5}, {2, 4, 0.333333333333333}, {3, 9, 0.25},
diff --git a/tools/testfiles/tdset-1.ls b/tools/testfiles/tdset-1.ls
index 6853429..b6e4671 100644
--- a/tools/testfiles/tdset-1.ls
+++ b/tools/testfiles/tdset-1.ls
@@ -1,6 +1,7 @@
#############################
output for 'h5ls -w80 -r -d tdset.h5'
#############################
+/ Group
/dset1 Dataset {10, 20}
Data:
(0,0) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
diff --git a/tools/testfiles/textlink-1.ls b/tools/testfiles/textlink-1.ls
index f92786b..87be5a7 100644
--- a/tools/testfiles/textlink-1.ls
+++ b/tools/testfiles/textlink-1.ls
@@ -1,5 +1,6 @@
#############################
output for 'h5ls -w80 -r textlink.h5'
#############################
+/ Group
/extlink1 -> file: filename path: objname
/extlink2 -> file: anotherfile path: anotherobj
diff --git a/tools/testfiles/tgroup-1.ls b/tools/testfiles/tgroup-1.ls
index 62ebe70..0ca929d 100644
--- a/tools/testfiles/tgroup-1.ls
+++ b/tools/testfiles/tgroup-1.ls
@@ -1,17 +1,29 @@
#############################
output for 'h5ls -w80 -r -g tgroup.h5'
#############################
-/ Group
-/g1 Group
-/g1/g1.1 Group
-/g1/g1.2 Group
-/g2 Group
-/g2/g2.1 Group
-/g2/g2.1/g2.1.1 Group
-/g2/g2.1/g2.1.2 Group
-/g2/g2.1/g2.1.3 Group
-/g3 Group
-/g3/g3.1 Group
-/g3/g3.2 Group
-/g3/g3.3 Group
-/g3/g3.4 Group
+Error: 'recursive' option not compatible with 'group info' option!
+
+usage: h5ls [OPTIONS] [OBJECTS...]
+ OPTIONS
+ -h, -?, --help Print a usage message and exit
+ -a, --address Print addresses for raw data
+ -d, --data Print the values of datasets
+ -e, --errors Show all HDF5 error reporting
+ -f, --full Print full path names instead of base names
+ -g, --group Show information about a group, not its contents
+ -l, --label Label members of compound datasets
+ -r, --recursive List all groups recursively, avoiding cycles
+ -s, --string Print 1-byte integer datasets as ASCII
+ -S, --simple Use a machine-readable output format
+ -wN, --width=N Set the number of columns of output
+ -v, --verbose Generate more verbose output
+ -V, --version Print version number and exit
+ --vfd=DRIVER Use the specified virtual file driver
+ -x, --hexdump Show raw data in hexadecimal format
+
+ OBJECTS
+ Each object consists of an HDF5 file name optionally followed by a
+ slash and an object name within the file (if no object is specified
+ within the file then the contents of the root group are displayed).
+ The file name may include a printf(3C) integer format such as
+ "%05d" to open a file family.
diff --git a/tools/testfiles/tgroup-2.ls b/tools/testfiles/tgroup-2.ls
new file mode 100644
index 0000000..0817d93
--- /dev/null
+++ b/tools/testfiles/tgroup-2.ls
@@ -0,0 +1,4 @@
+#############################
+ output for 'h5ls -w80 -g tgroup.h5/g1'
+#############################
+g1 Group
diff --git a/tools/testfiles/tloop-1.ls b/tools/testfiles/tloop-1.ls
index b9631b7..22cb6c7 100644
--- a/tools/testfiles/tloop-1.ls
+++ b/tools/testfiles/tloop-1.ls
@@ -1,6 +1,7 @@
#############################
output for 'h5ls -w80 -r -d tloop.h5'
#############################
+/ Group
/g1 Group
/g1/g1.1 Group
/g1/g1.1/g2.1 Group, same as /g1
diff --git a/tools/testfiles/tnestcomp-1.ls b/tools/testfiles/tnestcomp-1.ls
index eef41ef..9dc193d 100644
--- a/tools/testfiles/tnestcomp-1.ls
+++ b/tools/testfiles/tnestcomp-1.ls
@@ -1,6 +1,7 @@
#############################
output for 'h5ls -w80 -r -d tnestedcomp.h5'
#############################
+/ Group
/ArrayOfStructures Dataset {10}
Data:
(0) {0, 0, 1, {"A", [-100,100]}}, {1, 1, 0.5, {"B", [-100,100]}},
diff --git a/tools/testfiles/tsaf.ls b/tools/testfiles/tsaf.ls
index 8efc0f2..96d4811 100644
--- a/tools/testfiles/tsaf.ls
+++ b/tools/testfiles/tsaf.ls
@@ -1,6 +1,7 @@
#############################
output for 'h5ls -w80 -r -d tsaf.h5'
#############################
+/ Group
/.DSL_METADATA Dataset {5919/Inf}
Data:
(0) 47, 32, 67, 79, 78, 84, 65, 73, 78, 69, 82, 10, 47, 46, 97, 116,
diff --git a/tools/testfiles/tslink-1.ls b/tools/testfiles/tslink-1.ls
index 05b9bca..4c16958 100644
--- a/tools/testfiles/tslink-1.ls
+++ b/tools/testfiles/tslink-1.ls
@@ -1,5 +1,6 @@
#############################
output for 'h5ls -w80 -r tslink.h5'
#############################
+/ Group
/slink1 -> somevalue
/slink2 -> linkvalue
diff --git a/tools/testfiles/tstr-1.ls b/tools/testfiles/tstr-1.ls
index 1961fd4..8a223cc 100644
--- a/tools/testfiles/tstr-1.ls
+++ b/tools/testfiles/tstr-1.ls
@@ -1,6 +1,7 @@
#############################
output for 'h5ls -w80 -r -d tstr.h5'
#############################
+/ Group
/comp1 Dataset {3, 6}
Data:
(0,0) {[0,1,4,9,16,25,36,49,64,81,1,4,9,16,25,36,49,64,81,100,4,9,16,
diff --git a/tools/testfiles/tudlink-1.ls b/tools/testfiles/tudlink-1.ls
index e83fce7..b8578ce 100644
--- a/tools/testfiles/tudlink-1.ls
+++ b/tools/testfiles/tudlink-1.ls
@@ -1,5 +1,6 @@
#############################
output for 'h5ls -w80 -r tudlink.h5'
#############################
+/ Group
/udlink1 -> cannot follow UD links
/udlink2 -> cannot follow UD links
diff --git a/tools/testfiles/tvldtypes1.ls b/tools/testfiles/tvldtypes1.ls
index cf1688e..4c4c162 100644
--- a/tools/testfiles/tvldtypes1.ls
+++ b/tools/testfiles/tvldtypes1.ls
@@ -1,6 +1,7 @@
#############################
output for 'h5ls -w80 -r -d tvldtypes1.h5'
#############################
+/ Group
/Dataset1.0 Dataset {4}
Data:
(0) (0), (10,11), (20,21,22), (30,31,32,33)