summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2002-10-14 20:08:23 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2002-10-14 20:08:23 (GMT)
commit1e231d3283e9124cf53d28116b80fa4f8f20697e (patch)
tree31789f7c81a5e9a84aa4fa3acf68190d986b313b /src
parent92cfe70bb653ff2e5fca1063723749aa6f8bdaf5 (diff)
downloadhdf5-1e231d3283e9124cf53d28116b80fa4f8f20697e.zip
hdf5-1e231d3283e9124cf53d28116b80fa4f8f20697e.tar.gz
hdf5-1e231d3283e9124cf53d28116b80fa4f8f20697e.tar.bz2
[svn-r5995] Purpose:
Code cleanup/Bug Fix Description: Re-do the ID->name code again, taking into account many more weird and wonderful special cases stumbled across during the last set of test writing. Platforms tested: FreeBSD 4.6 (sleipnir) w and w/o parallel Linux 2.2.x (eirene) w/FORTRAN & C++ Solaris 2.7 (arabica) w/FORTRAN IRIX64 6.5 (modi4) w/FORTRAN & parallel
Diffstat (limited to 'src')
-rw-r--r--src/H5A.c4
-rw-r--r--src/H5D.c4
-rw-r--r--src/H5F.c16
-rw-r--r--src/H5G.c560
-rw-r--r--src/H5Gent.c33
-rw-r--r--src/H5Gnode.c2
-rw-r--r--src/H5Gprivate.h26
-rw-r--r--src/H5Gstab.c104
-rw-r--r--src/H5I.c6
-rw-r--r--src/H5Odtype.c6
-rw-r--r--src/H5T.c7
11 files changed, 470 insertions, 298 deletions
diff --git a/src/H5A.c b/src/H5A.c
index be0f182..b32572b 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -245,7 +245,7 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type,
attr->initialized = TRUE; /*for now, set to false later*/
/* Deep copy of the symbol table entry */
- if (H5G_ent_copy(ent,&(attr->ent))<0)
+ if (H5G_ent_copy(&(attr->ent),ent,H5G_COPY_DEEP)<0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry");
/* Compute the internal sizes */
@@ -500,7 +500,7 @@ H5A_open(H5G_entry_t *ent, unsigned idx)
attr->initialized=1;
/* Deep copy of the symbol table entry */
- if (H5G_ent_copy(ent,&(attr->ent))<0)
+ if (H5G_ent_copy(&(attr->ent),ent,H5G_COPY_DEEP)<0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry");
/* Hold the symbol table entry (and file) open */
diff --git a/src/H5D.c b/src/H5D.c
index 5bac61d..dbdfb49 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -1992,7 +1992,7 @@ H5D_open_oid(H5G_entry_t *ent)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Shallow copy (take ownership) of the group entry object */
- HDmemcpy(&(dataset->ent),ent,sizeof(H5G_entry_t));
+ H5G_ent_copy(&(dataset->ent),ent,H5G_COPY_SHALLOW);
/* Find the dataset object */
if (H5O_open(&(dataset->ent)) < 0)
@@ -2191,7 +2191,7 @@ H5D_close(H5D_t *dataset)
/* Update header message of layout for compact dataset. */
if(dataset->layout.type==H5D_COMPACT && dataset->layout.dirty) {
if(H5O_modify(&(dataset->ent), H5O_LAYOUT, 0, 0, &(dataset->layout))<0)
- HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message");
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message");
dataset->layout.dirty = FALSE;
} /* end if */
diff --git a/src/H5F.c b/src/H5F.c
index 01128bd..1455709 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -1195,7 +1195,7 @@ herr_t H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void** file_handle)
H5F_t *file=NULL;
herr_t ret_value;
- FUNC_ENTER_API(H5Fget_vfd_handle, NULL);
+ FUNC_ENTER_API(H5Fget_vfd_handle, FAIL);
/* Check args */
assert(file_handle);
@@ -2975,7 +2975,7 @@ H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
/* Search the open IDs and replace names for mount operation */
/* We pass H5G_UNKNOWN as object type; search all IDs */
- if (H5G_replace_name( H5G_UNKNOWN, loc, name, NULL, OP_MOUNT )<0)
+ if (H5G_replace_name( H5G_UNKNOWN, loc, name, NULL, NULL, NULL, OP_MOUNT )<0)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to replace name");
done:
@@ -3050,7 +3050,7 @@ H5F_unmount(H5G_entry_t *loc, const char *name)
for (i=0; i<parent->mtab.nmounts; i++) {
if (parent->mtab.child[i].file==child) {
/* Search the open IDs replace names to reflect unmount operation */
- if (H5G_replace_name( H5G_UNKNOWN, loc, name, NULL, OP_UNMOUNT )<0)
+ if (H5G_replace_name( H5G_UNKNOWN, mnt_ent, mnt_ent->user_path, NULL, NULL, NULL, OP_UNMOUNT )<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name ");
/* Unmount the child */
@@ -3164,17 +3164,11 @@ H5F_mountpoint(H5G_entry_t *find/*in,out*/)
/* Copy root info over to ENT */
if (0==cmp) {
- char *tmp_name, *tmp_old_name; /* Temporary string pointers for entry's name and "old name"*/
-
/* Get the entry for the root group in the child's file */
ent = H5G_entof(parent->mtab.child[md].file->shared->root_grp);
- /* Don't lose the name of the group when we copy the root group's entry */
- tmp_name = find->name;
- tmp_old_name = find->old_name;
- *find = *ent;
- find->name = tmp_name;
- find->old_name = tmp_old_name;
+ /* Don't lose the user path of the group when we copy the root group's entry */
+ H5G_ent_copy(find,ent,H5G_COPY_LIMITED);
/* Switch to child's file */
parent = ent->file;
diff --git a/src/H5G.c b/src/H5G.c
index bb13435..f6f0633 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -110,9 +110,11 @@ static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */
/* Struct only used by change name callback function */
typedef struct H5G_names_t {
+ H5G_entry_t *loc;
const char *src_name;
+ H5G_entry_t *src_loc;
const char *dst_name;
- H5G_entry_t *loc;
+ H5G_entry_t *dst_loc;
H5G_names_op_t op;
} H5G_names_t;
@@ -121,6 +123,8 @@ H5FL_DEFINE(H5G_t);
/* Private prototypes */
static herr_t H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key);
+static herr_t H5G_traverse_slink(H5G_entry_t *grp_ent/*in,out*/,
+ H5G_entry_t *obj_ent/*in,out*/, int *nlinks/*in,out*/);
/*-------------------------------------------------------------------------
@@ -1050,7 +1054,7 @@ H5G_basename(const char *name, size_t *size_p)
static herr_t
H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
H5G_entry_t *grp_ent/*out*/, H5G_entry_t *obj_ent/*out*/,
- unsigned target, int *nlinks)
+ unsigned target, int *nlinks/*out*/)
{
H5G_entry_t _grp_ent; /*entry for current group */
H5G_entry_t _obj_ent; /*entry found */
@@ -1064,10 +1068,19 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
FUNC_ENTER_NOINIT(H5G_namei);
- if (rest) *rest = name;
- if (!grp_ent) grp_ent = &_grp_ent;
- if (!obj_ent) obj_ent = &_obj_ent;
- if (!nlinks) nlinks = &_nlinks;
+ /* Set up "out" parameters */
+ if (rest)
+ *rest = name;
+ if (!grp_ent) {
+ HDmemset(&_grp_ent,0,sizeof(H5G_entry_t));
+ grp_ent = &_grp_ent;
+ } /* end if */
+ if (!obj_ent) {
+ HDmemset(&_obj_ent,0,sizeof(H5G_entry_t));
+ obj_ent = &_obj_ent;
+ } /* end if */
+ if (!nlinks)
+ nlinks = &_nlinks;
/* Check args */
if (!name || !*name)
@@ -1091,7 +1104,7 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
} /* end if */
/* Deep copy of the symbol table entry */
- if (H5G_ent_copy( loc_ent, obj_ent )<0)
+ if (H5G_ent_copy(obj_ent, loc_ent,H5G_COPY_DEEP)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to copy entry");
HDmemset(grp_ent, 0, sizeof(H5G_entry_t));
@@ -1136,7 +1149,7 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
H5G_free_ent_name(grp_ent);
/* Transfer "ownership" of the entry's information to the group entry */
- *grp_ent = *obj_ent;
+ H5G_ent_copy(grp_ent,obj_ent,H5G_COPY_SHALLOW);
HDmemset(obj_ent, 0, sizeof(H5G_entry_t));
obj_ent->header = HADDR_UNDEF;
@@ -1156,9 +1169,8 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
* is the last component of the name and the H5G_TARGET_SLINK bit of
* TARGET is set then we don't follow it.
*/
- if (H5G_CACHED_SLINK==obj_ent->type &&
- (0==(target & H5G_TARGET_SLINK) ||
- ((s=H5G_component(name+nchars, NULL)) && *s))) {
+ if(H5G_CACHED_SLINK==obj_ent->type && (0==(target & H5G_TARGET_SLINK) ||
+ ((s=H5G_component(name+nchars, NULL)) && *s))) {
if ((*nlinks)-- <= 0)
HGOTO_ERROR (H5E_SYM, H5E_SLINK, FAIL, "too many symbolic links");
if (H5G_traverse_slink (grp_ent, obj_ent, nlinks)<0)
@@ -1171,14 +1183,12 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
* component of the name.
*/
if (0==(target & H5G_TARGET_MOUNT) ||
- ((s=H5G_component(name+nchars, NULL)) && *s)) {
+ ((s=H5G_component(name+nchars, NULL)) && *s)) {
H5F_mountpoint(obj_ent/*in,out*/);
}
/* next component */
name += nchars;
-
-
} /* end while */
/* Update the "rest of name" pointer */
@@ -1220,7 +1230,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
H5G_entry_t *obj_ent/*in,out*/,
int *nlinks/*in,out*/)
@@ -1229,11 +1239,14 @@ H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
const char *clv = NULL; /*cached link value */
char *linkval = NULL; /*the copied link value */
H5G_entry_t tmp_grp_ent; /* Temporary copy of group entry */
- char *tmp_name, *tmp_old_name; /* Temporary pointer to object's name & "old name" */
+ char *tmp_user_path=NULL, *tmp_canon_path=NULL; /* Temporary pointer to object's user path & canonical path */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_traverse_slink, FAIL);
+ /* Portably initialize the temporary group entry */
+ HDmemset(&tmp_grp_ent,0,sizeof(H5G_entry_t));
+
/* Get the link value */
if (NULL==H5O_read (grp_ent, H5O_STAB, 0, &stab_mesg))
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address");
@@ -1242,14 +1255,17 @@ H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read symbolic link value");
linkval = H5MM_xstrdup (clv);
- /* Copy the entry's name (& old_name) to restore later, then free the names for the entries */
- tmp_name= H5MM_xstrdup(obj_ent->name);
- tmp_old_name= H5MM_xstrdup(obj_ent->old_name);
- H5G_free_ent_name(obj_ent);
+ /* Hold the entry's name (& old_name) to restore later */
+ tmp_user_path=obj_ent->user_path;
+ obj_ent->user_path=NULL;
+ tmp_canon_path=obj_ent->canon_path;
+ obj_ent->canon_path=NULL;
+
+ /* Free the names for the group entry */
H5G_free_ent_name(grp_ent);
/* Clone the group entry, so we can track the names properly */
- H5G_ent_copy(grp_ent,&tmp_grp_ent);
+ H5G_ent_copy(&tmp_grp_ent,grp_ent,H5G_COPY_DEEP);
/* Traverse the link */
if (H5G_namei (&tmp_grp_ent, linkval, NULL, grp_ent, obj_ent, H5G_TARGET_NORMAL, nlinks))
@@ -1259,15 +1275,17 @@ H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
H5G_free_ent_name(obj_ent);
/* Restore previous name for object */
- obj_ent->name = tmp_name;
- obj_ent->old_name = tmp_old_name;
+ obj_ent->user_path = tmp_user_path;
+ tmp_user_path=NULL;
+ obj_ent->canon_path = tmp_canon_path;
+ tmp_canon_path=NULL;
done:
/* Error cleanup */
- if (ret_value == FAIL ) {
- H5MM_xfree(tmp_name);
- H5MM_xfree(tmp_old_name);
- } /* end if */
+ if(tmp_user_path)
+ H5MM_xfree(tmp_user_path);
+ if(tmp_canon_path)
+ H5MM_xfree(tmp_canon_path);
/* Release cloned copy of group entry */
H5G_free_ent_name(&tmp_grp_ent);
@@ -1337,10 +1355,12 @@ H5G_mkroot (H5F_t *f, H5G_entry_t *ent)
H5O_reset (H5O_STAB, &stab);
}
- /* Create the name for the root group's entry */
- ent->name = HDstrdup("/");
- assert(ent->name);
- ent->old_name = NULL;
+ /* Create the path names for the root group's entry */
+ ent->user_path=HDstrdup("/");
+ assert(ent->user_path);
+ ent->canon_path=HDstrdup("/");
+ assert(ent->canon_path);
+ ent->user_path_hidden=0;
/*
* Create the group pointer. Also decrement the open object count so we
@@ -1580,7 +1600,7 @@ H5G_open_oid(H5G_entry_t *ent)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* Copy over (take ownership) of the group entry object */
- HDmemcpy(&(grp->ent),ent,sizeof(H5G_entry_t));
+ H5G_ent_copy(&(grp->ent),ent,H5G_COPY_SHALLOW);
/* Grab the object header */
if (H5O_open(&(grp->ent)) < 0)
@@ -2460,7 +2480,7 @@ H5G_unlink(H5G_entry_t *loc, const char *name)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unlink name from symbol table");
/* Search the open IDs and replace names for unlinked object */
- if (H5G_replace_name(statbuf.type, loc, name, NULL, OP_UNLINK )<0)
+ if (H5G_replace_name(statbuf.type, &obj_ent, name, NULL, NULL, NULL, OP_UNLINK )<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name");
done:
@@ -2499,7 +2519,8 @@ H5G_move(H5G_entry_t *src_loc, const char *src_name, H5G_entry_t *dst_loc,
H5G_stat_t sb;
char *linkval=NULL;
size_t lv_size=32;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5G_entry_t obj_ent; /* Object entry for object being moved */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_move, FAIL);
assert(src_loc);
@@ -2539,8 +2560,11 @@ H5G_move(H5G_entry_t *src_loc, const char *src_name, H5G_entry_t *dst_loc,
* This has to be done here because H5G_link and H5G_unlink have
* internal object entries, and do not modify the entries list
*/
- if (H5G_replace_name(sb.type, src_loc, src_name, dst_name, OP_MOVE )<0)
+ if (H5G_namei (src_loc, src_name, NULL, NULL, &obj_ent, H5G_TARGET_NORMAL|H5G_TARGET_SLINK, NULL))
+ HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link");
+ if (H5G_replace_name(sb.type, &obj_ent, src_name, src_loc, dst_name, dst_loc, OP_MOVE )<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name ");
+ H5G_free_ent_name(&obj_ent);
/* Remove the old name */
if (H5G_unlink(src_loc, src_name)<0)
@@ -2678,10 +2702,10 @@ H5G_free_ent_name(H5G_entry_t *ent)
/* Check args */
assert(ent);
- if ( ent->name )
- ent->name = H5MM_xfree(ent->name);
- if ( ent->old_name )
- ent->old_name = H5MM_xfree(ent->old_name);
+ if(ent->user_path)
+ ent->user_path = H5MM_xfree(ent->user_path);
+ if(ent->canon_path)
+ ent->canon_path = H5MM_xfree(ent->canon_path);
done:
FUNC_LEAVE(ret_value);
@@ -2689,69 +2713,14 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5G_insert_name
- *
- * Purpose: Insert a name into the symbol entry OBJ, located at LOC
- *
- * Return: Success: 0, Failure: -1
- *
- * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
- *
- * Date: August 22, 2002
- *
- * Comments: The allocated memory (H5MM_malloc) is freed in H5O_close
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_insert_name(H5G_entry_t *loc, H5G_entry_t *obj, const char *name)
-{
- size_t loc_name_len, name_len; /* Length of location's name and name to append */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5G_insert_name, FAIL);
-
- /* Only attempt to build a new name if the location's name exists */
- if(loc->name) {
- loc_name_len = HDstrlen(loc->name);
- name_len = HDstrlen(name);
- assert(name_len>0 && loc_name_len>0);
-
- /* Free the object's name, if it exists */
- if(obj->name)
- obj->name=H5MM_xfree(obj->name);
-
- /* The location's name already has a '/' separator */
- if ('/'==loc->name[loc_name_len-1]) {
- if (NULL==(obj->name = H5MM_malloc (loc_name_len+name_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrcpy(obj->name, loc->name);
- HDstrcat(obj->name, name);
- } /* end if */
- /* The location's name needs a separator */
- else {
- if (NULL==(obj->name = H5MM_malloc (loc_name_len+1+name_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrcpy(obj->name, loc->name);
- HDstrcat(obj->name, "/");
- HDstrcat(obj->name, name);
- } /* end else */
- } /* end if */
-
-done:
- FUNC_LEAVE(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_replace_name
*
* Purpose: Search the list of open IDs and replace names according to a
* particular operation. The operation occured on the LOC
* entry, which had SRC_NAME previously. The new name (if there
- * is one) is DST_NAME.
+ * is one) is DST_NAME. Additional entry location information
+ * (currently only needed for the 'move' operation) is passed
+ * in SRC_LOC and DST_LOC.
*
* Return: Success: 0, Failure: -1
*
@@ -2766,8 +2735,9 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5G_replace_name( int type, H5G_entry_t *loc, const char *src_name,
- const char *dst_name, H5G_names_op_t op )
+H5G_replace_name( int type, H5G_entry_t *loc,
+ const char *src_name, H5G_entry_t *src_loc,
+ const char *dst_name, H5G_entry_t *dst_loc, H5G_names_op_t op )
{
H5G_names_t names; /* Structure to hold operation information for callback */
unsigned search_group=0; /* Flag to indicate that groups are to be searched */
@@ -2781,6 +2751,8 @@ H5G_replace_name( int type, H5G_entry_t *loc, const char *src_name,
names.src_name=src_name;
names.dst_name=dst_name;
names.loc=loc;
+ names.src_loc=src_loc;
+ names.dst_loc=dst_loc;
names.op=op;
/* Determine which types of IDs need to be operated on */
@@ -2840,47 +2812,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5G_rest
- *
- * Purpose: Get the last component of the name
- *
- * Return: Pointer to the last component of a name, if found, otherwise NULL
- *
- * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
- *
- * Date: July 5, 2002
- *
- * Comments:
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static const char *
-H5G_rest(const char *name)
-{
- size_t nchars; /* Number of characters in component */
- const char *rest=NULL; /* Pointer to last component, if found */
-
- FUNC_ENTER_NOINIT(H5G_rest);
-
- /* traverse the name to find the last component */
- while ((name = H5G_component(name, &nchars)) && *name) {
- /* Get pointer to current component of name */
- rest = name;
-
- /* Advance to next component */
- name = rest+nchars;
- } /* end while */
-
-#ifdef LATER
-done:
-#endif /* LATER */
- FUNC_LEAVE(rest);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_common_path
*
* Purpose: Determine if one path is a valid prefix of another path
@@ -2966,8 +2897,8 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
{
const H5G_names_t *names = (const H5G_names_t *)key; /* Get operation's information */
H5G_entry_t *ent = NULL; /* Group entry for object that the ID refers to */
- const char *rest; /* The base name of an object */
- unsigned i; /* Local index variable */
+ H5F_t *top_ent_file; /* Top file in entry's mounted file chain */
+ H5F_t *top_loc_file; /* Top file in location's mounted file chain */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5G_replace_ent);
@@ -2997,68 +2928,30 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
} /* end switch */
assert(ent);
- /* Check if ID's entry is in a mounted file */
- if(ent->file->mtab.parent) {
- /* If the ID's entry's parent file is not in the file we operated on, skip it */
- if(ent->file->mtab.parent->shared != names->loc->file->shared )
- HGOTO_DONE(SUCCEED); /* Do not exit search over IDs */
-
- /* We need to recurse into the child's file for unlink and move operations */
- if(names->op==OP_UNLINK || names->op==OP_MOVE) {
- H5F_t *parent_file=ent->file->mtab.parent; /* Pointer to the parent's file info */
-
- /* Search through mounted files for the one which contains the ID's entry */
- for(i=0; i<parent_file->mtab.nmounts; i++) {
- H5F_mount_t *child_mnt = &parent_file->mtab.child[i]; /* Mount information for child file */
- H5F_t *child_file = child_mnt->file; /* Child's file info */
-
- /* we found the right file */
- if(ent->file->shared == child_file->shared ) {
- H5G_entry_t *child_grp_ent = &child_mnt->group->ent; /* Mount point's group entry */
- size_t child_len; /* Length of mount point's name */
- size_t dst_offset=0; /* Offset into destination name */
-
- /* Get the length of the child group's name (i.e. the mount point's name in parent group) */
- child_len = HDstrlen(child_grp_ent->name);
-
- /* Find the prefix of the name */
- if(HDstrncmp( child_grp_ent->name, names->src_name, child_len) == 0) {
- /* Advance the offset in the destination also for moves in mounted files */
- if (names->op==OP_MOVE)
- dst_offset=child_len;
-
- /* Search the open ID list and replace names */
- if (H5G_replace_name( H5G_UNKNOWN, child_grp_ent,
- names->src_name+child_len, names->dst_name+dst_offset,
- names->op )<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name");
- } /* end if */
- } /* end if */
- } /* end for */
- } /* end if */
- } /* end if */
- /* Verify if file IDs refer to the same file */
- else {
- /* If the ID's entry is not in the file we operated on, skip it */
- if( ent->file->shared != names->loc->file->shared )
- HGOTO_DONE(SUCCEED); /* Do not exit search over IDs */
- } /* end else */
-
- /* Get the type of call we are doing */
switch(names->op) {
/*-------------------------------------------------------------------------
* OP_MOUNT
*-------------------------------------------------------------------------
*/
case OP_MOUNT:
- /* Find entries that might contain part of this name */
- if(ent->name) {
- if(HDstrstr(ent->name, names->src_name)) {
- /* Keep the old name for when file is unmounted */
- ent->old_name = ent->name;
-
- /* Set the new name for the object */
- ent->name=H5MM_xstrdup(names->dst_name);
+ if(ent->file->mtab.parent && HDstrcmp(ent->user_path,ent->canon_path)) {
+ /* Find the "top" file in the chain of mounted files */
+ top_ent_file=ent->file->mtab.parent;
+ while(top_ent_file->mtab.parent!=NULL) {
+ top_ent_file=top_ent_file->mtab.parent;
+ } /* end while */
+ } /* end if */
+ else
+ top_ent_file=ent->file;
+
+ /* Check for entry being in correct file (or mounted file) */
+ if(top_ent_file->shared == names->loc->file->shared) {
+ /* Check if the source is along the entry's path */
+ /* (But not actually the entry itself) */
+ if(H5G_common_path(ent->user_path,names->src_name) &&
+ HDstrcmp(ent->user_path,names->src_name)!=0) {
+ /* Hide the user path */
+ ent->user_path_hidden++;
} /* end if */
} /* end if */
break;
@@ -3068,28 +2961,44 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
*-------------------------------------------------------------------------
*/
case OP_UNMOUNT:
- /* Find entries that might contain part of current name */
- if(ent->name) {
- if(HDstrstr(ent->name, names->src_name)) {
- /* Delete the old name */
- H5MM_xfree(ent->name);
-
- /* Copy the new name */
- ent->name=H5MM_xstrdup(names->dst_name);
- } /* end if */
- } /* end if*/
-
- /* See if the entry old name matches */
- if(ent->old_name) {
- if(HDstrstr(ent->old_name, names->src_name)) {
- /* Delete the old name */
- H5MM_xfree(ent->name);
-
- /* Copy the old name to the entry */
- ent->name = ent->old_name;
- ent->old_name = NULL;
+ if(ent->file->mtab.parent) {
+ /* Find the "top" file in the chain of mounted files for the entry */
+ top_ent_file=ent->file->mtab.parent;
+ while(top_ent_file->mtab.parent!=NULL) {
+ top_ent_file=top_ent_file->mtab.parent;
+ } /* end while */
+ } /* end if */
+ else
+ top_ent_file=ent->file;
+
+ if(names->loc->file->mtab.parent) {
+ /* Find the "top" file in the chain of mounted files for the location */
+ top_loc_file=names->loc->file->mtab.parent;
+ while(top_loc_file->mtab.parent!=NULL) {
+ top_loc_file=top_loc_file->mtab.parent;
+ } /* end while */
+ } /* end if */
+ else
+ top_loc_file=names->loc->file;
+
+ if(ent->user_path_hidden) {
+ /* If the ID's entry is not in the file we operated on, skip it */
+ if(top_ent_file->shared == top_loc_file->shared) {
+ if(H5G_common_path(ent->user_path,names->src_name)) {
+ /* Un-hide the user path */
+ ent->user_path_hidden--;
+ } /* end if */
} /* end if */
} /* end if */
+ else {
+ /* If the ID's entry is not in the file we operated on, skip it */
+ if(top_ent_file->shared == top_loc_file->shared) {
+ if(ent->user_path && H5G_common_path(ent->user_path,names->src_name)) {
+ /* Free user path */
+ ent->user_path=H5MM_xfree(ent->user_path);
+ } /* end if */
+ } /* end if */
+ } /* end else */
break;
/*-------------------------------------------------------------------------
@@ -3097,21 +3006,24 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
*-------------------------------------------------------------------------
*/
case OP_UNLINK:
- if(ent->name) {
- /* Found the correct entry, just replace the name */
- if(HDstrcmp(ent->name, names->src_name)==0) {
- /* Delete the old name */
- H5MM_xfree(ent->name);
-
- /* Copy destination name */
- ent->name=H5MM_xstrdup(names->dst_name);
+ /* If the ID's entry is not in the file we operated on, skip it */
+ if(ent->file->shared == names->loc->file->shared) {
+ /* Check if we are referring to the same object */
+ if(H5F_addr_eq(ent->header, names->loc->header)) {
+ /* Check if the object was opened with the same canonical path as the one being moved */
+ if(HDstrcmp(ent->canon_path,names->loc->canon_path)==0) {
+ /* Free user path */
+ ent->user_path=H5MM_xfree(ent->user_path);
+ } /* end if */
} /* end if */
- /* Find other entries that might contain part of this name */
else {
- if(H5G_common_path(ent->name, names->src_name))
- ent->name=H5MM_xfree(ent->name); /* Delete the old name and clear the entry */
+ /* Check if the location being unlinked is in the canonical path for the current object */
+ if(H5G_common_path(ent->canon_path,names->loc->canon_path)) {
+ /* Free user path */
+ ent->user_path=H5MM_xfree(ent->user_path);
+ } /* end if */
} /* end else */
- } /* end if*/
+ } /* end if */
break;
/*-------------------------------------------------------------------------
@@ -3119,32 +3031,172 @@ H5G_replace_ent(void *obj_ptr, hid_t obj_id, const void *key)
*-------------------------------------------------------------------------
*/
case OP_MOVE: /* H5Gmove case, check for relative names case */
- if(ent->name) {
- /* Verify if we have the wanted entry */
- if(HDstrcmp(ent->name, names->src_name)==0) {
- /* Delete the old name */
- H5MM_xfree(ent->name);
-
- /* Set the new name */
- ent->name=H5MM_xstrdup(names->dst_name);
+ /* If the ID's entry is not in the file we operated on, skip it */
+ if(ent->file->shared == names->loc->file->shared) {
+ char *src_path; /* Full user path of source name */
+ char *dst_path; /* Full user path of destination name */
+ char *canon_src_path; /* Pointer to canonical part of source path */
+ char *canon_dst_path; /* Pointer to canonical part of destination path */
+
+ /* Make certain that the source and destination names are full (not relative) paths */
+ if(*(names->src_name)!='/') {
+ size_t src_path_len; /* Length of the source path */
+ unsigned need_sep; /* Flag to indicate if separator is needed */
+
+ /* Get the length of the name for the source group's user path */
+ src_path_len=HDstrlen(names->src_loc->user_path);
+
+ /* Determine if there is a trailing separator in the name */
+ if(names->src_loc->user_path[src_path_len-1]=='/')
+ need_sep=0;
+ else
+ need_sep=1;
+
+ /* Add in the length needed for the '/' separator and the relative path */
+ src_path_len+=HDstrlen(names->src_name)+need_sep;
+
+ /* Allocate space for the path */
+ if(NULL==(src_path = H5MM_malloc(src_path_len+1)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+
+ HDstrcpy(src_path,names->src_loc->user_path);
+ if(need_sep)
+ HDstrcat(src_path,"/");
+ HDstrcat(src_path,names->src_name);
+ } /* end if */
+ else
+ src_path=HDstrdup(names->src_name);
+ if(*(names->dst_name)!='/') {
+ size_t dst_path_len; /* Length of the destination path */
+ unsigned need_sep; /* Flag to indicate if separator is needed */
+
+ /* Get the length of the name for the destination group's user path */
+ dst_path_len=HDstrlen(names->dst_loc->user_path);
+
+ /* Determine if there is a trailing separator in the name */
+ if(names->dst_loc->user_path[dst_path_len-1]=='/')
+ need_sep=0;
+ else
+ need_sep=1;
+
+ /* Add in the length needed for the '/' separator and the relative path */
+ dst_path_len+=HDstrlen(names->dst_name)+need_sep;
+
+ /* Allocate space for the path */
+ if(NULL==(dst_path = H5MM_malloc(dst_path_len+1)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+
+ HDstrcpy(dst_path,names->dst_loc->user_path);
+ if(need_sep)
+ HDstrcat(dst_path,"/");
+ HDstrcat(dst_path,names->dst_name);
+ } /* end if */
+ else
+ dst_path=HDstrdup(names->dst_name);
+
+ /* Get the canonical parts of the source and destination names */
+
+ /* Check if the object being moved was accessed through a mounted file */
+ if(HDstrcmp(names->loc->user_path,names->loc->canon_path)!=0) {
+ size_t non_canon_name_len; /* Length of non-canonical part of name */
+
+ /* Get current string lengths */
+ non_canon_name_len=HDstrlen(names->loc->user_path)-HDstrlen(names->loc->canon_path);
+
+ canon_src_path=src_path+non_canon_name_len;
+ canon_dst_path=dst_path+non_canon_name_len;
} /* end if */
else {
- /* Get the last component of the name */
- rest=H5G_rest(ent->name);
-
- /* Relative names case, build the full pathname */
- if(rest && HDstrcmp(rest, names->src_name)==0) {
- size_t ent_name_len = HDstrlen(ent->name); /* Length of entry's full pathname */
- size_t rest_len = HDstrlen(rest); /* Length of entry's last component of pathname */
-
- /* Reallocate buffer for entry's name */
- ent->name=H5MM_realloc(ent->name,
- ent_name_len+(HDstrlen(names->dst_name)-rest_len)+1);
-
- /* Overwrite last component of name */
- HDstrcpy(ent->name+(ent_name_len-rest_len),names->dst_name);
- } /* Relative names case */
- } /* wanted entry */
+ canon_src_path=src_path;
+ canon_dst_path=dst_path;
+ } /* end else */
+
+ /* Check if the link being changed in the file is along the canonical path for this object */
+ if(H5G_common_path(ent->canon_path,canon_src_path)) {
+ size_t user_dst_len; /* Length of destination user path */
+ size_t canon_dst_len; /* Length of destination canonical path */
+ char *old_user_path; /* Pointer to previous user path */
+ char *tail_path; /* Pointer to "tail" of path */
+ size_t tail_len; /* Pointer to "tail" of path */
+ char *src_canon_prefix; /* Pointer to source canonical path prefix of component which is moving */
+ size_t src_canon_prefix_len;/* Length of the source canonical path prefix */
+ char *dst_canon_prefix; /* Pointer to destination canonical path prefix of component which is moving */
+ size_t dst_canon_prefix_len;/* Length of the destination canonical path prefix */
+ char *user_prefix; /* Pointer to user path prefix of component which is moving */
+ size_t user_prefix_len; /* Length of the user path prefix */
+ char *src_comp; /* The source name of the component which is actually changing */
+ char *dst_comp; /* The destination name of the component which is actually changing */
+
+ /* Get the source & destination components */
+ src_comp=HDstrrchr(canon_src_path,'/');
+ assert(src_comp);
+ dst_comp=HDstrrchr(canon_dst_path,'/');
+ assert(dst_comp);
+
+ /* Find the canonical prefixes for the entry */
+ src_canon_prefix_len=HDstrlen(canon_src_path)-HDstrlen(src_comp);
+ if(NULL==(src_canon_prefix = H5MM_malloc(src_canon_prefix_len+1)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ HDstrncpy(src_canon_prefix,canon_src_path,src_canon_prefix_len);
+ src_canon_prefix[src_canon_prefix_len]='\0';
+
+ dst_canon_prefix_len=HDstrlen(canon_dst_path)-HDstrlen(dst_comp);
+ if(NULL==(dst_canon_prefix = H5MM_malloc(dst_canon_prefix_len+1)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ HDstrncpy(dst_canon_prefix,canon_dst_path,dst_canon_prefix_len);
+ dst_canon_prefix[dst_canon_prefix_len]='\0';
+
+ /* Find the user prefix for the entry */
+ user_prefix_len=HDstrlen(ent->user_path)-HDstrlen(ent->canon_path);
+ if(NULL==(user_prefix = H5MM_malloc(user_prefix_len+1)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ HDstrncpy(user_prefix,ent->user_path,user_prefix_len);
+ user_prefix[user_prefix_len]='\0';
+
+ /* Hold this for later use */
+ old_user_path=ent->user_path;
+
+ /* Set the tail path info */
+ tail_path=old_user_path+user_prefix_len+src_canon_prefix_len+HDstrlen(src_comp);
+ tail_len=HDstrlen(tail_path);
+
+ /* Free the old canonical path */
+ H5MM_xfree(ent->canon_path);
+
+ /* Get the length of the destination paths */
+ user_dst_len=user_prefix_len+dst_canon_prefix_len+HDstrlen(dst_comp)+tail_len;
+ canon_dst_len=dst_canon_prefix_len+HDstrlen(dst_comp)+tail_len;
+
+ /* Allocate space for the new user path */
+ if(NULL==(ent->user_path = H5MM_malloc(user_dst_len+1)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+
+ /* Allocate space for the new canonical path */
+ if(NULL==(ent->canon_path = H5MM_malloc(canon_dst_len+1)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+
+ /* Create the new names */
+ HDstrcpy(ent->user_path,user_prefix);
+ HDstrcat(ent->user_path,dst_canon_prefix);
+ HDstrcat(ent->user_path,dst_comp);
+ HDstrcat(ent->user_path,tail_path);
+ HDstrcpy(ent->canon_path,dst_canon_prefix);
+ HDstrcat(ent->canon_path,dst_comp);
+ HDstrcat(ent->canon_path,tail_path);
+
+ /* Free the old user path */
+ H5MM_xfree(old_user_path);
+
+ /* Free the extra paths allocated */
+ H5MM_xfree(src_canon_prefix);
+ H5MM_xfree(dst_canon_prefix);
+ H5MM_xfree(user_prefix);
+ } /* end if */
+
+
+ /* Free the extra paths allocated */
+ H5MM_xfree(src_path);
+ H5MM_xfree(dst_path);
} /* end if */
break;
diff --git a/src/H5Gent.c b/src/H5Gent.c
index 205f616..4e0a4f9 100644
--- a/src/H5Gent.c
+++ b/src/H5Gent.c
@@ -352,12 +352,28 @@ done:
* Comments:
*
* Modifications:
+ * Quincey Koziol, Sept. 25, 2002:
+ * - Changed source & destination parameters to match the rest
+ * of the functions in the library.
+ * - Added 'depth' parameter to determine how much of the group
+ * entry structure we want to copy. The new depths are:
+ * H5G_COPY_LIMITED - Copy all the fields from the
+ * source to the destination, except for the user path
+ * field, keeping it the same as its
+ * previous value in the destination.
+ * H5G_COPY_SHALLOW - Copy all the fields from the source
+ * to the destination, including the user path and
+ * canonical path.
+ * H5G_COPY_DEEP - Copy all the fields from the source to
+ * the destination, deep copying the user and canonical
+ * paths.
*
*-------------------------------------------------------------------------
*/
herr_t
-H5G_ent_copy( const H5G_entry_t *src, H5G_entry_t *dst )
+H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src, H5G_ent_copy_depth_t depth)
{
+ char *tmp_user_path=NULL; /* Temporary string pointers for entry's user path */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_ent_copy, FAIL);
@@ -366,12 +382,23 @@ H5G_ent_copy( const H5G_entry_t *src, H5G_entry_t *dst )
assert( src );
assert( dst );
+ /* If the depth is "very shallow", keep the old entry's user path */
+ if(depth==H5G_COPY_LIMITED) {
+ tmp_user_path=dst->user_path;
+ H5MM_xfree(dst->canon_path);
+ } /* end if */
+
/* Copy the top level information */
HDmemcpy(dst,src,sizeof(H5G_entry_t));
/* Deep copy the names */
- dst->name=H5MM_xstrdup(src->name);
- dst->old_name=H5MM_xstrdup(src->old_name);
+ if(depth==H5G_COPY_DEEP) {
+ dst->user_path=H5MM_xstrdup(src->user_path);
+ dst->canon_path=H5MM_xstrdup(src->canon_path);
+ } else if(depth==H5G_COPY_LIMITED) {
+ dst->user_path=tmp_user_path;
+ dst->canon_path=H5MM_xstrdup(src->canon_path);
+ } /* end if */
done:
FUNC_LEAVE(ret_value);
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index ff76674..ca3b973 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -856,7 +856,7 @@ H5G_node_insert(H5F_t *f, haddr_t addr, void UNUSED *_lt_key,
HDmemmove(insert_into->entry + idx + 1,
insert_into->entry + idx,
(insert_into->nsyms - idx) * sizeof(H5G_entry_t));
- H5G_ent_copy(&(bt_udata->ent), &(insert_into->entry[idx])); /* Deep copy the entry */
+ H5G_ent_copy(&(insert_into->entry[idx]), &(bt_udata->ent),H5G_COPY_DEEP);
insert_into->entry[idx].dirty = TRUE;
insert_into->nsyms += 1;
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 4b91daf..1028764 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -95,8 +95,9 @@ typedef struct H5G_entry_t {
H5G_type_t type; /*type of information cached */
H5G_cache_t cache; /*cached data from object header */
H5F_t *file; /*file to which this obj hdr belongs */
- char *name; /*name associated with atom */
- char *old_name; /*old name hidden by a file mount */
+ char *user_path; /* Path to object, as opened by user */
+ char *canon_path; /* Path to object, as found in file */
+ unsigned user_path_hidden; /* Whether the user's path is valid */
} H5G_entry_t;
typedef struct H5G_t H5G_t;
@@ -113,13 +114,20 @@ typedef struct H5G_typeinfo_t {
} H5G_typeinfo_t;
/* Type of operation being performed for call to H5G_replace_name() */
-typedef enum H5G_names_op_t {
+typedef enum {
OP_MOVE = 0, /* H5*move call */
OP_UNLINK, /* H5Gunlink call */
OP_MOUNT, /* H5Fmount call */
OP_UNMOUNT /* H5Funmount call */
} H5G_names_op_t;
+/* Depth of group entry copy */
+typedef enum {
+ H5G_COPY_LIMITED, /* Limited copy from source to destination, omitting name & old name fields */
+ H5G_COPY_SHALLOW, /* Copy from source to destination, including name & old name fields */
+ H5G_COPY_DEEP /* Deep copy from source to destination, including duplicating name & old name fields */
+} H5G_ent_copy_depth_t;
+
/*
* Library prototypes... These are the ones that other packages routinely
* call.
@@ -159,16 +167,14 @@ H5_DLL herr_t H5G_unlink(H5G_entry_t *loc, const char *name);
H5_DLL herr_t H5G_find(H5G_entry_t *loc, const char *name,
H5G_entry_t *grp_ent/*out*/, H5G_entry_t *ent/*out*/);
H5_DLL H5F_t *H5G_insertion_file(H5G_entry_t *loc, const char *name);
-H5_DLL herr_t H5G_traverse_slink(H5G_entry_t *grp_ent/*in,out*/,
- H5G_entry_t *obj_ent/*in,out*/,
- int *nlinks/*in,out*/);
H5_DLL herr_t H5G_ent_encode(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent);
H5_DLL herr_t H5G_ent_decode(H5F_t *f, const uint8_t **pp,
H5G_entry_t *ent/*out*/);
-H5_DLL herr_t H5G_replace_name(int type, H5G_entry_t *loc, const char *src_name,
- const char *dst_name, H5G_names_op_t op);
-H5_DLL herr_t H5G_insert_name(H5G_entry_t *loc, H5G_entry_t *obj, const char *name);
-H5_DLL herr_t H5G_ent_copy(const H5G_entry_t *src, H5G_entry_t *dst );
+H5_DLL herr_t H5G_replace_name(int type, H5G_entry_t *loc,
+ const char *src_name, H5G_entry_t *src_loc,
+ const char *dst_name, H5G_entry_t *dst_loc, H5G_names_op_t op);
+H5_DLL herr_t H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src,
+ H5G_ent_copy_depth_t depth);
H5_DLL herr_t H5G_free_grp_name(H5G_t *grp);
H5_DLL herr_t H5G_free_ent_name(H5G_entry_t *ent);
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index bc7c949..12d0ccb 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -21,6 +21,10 @@
static int interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+/* Private prototypes */
+static herr_t H5G_insert_name(H5G_entry_t *loc, H5G_entry_t *obj,
+ const char *name);
+
/*-------------------------------------------------------------------------
* Function: H5G_stab_create
@@ -157,7 +161,7 @@ H5G_stab_find(H5G_entry_t *grp_ent, const char *name,
else {
if (obj_ent) {
/* do a deep copy */
- if (H5G_ent_copy( &(udata.ent), obj_ent )<0)
+ if (H5G_ent_copy(obj_ent, &(udata.ent),H5G_COPY_DEEP)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to copy entry");
/* insert the name into the symbol entry OBJ_ENT */
@@ -210,13 +214,17 @@ H5G_stab_insert(H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent)
if (grp_ent->file->shared != obj_ent->file->shared)
HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "interfile hard links are not allowed");
+ /* insert the name into the symbol entry OBJ_ENT */
+ if(H5G_insert_name(grp_ent, obj_ent, name) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot insert name");
+
/* initialize data to pass through B-tree */
if (NULL == H5O_read(grp_ent, H5O_STAB, 0, &stab))
HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table");
udata.operation = H5G_OPER_INSERT;
udata.name = name;
udata.heap_addr = stab.heap_addr;
- udata.ent = *obj_ent; /* Shallow copy here, deep copy happens in H5G_node_insert() callback() */
+ H5G_ent_copy(&(udata.ent),obj_ent,H5G_COPY_SHALLOW); /* Shallow copy here, deep copy happens in H5G_node_insert() callback() */
/* insert */
if (H5B_insert(grp_ent->file, H5B_SNODE, stab.btree_addr, split_ratios, &udata) < 0)
@@ -225,10 +233,6 @@ H5G_stab_insert(H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent)
/* update the name offset in the entry */
obj_ent->name_off = udata.ent.name_off;
- /* insert the name into the symbol entry OBJ_ENT */
- if(H5G_insert_name(grp_ent, obj_ent, name) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot insert name");
-
done:
FUNC_LEAVE(ret_value);
}
@@ -272,7 +276,95 @@ H5G_stab_remove(H5G_entry_t *grp_ent, const char *name)
if (H5B_remove(grp_ent->file, H5B_SNODE, stab.btree_addr, &udata)<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry");
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_insert_name
+ *
+ * Purpose: Insert a name into the symbol entry OBJ, located at LOC
+ *
+ * Return: Success: 0, Failure: -1
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: August 22, 2002
+ *
+ * Comments: The allocated memory (H5MM_malloc) is freed in H5O_close
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_insert_name(H5G_entry_t *loc, H5G_entry_t *obj, const char *name)
+{
+ size_t name_len; /* Length of name to append */
+ size_t user_path_len; /* Length of location's user path name */
+ size_t canon_path_len; /* Length of location's canonical path name */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5G_insert_name, FAIL);
+
+ assert(loc);
+ assert(obj);
+ assert(name);
+
+ /* Only attempt to build a new name if the location's name exists */
+ if(loc->canon_path) {
+
+ /* Reset the object's previous names, if they exist */
+ H5MM_xfree(obj->user_path);
+ H5MM_xfree(obj->canon_path);
+ obj->user_path_hidden=0;
+
+ /* Get the length of the strings involved */
+ user_path_len = HDstrlen(loc->user_path);
+ canon_path_len = HDstrlen(loc->canon_path);
+ name_len = HDstrlen(name);
+
+ /* Modify the object's user path */
+
+ /* The location's user path already ends in a '/' separator */
+ if ('/'==loc->user_path[user_path_len-1]) {
+ if (NULL==(obj->user_path = H5MM_malloc (user_path_len+name_len+1)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ HDstrcpy(obj->user_path, loc->user_path);
+ } /* end if */
+ /* The location's user path needs a separator */
+ else {
+ if (NULL==(obj->user_path = H5MM_malloc (user_path_len+1+name_len+1)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ HDstrcpy(obj->user_path, loc->user_path);
+ HDstrcat(obj->user_path, "/");
+ } /* end else */
+
+ /* Append the component's name */
+ HDstrcat(obj->user_path, name);
+
+ /* Modify the object's canonical path */
+
+ /* The location's canonical path already ends in a '/' separator */
+ if ('/'==loc->canon_path[canon_path_len-1]) {
+ if (NULL==(obj->canon_path = H5MM_malloc (canon_path_len+name_len+1)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ HDstrcpy(obj->canon_path, loc->canon_path);
+ } /* end if */
+ /* The location's canonical path needs a separator */
+ else {
+ if (NULL==(obj->canon_path = H5MM_malloc (canon_path_len+1+name_len+1)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ HDstrcpy(obj->canon_path, loc->canon_path);
+ HDstrcat(obj->canon_path, "/");
+ } /* end else */
+
+ /* Append the component's name */
+ HDstrcat(obj->canon_path, name);
+ } /* end if */
done:
FUNC_LEAVE(ret_value);
}
+
diff --git a/src/H5I.c b/src/H5I.c
index f04914a..65d7a90 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -1156,11 +1156,11 @@ H5Iget_name(hid_t id, char *name/*out*/, size_t size)
/* get symbol table entry */
if(NULL!=(ent = H5G_loc(id))) {
- if (ent->name != NULL) {
- len = HDstrlen(ent->name);
+ if (ent->user_path != NULL && ent->user_path_hidden==0) {
+ len = HDstrlen(ent->user_path);
if(name) {
- HDstrncpy(name, ent->name, MIN(len+1,size));
+ HDstrncpy(name, ent->user_path, MIN(len+1,size));
if(len >= size)
name[size-1]='\0';
} /* end if */
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index df0e88d..1d8b254 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -1127,11 +1127,11 @@ H5O_dtype_set_share (H5F_t UNUSED *f, void *_mesg/*in,out*/,
assert (!sh->in_gh);
/* Shallow copy the symbol table entry */
- dt->ent = sh->u.ent;
+ H5G_ent_copy(&(dt->ent),&(sh->u.ent),H5G_COPY_SHALLOW);
/* Reset the names of the copied symbol table entry */
- dt->ent.name = NULL;
- dt->ent.old_name = NULL;
+ dt->ent.user_path = NULL;
+ dt->ent.canon_path = NULL;
/* Note that the datatype is a named datatype */
dt->state = H5T_STATE_NAMED;
diff --git a/src/H5T.c b/src/H5T.c
index e297263..3cfe306 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -5360,7 +5360,8 @@ H5T_open_oid (H5G_entry_t *ent)
/* Mark the type as named and open */
dt->state = H5T_STATE_OPEN;
- dt->ent = *ent;
+ /* Shallow copy (take ownership) of the group entry object */
+ H5G_ent_copy(&(dt->ent),ent,H5G_COPY_SHALLOW);
/* Set return value */
ret_value=dt;
@@ -5577,7 +5578,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
} /* end switch */
/* Deep copy of the symbol table entry */
- if (H5G_ent_copy(&(old_dt->ent),&(new_dt->ent))<0)
+ if (H5G_ent_copy(&(new_dt->ent), &(old_dt->ent),H5G_COPY_DEEP)<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to copy entry");
/* Set return value */
@@ -5782,7 +5783,7 @@ H5T_close(H5T_t *dt)
break;
}
- /*Free the ID to name buffer */
+ /* Free the ID to name info */
H5G_free_ent_name(&(dt->ent));
/* Free the datatype struct */