summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-11-24 19:28:15 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-11-24 19:28:15 (GMT)
commite4f62217b88a1ad842cd5f226c2729feb3b8c559 (patch)
treeecfb2a8ef1a4106cc32bb4c34aa7074281338c3f
parent2f36ea99d4ad1b036d377719e49eaab2dec64444 (diff)
downloadhdf5-e4f62217b88a1ad842cd5f226c2729feb3b8c559.zip
hdf5-e4f62217b88a1ad842cd5f226c2729feb3b8c559.tar.gz
hdf5-e4f62217b88a1ad842cd5f226c2729feb3b8c559.tar.bz2
[svn-r14285] Description:
Add H5Lvisit() API routine. Add explicit regression tests for H5Lvisit_by_name(). Correct error with visiting links when links contain loop to group already encountered. Tested on: FreeBSD/32 6.2 (duty) in debug mode FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Mac OS X/32 10.4.10 (amazon) in debug mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode
-rw-r--r--src/H5G.c43
-rw-r--r--src/H5L.c58
-rw-r--r--src/H5Lpublic.h2
-rw-r--r--test/Makefile.am2
-rw-r--r--test/links.c445
5 files changed, 506 insertions, 44 deletions
diff --git a/src/H5G.c b/src/H5G.c
index 116cdf8..675b166 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -1753,9 +1753,7 @@ H5G_visit_cb(const H5O_link_t *lnk, void *_udata)
/* Check for doing more work */
if(ret_value == H5_ITER_CONT && lnk->type == H5L_TYPE_HARD) {
- H5O_type_t otype; /* Basic object type (group, dataset, etc.) */
H5_obj_t obj_pos; /* Object "position" for this object */
- unsigned rc; /* Reference count of object */
/* Set up opened group location to fill in */
obj_loc.oloc = &obj_oloc;
@@ -1774,6 +1772,9 @@ H5G_visit_cb(const H5O_link_t *lnk, void *_udata)
/* Check if we've seen the object the link references before */
if(NULL == H5SL_search(udata->visited, &obj_pos)) {
+ H5O_type_t otype; /* Basic object type (group, dataset, etc.) */
+ unsigned rc; /* Reference count of object */
+
/* Get the object's reference count and type */
if(H5O_get_rc_and_type(&obj_oloc, udata->dxpl_id, &rc, &otype) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to get object info")
@@ -1888,13 +1889,15 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type,
H5_iter_order_t order, H5L_iterate_t op, void *op_data, hid_t lapl_id,
hid_t dxpl_id)
{
- H5G_iter_visit_ud_t udata; /* User data for callback */
- H5O_linfo_t linfo; /* Link info message */
- hid_t gid = (-1); /* Group ID */
- H5G_t *grp = NULL; /* Group opened */
- H5G_loc_t loc; /* Location of group passed in */
- H5G_loc_t start_loc; /* Location of starting group */
- herr_t ret_value; /* Return value */
+ H5G_iter_visit_ud_t udata; /* User data for callback */
+ H5O_linfo_t linfo; /* Link info message */
+ hid_t gid = (-1); /* Group ID */
+ H5G_t *grp = NULL; /* Group opened */
+ H5G_loc_t loc; /* Location of group passed in */
+ H5G_loc_t start_loc; /* Location of starting group */
+ H5O_type_t otype; /* Basic object type (group, dataset, etc.) */
+ unsigned rc; /* Reference count of object */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_visit, FAIL)
@@ -1934,6 +1937,28 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type,
if((udata.visited = H5SL_create(H5SL_TYPE_OBJ, 0.5, (size_t)16)) == NULL)
HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create skip list for visited objects")
+ /* Get the group's reference count and type */
+ if(H5O_get_rc_and_type(&grp->oloc, dxpl_id, &rc, &otype) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object info")
+
+ /* If its ref count is > 1, we add it to the list of visited objects */
+ /* (because it could come up again during traversal) */
+ if(rc > 1) {
+ H5_obj_t *obj_pos; /* New object node for visited list */
+
+ /* Allocate new object "position" node */
+ if((obj_pos = H5FL_MALLOC(H5_obj_t)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate object node")
+
+ /* Construct unique "position" for this object */
+ H5F_GET_FILENO(grp->oloc.file, obj_pos->fileno);
+ obj_pos->addr = grp->oloc.addr;
+
+ /* Add to list of visited objects */
+ if(H5SL_insert(udata.visited, obj_pos, obj_pos) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert object node into visited list")
+ } /* end if */
+
/* Attempt to get the link info for this group */
if(H5G_obj_get_linfo(&(grp->oloc), &linfo, dxpl_id)) {
/* Check for creation order tracking, if creation order index lookup requested */
diff --git a/src/H5L.c b/src/H5L.c
index 9917fe7..d50ae19 100644
--- a/src/H5L.c
+++ b/src/H5L.c
@@ -1259,6 +1259,64 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Lvisit
+ *
+ * Purpose: Recursively visit all the links in a group and all
+ * the groups that are linked to from that group. Links within
+ * each group are visited according to the order within the
+ * specified index (unless the specified index does not exist for
+ * a particular group, then the "name" index is used).
+ *
+ * NOTE: Each _link_ reachable from the initial group will only be
+ * visited once. However, because an object may be reached from
+ * more than one link, the visitation may call the application's
+ * callback with more than one link that points to a particular
+ * _object_.
+ *
+ * Return: Success: The return value of the first operator that
+ * returns non-zero, or zero if all members were
+ * processed with no operator returning non-zero.
+ *
+ * Failure: Negative if something goes wrong within the
+ * library, or the negative value returned by one
+ * of the operators.
+ *
+ * Programmer: Quincey Koziol
+ * November 24 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lvisit(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order,
+ H5L_iterate_t op, void *op_data)
+{
+ H5I_type_t id_type; /* Type of ID */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5Lvisit, FAIL)
+ H5TRACE5("e", "iIiIox*x", grp_id, idx_type, order, op, op_data);
+
+ /* Check args */
+ id_type = H5I_get_type(grp_id);
+ if(!(H5I_GROUP == id_type || H5I_FILE == id_type))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
+ if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
+ if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
+ if(!op)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified")
+
+ /* Call internal group visitation routine */
+ if((ret_value = H5G_visit(grp_id, ".", idx_type, order, op, op_data, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link visitation failed")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lvisit() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Lvisit_by_name
*
* Purpose: Recursively visit all the links in a group and all
diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h
index 0dc3f65..823b046 100644
--- a/src/H5Lpublic.h
+++ b/src/H5Lpublic.h
@@ -170,6 +170,8 @@ H5_DLL herr_t H5Literate(hid_t grp_id, H5_index_t idx_type,
H5_DLL herr_t H5Literate_by_name(hid_t loc_id, const char *group_name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx,
H5L_iterate_t op, void *op_data, hid_t lapl_id);
+H5_DLL herr_t H5Lvisit(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order,
+ H5L_iterate_t op, void *op_data);
H5_DLL herr_t H5Lvisit_by_name(hid_t loc_id, const char *group_name,
H5_index_t idx_type, H5_iter_order_t order, H5L_iterate_t op,
void *op_data, hid_t lapl_id);
diff --git a/test/Makefile.am b/test/Makefile.am
index 0947adc..e5a1394 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -105,7 +105,7 @@ flush2.chkexe_: flush1.chkexe_
CHECK_CLEANFILES+=cmpd_dset.h5 compact_dataset.h5 dataset.h5 extend.h5 istore.h5\
tfile[1-4].h5 th5s[1-3].h5 lheap.h5 fheap.h5 ohdr.h5 stab.h5 \
extern_[1-3].h5 extern_[1-4][ab].raw gheap[0-4].h5 dt_arith[1-2]\
- links.h5 links[1-3].h5 big.data big[0-9][0-9][0-9][0-9][0-9].h5 \
+ links.h5 links[0-6]*.h5 big.data big[0-9][0-9][0-9][0-9][0-9].h5 \
stdio.h5 sec2.h5 dtypes[1-8].h5 dt_arith[1-2].h5 tattr.h5 h5 \
tselect.h5 mtime.h5 unlink.h5 unicode.h5 \
fillval_[0-9].h5 fillval.raw mount_[0-9].h5 testmeta.h5 ttime.h5 \
diff --git a/test/links.c b/test/links.c
index 0a164d9..8208b2c 100644
--- a/test/links.c
+++ b/test/links.c
@@ -32,6 +32,9 @@
#define H5G_TESTING
#include "H5Gpkg.h" /* Groups */
+/* File for external link test. Created with gen_udlinks.c */
+#define LINKED_FILE "be_extlink2.h5"
+
const char *FILENAME[] = {
"links0",
"links1",
@@ -42,6 +45,7 @@ const char *FILENAME[] = {
"links4c",
"links4d",
"links5",
+ "links6",
NULL
};
@@ -95,6 +99,78 @@ typedef struct {
hbool_t *visited; /* Pointer to array of "visited link" flags */
} link_iter_info_t;
+/* Link visit structs */
+typedef struct {
+ const char *path; /* Path to link */
+ H5L_type_t type; /* Type of link */
+} link_visit_t;
+static const link_visit_t lvisit0[] = {
+ {"Dataset_zero", 0},
+ {"Group1", 0},
+ {"Group1/Dataset_one", 0},
+ {"Group1/Group2", 0},
+ {"Group1/Group2/Dataset_two", 0},
+ {"Group1/Group2/Type_two", 0},
+ {"Group1/Group2/hard_zero", 0},
+ {"Group1/Type_one", 0},
+ {"Group1/hard_one", 0},
+ {"Type_zero", 0},
+ {"ext_dangle", 64},
+ {"ext_one", 64},
+ {"hard_one", 0},
+ {"hard_two", 0},
+ {"hard_zero", 0},
+ {"soft_dangle", 1},
+ {"soft_one", 1},
+ {"soft_two", 1}
+};
+static const link_visit_t lvisit1[] = {
+ {"Dataset_one", 0},
+ {"Group2", 0},
+ {"Group2/Dataset_two", 0},
+ {"Group2/Type_two", 0},
+ {"Group2/hard_zero", 0},
+ {"Group2/hard_zero/Dataset_zero", 0},
+ {"Group2/hard_zero/Group1", 0},
+ {"Group2/hard_zero/Type_zero", 0},
+ {"Group2/hard_zero/ext_dangle", 64},
+ {"Group2/hard_zero/ext_one", 64},
+ {"Group2/hard_zero/hard_one", 0},
+ {"Group2/hard_zero/hard_two", 0},
+ {"Group2/hard_zero/hard_zero", 0},
+ {"Group2/hard_zero/soft_dangle", 1},
+ {"Group2/hard_zero/soft_one", 1},
+ {"Group2/hard_zero/soft_two", 1},
+ {"Type_one", 0},
+ {"hard_one", 0}
+};
+static const link_visit_t lvisit2[] = {
+ {"Dataset_two", 0},
+ {"Type_two", 0},
+ {"hard_zero", 0},
+ {"hard_zero/Dataset_zero", 0},
+ {"hard_zero/Group1", 0},
+ {"hard_zero/Group1/Dataset_one", 0},
+ {"hard_zero/Group1/Group2", 0},
+ {"hard_zero/Group1/Type_one", 0},
+ {"hard_zero/Group1/hard_one", 0},
+ {"hard_zero/Type_zero", 0},
+ {"hard_zero/ext_dangle", 64},
+ {"hard_zero/ext_one", 64},
+ {"hard_zero/hard_one", 0},
+ {"hard_zero/hard_two", 0},
+ {"hard_zero/hard_zero", 0},
+ {"hard_zero/soft_dangle", 1},
+ {"hard_zero/soft_one", 1},
+ {"hard_zero/soft_two", 1}
+};
+
+
+typedef struct {
+ unsigned idx; /* Index in visit structure */
+ const link_visit_t *info; /* Pointer to the visit structure to use */
+} lvisit_ud_t;
+
/*-------------------------------------------------------------------------
* Function: mklinks
@@ -5164,6 +5240,294 @@ error:
return -1;
} /* end check_all_closed() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: build_visit_file
+ *
+ * Purpose: Build an "interesting" file to use for visiting links & objects
+ *
+ * Return: Success: >0, File ID for file built
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, November 24, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+build_visit_file(hid_t fapl)
+{
+ hid_t fid = -1; /* File ID */
+ hid_t gid = -1, gid2 = -1; /* Group IDs */
+ hid_t sid = (-1); /* Dataspace ID */
+ hid_t did = (-1); /* Dataset ID */
+ hid_t tid = (-1); /* Datatype ID */
+ char filename[NAME_BUF_SIZE];
+ char pathname[1024]; /* Path of external link file */
+ char *srcdir = getenv("srcdir"); /* where the src code is located */
+
+ h5_fixname(FILENAME[9], fapl, filename, sizeof filename);
+
+ /* Create file for visiting */
+ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create group */
+ if((gid = H5Gcreate2(fid, "/Group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Create nested group */
+ if((gid2 = H5Gcreate2(gid, "Group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Close groups */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+
+ /* Create soft links to groups created */
+ if(H5Lcreate_soft("/Group1", fid, "/soft_one", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lcreate_soft("/Group1/Group2", fid, "/soft_two", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Create dangling soft link */
+ if(H5Lcreate_soft("nowhere", fid, "/soft_dangle", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+
+ /* Create hard links to all groups */
+ if(H5Lcreate_hard(fid, "/", fid, "hard_zero", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lcreate_hard(fid, "/Group1", fid, "hard_one", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lcreate_hard(fid, "/Group1/Group2", fid, "hard_two", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Create loops w/hard links */
+ if(H5Lcreate_hard(fid, "/Group1", fid, "/Group1/hard_one", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lcreate_hard(fid, "/", fid, "/Group1/Group2/hard_zero", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Create external link to existing file */
+ pathname[0] = '\0';
+ /* Generate correct name for test file by prepending the source path */
+ if(srcdir && ((HDstrlen(srcdir) + HDstrlen(LINKED_FILE) + 1) < sizeof(pathname))) {
+ HDstrcpy(pathname, srcdir);
+ HDstrcat(pathname, "/");
+ }
+ HDstrcat(pathname, LINKED_FILE);
+
+ if(H5Lcreate_external(pathname, "/group", fid, "/ext_one", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Create dangling external link to non-existant file */
+ if(H5Lcreate_external("foo.h5", "/group", fid, "/ext_dangle", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Create dataset in each group */
+ if((sid = H5Screate(H5S_SCALAR)) < 0) TEST_ERROR
+
+ if((did = H5Dcreate2(fid, "/Dataset_zero", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ if((did = H5Dcreate2(fid, "/Group1/Dataset_one", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ if((did = H5Dcreate2(fid, "/Group1/Group2/Dataset_two", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ /* Create named datatype in each group */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if(H5Tcommit2(fid, "/Type_zero", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if(H5Tcommit2(fid, "/Group1/Type_one", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if(H5Tcommit2(fid, "/Group1/Group2/Type_two", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ return(fid);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end build_visit_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: visit_link_cb
+ *
+ * Purpose: Callback routine for visiting links in a file
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, November 24, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+visit_link_cb(hid_t UNUSED group_id, const char *name, const H5L_info_t *linfo,
+ void *_op_data)
+{
+ lvisit_ud_t *op_data = (lvisit_ud_t *)_op_data;
+
+ /* Check for correct link information */
+ if(HDstrcmp(op_data->info[op_data->idx].path, name)) return(H5_ITER_ERROR);
+ if(op_data->info[op_data->idx].type != linfo->type) return(H5_ITER_ERROR);
+
+ /* Advance to next location in expected output */
+ op_data->idx++;
+
+ return(H5_ITER_CONT);
+} /* end visit_link_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: link_visit
+ *
+ * Purpose: Test the link visiting routine
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, November 24, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+link_visit(hid_t fapl, hbool_t new_format)
+{
+ lvisit_ud_t udata; /* User-data for visiting */
+ hid_t fid = -1;
+ hid_t gid = -1; /* Group ID */
+
+ if(new_format)
+ TESTING("link visiting (w/new group format)")
+ else
+ TESTING("link visiting")
+
+ /* Construct "interesting" file to visit */
+ if((fid = build_visit_file(fapl)) < 0) TEST_ERROR
+
+ /* Visit all the links reachable from the root group (with file ID) */
+ udata.idx = 0;
+ udata.info = lvisit0;
+ if(H5Lvisit(fid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR
+
+ /* Visit all the links reachable from the root group (with group ID) */
+ if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
+ udata.idx = 0;
+ udata.info = lvisit0;
+ if(H5Lvisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR
+ if(H5Gclose(gid) < 0) FAIL_STACK_ERROR
+
+
+ /* Visit all the links reachable from each internal group */
+ if((gid = H5Gopen2(fid, "/Group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
+ udata.idx = 0;
+ udata.info = lvisit1;
+ if(H5Lvisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR
+ if(H5Gclose(gid) < 0) FAIL_STACK_ERROR
+
+ if((gid = H5Gopen2(fid, "/Group1/Group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
+ udata.idx = 0;
+ udata.info = lvisit2;
+ if(H5Lvisit(gid, H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata) < 0) FAIL_STACK_ERROR
+ if(H5Gclose(gid) < 0) FAIL_STACK_ERROR
+
+
+ /* Close file created */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end link_visit() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: link_visit_by_name
+ *
+ * Purpose: Test the link visiting "by name" routine
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, November 24, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+link_visit_by_name(hid_t fapl, hbool_t new_format)
+{
+ lvisit_ud_t udata; /* User-data for visiting */
+ hid_t fid = -1;
+ hid_t gid = -1; /* Group ID */
+
+ if(new_format)
+ TESTING("link visiting by name (w/new group format)")
+ else
+ TESTING("link visiting by name")
+
+ /* Construct "interesting" file to visit */
+ if((fid = build_visit_file(fapl)) < 0) TEST_ERROR
+
+ /* Visit all the links reachable from the root group (with file ID) */
+ udata.idx = 0;
+ udata.info = lvisit0;
+ if(H5Lvisit_by_name(fid, "/", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
+
+ /* Visit all the links reachable from the root group (with group ID) */
+ if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
+ udata.idx = 0;
+ udata.info = lvisit0;
+ if(H5Lvisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
+ if(H5Gclose(gid) < 0) FAIL_STACK_ERROR
+
+
+ /* Visit all the links reachable from each internal group */
+ udata.idx = 0;
+ udata.info = lvisit1;
+ if(H5Lvisit_by_name(fid, "/Group1", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
+
+ if((gid = H5Gopen2(fid, "/Group1", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
+ udata.idx = 0;
+ udata.info = lvisit1;
+ if(H5Lvisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
+ if(H5Gclose(gid) < 0) FAIL_STACK_ERROR
+
+ udata.idx = 0;
+ udata.info = lvisit2;
+ if(H5Lvisit_by_name(fid, "/Group1/Group2", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
+
+ if((gid = H5Gopen2(fid, "/Group1/Group2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
+ udata.idx = 0;
+ udata.info = lvisit2;
+ if(H5Lvisit_by_name(gid, ".", H5_INDEX_NAME, H5_ITER_INC, visit_link_cb, &udata, H5P_DEFAULT) < 0) FAIL_STACK_ERROR
+ if(H5Gclose(gid) < 0) FAIL_STACK_ERROR
+
+
+ /* Close file created */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end link_visit_by_name() */
+
/*-------------------------------------------------------------------------
* Function: corder_create_empty
@@ -9595,44 +9959,52 @@ main(void)
/* Loop over using new group format */
for(new_format = FALSE; new_format <= TRUE; new_format++) {
+ hid_t my_fapl;
+
+ /* Check for FAPL to use */
+ if(new_format)
+ my_fapl = fapl2;
+ else
+ my_fapl = fapl;
+
/* General tests... (on both old & new format groups */
- nerrors += mklinks((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += cklinks((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += new_links((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += ck_new_links((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += long_links((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += toomany((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
+ nerrors += mklinks(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += cklinks(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += new_links(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += ck_new_links(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += long_links(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += toomany(my_fapl, new_format) < 0 ? 1 : 0;
/* Test new H5L link creation routine */
- nerrors += test_lcpl((new_format ? fapl2 : fapl), new_format);
- nerrors += test_move((new_format ? fapl2 : fapl), new_format);
- nerrors += test_copy((new_format ? fapl2 : fapl), new_format);
- nerrors += test_move_preserves((new_format ? fapl2 : fapl), new_format);
+ nerrors += test_lcpl(my_fapl, new_format);
+ nerrors += test_move(my_fapl, new_format);
+ nerrors += test_copy(my_fapl, new_format);
+ nerrors += test_move_preserves(my_fapl, new_format);
#ifndef H5_NO_DEPRECATED_SYMBOLS
- nerrors += test_deprec((new_format ? fapl2 : fapl), new_format);
+ nerrors += test_deprec(my_fapl, new_format);
#endif /* H5_NO_DEPRECATED_SYMBOLS */
#ifndef H5_CANNOT_OPEN_TWICE
- nerrors += external_link_root((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
+ nerrors += external_link_root(my_fapl, new_format) < 0 ? 1 : 0;
#endif /* H5_CANNOT_OPEN_TWICE */
- nerrors += external_link_path((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += external_link_mult((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
+ nerrors += external_link_path(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += external_link_mult(my_fapl, new_format) < 0 ? 1 : 0;
#ifndef H5_CANNOT_OPEN_TWICE
- nerrors += external_link_self((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += external_link_pingpong((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += external_link_toomany((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
+ nerrors += external_link_self(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += external_link_pingpong(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += external_link_toomany(my_fapl, new_format) < 0 ? 1 : 0;
#endif /* H5_CANNOT_OPEN_TWICE */
- nerrors += external_link_dangling((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += external_link_recursive((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += external_link_query((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += external_link_unlink_compact((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += external_link_unlink_dense((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += external_link_move((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += external_link_ride((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
+ nerrors += external_link_dangling(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += external_link_recursive(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += external_link_query(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += external_link_unlink_compact(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += external_link_unlink_dense(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += external_link_move(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += external_link_ride(my_fapl, new_format) < 0 ? 1 : 0;
#ifndef H5_CANNOT_OPEN_TWICE
- nerrors += external_link_closing((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
+ nerrors += external_link_closing(my_fapl, new_format) < 0 ? 1 : 0;
#endif /* H5_CANNOT_OPEN_TWICE */
- nerrors += external_link_endian((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += external_link_strong((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
+ nerrors += external_link_endian(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += external_link_strong(my_fapl, new_format) < 0 ? 1 : 0;
/* These tests assume that external links are a form of UD links,
* so assume that everything that passed for external links
@@ -9642,13 +10014,18 @@ main(void)
nerrors += ud_hard_links(fapl2) < 0 ? 1 : 0; /* requires new format groups */
nerrors += ud_link_reregister(fapl2) < 0 ? 1 : 0; /* requires new format groups */
} /* end if */
- nerrors += ud_callbacks((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += ud_link_errors((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += lapl_udata((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += lapl_nlinks((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
- nerrors += linkinfo((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
-
- nerrors += check_all_closed((new_format ? fapl2 : fapl), new_format) < 0 ? 1 : 0;
+ nerrors += ud_callbacks(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += ud_link_errors(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += lapl_udata(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += lapl_nlinks(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += linkinfo(my_fapl, new_format) < 0 ? 1 : 0;
+
+ /* Misc. extra tests, useful for both new & old format files */
+ nerrors += link_visit(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += link_visit_by_name(my_fapl, new_format) < 0 ? 1 : 0;
+
+ /* Keep this test last, it's testing files that are used above */
+ nerrors += check_all_closed(my_fapl, new_format) < 0 ? 1 : 0;
} /* end for */
/* New group revision feature tests */