summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2008-10-16 03:52:16 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2008-10-16 03:52:16 (GMT)
commitad28fa5b0c1384fe70397fb2eaa83e2a6e62699d (patch)
treea71c5b86d440ffdb059864d75e35e3c41102a01b
parent273f31211ed4725fde9e7b5b35a884d3f2359246 (diff)
downloadhdf5-ad28fa5b0c1384fe70397fb2eaa83e2a6e62699d.zip
hdf5-ad28fa5b0c1384fe70397fb2eaa83e2a6e62699d.tar.gz
hdf5-ad28fa5b0c1384fe70397fb2eaa83e2a6e62699d.tar.bz2
[svn-r15886] Purpose: Close bug 1332
Description: Improved external link traversal of h5dump. h5dump will now properly avoid all cycles, even those spanning multiple files. Improvement to the output of committed datatypes. Committed datatypes are now checked for uniqueness (like other objects). Tests added for these cases. Tested: kagiso, linew, smirom (h5committest)
-rw-r--r--MANIFEST3
-rw-r--r--release_docs/RELEASE.txt4
-rw-r--r--tools/h5dump/h5dump.c394
-rw-r--r--tools/h5dump/h5dumpgentest.c31
-rw-r--r--tools/h5dump/testh5dump.sh.in4
-rw-r--r--tools/h5ls/h5ls.c2
-rw-r--r--tools/lib/h5tools_utils.c28
-rw-r--r--tools/testfiles/textlinkfar.ddl69
-rw-r--r--tools/testfiles/textlinkfar.h5bin0 -> 888 bytes
-rw-r--r--tools/testfiles/textlinksrc-1.ls2
-rw-r--r--tools/testfiles/textlinksrc-3.ls2
-rw-r--r--tools/testfiles/textlinksrc.ddl60
-rw-r--r--tools/testfiles/textlinktar.h5bin5664 -> 6752 bytes
-rw-r--r--tools/testfiles/thlink.h5.xml4
-rw-r--r--tools/testfiles/tmany.h5.xml4
-rw-r--r--tools/testfiles/tnamed_dtype_attr.ddl4
-rw-r--r--tools/testfiles/tnamed_dtype_attr.h5bin2304 -> 2304 bytes
-rw-r--r--tools/testfiles/tnamed_dtype_attr.h5.xml15
-rw-r--r--tools/testfiles/torderattr1.ddl4
-rw-r--r--tools/testfiles/torderattr2.ddl4
-rw-r--r--tools/testfiles/torderattr3.ddl4
-rw-r--r--tools/testfiles/torderattr4.ddl4
-rw-r--r--tools/testfiles/tvlstr.ddl2
-rw-r--r--windows/tools/h5dump/testh5dump.bat4
24 files changed, 541 insertions, 107 deletions
diff --git a/MANIFEST b/MANIFEST
index 9d2e2af..4fe181e 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1154,6 +1154,9 @@
./tools/testfiles/textlink.h5
./tools/testfiles/textlink.h5.xml
./tools/testfiles/textlink-1.ls
+./tools/testfiles/textlinkfar.ddl
+./tools/testfiles/textlinkfar.h5
+./tools/testfiles/textlinksrc.ddl
./tools/testfiles/textlinksrc.h5
./tools/testfiles/textlinksrc-1.ls
./tools/testfiles/textlinksrc-2.ls
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index a1711d1..80a57c7 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -175,6 +175,10 @@ Bug Fixes since HDF5-1.8.0 release
Tools
-----
+ - h5dump now checks for uniqueness of committed datatypes.
+ (NAF - 2008/10/15)
+ - Fixed unnecessary indentation of committed datatypes in h5dump.
+ (NAF - 2008/10/15)
- Fixed bugs in h5stat:segmemtation fault when printing groups and
print warning message when traversal of objects is unsuccessful.
(see bug #1253) (VC- 2008/10/13)
diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c
index 8ace682..979c2ff 100644
--- a/tools/h5dump/h5dump.c
+++ b/tools/h5dump/h5dump.c
@@ -55,9 +55,24 @@ const char *progname = "h5dump";
#define H5_SZIP_MSB_OPTION_MASK 16
#define H5_SZIP_RAW_OPTION_MASK 128
+/* List of table structures. There is one table structure for each file */
+typedef struct h5dump_table_list_t {
+ size_t nalloc;
+ size_t nused;
+ struct {
+ unsigned long fileno; /* File number that these tables refer to */
+ hid_t oid; /* ID of an object in this file, held open so fileno is consistent */
+ table_t *group_table; /* Table of groups */
+ table_t *dset_table; /* Table of datasets */
+ table_t *type_table; /* Table of datatypes */
+ } *tables;
+} h5dump_table_list_t;
+
int d_status = EXIT_SUCCESS;
static int unamedtype = 0; /* shared datatype with no name */
+static h5dump_table_list_t table_list = {0, 0, NULL};
static table_t *group_table = NULL, *dset_table = NULL, *type_table = NULL;
+static hbool_t hit_elink = FALSE; /* whether we have traversed an external link */
static size_t prefix_len = 1024;
static char *prefix;
static const char *driver = NULL; /* The driver to open the file with. */
@@ -106,7 +121,7 @@ static void init_prefix(char **prfx, size_t prfx_len);
static void add_prefix(char **prfx, size_t *prfx_len, const char *name);
/* callback function used by H5Literate() */
static herr_t dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void *op_data);
-static int dump_extlink(const char *filename, const char *targname);
+static int dump_extlink(hid_t group, const char *linkname, const char *objname);
static h5tool_format_t dataformat = {
@@ -359,7 +374,7 @@ static char *xml_escape_the_name(const char *);
/* a structure for handling the order command-line parameters come in */
struct handler_t {
- void (*func)(hid_t, const char *, void *, int);
+ void (*func)(hid_t, const char *, void *, int, const char *);
char *obj;
struct subset_t *subset_info;
};
@@ -690,6 +705,126 @@ usage(const char *prog)
fprintf(stdout, "\n");
}
+
+/*-------------------------------------------------------------------------
+ * Function: table_list_add
+ *
+ * Purpose: Add a new set of tables
+ *
+ * Return: index of added table on success, -1 on failure
+ *
+ * Programmer: Neil Fortner, nfortne2@hdfgroup.org
+ * Adapted from trav_addr_add in h5trav.c by Quincey Koziol
+ *
+ * Date: October 13, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static ssize_t
+table_list_add(hid_t oid, unsigned long file_no)
+{
+ size_t idx; /* Index of table to use */
+ find_objs_t info;
+ void *tmp_ptr;
+
+ /* Allocate space if necessary */
+ if(table_list.nused == table_list.nalloc) {
+ table_list.nalloc = MAX(1, table_list.nalloc * 2);
+ if(NULL == (tmp_ptr = HDrealloc(table_list.tables, table_list.nalloc * sizeof(table_list.tables[0]))))
+ return -1;
+ table_list.tables = tmp_ptr;
+ } /* end if */
+
+ /* Append it */
+ idx = table_list.nused++;
+ table_list.tables[idx].fileno = file_no;
+ table_list.tables[idx].oid = oid;
+ if(H5Iinc_ref(oid) < 0) {
+ table_list.nused--;
+ return -1;
+ }
+ if(init_objs(oid, &info, &table_list.tables[idx].group_table,
+ &table_list.tables[idx].dset_table, &table_list.tables[idx].type_table) < 0) {
+ H5Idec_ref(oid);
+ table_list.nused--;
+ return -1;
+ }
+
+#ifdef H5DUMP_DEBUG
+ dump_tables(&info);
+#endif /* H5DUMP_DEBUG */
+
+ return((ssize_t) idx);
+} /* end table_list_add() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: table_list_visited
+ *
+ * Purpose: Check if a table already exists for the specified fileno
+ *
+ * Return: The index of the matching table, or -1 if no matches found
+ *
+ * Programmer: Neil Fortner, nfortne2@hdfgroup.org
+ * Adapted from trav_addr_visited in h5trav.c by Quincey Koziol
+ *
+ * Date: October 13, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static ssize_t
+table_list_visited(unsigned long file_no)
+{
+ size_t u; /* Local index variable */
+
+ /* Look for table */
+ for(u = 0; u < table_list.nused; u++)
+ /* Check for fileno value already in array */
+ if(table_list.tables[u].fileno == file_no)
+ return((ssize_t) u);
+
+ /* Didn't find table */
+ return(-1);
+} /* end table_list_visited() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: table_list_free
+ *
+ * Purpose: Frees the table list
+ *
+ * Return: void
+ *
+ * Programmer: Neil Fortner, nfortne2@hdfgroup.org
+ *
+ * Date: October 13, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+table_list_free(void)
+{
+ size_t u; /* Local index variable */
+
+ /* Iterate over tables */
+ for(u = 0; u < table_list.nused; u++) {
+ /* Release object id */
+ if(H5Idec_ref(table_list.tables[u].oid) < 0)
+ d_status = EXIT_FAILURE;
+
+ /* Free each table */
+ free_table(table_list.tables[u].group_table);
+ free_table(table_list.tables[u].dset_table);
+ free_table(table_list.tables[u].type_table);
+ }
+
+ /* Free the table list */
+ HDfree(table_list.tables);
+ table_list.tables = NULL;
+ table_list.nalloc = table_list.nused = 0;
+} /* end table_list_free() */
+
+
/*-------------------------------------------------------------------------
* Function: print_datatype
*
@@ -1443,7 +1578,7 @@ dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void UNUSED
case H5O_TYPE_DATASET:
if((obj = H5Dopen2(group, name, H5P_DEFAULT)) >= 0) {
- if(oinfo.rc > 1) {
+ if(oinfo.rc > 1 || hit_elink) {
obj_t *found_obj; /* Found object */
found_obj = search_obj(dset_table, oinfo.addr);
@@ -1479,6 +1614,7 @@ dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void UNUSED
char *t_obj_path = xml_escape_the_name(obj_path);
char *t_prefix = xml_escape_the_name(HDstrcmp(prefix,"") ? prefix : "/");
char *t_name = xml_escape_the_name(name);
+ char *t_objname = xml_escape_the_name(found_obj->objname);
char dsetxid[100];
char parentxid[100];
char pointerxid[100];
@@ -1501,13 +1637,14 @@ dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void UNUSED
xml_name_to_XID(found_obj->objname, pointerxid, sizeof(pointerxid), 1);
printf("<%sDatasetPtr OBJ-XID=\"%s\" H5Path=\"%s\"/>\n",
xmlnsprefix,
- pointerxid,t_obj_path);
+ pointerxid,t_objname);
indentation(indent);
printf("</%sDataset>\n", xmlnsprefix);
HDfree(t_name);
HDfree(t_obj_path);
HDfree(t_prefix);
+ HDfree(t_objname);
}
H5Dclose(obj);
@@ -1672,7 +1809,7 @@ dump_all_cb(hid_t group, const char *name, const H5L_info_t *linfo, void UNUSED
/* dump the external link */
- dump_extlink(filename,targname);
+ dump_extlink(group, name, targname);
} /* end if */
@@ -1786,7 +1923,7 @@ done:
static void
dump_named_datatype(hid_t tid, const char *name)
{
-
+ H5O_info_t oinfo;
unsigned attr_crt_order_flags;
hid_t tcpl_id; /* datatype creation property list ID */
@@ -1814,13 +1951,33 @@ dump_named_datatype(hid_t tid, const char *name)
printf("%s \"%s\" %s", dump_header_format->datatypebegin, name,
dump_header_format->datatypeblockbegin);
- if(H5Tget_class(tid) == H5T_COMPOUND)
- print_datatype(tid, 1);
- else {
- indentation(indent + COL);
- print_datatype(tid, 1);
+ H5Oget_info(tid, &oinfo);
+
+ /* Must check for uniqueness of all objects if we've traversed an elink,
+ * otherwise only check if the reference count > 1.
+ */
+ if(oinfo.rc > 1 || hit_elink) {
+ obj_t *found_obj; /* Found object */
+
+ found_obj = search_obj(type_table, oinfo.addr);
+
+ if (found_obj == NULL) {
+ error_msg(progname, "internal error (file %s:line %d)\n",
+ __FILE__, __LINE__);
+ d_status = EXIT_FAILURE;
+ goto done;
+ }
+ else if (found_obj->displayed) {
+ printf("%s \"%s\"\n", HARDLINK, found_obj->objname);
+ goto done;
+ }
+ else
+ found_obj->displayed = TRUE;
+ } /* end if */
+
+ print_datatype(tid, 1);
+ if(H5Tget_class(tid) != H5T_COMPOUND)
printf(";\n");
- } /* end else */
/* print attributes */
indent += COL;
@@ -1834,6 +1991,8 @@ dump_named_datatype(hid_t tid, const char *name)
H5Aiterate2(tid, H5_INDEX_NAME, sort_order, NULL, dump_attr_cb, NULL);
indent -= COL;
+
+done:
end_obj(dump_header_format->datatypeend,
dump_header_format->datatypeblockend);
}
@@ -1921,7 +2080,10 @@ dump_group(hid_t gid, const char *name)
H5Oget_info(gid, &oinfo);
- if(oinfo.rc > 1) {
+ /* Must check for uniqueness of all objects if we've traversed an elink,
+ * otherwise only check if the reference count > 1.
+ */
+ if(oinfo.rc > 1 || hit_elink) {
obj_t *found_obj; /* Found object */
found_obj = search_obj(group_table, oinfo.addr);
@@ -3149,7 +3311,7 @@ set_sort_order(const char *form)
*-------------------------------------------------------------------------
*/
static void
-handle_attributes(hid_t fid, const char *attr, void UNUSED * data, int pe)
+handle_attributes(hid_t fid, const char *attr, void UNUSED * data, int UNUSED pe, const char UNUSED *display_name)
{
dump_selected_attr(fid, attr);
}
@@ -3301,20 +3463,21 @@ parse_subset_params(char *dset)
*-------------------------------------------------------------------------
*/
static void
-handle_datasets(hid_t fid, const char *dset, void *data, int pe)
+handle_datasets(hid_t fid, const char *dset, void *data, int pe, const char *display_name)
{
H5O_info_t oinfo;
hid_t dsetid;
struct subset_t *sset = (struct subset_t *)data;
+ const char *real_name = display_name ? display_name : dset;
if((dsetid = H5Dopen2(fid, dset, H5P_DEFAULT)) < 0)
{
if (pe)
{
- begin_obj(dump_header_format->datasetbegin, dset,
+ begin_obj(dump_header_format->datasetbegin, real_name,
dump_header_format->datasetblockbegin);
indentation(COL);
- error_msg(progname, "unable to open dataset \"%s\"\n", dset);
+ error_msg(progname, "unable to open dataset \"%s\"\n", real_name);
end_obj(dump_header_format->datasetend,
dump_header_format->datasetblockend);
d_status = EXIT_FAILURE;
@@ -3407,14 +3570,15 @@ handle_datasets(hid_t fid, const char *dset, void *data, int pe)
}
H5Oget_info(dsetid, &oinfo);
- if(oinfo.rc > 1) {
+ if(oinfo.rc > 1 || hit_elink) {
obj_t *found_obj; /* Found object */
found_obj = search_obj(dset_table, oinfo.addr);
if(found_obj) {
if (found_obj->displayed) {
- begin_obj(dump_header_format->datasetbegin, dset,
+ indentation(indent);
+ begin_obj(dump_header_format->datasetbegin, real_name,
dump_header_format->datasetblockbegin);
indentation(indent + COL);
printf("%s \"%s\"\n", HARDLINK, found_obj->objname);
@@ -3423,14 +3587,14 @@ handle_datasets(hid_t fid, const char *dset, void *data, int pe)
dump_header_format->datasetblockend);
} else {
found_obj->displayed = TRUE;
- dump_dataset(dsetid, dset, sset);
+ dump_dataset(dsetid, real_name, sset);
}
}
else
d_status = EXIT_FAILURE;
}
else
- dump_dataset(dsetid, dset, sset);
+ dump_dataset(dsetid, real_name, sset);
if(H5Dclose(dsetid) < 0)
d_status = EXIT_FAILURE;
@@ -3459,18 +3623,19 @@ handle_datasets(hid_t fid, const char *dset, void *data, int pe)
*-------------------------------------------------------------------------
*/
static void
-handle_groups(hid_t fid, const char *group, void UNUSED * data, int pe)
+handle_groups(hid_t fid, const char *group, void UNUSED * data, int pe, const char * display_name)
{
- hid_t gid;
+ hid_t gid;
+ const char *real_name = display_name ? display_name : group;
if((gid = H5Gopen2(fid, group, H5P_DEFAULT)) < 0)
{
if ( pe )
{
- begin_obj(dump_header_format->groupbegin, group, dump_header_format->groupblockbegin);
+ begin_obj(dump_header_format->groupbegin, real_name, dump_header_format->groupblockbegin);
indentation(COL);
- error_msg(progname, "unable to open group \"%s\"\n", group);
+ error_msg(progname, "unable to open group \"%s\"\n", real_name);
end_obj(dump_header_format->groupend, dump_header_format->groupblockend);
d_status = EXIT_FAILURE;
}
@@ -3488,7 +3653,7 @@ handle_groups(hid_t fid, const char *group, void UNUSED * data, int pe)
HDstrcpy(prefix, group);
- dump_group(gid, group);
+ dump_group(gid, real_name);
if(H5Gclose(gid) < 0)
d_status = EXIT_FAILURE;
@@ -3510,7 +3675,7 @@ handle_groups(hid_t fid, const char *group, void UNUSED * data, int pe)
*-------------------------------------------------------------------------
*/
static void
-handle_links(hid_t fid, const char *links, void UNUSED * data, int pe)
+handle_links(hid_t fid, const char *links, void UNUSED * data, int UNUSED pe, const char UNUSED *display_name)
{
H5L_info_t linfo;
@@ -3602,9 +3767,10 @@ handle_links(hid_t fid, const char *links, void UNUSED * data, int pe)
*-------------------------------------------------------------------------
*/
static void
-handle_datatypes(hid_t fid, const char *type, void UNUSED * data, int pe)
+handle_datatypes(hid_t fid, const char *type, void UNUSED * data, int pe, const char *display_name)
{
hid_t type_id;
+ const char *real_name = display_name ? display_name : type;
if((type_id = H5Topen2(fid, type, H5P_DEFAULT)) < 0)
{
@@ -3619,7 +3785,7 @@ handle_datatypes(hid_t fid, const char *type, void UNUSED * data, int pe)
/* unamed datatype */
sprintf(name, "/#"H5_PRINTF_HADDR_FMT, type_table->objs[idx].objno);
- if(!HDstrcmp(name, type))
+ if(!HDstrcmp(name, real_name))
break;
} /* end if */
@@ -3631,10 +3797,10 @@ handle_datatypes(hid_t fid, const char *type, void UNUSED * data, int pe)
if ( pe )
{
/* unknown type */
- begin_obj(dump_header_format->datatypebegin, type,
+ begin_obj(dump_header_format->datatypebegin, real_name,
dump_header_format->datatypeblockbegin);
indentation(COL);
- error_msg(progname, "unable to open datatype \"%s\"\n", type);
+ error_msg(progname, "unable to open datatype \"%s\"\n", real_name);
end_obj(dump_header_format->datatypeend,
dump_header_format->datatypeblockend);
d_status = EXIT_FAILURE;
@@ -3645,14 +3811,14 @@ handle_datatypes(hid_t fid, const char *type, void UNUSED * data, int pe)
{
hid_t dsetid = H5Dopen2(fid, type_table->objs[idx].objname, H5P_DEFAULT);
type_id = H5Dget_type(dsetid);
- dump_named_datatype(type_id, type);
+ dump_named_datatype(type_id, real_name);
H5Tclose(type_id);
H5Dclose(dsetid);
}
}
else
{
- dump_named_datatype(type_id, type);
+ dump_named_datatype(type_id, real_name);
if(H5Tclose(type_id) < 0)
d_status = EXIT_FAILURE;
@@ -4073,7 +4239,7 @@ main(int argc, const char *argv[])
char *fname = NULL;
void *edata;
H5E_auto2_t func;
- find_objs_t info;
+ H5O_info_t oi;
struct handler_t *hand;
int i;
unsigned u;
@@ -4162,12 +4328,22 @@ main(int argc, const char *argv[])
}
- /* find all shared objects */
- if(init_objs(fid, &info, &group_table, &dset_table, &type_table) < 0) {
+ /* Get object info for root group */
+ if(H5Oget_info_by_name(fid, "/", &oi, H5P_DEFAULT) < 0) {
error_msg(progname, "internal error (file %s:line %d)\n", __FILE__, __LINE__);
d_status = EXIT_FAILURE;
goto done;
}
+
+ /* Initialize object tables */
+ if(table_list_add(fid, oi.fileno) < 0) {
+ error_msg(progname, "internal error (file %s:line %d)\n", __FILE__, __LINE__);
+ d_status = EXIT_FAILURE;
+ goto done;
+ }
+ group_table = table_list.tables[0].group_table;
+ dset_table = table_list.tables[0].dset_table;
+ type_table = table_list.tables[0].type_table;
/* does there exist unamed committed datatype */
for (u = 0; u < type_table->nobjs; u++)
@@ -4176,10 +4352,6 @@ main(int argc, const char *argv[])
break;
} /* end if */
-#ifdef H5DUMP_DEBUG
- dump_tables(&info);
-#endif /* H5DUMP_DEBUG */
-
/* start to dump - display file header information */
if (!doxml) {
begin_obj(dump_header_format->filebegin, fname,
@@ -4257,7 +4429,7 @@ main(int argc, const char *argv[])
for(i = 0; i < argc; i++)
if(hand[i].func)
- hand[i].func(fid, hand[i].obj, hand[i].subset_info, 1);
+ hand[i].func(fid, hand[i].obj, hand[i].subset_info, 1, NULL);
}
if (!doxml) {
@@ -4267,16 +4439,14 @@ main(int argc, const char *argv[])
}
done:
+ /* Free tables for objects */
+ table_list_free();
+
if (H5Fclose(fid) < 0)
d_status = EXIT_FAILURE;
free_handler(hand, argc);
- /* Free tables for objects */
- free_table(group_table);
- free_table(dset_table);
- free_table(type_table);
-
HDfree(prefix);
HDfree(fname);
@@ -5435,20 +5605,49 @@ xml_dump_named_datatype(hid_t type, const char *name)
"Parents=\"%s\" H5ParentPaths=\"%s\">\n",
xmlnsprefix,
name, dtxid,
- parentxid,(HDstrcmp(prefix, "") ? t_prefix : "/"));
+ parentxid, HDstrcmp(prefix,"") ? t_prefix : "/");
} else {
+ H5O_info_t oinfo; /* Object info */
+
printf("<%sNamedDataType Name=\"%s\" OBJ-XID=\"%s\" "
"H5Path=\"%s\" Parents=\"%s\" H5ParentPaths=\"%s\">\n",
xmlnsprefix,
t_name, dtxid,
t_tmp, parentxid, (HDstrcmp(prefix, "") ? t_prefix : "/"));
+
+ /* Check uniqueness of named datatype */
+ H5Oget_info(type, &oinfo);
+ if(oinfo.rc > 1) {
+ obj_t *found_obj; /* Found object */
+
+ /* Group with more than one link to it... */
+ found_obj = search_obj(type_table, oinfo.addr);
+
+ if (found_obj == NULL) {
+ indentation(indent);
+ error_msg(progname, "internal error (file %s:line %d)\n",
+ __FILE__, __LINE__);
+ d_status = EXIT_FAILURE;
+ goto done;
+ } else if(found_obj->displayed) {
+ /* We have already printed this named datatype, print it as a
+ * NamedDatatypePtr
+ */
+ char pointerxid[100];
+ char *t_objname = xml_escape_the_name(found_obj->objname);
+
+ indentation(indent + COL);
+ xml_name_to_XID(found_obj->objname, pointerxid, sizeof(pointerxid), 1);
+ printf("<%sNamedDatatypePtr OBJ-XID=\"%s\" H5Path=\"%s\"/>\n",
+ xmlnsprefix, pointerxid, t_objname);
+ indentation(indent);
+ printf("</%sNamedDataType>\n", xmlnsprefix);
+ HDfree(t_objname);
+ goto done;
+ } else
+ found_obj->displayed = TRUE;
+ }
}
- HDfree(dtxid);
- HDfree(parentxid);
- HDfree(t_tmp);
- HDfree(t_prefix);
- HDfree(t_name);
- HDfree(tmp);
indent += COL;
indentation(indent);
@@ -5464,6 +5663,14 @@ xml_dump_named_datatype(hid_t type, const char *name)
indent -= COL;
indentation(indent);
printf("</%sNamedDataType>\n",xmlnsprefix);
+
+done:
+ HDfree(dtxid);
+ HDfree(parentxid);
+ HDfree(t_tmp);
+ HDfree(t_prefix);
+ HDfree(t_name);
+ HDfree(tmp);
}
/*-------------------------------------------------------------------------
@@ -5581,7 +5788,7 @@ xml_dump_group(hid_t gid, const char *name)
indentation(indent + COL);
ptrstr = malloc(100);
- t_objname = xml_escape_the_name(found_obj->objname);
+ t_objname = xml_escape_the_name(found_obj->objname);/* point to the NDT by name */
par_name = xml_escape_the_name(par);
xml_name_to_XID(found_obj->objname, ptrstr, 100, 1);
xml_name_to_XID(par, parentxid, 100, 1);
@@ -6704,32 +6911,87 @@ add_prefix(char **prfx, size_t *prfx_len, const char *name)
* basis, attempting to dump as a dataset, as a group and as a named datatype
* Error messages are supressed
*
+ * Modifications:
+ * Neil Fortner
+ * 13 October 2008
+ * Function basically rewritten. No longer directly opens the target file,
+ * now initializes a new set of tables for the external file. No longer
+ * dumps on a trial and error basis, but errors are still suppressed.
+ *
*-------------------------------------------------------------------------
*/
-static int dump_extlink(const char *filename, const char *targname)
+static int dump_extlink(hid_t group, const char *linkname, const char *objname)
{
- hid_t fid;
+ hid_t oid;
+ H5O_info_t oi;
+ table_t *old_group_table = group_table;
+ table_t *old_dset_table = dset_table;
+ table_t *old_type_table = type_table;
+ hbool_t old_hit_elink;
+ ssize_t idx;
- fid = h5tools_fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT, driver, NULL, 0);
+ /* Open target object */
+ if ((oid = H5Oopen(group, linkname, H5P_DEFAULT)) < 0)
+ goto fail;
- if (fid < 0)
- {
+ /* Get object info */
+ if (H5Oget_info(oid, &oi) < 0) {
+ H5Oclose(oid);
goto fail;
}
- /* add some indentation to distinguish that these objects are external */
- indent += 2*COL;
+ /* Check if we have visited this file already */
+ if ((idx = table_list_visited(oi.fileno)) < 0) {
+ /* We have not visited this file, build object tables */
+ if ((idx = table_list_add(oid, oi.fileno)) < 0) {
+ H5Oclose(oid);
+ goto fail;
+ }
+ }
- handle_datasets(fid, targname, NULL, 0);
- handle_groups(fid, targname, NULL, 0);
- handle_datatypes(fid, targname, NULL, 0);
+ /* Do not recurse through an external link into the original file (idx=0) */
+ if (idx) {
+ /* Update table pointers */
+ group_table = table_list.tables[idx].group_table;
+ dset_table = table_list.tables[idx].dset_table;
+ type_table = table_list.tables[idx].type_table;
- indent -= 2*COL;
+ /* We will now traverse the external link, set this global to indicate this */
+ old_hit_elink = hit_elink;
+ hit_elink = TRUE;
+ /* add some indentation to distinguish that these objects are external */
+ indent += 2*COL;
- if (H5Fclose(fid) < 0)
+ /* Recurse into the external file */
+ switch (oi.type) {
+ case H5O_TYPE_GROUP:
+ handle_groups(group, linkname, NULL, 0, objname);
+ break;
+ case H5O_TYPE_DATASET:
+ handle_datasets(group, linkname, NULL, 0, objname);
+ break;
+ case H5O_TYPE_NAMED_DATATYPE:
+ handle_datatypes(group, linkname, NULL, 0, objname);
+ break;
+ default:
+ d_status = EXIT_FAILURE;
+ }
+
+ indent -= 2*COL;
+
+ /* Reset table pointers */
+ group_table = old_group_table;
+ dset_table = old_dset_table;
+ type_table = old_type_table;
+
+ /* Reset hit_elink */
+ hit_elink = old_hit_elink;
+ } /* end if */
+
+ if (H5Idec_ref(oid) < 0)
d_status = EXIT_FAILURE;
diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c
index bd3c4de..05efda8 100644
--- a/tools/h5dump/h5dumpgentest.c
+++ b/tools/h5dump/h5dumpgentest.c
@@ -90,6 +90,7 @@
#define FILE60 "tfpformat.h5"
#define FILE61 "textlinksrc.h5"
#define FILE62 "textlinktar.h5"
+#define FILE63 "textlinkfar.h5"
@@ -225,6 +226,7 @@ typedef struct s1_t {
#define F42_DSETNAME "Dataset"
#define F42_TYPENAME "Datatype"
#define F42_ATTRNAME "Attribute"
+#define F42_LINKNAME "Link_to_Datatype"
/* "File 43" macros */
/* Name of dataset to create in datafile */
@@ -4417,6 +4419,10 @@ static void gent_named_dtype_attr(void)
ret = H5Tcommit2(fid, F42_TYPENAME, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
assert(ret >= 0);
+ /* Create a hard link to the datatype */
+ ret = H5Lcreate_hard(fid, F42_TYPENAME, fid, F42_LINKNAME, H5P_DEFAULT, H5P_DEFAULT);
+ assert(ret >= 0);
+
/* Create a scalar dataspace used for all objects */
sid = H5Screate(H5S_SCALAR);
assert(sid > 0);
@@ -6179,27 +6185,28 @@ gent_fpformat(void)
/*-------------------------------------------------------------------------
* Function: gent_extlinks
*
- * Purpose: Generate 2 files to be used in the external links test
- * External links point from one HDF5 file to an object (Group, Dataset, or
- * committed Datatype) in another file.
+ * Purpose: Generate 3 files to be used in the external links test
+ * External links point from one HDF5 file to an object (Group, Dataset,
+ * or committed Datatype) in another file. Try to create cycles.
*
*-------------------------------------------------------------------------
*/
static void
gent_extlinks(void)
{
- hid_t source_fid, target_fid, sid, did, gid, tid;
+ hid_t source_fid, target_fid, far_fid, sid, did, gid, gid2, tid;
hsize_t dims[1] = {6};
int buf[6] = {1, 2, 3, 4, 5, 6};
/* create two files, a source and a target */
source_fid = H5Fcreate(FILE61, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
target_fid = H5Fcreate(FILE62, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ far_fid = H5Fcreate(FILE63, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
/*-------------------------------------------------------------------------
- * create Groups, a Dataset, a committed Datatype, and external links in
- * the target
+ * create Groups, a Dataset, a committed Datatype, external links, and a
+ * cycle in the target
*-------------------------------------------------------------------------
*/
@@ -6210,8 +6217,13 @@ gent_extlinks(void)
H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
H5Lcreate_external(FILE61, "/", gid, "elink_t1", H5P_DEFAULT, H5P_DEFAULT);
H5Lcreate_external(FILE61, "/ext_link4", gid, "elink_t2", H5P_DEFAULT, H5P_DEFAULT);
+
+ gid2 = H5Gcreate2(gid, "subgroup", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ H5Lcreate_hard(target_fid, "/group", gid2, "link_to_group", H5P_DEFAULT, H5P_DEFAULT);
+
H5Dclose(did);
H5Sclose(sid);
+ H5Gclose(gid2);
H5Gclose(gid);
@@ -6236,9 +6248,16 @@ gent_extlinks(void)
H5Lcreate_external(FILE62, "group/elink_t2", source_fid, "ext_link4", H5P_DEFAULT, H5P_DEFAULT);
H5Lcreate_external(FILE62, "empty_group", source_fid, "ext_link5", H5P_DEFAULT, H5P_DEFAULT);
+/*-------------------------------------------------------------------------
+ * create external link in the "far" file pointing to the source file
+ *-------------------------------------------------------------------------
+ */
+ H5Lcreate_external(FILE61, "/", far_fid, "src_file", H5P_DEFAULT, H5P_DEFAULT);
+
/* close */
H5Fclose(source_fid);
H5Fclose(target_fid);
+ H5Fclose(far_fid);
}
diff --git a/tools/h5dump/testh5dump.sh.in b/tools/h5dump/testh5dump.sh.in
index 034c456..c1458a1 100644
--- a/tools/h5dump/testh5dump.sh.in
+++ b/tools/h5dump/testh5dump.sh.in
@@ -499,6 +499,10 @@ TOOLTEST torderattr4.ddl -H --sort_by=creation_order --sort_order=descending tor
# tests for floating point user defined printf format
TOOLTEST tfpformat.ddl -m %.7f tfpformat.h5
+# tests for traversal of external links
+TOOLTEST textlinksrc.ddl textlinksrc.h5
+TOOLTEST textlinkfar.ddl textlinkfar.h5
+
if test $nerrors -eq 0 ; then
diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c
index c5ff96e..eec1fcd 100644
--- a/tools/h5ls/h5ls.c
+++ b/tools/h5ls/h5ls.c
@@ -1845,8 +1845,8 @@ elink_trav_visited(elink_trav_t *visited, const char *file, const char *path)
/* Didn't find elink */
return(FALSE);
} /* end elink_trav_visited() */
-
+
/*-------------------------------------------------------------------------
* Function: list_lnk
*
diff --git a/tools/lib/h5tools_utils.c b/tools/lib/h5tools_utils.c
index 0be3a91..a221465 100644
--- a/tools/lib/h5tools_utils.c
+++ b/tools/lib/h5tools_utils.c
@@ -485,21 +485,21 @@ find_objs_cb(const char *name, const H5O_info_t *oinfo, const char *already_seen
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 */
+ if(NULL == already_seen) {
+ 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 */
+ } /* end if */
break;
- }
default:
break;
diff --git a/tools/testfiles/textlinkfar.ddl b/tools/testfiles/textlinkfar.ddl
new file mode 100644
index 0000000..4151710
--- /dev/null
+++ b/tools/testfiles/textlinkfar.ddl
@@ -0,0 +1,69 @@
+#############################
+Expected output for 'h5dump textlinkfar.h5'
+#############################
+HDF5 "textlinkfar.h5" {
+GROUP "/" {
+ EXTERNAL_LINK "src_file" {
+ TARGETFILE "textlinksrc.h5"
+ TARGETPATH "/"
+ GROUP "/" {
+ EXTERNAL_LINK "ext_link1" {
+ TARGETFILE "textlinktar.h5"
+ TARGETPATH "group"
+ GROUP "group" {
+ DATASET "dset" {
+ DATATYPE H5T_STD_I32LE
+ DATASPACE SIMPLE { ( 6 ) / ( 6 ) }
+ DATA {
+ (0): 1, 2, 3, 4, 5, 6
+ }
+ }
+ EXTERNAL_LINK "elink_t1" {
+ TARGETFILE "textlinksrc.h5"
+ TARGETPATH "/"
+ GROUP "/" {
+ HARDLINK "/"
+ }
+ }
+ EXTERNAL_LINK "elink_t2" {
+ TARGETFILE "textlinksrc.h5"
+ TARGETPATH "/ext_link4"
+ }
+ GROUP "subgroup" {
+ GROUP "link_to_group" {
+ HARDLINK "/group"
+ }
+ }
+ }
+ }
+ EXTERNAL_LINK "ext_link2" {
+ TARGETFILE "textlinktar.h5"
+ TARGETPATH "dset"
+ DATASET "dset" {
+ DATATYPE H5T_STD_I32LE
+ DATASPACE SIMPLE { ( 6 ) / ( 6 ) }
+ DATA {
+ (0): 1, 2, 3, 4, 5, 6
+ }
+ }
+ }
+ EXTERNAL_LINK "ext_link3" {
+ TARGETFILE "textlinktar.h5"
+ TARGETPATH "type"
+ DATATYPE "type" H5T_STD_I32LE;
+
+ }
+ EXTERNAL_LINK "ext_link4" {
+ TARGETFILE "textlinktar.h5"
+ TARGETPATH "group/elink_t2"
+ }
+ EXTERNAL_LINK "ext_link5" {
+ TARGETFILE "textlinktar.h5"
+ TARGETPATH "empty_group"
+ GROUP "empty_group" {
+ }
+ }
+ }
+ }
+}
+}
diff --git a/tools/testfiles/textlinkfar.h5 b/tools/testfiles/textlinkfar.h5
new file mode 100644
index 0000000..6fb3130
--- /dev/null
+++ b/tools/testfiles/textlinkfar.h5
Binary files differ
diff --git a/tools/testfiles/textlinksrc-1.ls b/tools/testfiles/textlinksrc-1.ls
index 3b0da0b..5e81dec 100644
--- a/tools/testfiles/textlinksrc-1.ls
+++ b/tools/testfiles/textlinksrc-1.ls
@@ -11,6 +11,8 @@
/ext_link1/elink_t1/ext_link4 External Link {textlinktar.h5//group/elink_t2} {**NOT FOUND**}
/ext_link1/elink_t1/ext_link5 External Link {textlinktar.h5//empty_group} {Group}
/ext_link1/elink_t2 External Link {textlinksrc.h5//ext_link4} {**NOT FOUND**}
+/ext_link1/subgroup Group
+/ext_link1/subgroup/link_to_group Group, same as /ext_link1
/ext_link2 External Link {textlinktar.h5//dset} {Already Visited}
/ext_link3 External Link {textlinktar.h5//type} {Already Visited}
/ext_link4 External Link {textlinktar.h5//group/elink_t2} {Already Visited}
diff --git a/tools/testfiles/textlinksrc-3.ls b/tools/testfiles/textlinksrc-3.ls
index dd9d1b1..a86ca32 100644
--- a/tools/testfiles/textlinksrc-3.ls
+++ b/tools/testfiles/textlinksrc-3.ls
@@ -10,3 +10,5 @@ ext_link1 External Link {textlinktar.h5//group} {Group}
/elink_t1/ext_link4 External Link {textlinktar.h5//group/elink_t2} {**NOT FOUND**}
/elink_t1/ext_link5 External Link {textlinktar.h5//empty_group} {Group}
/elink_t2 External Link {textlinksrc.h5//ext_link4} {**NOT FOUND**}
+/subgroup Group
+/subgroup/link_to_group Group, same as /ext_link1
diff --git a/tools/testfiles/textlinksrc.ddl b/tools/testfiles/textlinksrc.ddl
new file mode 100644
index 0000000..b806c56
--- /dev/null
+++ b/tools/testfiles/textlinksrc.ddl
@@ -0,0 +1,60 @@
+#############################
+Expected output for 'h5dump textlinksrc.h5'
+#############################
+HDF5 "textlinksrc.h5" {
+GROUP "/" {
+ EXTERNAL_LINK "ext_link1" {
+ TARGETFILE "textlinktar.h5"
+ TARGETPATH "group"
+ GROUP "group" {
+ DATASET "dset" {
+ DATATYPE H5T_STD_I32LE
+ DATASPACE SIMPLE { ( 6 ) / ( 6 ) }
+ DATA {
+ (0): 1, 2, 3, 4, 5, 6
+ }
+ }
+ EXTERNAL_LINK "elink_t1" {
+ TARGETFILE "textlinksrc.h5"
+ TARGETPATH "/"
+ }
+ EXTERNAL_LINK "elink_t2" {
+ TARGETFILE "textlinksrc.h5"
+ TARGETPATH "/ext_link4"
+ }
+ GROUP "subgroup" {
+ GROUP "link_to_group" {
+ HARDLINK "/group"
+ }
+ }
+ }
+ }
+ EXTERNAL_LINK "ext_link2" {
+ TARGETFILE "textlinktar.h5"
+ TARGETPATH "dset"
+ DATASET "dset" {
+ DATATYPE H5T_STD_I32LE
+ DATASPACE SIMPLE { ( 6 ) / ( 6 ) }
+ DATA {
+ (0): 1, 2, 3, 4, 5, 6
+ }
+ }
+ }
+ EXTERNAL_LINK "ext_link3" {
+ TARGETFILE "textlinktar.h5"
+ TARGETPATH "type"
+ DATATYPE "type" H5T_STD_I32LE;
+
+ }
+ EXTERNAL_LINK "ext_link4" {
+ TARGETFILE "textlinktar.h5"
+ TARGETPATH "group/elink_t2"
+ }
+ EXTERNAL_LINK "ext_link5" {
+ TARGETFILE "textlinktar.h5"
+ TARGETPATH "empty_group"
+ GROUP "empty_group" {
+ }
+ }
+}
+}
diff --git a/tools/testfiles/textlinktar.h5 b/tools/testfiles/textlinktar.h5
index bf009eb..fe33e10 100644
--- a/tools/testfiles/textlinktar.h5
+++ b/tools/testfiles/textlinktar.h5
Binary files differ
diff --git a/tools/testfiles/thlink.h5.xml b/tools/testfiles/thlink.h5.xml
index 72b7b31..c2737b9 100644
--- a/tools/testfiles/thlink.h5.xml
+++ b/tools/testfiles/thlink.h5.xml
@@ -31,11 +31,11 @@ Expected output for 'h5dump --xml thlink.h5'
</hdf5:Dataset>
<hdf5:Group Name="g1" OBJ-XID="xid_1408" H5Path="/g1" Parents="xid_96" H5ParentPaths="/" >
<hdf5:Dataset Name="dset2" OBJ-XID="xid_808-1" H5Path="/g1/dset2" Parents="xid_1408" H5ParentPaths="/g1">
- <hdf5:DatasetPtr OBJ-XID="xid_808" H5Path="/g1/dset2"/>
+ <hdf5:DatasetPtr OBJ-XID="xid_808" H5Path="/dset1"/>
</hdf5:Dataset>
<hdf5:Group Name="g1.1" OBJ-XID="xid_2000" H5Path="/g1/g1.1" Parents="xid_1408" H5ParentPaths="/g1" >
<hdf5:Dataset Name="dset3" OBJ-XID="xid_808-2" H5Path="/g1/g1.1/dset3" Parents="xid_2000" H5ParentPaths="/g1/g1.1">
- <hdf5:DatasetPtr OBJ-XID="xid_808" H5Path="/g1/g1.1/dset3"/>
+ <hdf5:DatasetPtr OBJ-XID="xid_808" H5Path="/dset1"/>
</hdf5:Dataset>
</hdf5:Group>
</hdf5:Group>
diff --git a/tools/testfiles/tmany.h5.xml b/tools/testfiles/tmany.h5.xml
index 49efc51..93a0610 100644
--- a/tools/testfiles/tmany.h5.xml
+++ b/tools/testfiles/tmany.h5.xml
@@ -267,7 +267,7 @@ Expected output for 'h5dump --xml tmany.h5'
</hdf5:Group>
<hdf5:Group Name="g1.2" OBJ-XID="xid_5968" H5Path="/g1/g1.2" Parents="xid_800" H5ParentPaths="/g1" >
<hdf5:Dataset Name="link1" OBJ-XID="xid_2864-1" H5Path="/g1/g1.2/link1" Parents="xid_5968" H5ParentPaths="/g1/g1.2">
- <hdf5:DatasetPtr OBJ-XID="xid_2864" H5Path="/g1/g1.2/link1"/>
+ <hdf5:DatasetPtr OBJ-XID="xid_2864" H5Path="/g1/g1.1/dset1"/>
</hdf5:Dataset>
</hdf5:Group>
</hdf5:Group>
@@ -313,7 +313,7 @@ Expected output for 'h5dump --xml tmany.h5'
</hdf5:Group>
<hdf5:Group Name="g4" OBJ-XID="xid_10784" H5Path="/g4" Parents="xid_96" H5ParentPaths="/" >
<hdf5:Dataset Name="dset2" OBJ-XID="xid_11488-2" H5Path="/g4/dset2" Parents="xid_10784" H5ParentPaths="/g4">
- <hdf5:DatasetPtr OBJ-XID="xid_11488" H5Path="/g4/dset2"/>
+ <hdf5:DatasetPtr OBJ-XID="xid_11488" H5Path="/g3/link3"/>
</hdf5:Dataset>
</hdf5:Group>
<hdf5:Group Name="g5" OBJ-XID="xid_8416" H5Path="/g5" Parents="xid_96" H5ParentPaths="/" >
diff --git a/tools/testfiles/tnamed_dtype_attr.ddl b/tools/testfiles/tnamed_dtype_attr.ddl
index 391abf8..4ef3158 100644
--- a/tools/testfiles/tnamed_dtype_attr.ddl
+++ b/tools/testfiles/tnamed_dtype_attr.ddl
@@ -17,7 +17,7 @@ GROUP "/" {
}
}
}
- DATATYPE "Datatype" H5T_STD_I32LE;
+ DATATYPE "Datatype" H5T_STD_I32LE;
ATTRIBUTE "Attribute" {
DATATYPE H5T_STD_I32LE
DATASPACE SCALAR
@@ -26,6 +26,8 @@ GROUP "/" {
}
}
+ DATATYPE "Link_to_Datatype" HARDLINK "/Datatype"
+
GROUP "g1" {
ATTRIBUTE "Attribute" {
DATATYPE "/Datatype"
diff --git a/tools/testfiles/tnamed_dtype_attr.h5 b/tools/testfiles/tnamed_dtype_attr.h5
index 9be537c..e7bf23d 100644
--- a/tools/testfiles/tnamed_dtype_attr.h5
+++ b/tools/testfiles/tnamed_dtype_attr.h5
Binary files differ
diff --git a/tools/testfiles/tnamed_dtype_attr.h5.xml b/tools/testfiles/tnamed_dtype_attr.h5.xml
index 0b9ceae..2e3cfa3 100644
--- a/tools/testfiles/tnamed_dtype_attr.h5.xml
+++ b/tools/testfiles/tnamed_dtype_attr.h5.xml
@@ -4,7 +4,7 @@ Expected output for 'h5dump --xml tnamed_dtype_attr.h5'
<?xml version="1.0" encoding="UTF-8"?>
<hdf5:HDF5-File xmlns:hdf5="http://hdfgroup.org/DTDs/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdfgroup.org/DTDs/HDF5File http://hdfgroup.org/DTDs/HDF5-File.xsd">
<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/">
- <hdf5:Dataset Name="Dataset" OBJ-XID="xid_1264" H5Path= "/Dataset" Parents="xid_96" H5ParentPaths="/">
+ <hdf5:Dataset Name="Dataset" OBJ-XID="xid_1256" H5Path= "/Dataset" Parents="xid_96" H5ParentPaths="/">
<hdf5:StorageLayout>
<hdf5:ContiguousLayout/>
</hdf5:StorageLayout>
@@ -16,12 +16,12 @@ Expected output for 'h5dump --xml tnamed_dtype_attr.h5'
<hdf5:Dataspace>
<hdf5:ScalarDataspace />
</hdf5:Dataspace>
- <hdf5:NamedDataTypePtr OBJ-XID="xid_792" H5Path="/Datatype" />
+ <hdf5:NamedDataTypePtr OBJ-XID="xid_800" H5Path="/Datatype" />
<hdf5:Attribute Name="Attribute">
<hdf5:Dataspace>
<hdf5:ScalarDataspace />
</hdf5:Dataspace>
- <hdf5:NamedDataTypePtr OBJ-XID="xid_792" H5Path="/Datatype" />
+ <hdf5:NamedDataTypePtr OBJ-XID="xid_800" H5Path="/Datatype" />
<hdf5:Data>
<hdf5:DataFromFile>
8
@@ -32,19 +32,22 @@ Expected output for 'h5dump --xml tnamed_dtype_attr.h5'
<hdf5:NoData/>
</hdf5:Data>
</hdf5:Dataset>
- <hdf5:NamedDataType Name="Datatype" OBJ-XID="xid_792" H5Path="/Datatype" Parents="xid_96" H5ParentPaths="/">
+ <hdf5:NamedDataType Name="Datatype" OBJ-XID="xid_800" H5Path="/Datatype" Parents="xid_96" H5ParentPaths="/">
<hdf5:DataType>
<hdf5:AtomicType>
<hdf5:IntegerType ByteOrder="LE" Sign="true" Size="4" />
</hdf5:AtomicType>
</hdf5:DataType>
</hdf5:NamedDataType>
- <hdf5:Group Name="g1" OBJ-XID="xid_1536" H5Path="/g1" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:NamedDataType Name="Link_to_Datatype" OBJ-XID="xid_800" H5Path="/Link_to_Datatype" Parents="xid_96" H5ParentPaths="/">
+ <hdf5:NamedDatatypePtr OBJ-XID="xid_800" H5Path="/Datatype"/>
+ </hdf5:NamedDataType>
+ <hdf5:Group Name="g1" OBJ-XID="xid_1528" H5Path="/g1" Parents="xid_96" H5ParentPaths="/" >
<hdf5:Attribute Name="Attribute">
<hdf5:Dataspace>
<hdf5:ScalarDataspace />
</hdf5:Dataspace>
- <hdf5:NamedDataTypePtr OBJ-XID="xid_792" H5Path="/Datatype" />
+ <hdf5:NamedDataTypePtr OBJ-XID="xid_800" H5Path="/Datatype" />
<hdf5:Data>
<hdf5:DataFromFile>
8
diff --git a/tools/testfiles/torderattr1.ddl b/tools/testfiles/torderattr1.ddl
index 3c4bd6b..de3b72b 100644
--- a/tools/testfiles/torderattr1.ddl
+++ b/tools/testfiles/torderattr1.ddl
@@ -75,7 +75,7 @@ GROUP "/" {
DATASPACE SCALAR
}
}
- DATATYPE "t" H5T_STD_I32LE;
+ DATATYPE "t" H5T_STD_I32LE;
ATTRIBUTE "a" {
DATATYPE H5T_STD_U8LE
DATASPACE SCALAR
@@ -89,7 +89,7 @@ GROUP "/" {
DATASPACE SCALAR
}
- DATATYPE "tt" H5T_STD_I32LE;
+ DATATYPE "tt" H5T_STD_I32LE;
ATTRIBUTE "a" {
DATATYPE H5T_STD_U8LE
DATASPACE SCALAR
diff --git a/tools/testfiles/torderattr2.ddl b/tools/testfiles/torderattr2.ddl
index 89799d3..3686984 100644
--- a/tools/testfiles/torderattr2.ddl
+++ b/tools/testfiles/torderattr2.ddl
@@ -15,7 +15,7 @@ GROUP "/" {
DATATYPE H5T_STD_U8LE
DATASPACE SCALAR
}
- DATATYPE "tt" H5T_STD_I32LE;
+ DATATYPE "tt" H5T_STD_I32LE;
ATTRIBUTE "c" {
DATATYPE H5T_STD_U8LE
DATASPACE SCALAR
@@ -29,7 +29,7 @@ GROUP "/" {
DATASPACE SCALAR
}
- DATATYPE "t" H5T_STD_I32LE;
+ DATATYPE "t" H5T_STD_I32LE;
ATTRIBUTE "c" {
DATATYPE H5T_STD_U8LE
DATASPACE SCALAR
diff --git a/tools/testfiles/torderattr3.ddl b/tools/testfiles/torderattr3.ddl
index 5dba83e..9dc027a 100644
--- a/tools/testfiles/torderattr3.ddl
+++ b/tools/testfiles/torderattr3.ddl
@@ -75,7 +75,7 @@ GROUP "/" {
DATASPACE SCALAR
}
}
- DATATYPE "t" H5T_STD_I32LE;
+ DATATYPE "t" H5T_STD_I32LE;
ATTRIBUTE "a" {
DATATYPE H5T_STD_U8LE
DATASPACE SCALAR
@@ -89,7 +89,7 @@ GROUP "/" {
DATASPACE SCALAR
}
- DATATYPE "tt" H5T_STD_I32LE;
+ DATATYPE "tt" H5T_STD_I32LE;
ATTRIBUTE "c" {
DATATYPE H5T_STD_U8LE
DATASPACE SCALAR
diff --git a/tools/testfiles/torderattr4.ddl b/tools/testfiles/torderattr4.ddl
index fc59f6a..38af25d 100644
--- a/tools/testfiles/torderattr4.ddl
+++ b/tools/testfiles/torderattr4.ddl
@@ -15,7 +15,7 @@ GROUP "/" {
DATATYPE H5T_STD_U8LE
DATASPACE SCALAR
}
- DATATYPE "tt" H5T_STD_I32LE;
+ DATATYPE "tt" H5T_STD_I32LE;
ATTRIBUTE "a" {
DATATYPE H5T_STD_U8LE
DATASPACE SCALAR
@@ -29,7 +29,7 @@ GROUP "/" {
DATASPACE SCALAR
}
- DATATYPE "t" H5T_STD_I32LE;
+ DATATYPE "t" H5T_STD_I32LE;
ATTRIBUTE "c" {
DATATYPE H5T_STD_U8LE
DATASPACE SCALAR
diff --git a/tools/testfiles/tvlstr.ddl b/tools/testfiles/tvlstr.ddl
index 3b67af6..eda8e000 100644
--- a/tools/testfiles/tvlstr.ddl
+++ b/tools/testfiles/tvlstr.ddl
@@ -24,7 +24,7 @@ GROUP "/" {
(2): "", NULL
}
}
- DATATYPE "vl_string_type" H5T_STRING {
+ DATATYPE "vl_string_type" H5T_STRING {
STRSIZE H5T_VARIABLE;
STRPAD H5T_STR_NULLPAD;
CSET H5T_CSET_ASCII;
diff --git a/windows/tools/h5dump/testh5dump.bat b/windows/tools/h5dump/testh5dump.bat
index 0b75d06..6920df8 100644
--- a/windows/tools/h5dump/testh5dump.bat
+++ b/windows/tools/h5dump/testh5dump.bat
@@ -594,6 +594,10 @@ rem ############################################################################
rem Note: Make sure to use PERCENT rather than "%", because Windows needs
rem to handle it specially. --SJW 5/12/08
call :tooltest tfpformat.ddl -m PERCENT.7f tfpformat.h5
+
+ rem tests for traversal of external links
+ call :tooltest textlinksrc.ddl textlinksrc.h5
+ call :tooltest textlinkfar.ddl textlinkfar.h5