summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-02-03 15:05:41 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-02-03 15:05:41 (GMT)
commitc8d05fbe4d4d135ee2ec352f6437e43bdbe423b7 (patch)
tree1257e54854f3b85d498ad078aaa562cc9cd2680d
parent1c05d48b9329e05f874e494c45c429f6cadc1ee5 (diff)
downloadhdf5-c8d05fbe4d4d135ee2ec352f6437e43bdbe423b7.zip
hdf5-c8d05fbe4d4d135ee2ec352f6437e43bdbe423b7.tar.gz
hdf5-c8d05fbe4d4d135ee2ec352f6437e43bdbe423b7.tar.bz2
[svn-r18205] Description:
Add prototype of new H5Oexists() API routine. Tested on: Mac OS X/32 10.6.2 (amazon) (further tests pending shortly)
-rw-r--r--src/H5Gloc.c91
-rw-r--r--src/H5Gpkg.h5
-rw-r--r--src/H5Gprivate.h2
-rw-r--r--src/H5Gtraverse.c104
-rw-r--r--src/H5O.c41
-rw-r--r--src/H5Opublic.h1
-rw-r--r--test/links.c319
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);
diff --git a/src/H5O.c b/src/H5O.c
index d437f8f..253ed8d 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -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 */