diff options
-rw-r--r-- | src/H5Gloc.c | 91 | ||||
-rw-r--r-- | src/H5Gpkg.h | 5 | ||||
-rw-r--r-- | src/H5Gprivate.h | 2 | ||||
-rw-r--r-- | src/H5Gtraverse.c | 104 | ||||
-rw-r--r-- | src/H5O.c | 41 | ||||
-rw-r--r-- | src/H5Opublic.h | 1 | ||||
-rw-r--r-- | test/links.c | 319 |
7 files changed, 507 insertions, 56 deletions
diff --git a/src/H5Gloc.c b/src/H5Gloc.c index 47214a4..6145839 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -40,6 +40,8 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ + /****************/ /* Local Macros */ @@ -56,6 +58,12 @@ typedef struct { H5G_loc_t *loc; /* Group location to set */ } H5G_loc_fnd_t; +/* User data for checking if an object exists */ +typedef struct { + /* upward */ + hbool_t exists; /* Whether the object exists */ +} H5G_loc_exists_t; + /* User data for looking up an object in a group by index */ typedef struct { /* downward */ @@ -493,8 +501,9 @@ H5G_loc_find_by_idx_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, H5G_loc_fbi_t *udata = (H5G_loc_fbi_t *)_udata; /* User data passed in */ H5O_link_t fnd_lnk; /* Link within group */ hbool_t lnk_copied = FALSE; /* Whether the link was copied */ - size_t links_left = 1; /* # of links left to traverse (somewhat bogus... :-/ ) */ + size_t links_left = H5L_NUM_LINKS; /* # of links left to traverse */ hbool_t obj_loc_valid = FALSE; /* Flag to indicate that the object location is valid */ + hbool_t obj_exists = FALSE; /* Whether the object exists (unused) */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_loc_find_by_idx_cb) @@ -517,7 +526,7 @@ H5G_loc_find_by_idx_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, /* Perform any special traversals that the link needs */ /* (soft links, user-defined links, file mounting, etc.) */ /* (may modify the object location) */ - if(H5G_traverse_special(obj_loc, &fnd_lnk, H5G_TARGET_NORMAL, &links_left, TRUE, udata->loc, udata->lapl_id, udata->dxpl_id) < 0) + if(H5G_traverse_special(obj_loc, &fnd_lnk, H5G_TARGET_NORMAL, &links_left, TRUE, udata->loc, &obj_exists, udata->lapl_id, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "special link traversal failed") done: @@ -631,6 +640,84 @@ done: /*------------------------------------------------------------------------- + * Function: H5G_loc_exists_cb + * + * Purpose: Callback for checking if an object exists + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, February 2, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_loc_exists_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, + const H5O_link_t UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/) +{ + H5G_loc_exists_t *udata = (H5G_loc_exists_t *)_udata; /* User data passed in */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_loc_exists_cb) + + /* Check if the name in this group resolved to a valid object */ + if(obj_loc == NULL) + if(lnk) + udata->exists = FALSE; + else + udata->exists = FAIL; + else + udata->exists = TRUE; + + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5G_loc_exists_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_exists + * + * Purpose: Check if an object actually exists at a location + * + * Return: Success: TRUE/FALSE + * Failure: Negative + * + * Programmer: Quincey Koziol + * Tuesday, February 2, 2010 + * + *------------------------------------------------------------------------- + */ +htri_t +H5G_loc_exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id) +{ + H5G_loc_exists_t udata; /* User data for traversal callback */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_loc_exists, FAIL) + + /* Check args. */ + HDassert(loc); + HDassert(name && *name); + + /* Set up user data for locating object */ + udata.exists = FALSE; + + /* Traverse group hierarchy to locate object */ + if(H5G_traverse(loc, name, H5G_TARGET_EXISTS, H5G_loc_exists_cb, &udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't check if object exists") + + /* Set return value */ + ret_value = (htri_t)udata.exists; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_exists() */ + + +/*------------------------------------------------------------------------- * Function: H5G_loc_info_cb * * Purpose: Callback for retrieving object info for an object in a group diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 33ec680..f465d1e 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -55,7 +55,8 @@ #define H5G_TARGET_SLINK 0x0001 #define H5G_TARGET_MOUNT 0x0002 #define H5G_TARGET_UDLINK 0x0004 -#define H5G_CRT_INTMD_GROUP 0x0008 +#define H5G_TARGET_EXISTS 0x0008 +#define H5G_CRT_INTMD_GROUP 0x0010 /****************************/ /* Package Private Typedefs */ @@ -369,7 +370,7 @@ H5_DLL herr_t H5G_iterate(hid_t loc_id, const char *group_name, H5_DLL herr_t H5G_traverse_term_interface(void); H5_DLL herr_t H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, unsigned target, size_t *nlinks, hbool_t last_comp, - H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id); + H5G_loc_t *obj_loc, hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id); H5_DLL herr_t H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traverse_t op, void *op_data, hid_t lapl_id, hid_t dxpl_id); diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index dec40f3..3e66777 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -210,6 +210,8 @@ H5_DLL herr_t H5G_loc_find(const H5G_loc_t *loc, const char *name, H5_DLL herr_t H5G_loc_find_by_idx(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5G_loc_t *obj_loc/*out*/, hid_t lapl_id, hid_t dxpl_id); +H5_DLL htri_t H5G_loc_exists(const H5G_loc_t *loc, const char *name, + hid_t lapl_id, hid_t dxpl_id); H5_DLL herr_t H5G_loc_info(H5G_loc_t *loc, const char *name, hbool_t want_ih_info, H5O_info_t *oinfo/*out*/, hid_t lapl_id, hid_t dxpl_id); diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 4c287d5..e9f3010 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -43,8 +43,13 @@ /* User data for path traversal routine */ typedef struct { + /* down */ + hbool_t chk_exists; /* Flag to indicate we are checking if object exists */ + + /* up */ H5G_loc_t *obj_loc; /* Object location */ -} H5G_trav_ud1_t; + hbool_t exists; /* Indicate if object exists */ +} H5G_trav_slink_t; /* Private macros */ @@ -53,15 +58,15 @@ static char *H5G_comp_g = NULL; /*component buffer */ static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */ /* PRIVATE PROTOTYPES */ -static herr_t H5G_traverse_link_cb(H5G_loc_t *grp_loc, const char *name, +static herr_t H5G_traverse_slink_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/); static herr_t H5G_traverse_ud(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id, - hid_t dxpl_id); + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id); static herr_t H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id, - hid_t dxpl_id); + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id); static herr_t H5G_traverse_mount(H5G_loc_t *loc/*in,out*/); static herr_t H5G_traverse_real(const H5G_loc_t *loc, const char *name, unsigned target, size_t *nlinks, H5G_traverse_t op, void *op_data, @@ -97,9 +102,9 @@ H5G_traverse_term_interface(void) /*------------------------------------------------------------------------- - * Function: H5G_traverse_link_cb + * Function: H5G_traverse_slink_cb * - * Purpose: Callback for link traversal. This routine sets the + * Purpose: Callback for soft link traversal. This routine sets the * correct information for the object location. * * Return: Non-negative on success/Negative on failure @@ -110,20 +115,29 @@ H5G_traverse_term_interface(void) *------------------------------------------------------------------------- */ static herr_t -H5G_traverse_link_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) +H5G_traverse_slink_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, + const H5O_link_t UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/) { - H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */ + H5G_trav_slink_t *udata = (H5G_trav_slink_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_link_cb) + FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_slink_cb) /* Check for dangling soft link */ - if(obj_loc == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found") + if(obj_loc == NULL) { + if(udata->chk_exists) + udata->exists = FALSE; + else + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found") + } /* end if */ + else { + /* Copy new location information for resolved object */ + H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP); - /* Copy new location information for resolved object */ - H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP); + /* Indicate that the object exists */ + udata->exists = TRUE; + } /* end else */ done: /* Indicate that this callback didn't take ownership of the group * @@ -131,7 +145,7 @@ done: *own_loc = H5G_OWN_NONE; FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_traverse_link_cb() */ +} /* end H5G_traverse_slink_cb() */ /*------------------------------------------------------------------------- @@ -149,8 +163,8 @@ done: */ static herr_t H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t _lapl_id, - hid_t dxpl_id) + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t _lapl_id, hid_t dxpl_id) { const H5L_class_t *link_class; /* User-defined link class */ hid_t cb_return = -1; /* The ID the user-defined callback returned */ @@ -222,8 +236,25 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk, HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info") /* User-defined callback function */ - if((cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID") + cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id); + + /* Check for failing to locate the object */ + if(cb_return < 0) { + /* Check if we just needed to know if the object exists */ + if(target & H5G_TARGET_EXISTS) { + /* Clear any errors from the stack */ + H5E_clear_stack(NULL); + + /* Indicate that the object doesn't exist */ + *obj_exists = FALSE; + + /* Get out now */ + HGOTO_DONE(SUCCEED); + } /* end if */ + /* else, we really needed to open the object */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID") + } /* end if */ /* Get the oloc from the ID the user callback returned */ switch(H5I_get_type(cb_return)) { @@ -306,10 +337,10 @@ done: */ static herr_t H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id, - hid_t dxpl_id) + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id) { - H5G_trav_ud1_t udata; /* User data to pass to link traversal callback */ + H5G_trav_slink_t udata; /* User data to pass to link traversal callback */ H5G_name_t tmp_obj_path; /* Temporary copy of object's path */ hbool_t tmp_obj_path_set = FALSE; /* Flag to indicate that tmp object path is initialized */ H5O_loc_t tmp_grp_oloc; /* Temporary copy of group entry */ @@ -347,12 +378,17 @@ H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, tmp_obj_path_set = TRUE; /* Set up user data for traversal callback */ + udata.chk_exists = (target & H5G_TARGET_EXISTS) ? TRUE : FALSE; + udata.exists = FALSE; udata.obj_loc = obj_loc; /* Traverse the link */ - if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, H5G_TARGET_NORMAL, nlinks, H5G_traverse_link_cb, &udata, lapl_id, dxpl_id) < 0) + if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, target, nlinks, H5G_traverse_slink_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link") + /* Pass back information about whether the object exists */ + *obj_exists = udata.exists; + done: /* Restore object's group hier. path */ if(tmp_obj_path_set) { @@ -464,7 +500,7 @@ done: herr_t H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, unsigned target, size_t *nlinks, hbool_t last_comp, - H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id) + H5G_loc_t *obj_loc, hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id) { herr_t ret_value = SUCCEED; /* Return value */ @@ -485,7 +521,7 @@ H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, (0 == (target & H5G_TARGET_SLINK) || !last_comp)) { if((*nlinks)-- <= 0) HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links") - if(H5G_traverse_slink(grp_loc, lnk, obj_loc, nlinks, lapl_id, dxpl_id) < 0) + if(H5G_traverse_slink(grp_loc, lnk, obj_loc, (target & H5G_TARGET_EXISTS), nlinks, obj_exists, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "symbolic link traversal failed") } /* end if */ @@ -498,7 +534,7 @@ H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, (0 == (target & H5G_TARGET_UDLINK) || !last_comp) ) { if((*nlinks)-- <= 0) HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links") - if(H5G_traverse_ud(grp_loc, lnk, obj_loc, nlinks, lapl_id, dxpl_id) < 0) + if(H5G_traverse_ud(grp_loc, lnk, obj_loc, (target & H5G_TARGET_EXISTS), nlinks, obj_exists, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "user-defined link traversal failed") } /* end if */ @@ -634,6 +670,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, while((name = H5G_component(name, &nchars)) && *name) { const char *s; /* Temporary string pointer */ htri_t lookup_status; /* Status from object lookup */ + hbool_t obj_exists; /* Whether the object exists */ /* * Copy the component name into a null-terminated buffer so @@ -663,6 +700,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Get information for object in current group */ if((lookup_status = H5G_obj_lookup(grp_loc.oloc, H5G_comp_g, &lnk/*out*/, dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't look up component") + obj_exists = FALSE; /* If the lookup was OK, build object location and traverse special links, etc. */ if(lookup_status) { @@ -676,9 +714,12 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot initialize object location") obj_loc_valid = TRUE; + /* Assume object exists */ + obj_exists = TRUE; + /* Perform any special traversals that the link needs */ /* (soft links, user-defined links, file mounting, etc.) */ - if(H5G_traverse_special(&grp_loc, &lnk, target, nlinks, last_comp, &obj_loc, lapl_id, dxpl_id) < 0) + if(H5G_traverse_special(&grp_loc, &lnk, target, nlinks, last_comp, &obj_loc, &obj_exists, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "special link traversal failed") } /* end if */ @@ -690,7 +731,10 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Set callback parameters appropriately, based on link being found */ if(lookup_status) { cb_lnk = &lnk; - cb_loc = &obj_loc; + if(obj_exists) + cb_loc = &obj_loc; + else + cb_loc = NULL; } /* end if */ else { HDassert(!obj_loc_valid); @@ -537,6 +537,47 @@ done: /*------------------------------------------------------------------------- + * Function: H5Oexists + * + * Purpose: Determine if a linked-to object exists + * + * Return: Success: TRUE/FALSE + * Failure: Negative + * + * Programmer: Quincey Koziol + * February 2 2010 + * + *------------------------------------------------------------------------- + */ +htri_t +H5Oexists(hid_t loc_id, const char *name, hid_t lapl_id) +{ + H5G_loc_t loc; /* Location info */ + hid_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_API(H5Oexists, FAIL) + + /* Check args */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + if(H5P_DEFAULT == lapl_id) + lapl_id = H5P_LINK_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") + + /* Check if the object exists */ + if((ret_value = H5G_loc_exists(&loc, name, lapl_id, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine if '%s' exists", name) + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oexists() */ + + +/*------------------------------------------------------------------------- * Function: H5Oget_info * * Purpose: Retrieve information about an object. diff --git a/src/H5Opublic.h b/src/H5Opublic.h index 84fdecc..ca11554 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -148,6 +148,7 @@ H5_DLL hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id); H5_DLL hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr); H5_DLL hid_t H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id); +H5_DLL htri_t H5Oexists(hid_t loc_id, const char *name, hid_t lapl_id); H5_DLL herr_t H5Oget_info(hid_t loc_id, H5O_info_t *oinfo); H5_DLL herr_t H5Oget_info_by_name(hid_t loc_id, const char *name, H5O_info_t *oinfo, hid_t lapl_id); diff --git a/test/links.c b/test/links.c index bcf430f..933776a 100644 --- a/test/links.c +++ b/test/links.c @@ -638,7 +638,7 @@ cklinks(hid_t fapl, hbool_t new_format) TEST_ERROR } /* end if */ - /* Non-existant link */ + /* Non-existent link */ if(H5Lexists(file, "foobar", H5P_DEFAULT) == TRUE) FAIL_STACK_ERROR /* Cleanup */ @@ -2322,8 +2322,8 @@ external_link_self(const char *env_h5_drvr, hid_t fapl, hbool_t new_format) error: H5E_BEGIN_TRY { - H5Fclose(gid2); - H5Fclose(gid); + H5Gclose(gid2); + H5Gclose(gid); H5Pclose(lcpl_id); H5Fclose(fid); } H5E_END_TRY; @@ -8237,7 +8237,7 @@ build_visit_file(hid_t fapl) if(H5Lcreate_external(pathname, "/group", fid, "/ext_one", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR - /* Create dangling external link to non-existant file */ + /* Create dangling external link to non-existent file */ if(H5Lcreate_external("foo.h5", "/group", fid, "/ext_dangle", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR /* Create dataset in each group */ @@ -8370,7 +8370,7 @@ link_visit(hid_t fapl, hbool_t new_format) error: H5E_BEGIN_TRY { - H5Fclose(gid); + H5Gclose(gid); H5Fclose(fid); } H5E_END_TRY; return -1; @@ -8448,7 +8448,7 @@ link_visit_by_name(hid_t fapl, hbool_t new_format) error: H5E_BEGIN_TRY { - H5Fclose(gid); + H5Gclose(gid); H5Fclose(fid); } H5E_END_TRY; return -1; @@ -8548,7 +8548,7 @@ obj_visit(hid_t fapl, hbool_t new_format) error: H5E_BEGIN_TRY { - H5Fclose(gid); + H5Gclose(gid); H5Fclose(fid); } H5E_END_TRY; return -1; @@ -8627,7 +8627,7 @@ obj_visit_by_name(hid_t fapl, hbool_t new_format) error: H5E_BEGIN_TRY { - H5Fclose(gid); + H5Gclose(gid); H5Fclose(fid); } H5E_END_TRY; return -1; @@ -9099,6 +9099,294 @@ error: /*------------------------------------------------------------------------- + * Function: obj_exists + * + * Purpose: Test the 'object exists' routine + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Tuesday, February 2, 2010 + * + *------------------------------------------------------------------------- + */ +static int +obj_exists(hid_t fapl, hbool_t new_format) +{ + char filename[NAME_BUF_SIZE]; /* Buffer for file name */ + hid_t fid = -1; /* File ID */ + hid_t gid = -1; /* Group ID */ + herr_t status; /* Generic return value */ + + if(new_format) + TESTING("object exists (w/new group format)") + else + TESTING("object exists") + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR + +/* Hard links */ + /* Verify that H5Oexists() fails for non-existent link in root group */ + H5E_BEGIN_TRY { + status = H5Oexists(fid, "foo", H5P_DEFAULT); + } H5E_END_TRY + if(status >= 0) TEST_ERROR + + /* Create a group, as a destination for testing */ + if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() succeeds for hard linked object */ + if(TRUE != H5Oexists(fid, "group", H5P_DEFAULT)) + TEST_ERROR + + /* Verify that H5Oexists() fails for non-existent link in non-root group */ + H5E_BEGIN_TRY { + status = H5Oexists(fid, "group/foo", H5P_DEFAULT); + } H5E_END_TRY + if(status >= 0) TEST_ERROR + + +/* Soft links */ + /* Create dangling soft-link in root group */ + if(H5Lcreate_soft("dangle", fid, "soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns FALSE for dangling soft-link in root group */ + if(FALSE != H5Oexists(fid, "soft1", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in root group that points to object */ + if(H5Lcreate_soft("/group", fid, "soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns TRUE for soft-link in root group that points to object */ + if(TRUE != H5Oexists(fid, "soft2", H5P_DEFAULT)) + TEST_ERROR + + /* Create dangling soft-link in non-root group */ + if(H5Lcreate_soft("dangle", fid, "group/soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns FALSE for dangling soft-link in non-root group */ + if(FALSE != H5Oexists(fid, "group/soft1", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in non-root group that points to object */ + if(H5Lcreate_soft("/group", fid, "group/soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns TRUE for soft-link in non-root group that points to object */ + if(TRUE != H5Oexists(fid, "group/soft2", H5P_DEFAULT)) + TEST_ERROR + + +/* External links */ + /* Create dangling (file doesn't exist) external link in root group */ + if(H5Lcreate_external("nofile", "dangle", fid, "external1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns FALSE for dangling (file doesn't exist) external link in root group */ + if(FALSE != H5Oexists(fid, "external1", H5P_DEFAULT)) + TEST_ERROR + + /* Create dangling (object doesn't exist) external link in root group */ + if(H5Lcreate_external(filename, "dangle", fid, "external2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns FALSE for dangling (object doesn't exist) external link in root group */ + if(FALSE != H5Oexists(fid, "external2", H5P_DEFAULT)) + TEST_ERROR + + /* Create external link in root group that points to object */ + if(H5Lcreate_external(filename, "group", fid, "external3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns TRUE for external link in root group that points to object */ + if(TRUE != H5Oexists(fid, "external3", H5P_DEFAULT)) + TEST_ERROR + + /* Create dangling (file doesn't exist) external link in non-root group */ + if(H5Lcreate_external("nofile", "dangle", fid, "group/external1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns FALSE for dangling (file doesn't exist) external link in non-root group */ + if(FALSE != H5Oexists(fid, "group/external1", H5P_DEFAULT)) + TEST_ERROR + + /* Create dangling (object doesn't exist) external link in non-root group */ + if(H5Lcreate_external(filename, "dangle", fid, "group/external2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns FALSE for dangling (object doesn't exist) external link in non-root group */ + if(FALSE != H5Oexists(fid, "group/external2", H5P_DEFAULT)) + TEST_ERROR + + /* Create external link in non-root group that points to object */ + if(H5Lcreate_external(filename, "group", fid, "group/external3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns TRUE for external link in non-root group that points to object */ + if(TRUE != H5Oexists(fid, "group/external3", H5P_DEFAULT)) + TEST_ERROR + + +/* Soft->External links */ + /* Create soft-link in root group that points to dangling (file doesn't exist) external link */ + if(H5Lcreate_soft("external1", fid, "soft-elink1", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "soft-elink1", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in root group that points to dangling (object doesn't exist) external link */ + if(H5Lcreate_soft("external2", fid, "soft-elink2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "soft-elink2", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in root group that points to external link that points to object */ + if(H5Lcreate_soft("external3", fid, "soft-elink3", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns TRUE */ + if(TRUE != H5Oexists(fid, "soft-elink3", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in root group that points to dangling (file doesn't exist) external link in non-root group */ + if(H5Lcreate_soft("group/external1", fid, "soft-elink4", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "soft-elink4", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in root group that points to dangling (object doesn't exist) external link in non-root group */ + if(H5Lcreate_soft("group/external2", fid, "soft-elink5", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "soft-elink5", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in root group that points to external link in non-root group that points to object */ + if(H5Lcreate_soft("group/external3", fid, "soft-elink6", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns TRUE */ + if(TRUE != H5Oexists(fid, "soft-elink6", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in non-root group that points to dangling (file doesn't exist) external link */ + if(H5Lcreate_soft("/external1", fid, "group/soft-elink1", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "group/soft-elink1", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in non-root group that points to dangling (object doesn't exist) external link */ + if(H5Lcreate_soft("/external2", fid, "group/soft-elink2", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "group/soft-elink2", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in non-root group that points to external link that points to object */ + if(H5Lcreate_soft("/external3", fid, "group/soft-elink3", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns TRUE */ + if(TRUE != H5Oexists(fid, "group/soft-elink3", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in non-root group that points to dangling (file doesn't exist) external link in non-root group */ + if(H5Lcreate_soft("/group/external1", fid, "group/soft-elink4", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "group/soft-elink4", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in non-root group that points to dangling (object doesn't exist) external link in non-root group */ + if(H5Lcreate_soft("/group/external2", fid, "group/soft-elink5", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "group/soft-elink5", H5P_DEFAULT)) + TEST_ERROR + + /* Create soft-link in non-root group that points to external link in non-root group that points to object */ + if(H5Lcreate_soft("/group/external3", fid, "group/soft-elink6", H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR + + /* Verify that H5Oexists() returns TRUE */ + if(TRUE != H5Oexists(fid, "group/soft-elink6", H5P_DEFAULT)) + TEST_ERROR + + +/* External->Soft links */ + /* Create external link in root group that points to dangling soft link in root group */ + if(H5Lcreate_external(filename, "soft1", fid, "elink-soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "elink-soft1", H5P_DEFAULT)) + TEST_ERROR + + /* Create external link in root group that points to soft link in root group that points to object */ + if(H5Lcreate_external(filename, "soft2", fid, "elink-soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns TRUE */ + if(TRUE != H5Oexists(fid, "elink-soft2", H5P_DEFAULT)) + TEST_ERROR + + /* Create external link in root group that points to dangling soft link in non-root group */ + if(H5Lcreate_external(filename, "group/soft1", fid, "elink-soft3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "elink-soft3", H5P_DEFAULT)) + TEST_ERROR + + /* Create external link in root group that points to soft link in root group that points to object */ + if(H5Lcreate_external(filename, "group/soft2", fid, "elink-soft4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns TRUE */ + if(TRUE != H5Oexists(fid, "elink-soft4", H5P_DEFAULT)) + TEST_ERROR + + /* Create external link in non-root group that points to dangling soft link in root group */ + if(H5Lcreate_external(filename, "soft1", fid, "group/elink-soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "group/elink-soft1", H5P_DEFAULT)) + TEST_ERROR + + /* Create external link in non-root group that points to soft link in root group that points to object */ + if(H5Lcreate_external(filename, "soft2", fid, "group/elink-soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns TRUE */ + if(TRUE != H5Oexists(fid, "group/elink-soft2", H5P_DEFAULT)) + TEST_ERROR + + /* Create external link in non-root group that points to dangling soft link in non-root group */ + if(H5Lcreate_external(filename, "group/soft1", fid, "group/elink-soft3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns FALSE */ + if(FALSE != H5Oexists(fid, "group/elink-soft3", H5P_DEFAULT)) + TEST_ERROR + + /* Create external link in non-root group that points to soft link in non-root group that points to object */ + if(H5Lcreate_external(filename, "group/soft2", fid, "group/elink-soft4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that H5Oexists() returns TRUE */ + if(TRUE != H5Oexists(fid, "group/elink-soft4", H5P_DEFAULT)) + TEST_ERROR + + + /* Close file created */ + if(H5Fclose(fid) < 0) FAIL_STACK_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid); + H5Fclose(fid); + } H5E_END_TRY; + return -1; +} /* end obj_exists() */ + + +/*------------------------------------------------------------------------- * Function: corder_create_empty * * Purpose: Create an empty group with creation order indices @@ -10887,13 +11175,6 @@ link_iterate_cb(hid_t group_id, const char *link_name, const H5L_info_t *info, char objname[NAME_BUF_SIZE]; /* Object name */ H5L_info_t my_info; /* Local link info */ -#ifdef QAK -HDfprintf(stderr, "link_name = '%s'\n", link_name); -if(info) - HDfprintf(stderr, "info->corder = %Hd\n", info->corder); -HDfprintf(stderr, "op_data->curr = %Hd\n", op_data->curr); -#endif /* QAK */ - /* Increment # of times the callback was called */ op_data->ncalled++; @@ -11372,13 +11653,6 @@ link_iterate_old_cb(hid_t group_id, const char *link_name, const H5L_info_t *inf char objname[NAME_BUF_SIZE]; /* Object name */ H5L_info_t my_info; /* Local link info */ -#ifdef QAK -HDfprintf(stderr, "link_name = '%s'\n", link_name); -if(info) - HDfprintf(stderr, "info->corder = %Hd\n", info->corder); -HDfprintf(stderr, "op_data->curr = %Hd\n", op_data->curr); -#endif /* QAK */ - /* Increment # of times the callback was called */ op_data->ncalled++; @@ -13637,6 +13911,7 @@ main(void) nerrors += obj_visit_by_name(my_fapl, new_format) < 0 ? 1 : 0; nerrors += obj_visit_stop(my_fapl, new_format) < 0 ? 1 : 0; nerrors += link_filters(my_fapl, new_format) < 0 ? 1 : 0; + nerrors += obj_exists(my_fapl, new_format) < 0 ? 1 : 0; /* Keep this test last, it's testing files that are used above */ /* do not do this for files used by external link tests */ |