/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * Copyright by the Board of Trustees of the University of Illinois. * * All rights reserved. * * * * This file is part of HDF5. The full HDF5 copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the COPYING file, which can be found at the root of the source code * * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /*------------------------------------------------------------------------- * * Created: H5Gloc.c * Sep 13 2005 * Quincey Koziol * * Purpose: Functions for working with group "locations" * *------------------------------------------------------------------------- */ /****************/ /* Module Setup */ /****************/ #include "H5Gmodule.h" /* This source code file is part of the H5G module */ /***********/ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ #include "H5Aprivate.h" /* Attributes */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ /****************/ /* Local Macros */ /****************/ /******************/ /* Local Typedefs */ /******************/ /* User data for looking up an object in a group */ typedef struct { /* upward */ H5G_loc_t *loc; /* Group location to set */ } H5G_loc_fnd_t; /* User data for checking if an object exists */ typedef struct { /* upward */ htri_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 */ H5_index_t idx_type; /* Index to use */ H5_iter_order_t order; /* Iteration order within index */ hsize_t n; /* Offset within index */ /* upward */ H5G_loc_t *loc; /* Group location to set */ } H5G_loc_fbi_t; /* User data for getting an object's info in a group */ typedef struct { /* downward */ unsigned fields; /* which fields in H5O_info_t struct to fill in */ /* upward */ H5O_info_t *oinfo; /* Object information to retrieve */ } H5G_loc_info_t; /* User data for setting an object's comment in a group */ typedef struct { /* downward */ const char *comment; /* Object comment buffer */ /* upward */ } H5G_loc_sc_t; /* User data for getting an object's comment in a group */ typedef struct { /* downward */ char *comment; /* Object comment buffer */ size_t bufsize; /* Size of object comment buffer */ /* upward */ ssize_t comment_size; /* Actual size of object comment */ } H5G_loc_gc_t; /********************/ /* Local Prototypes */ /********************/ /* Group traversal callbacks */ static herr_t H5G__loc_find_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, H5G_own_loc_t *own_loc); static herr_t H5G__loc_find_by_idx_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, H5G_own_loc_t *own_loc); static herr_t H5G__loc_set_comment_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, H5G_own_loc_t *own_loc); static herr_t H5G__loc_get_comment_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, H5G_own_loc_t *own_loc); /*********************/ /* Package Variables */ /*********************/ /*****************************/ /* Library Private Variables */ /*****************************/ /*******************/ /* Local Variables */ /*******************/ /*------------------------------------------------------------------------- * Function: H5G_loc_real * * Purpose: Utility routine to get object location * * Returns: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5G_loc_real(void *obj, H5I_type_t type, H5G_loc_t *loc) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) switch(type) { case H5I_FILE: { H5F_t *f = (H5F_t *)obj; /* Construct a group location for root group of the file */ if(H5G_root_loc(f, loc) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to create location for file") break; } case H5I_GROUP: { H5G_t *group = (H5G_t *)obj; if(NULL == (loc->oloc = H5G_oloc(group))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of group") if(NULL == (loc->path = H5G_nameof(group))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of group") break; } case H5I_DATATYPE: { H5T_t *dt = NULL; /* Get the actual datatype object if the VOL object is set */ dt = H5T_get_actual_type((H5T_t *)obj); if(NULL == (loc->oloc = H5T_oloc(dt))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of datatype") if(NULL == (loc->path = H5T_nameof(dt))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of datatype") break; } case H5I_DATASET: { H5D_t *dset = (H5D_t *)obj; if(NULL == (loc->oloc = H5D_oloc(dset))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of dataset") if(NULL == (loc->path = H5D_nameof(dset))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of dataset") break; } case H5I_ATTR: { H5A_t *attr = (H5A_t *)obj; if(NULL == (loc->oloc = H5A_oloc(attr))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of attribute") if(NULL == (loc->path = H5A_nameof(attr))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of attribute") break; } case H5I_DATASPACE: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of dataspace") case H5I_GENPROP_CLS: case H5I_GENPROP_LST: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of property list") case H5I_ERROR_CLASS: case H5I_ERROR_MSG: case H5I_ERROR_STACK: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of error class, message or stack") case H5I_VFL: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of a virtual file driver (VFD)") case H5I_VOL: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of a virtual object layer (VOL) driver") case H5I_UNINIT: case H5I_BADID: case H5I_NTYPES: default: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid location ID") } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_real() */ /*------------------------------------------------------------------------- * Function: H5G_loc * * Purpose: Given an object ID return a location for the object. * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5G_loc(hid_t loc_id, H5G_loc_t *loc) { void *obj = NULL; /* VOL object */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Get the object from the VOL */ if(NULL == (obj = H5VL_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Fill in the struct */ if(H5G_loc_real(obj, H5I_get_type(loc_id), loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to fill in location struct") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc() */ /*------------------------------------------------------------------------- * Function: H5G_loc_copy * * Purpose: Copy over information for a location * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc_copy(H5G_loc_t *dst, const H5G_loc_t *src, H5_copy_depth_t depth) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check args. */ HDassert(dst); HDassert(src); /* Copy components of the location */ if(H5O_loc_copy(dst->oloc, src->oloc, depth) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") if(H5G_name_copy(dst->path, src->path, depth) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy path") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_copy() */ /*------------------------------------------------------------------------- * Function: H5G_loc_reset * * Purpose: Reset information for a location * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc_reset(H5G_loc_t *loc) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check args. */ HDassert(loc); /* Reset components of the location */ if(H5O_loc_reset(loc->oloc) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset entry") if(H5G_name_reset(loc->path) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset path") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_reset() */ /*------------------------------------------------------------------------- * Function: H5G_loc_free * * Purpose: Free information for a location * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc_free(H5G_loc_t *loc) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check args. */ HDassert(loc); /* Reset components of the location */ if(H5G_name_free(loc->path) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to free path") if(H5O_loc_free(loc->oloc) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to free object header location") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_free() */ /*------------------------------------------------------------------------- * Function: H5G__loc_find_cb * * Purpose: Callback for retrieving object location for an object in a group * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Monday, October 17, 2005 * *------------------------------------------------------------------------- */ static herr_t H5G__loc_find_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char *name, const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) { H5G_loc_fnd_t *udata = (H5G_loc_fnd_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC /* Check if the name in this group resolved to a valid object */ if(obj_loc == NULL) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object '%s' doesn't exist", name) /* Take ownership of the object's group location */ /* (Group traversal callbacks are responsible for either taking ownership * of the group location for the object, or freeing it. - QAK) */ H5G_loc_copy(udata->loc, obj_loc, H5_COPY_SHALLOW); *own_loc = H5G_OWN_OBJ_LOC; done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__loc_find_cb() */ /*------------------------------------------------------------------------- * Function: H5G_loc_find * * Purpose: Find a symbol from a location * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc_find(const H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc/*out*/) { H5G_loc_fnd_t udata; /* User data for traversal callback */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check args. */ HDassert(loc); HDassert(name && *name); HDassert(obj_loc); /* Set up user data for locating object */ udata.loc = obj_loc; /* Traverse group hierarchy to locate object */ if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G__loc_find_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_find() */ /*------------------------------------------------------------------------- * Function: H5G__loc_find_by_idx_cb * * Purpose: Callback for retrieving object location for an object in a group * according to the order within an index * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Monday, November 20, 2006 * *------------------------------------------------------------------------- */ static herr_t H5G__loc_find_by_idx_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) { 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 */ 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_STATIC /* Check if the name in this group resolved to a valid link */ if(obj_loc == NULL) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group doesn't exist") /* Query link */ if(H5G_obj_lookup_by_idx(obj_loc->oloc, udata->idx_type, udata->order, udata->n, &fnd_lnk) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "link not found") lnk_copied = TRUE; /* Build the initial object location for the link */ if(H5G__link_to_loc(obj_loc, &fnd_lnk, udata->loc) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot initialize object location") obj_loc_valid = TRUE; /* 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, TRUE, udata->loc, &obj_exists) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "special link traversal failed") done: /* Reset the link information, if we have a copy */ if(lnk_copied) H5O_msg_reset(H5O_LINK_ID, &fnd_lnk); /* Release the object location if we failed after copying it */ if(ret_value < 0 && obj_loc_valid) if(H5G_loc_free(udata->loc) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") /* Indicate that this callback didn't take ownership of the group * * location for the object */ *own_loc = H5G_OWN_NONE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__loc_find_by_idx_cb() */ /*------------------------------------------------------------------------- * Function: H5G_loc_find_by_idx * * Purpose: Find a symbol from a location, according to the order in an index * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Monday, November 20, 2006 * *------------------------------------------------------------------------- */ herr_t H5G_loc_find_by_idx(const 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*/) { H5G_loc_fbi_t udata; /* User data for traversal callback */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check args. */ HDassert(loc); HDassert(group_name && *group_name); HDassert(obj_loc); /* Set up user data for locating object */ udata.idx_type = idx_type; udata.order = order; udata.n = n; udata.loc = obj_loc; /* Traverse group hierarchy to locate object */ if(H5G_traverse(loc, group_name, H5G_TARGET_NORMAL, H5G__loc_find_by_idx_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_find_by_idx() */ /*------------------------------------------------------------------------- * Function: H5G__loc_insert * * Purpose: Insert an object at a location * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ herr_t H5G__loc_insert(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, H5O_type_t obj_type, const void *crt_info) { H5O_link_t lnk; /* Link for object to insert */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Check args. */ HDassert(grp_loc); HDassert(name && *name); HDassert(obj_loc); /* Create link object for the object location */ lnk.type = H5L_TYPE_HARD; lnk.cset = H5F_DEFAULT_CSET; lnk.corder = 0; /* Will be reset if the group is tracking creation order */ lnk.corder_valid = FALSE; /* Indicate that the creation order isn't valid (yet) */ /* Casting away const OK -QAK */ lnk.name = (char *)name; lnk.u.hard.addr = obj_loc->oloc->addr; /* Insert new group into current group's symbol table */ if(H5G_obj_insert(grp_loc->oloc, name, &lnk, TRUE, obj_type, crt_info) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert object") /* Set the name of the object location */ if(H5G_name_set(grp_loc->path, obj_loc->path, name) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot set name") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__loc_insert() */ /*------------------------------------------------------------------------- * 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 H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_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_NOERR /* 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) { H5G_loc_exists_t udata; /* User data for traversal callback */ htri_t ret_value = FAIL; /* Return value */ FUNC_ENTER_NOAPI(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) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't check if object exists") /* Set return value */ ret_value = 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 * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Thursday, November 23, 2006 * *------------------------------------------------------------------------- */ static herr_t H5G_loc_info_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) { H5G_loc_info_t *udata = (H5G_loc_info_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Check if the name in this group resolved to a valid link */ if(obj_loc == NULL) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") /* Query object information */ if(H5O_get_info(obj_loc->oloc, udata->oinfo, udata->fields) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object info") done: /* Indicate that this callback didn't take ownership of the group * * location for the object */ *own_loc = H5G_OWN_NONE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_info_cb() */ /*------------------------------------------------------------------------- * Function: H5G_loc_info * * Purpose: Retrieve the information for an object from a group location * and path to that object * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Thursday, November 23, 2006 * *------------------------------------------------------------------------- */ herr_t H5G_loc_info(const H5G_loc_t *loc, const char *name, H5O_info_t *oinfo/*out*/, unsigned fields) { H5G_loc_info_t udata; /* User data for traversal callback */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check args. */ HDassert(loc); HDassert(name && *name); HDassert(oinfo); /* Set up user data for locating object */ udata.fields = fields; udata.oinfo = oinfo; /* Traverse group hierarchy to locate object */ if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_info_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_info() */ /*------------------------------------------------------------------------- * Function: H5G__loc_set_comment_cb * * Purpose: Callback for (re)setting object comment for an object in a group * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Thursday, August 30, 2007 * *------------------------------------------------------------------------- */ static herr_t H5G__loc_set_comment_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) { H5G_loc_sc_t *udata = (H5G_loc_sc_t *)_udata; /* User data passed in */ H5O_name_t comment; /* Object header "comment" message */ htri_t exists; /* Whether a "comment" message already exists */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC /* Check if the name in this group resolved to a valid link */ if(obj_loc == NULL) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") /* Check for existing comment message */ if((exists = H5O_msg_exists(obj_loc->oloc, H5O_NAME_ID)) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read object header") /* Remove the previous comment message if any */ if(exists) if(H5O_msg_remove(obj_loc->oloc, H5O_NAME_ID, 0, TRUE) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete existing comment object header message") /* Add the new message */ if(udata->comment && *udata->comment) { /* Casting away const OK -QAK */ comment.s = (char *)udata->comment; if(H5O_msg_create(obj_loc->oloc, H5O_NAME_ID, 0, H5O_UPDATE_TIME, &comment) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to set comment object header message") } /* end if */ done: /* Indicate that this callback didn't take ownership of the group * * location for the object */ *own_loc = H5G_OWN_NONE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__loc_set_comment_cb() */ /*------------------------------------------------------------------------- * Function: H5G_loc_set_comment * * Purpose: (Re)set the information for an object from a group location * and path to that object * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Thursday, August 30, 2007 * *------------------------------------------------------------------------- */ herr_t H5G_loc_set_comment(const H5G_loc_t *loc, const char *name, const char *comment) { H5G_loc_sc_t udata; /* User data for traversal callback */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check args. */ HDassert(loc); HDassert(name && *name); /* Set up user data for locating object */ udata.comment = comment; /* Traverse group hierarchy to locate object */ if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G__loc_set_comment_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_set_comment() */ /*------------------------------------------------------------------------- * Function: H5G__loc_get_comment_cb * * Purpose: Callback for retrieving object comment for an object in a group * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Thursday, August 30, 2007 * *------------------------------------------------------------------------- */ static herr_t H5G__loc_get_comment_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) { H5G_loc_gc_t *udata = (H5G_loc_gc_t *)_udata; /* User data passed in */ H5O_name_t comment; /* Object header "comment" message */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC /* Check if the name in this group resolved to a valid link */ if(obj_loc == NULL) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") /* Query object comment */ comment.s = NULL; if(NULL == H5O_msg_read(obj_loc->oloc, H5O_NAME_ID, &comment)) { if(udata->comment && udata->bufsize > 0) udata->comment[0] = '\0'; udata->comment_size = 0; } else { if(udata->comment && udata->bufsize) HDstrncpy(udata->comment, comment.s, udata->bufsize); udata->comment_size = (ssize_t)HDstrlen(comment.s); H5O_msg_reset(H5O_NAME_ID, &comment); } done: /* Indicate that this callback didn't take ownership of the group * * location for the object. */ *own_loc = H5G_OWN_NONE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__loc_get_comment_cb() */ /*------------------------------------------------------------------------- * Function: H5G_loc_get_comment * * Purpose: Retrieve the information for an object from a group location * and path to that object * * Return: Success: Number of bytes in the comment excluding the * null terminator. Zero if the object has no * comment. * * Failure: Negative * * Programmer: Quincey Koziol * Thursday, August 30, 2007 * *------------------------------------------------------------------------- */ ssize_t H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, char *comment/*out*/, size_t bufsize) { H5G_loc_gc_t udata; /* User data for traversal callback */ ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check args. */ HDassert(loc); HDassert(name && *name); /* Set up user data for locating object */ udata.comment = comment; udata.bufsize = bufsize; udata.comment_size = (-1); /* Traverse group hierarchy to locate object */ if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G__loc_get_comment_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") /* Set the return value */ ret_value = udata.comment_size; done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_get_comment() */ --------------------------------------------------------- - * Function: H5E_walk + * Function: H5E_walk_stack * * Purpose: Private function for H5Ewalk. * Walks the error stack, calling the specified function for @@ -2076,13 +2067,13 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5E_walk (const H5E_t *estack, H5E_direction_t direction, H5E_walk_t func, void *client_data) +H5E_walk_stack(const H5E_t *estack, H5E_direction_t direction, H5E_walk_t func, void *client_data) { int i; /* Local index variable */ herr_t status; /* Status from callback function */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5E_walk, FAIL) + FUNC_ENTER_NOAPI(H5E_walk_stack, FAIL) /* Sanity check */ assert (estack); @@ -2094,16 +2085,7 @@ H5E_walk (const H5E_t *estack, H5E_direction_t direction, H5E_walk_t func, void /* Walk the stack if a callback function was given */ if(func) { status=SUCCEED; -#ifdef H5_WANT_H5_V1_6_COMPAT - if (H5E_WALK_UPWARD==direction) { - for (i=0; i<(int)estack->nused && status>=0; i++) - status = (func)(i, estack->slot+i, client_data); - } else { - H5_CHECK_OVERFLOW(estack->nused-1,size_t,int); - for (i=(int)(estack->nused-1); i>=0 && status>=0; i--) - status = (func)((int)estack->nused-(i+1), estack->slot+i, client_data); - } -#else /* H5_WANT_H5_V1_6_COMPAT */ + if (H5E_WALK_UPWARD==direction) { for (i=0; i<(int)estack->nused && status>=0; i++) status = (func)((unsigned)i, estack->slot+i, client_data); @@ -2112,7 +2094,7 @@ H5E_walk (const H5E_t *estack, H5E_direction_t direction, H5E_walk_t func, void for (i=(int)(estack->nused-1); i>=0 && status>=0; i--) status = (func)((unsigned)(estack->nused-(size_t)(i+1)), estack->slot+i, client_data); } -#endif /* H5_WANT_H5_V1_6_COMPAT */ + if(status<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTLIST, FAIL, "can't walk error stack") } /* end if */ @@ -2155,13 +2137,8 @@ done: * *------------------------------------------------------------------------- */ -#ifdef H5_WANT_H5_V1_6_COMPAT -static herr_t -H5E_walk_cb(int n, H5E_error_t *err_desc, void *client_data) -#else /* H5_WANT_H5_V1_6_COMPAT */ static herr_t H5E_walk_cb(unsigned n, const H5E_error_t *err_desc, void *client_data) -#endif /* H5_WANT_H5_V1_6_COMPAT */ { H5E_print_t *eprint = (H5E_print_t *)client_data; FILE *stream; /* I/O stream to print output to */ @@ -2225,24 +2202,16 @@ H5E_walk_cb(unsigned n, const H5E_error_t *err_desc, void *client_data) have_desc=0; /* Print error message */ -#ifdef H5_WANT_H5_V1_6_COMPAT - fprintf (stream, "%*s#%03d: %s line %u in %s()%s%s\n", - H5E_INDENT, "", n, err_desc->file_name, err_desc->line, - err_desc->func_name, (have_desc ? ": " : ""), - (err_desc->desc ? err_desc->desc : "")); -#else /* H5_WANT_H5_V1_6_COMPAT */ fprintf (stream, "%*s#%03u: %s line %u in %s()%s%s\n", H5E_INDENT, "", n, err_desc->file_name, err_desc->line, err_desc->func_name, (have_desc ? ": " : ""), (have_desc ? err_desc->desc : "")); -#endif /* H5_WANT_H5_V1_6_COMPAT */ fprintf (stream, "%*smajor: %s\n", H5E_INDENT*2, "", maj_str); fprintf (stream, "%*sminor: %s\n", H5E_INDENT*2, "", min_str); FUNC_LEAVE_NOAPI(SUCCEED) } -#ifdef H5_WANT_H5_V1_6_COMPAT /*------------------------------------------------------------------------- * Function: H5Eget_auto @@ -2276,17 +2245,16 @@ H5Eget_auto(H5E_auto_t *func, void **client_data) HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack") /* Get the automatic error reporting information */ - if(H5E_get_auto(estack, func, client_data)<0) + if(H5E_get_auto_stack(estack, func, client_data)<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info") done: FUNC_LEAVE_API(ret_value) } -#else /*------------------------------------------------------------------------- - * Function: H5Eget_auto + * Function: H5Eget_auto_stack * * Purpose: Returns the current settings for the automatic error stack * traversal function and its data for specific error stack. @@ -2307,12 +2275,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Eget_auto(hid_t estack_id, H5E_auto_t *func, void **client_data) +H5Eget_auto_stack(hid_t estack_id, H5E_auto_t *func, void **client_data) { H5E_t *estack; /* Error stack to operate on */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5Eget_auto, FAIL) + FUNC_ENTER_API(H5Eget_auto_stack, FAIL) H5TRACE3("e","i*xx",estack_id,func,client_data); if(estack_id == H5E_DEFAULT) { @@ -2324,17 +2292,16 @@ H5Eget_auto(hid_t estack_id, H5E_auto_t *func, void **client_data) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") /* Get the automatic error reporting information */ - if(H5E_get_auto(estack, func, client_data)<0) + if(H5E_get_auto_stack(estack, func, client_data)<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info") done: FUNC_LEAVE_API(ret_value) } -#endif /* H5_WANT_H5_V1_6_COMPAT */ /*------------------------------------------------------------------------- - * Function: H5E_get_auto + * Function: H5E_get_auto_stack * * Purpose: Private function to return the current settings for the * automatic error stack traversal function and its data @@ -2351,11 +2318,11 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5E_get_auto(const H5E_t *estack, H5E_auto_t *func, void **client_data) +H5E_get_auto_stack(const H5E_t *estack, H5E_auto_t *func, void **client_data) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5E_get_auto, FAIL) + FUNC_ENTER_NOAPI(H5E_get_auto_stack, FAIL) assert (estack); @@ -2367,7 +2334,6 @@ done: FUNC_LEAVE_NOAPI(ret_value) } -#ifdef H5_WANT_H5_V1_6_COMPAT /*------------------------------------------------------------------------- * Function: H5Eset_auto @@ -2409,17 +2375,16 @@ H5Eset_auto(H5E_auto_t func, void *client_data) HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack") /* Set the automatic error reporting information */ - if(H5E_set_auto(estack, func, client_data)<0) + if(H5E_set_auto_stack(estack, func, client_data)<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't set automatic error info") done: FUNC_LEAVE_API(ret_value) } -#else /*------------------------------------------------------------------------- - * Function: H5Eset_auto + * Function: H5Eset_auto_stack * * Purpose: Turns on or off automatic printing of errors for certain * error stack. When turned on (non-null FUNC pointer) any @@ -2445,12 +2410,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Eset_auto(hid_t estack_id, H5E_auto_t func, void *client_data) +H5Eset_auto_stack(hid_t estack_id, H5E_auto_t func, void *client_data) { H5E_t *estack; /* Error stack to operate on */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5Eset_auto, FAIL) + FUNC_ENTER_API(H5Eset_auto_stack, FAIL) H5TRACE3("e","ixx",estack_id,func,client_data); if(estack_id == H5E_DEFAULT) { @@ -2462,17 +2427,16 @@ H5Eset_auto(hid_t estack_id, H5E_auto_t func, void *client_data) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") /* Set the automatic error reporting information */ - if(H5E_set_auto(estack, func, client_data)<0) + if(H5E_set_auto_stack(estack, func, client_data)<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't set automatic error info") done: FUNC_LEAVE_API(ret_value) } -#endif /* H5_WANT_H5_V1_6_COMPAT */ /*------------------------------------------------------------------------- - * Function: H5E_set_auto + * Function: H5E_set_auto_stack * * Purpose: Private function to turn on or off automatic printing of * errors for certain error stack. When turned on (non-null @@ -2499,11 +2463,11 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5E_set_auto(H5E_t *estack, H5E_auto_t func, void *client_data) +H5E_set_auto_stack(H5E_t *estack, H5E_auto_t func, void *client_data) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5E_set_auto, FAIL) + FUNC_ENTER_NOAPI(H5E_set_auto_stack, FAIL) assert(estack); @@ -2545,11 +2509,7 @@ H5E_dump_api_stack(int is_api) assert(estack); if (estack->func) -#ifdef H5_WANT_H5_V1_6_COMPAT - (void)((estack->func)(estack->auto_data)); -#else /*H5_WANT_H5_V1_6_COMPAT*/ (void)((estack->func)(H5E_DEFAULT, estack->auto_data)); -#endif /* H5_WANT_H5_V1_6_COMPAT */ } /* end if */ done: diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h index b874157..4dbb670 100644 --- a/src/H5Eprivate.h +++ b/src/H5Eprivate.h @@ -63,7 +63,7 @@ typedef struct H5E_print_t { * and a FUNC_LEAVE() within a function body. The arguments are the major * error number, the minor error number, and a description of the error. */ -#define HERROR(maj_id, min_id, str) H5E_push(NULL, __FILE__, FUNC, __LINE__, H5E_ERR_CLS_g, maj_id, min_id, str) +#define HERROR(maj_id, min_id, str) H5E_push_stack(NULL, __FILE__, FUNC, __LINE__, H5E_ERR_CLS_g, maj_id, min_id, str) /* * HCOMMON_ERROR macro, used by HDONE_ERROR and HGOTO_ERROR @@ -109,9 +109,9 @@ typedef struct H5E_print_t { /* Library-private functions defined in H5E package */ H5_DLL herr_t H5E_init(void); -H5_DLL herr_t H5E_push(H5E_t *estack, const char *file, const char *func, unsigned line, +H5_DLL herr_t H5E_push_stack(H5E_t *estack, const char *file, const char *func, unsigned line, hid_t cls_id, hid_t maj_id, hid_t min_id, const char *desc); -H5_DLL herr_t H5E_clear(H5E_t *estack); +H5_DLL herr_t H5E_clear_stack(H5E_t *estack); H5_DLL herr_t H5E_dump_api_stack(int is_api); #ifdef H5_HAVE_PARALLEL diff --git a/src/H5Epublic.h b/src/H5Epublic.h index e9cf481..247767c 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -36,10 +36,9 @@ typedef enum H5E_type_t { H5E_MINOR } H5E_type_t; -#ifdef H5_WANT_H5_V1_6_COMPAT +/* For backward compatibility with v1.6 */ typedef hid_t H5E_major_t; typedef hid_t H5E_minor_t; -#endif /* H5_WANT_H5_V1_6_COMPAT */ /* Information about an error; element of error stack */ typedef struct H5E_error_t { @@ -81,69 +80,43 @@ H5_DLLVAR hid_t H5E_ERR_CLS_g; * * Warning: don't break, return, or longjmp() from the body of the loop or * the error reporting won't be properly restored! + * + * These two macros still use the old API functions for backward compatibility + * purpose. */ -#ifdef H5_WANT_H5_V1_6_COMPAT #define H5E_BEGIN_TRY { \ H5E_auto_t H5E_saved_efunc; \ void *H5E_saved_edata; \ - (void)H5Eget_auto(&H5E_saved_efunc, &H5E_saved_edata); \ - (void)H5Eset_auto(NULL, NULL); + (void)H5Eget_auto_stack(H5E_DEFAULT, &H5E_saved_efunc, &H5E_saved_edata); \ + (void)H5Eset_auto_stack(H5E_DEFAULT, NULL, NULL); #define H5E_END_TRY \ - (void)H5Eset_auto (H5E_saved_efunc, H5E_saved_edata); \ + (void)H5Eset_auto_stack(H5E_DEFAULT, H5E_saved_efunc, H5E_saved_edata); \ } -#else /* H5_WANT_H5_V1_6_COMPAT */ -#define H5E_BEGIN_TRY { \ - H5E_auto_t H5E_saved_efunc; \ - void *H5E_saved_edata; \ - (void)H5Eget_auto(H5E_DEFAULT, &H5E_saved_efunc, &H5E_saved_edata); \ - (void)H5Eset_auto(H5E_DEFAULT, NULL, NULL); - -#define H5E_END_TRY \ - (void)H5Eset_auto (H5E_DEFAULT, H5E_saved_efunc, H5E_saved_edata); \ -} -#endif /* H5_WANT_H5_V1_6_COMPAT */ /* * Public API Convenience Macros for Error reporting - Documented */ /* Use the Standard C __FILE__ & __LINE__ macros instead of typing them in */ -#ifdef H5_WANT_H5_V1_6_COMPAT -#define H5Epush_sim(func,cls,maj,min,str) H5Epush(__FILE__,func,__LINE__,maj,min,str) -#else -#define H5Epush_sim(func,cls,maj,min,str) H5Epush(H5E_DEFAULT,__FILE__,func,__LINE__,cls,maj,min,str) -#endif /* H5_WANT_H5_V1_6_COMPAT */ +#define H5Epush_sim(func,cls,maj,min,str) H5Epush_stack(H5E_DEFAULT,__FILE__,func,__LINE__,cls,maj,min,str) /* * Public API Convenience Macros for Error reporting - Undocumented */ /* Use the Standard C __FILE__ & __LINE__ macros instead of typing them in */ /* And return after pushing error onto stack */ -#ifdef H5_WANT_H5_V1_6_COMPAT #define H5Epush_ret(func,cls,maj,min,str,ret) { \ - H5Epush(__FILE__,func,__LINE__,maj,min,str); \ + H5Epush_stack(H5E_DEFAULT,__FILE__,func,__LINE__,cls,maj,min,str); \ return(ret); \ } -#else -#define H5Epush_ret(func,cls,maj,min,str,ret) { \ - H5Epush(H5E_DEFAULT,__FILE__,func,__LINE__,cls,maj,min,str); \ - return(ret); \ -} -#endif /* H5_WANT_H5_V1_6_COMPAT */ -/* Use the Standard C __FILE__ & __LINE__ macros instead of typing them in */ -/* And goto a label after pushing error onto stack */ -#ifdef H5_WANT_H5_V1_6_COMPAT -#define H5Epush_goto(func,cls,maj,min,str,label) { \ - H5Epush(__FILE__,func,__LINE__,maj,min,str); \ - goto label; \ -} -#else +/* Use the Standard C __FILE__ & __LINE__ macros instead of typing them in + * And goto a label after pushing error onto stack. + */ #define H5Epush_goto(func,cls,maj,min,str,label) { \ - H5Epush(H5E_DEFAULT,__FILE__,func,__LINE__,cls,maj,min,str); \ + H5Epush_stack(H5E_DEFAULT,__FILE__,func,__LINE__,cls,maj,min,str); \ goto label;