From e4f62217b88a1ad842cd5f226c2729feb3b8c559 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 24 Nov 2007 14:28:15 -0500 Subject: [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 --- src/H5G.c | 43 ++++-- src/H5L.c | 58 ++++++++ src/H5Lpublic.h | 2 + test/Makefile.am | 2 +- test/links.c | 445 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 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 */ -- cgit v0.12