summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt7
-rw-r--r--src/H5Dint.c2
-rw-r--r--src/H5E.c2
-rw-r--r--src/H5F.c30
-rw-r--r--src/H5Fprivate.h4
-rw-r--r--src/H5Gname.c6
-rw-r--r--src/H5I.c11
-rw-r--r--src/H5Iprivate.h2
-rw-r--r--src/H5Oattribute.c4
-rw-r--r--src/H5Pint.c4
-rw-r--r--src/H5T.c2
-rw-r--r--src/H5Tconv.c68
-rw-r--r--test/dtypes.c180
13 files changed, 246 insertions, 76 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 473df55..c0cc931 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -93,6 +93,9 @@ New Features
the same. (PVN - 2008/08/26)
- h5ls: added capability to traverse through external links when the -r
(recursive) flag is given. (NAF - 2008/09/16)
+ - h5ls: added -E option to enable traversal of external links. h5ls will
+ not traverse external links without this flag being set.
+ (NAF - 2008/10/06)
@@ -111,6 +114,10 @@ Bug Fixes since HDF5-1.8.0 release
Library
-------
+ - Changed H5Fget_obj_count and H5Fget_obj_ids to ignore objects registered
+ by the library for internal library use. (NAF - 2008/10/06)
+ - Fixed potential memory leak during compound conversion.
+ (NAF - 2008/10/06)
- Changed the return value of H5Fget_obj_count from INT to SSIZE_T. Also
changed the return value of H5Fget_obj_ids from HERR_T to SSIZE_T and
the type of the parameter MAX_OBJS from INT to SIZE_T. (SLU - 2008/09/26)
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 7a2dcc9..bab3038 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -2570,7 +2570,7 @@ H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags)
udata.flags = flags;
/* Iterate over all the open datasets */
- H5I_search(H5I_DATASET, H5D_flush_cb, &udata);
+ H5I_search(H5I_DATASET, H5D_flush_cb, &udata, FALSE);
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5E.c b/src/H5E.c
index 2aaa342..6eb7768 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -501,7 +501,7 @@ H5E_unregister_class(H5E_cls_t *cls)
/* Iterate over all the messages and delete those in this error class */
/* (Ignore return value, since callback isn't designed to return a particular object) */
- (void)H5I_search(H5I_ERROR_MSG, H5E_close_msg_cb, cls);
+ (void)H5I_search(H5I_ERROR_MSG, H5E_close_msg_cb, cls, FALSE);
/* Free error class structure */
if(cls->cls_name)
diff --git a/src/H5F.c b/src/H5F.c
index 083adcc..02687eb 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -64,7 +64,7 @@ typedef struct H5F_olist_t {
} H5F_olist_t;
/* PRIVATE PROTOTYPES */
-static size_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list);
+static size_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref);
static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
static herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void** file_handle);
static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id,
@@ -393,7 +393,7 @@ H5Fget_obj_count(hid_t file_id, unsigned types)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type")
/* H5F_get_obj_count doesn't fail */
- ret_value = H5F_get_obj_count(f, types);
+ ret_value = H5F_get_obj_count(f, types, TRUE);
done:
FUNC_LEAVE_API(ret_value)
@@ -420,14 +420,14 @@ done:
*-------------------------------------------------------------------------
*/
size_t
-H5F_get_obj_count(const H5F_t *f, unsigned types)
+H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref)
{
size_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_count)
/* H5F_get_objects doesn't fail */
- ret_value=H5F_get_objects(f, types, 0, NULL);
+ ret_value=H5F_get_objects(f, types, 0, NULL, app_ref);
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -467,7 +467,7 @@ H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list)
HDassert(oid_list);
/* H5F_get_objects doesn't fail */
- ret_value = H5F_get_obj_ids(f, types, max_objs, oid_list);
+ ret_value = H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE);
done:
FUNC_LEAVE_API(ret_value)
@@ -493,14 +493,14 @@ done:
*-------------------------------------------------------------------------
*/
size_t
-H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list)
+H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref)
{
size_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_ids)
/* H5F_get_objects doesn't fail */
- ret_value = H5F_get_objects(f, types, max_objs, oid_list);
+ ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref);
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -522,7 +522,7 @@ H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list
*---------------------------------------------------------------------------
*/
static size_t
-H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list)
+H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref)
{
size_t obj_id_count=0; /* Number of open IDs */
H5F_olist_t olist; /* Structure to hold search results */
@@ -551,35 +551,35 @@ H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_
* is found, so don't return failure in this function. */
if(types & H5F_OBJ_FILE) {
olist.obj_type = H5I_FILE;
- (void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist);
+ (void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist, app_ref);
} /* end if */
/* Search through dataset IDs to count number of datasets, and put their
* IDs on the object list */
if(types & H5F_OBJ_DATASET) {
olist.obj_type = H5I_DATASET;
- (void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist);
+ (void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref);
}
/* Search through group IDs to count number of groups, and put their
* IDs on the object list */
if(types & H5F_OBJ_GROUP) {
olist.obj_type = H5I_GROUP;
- (void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist);
+ (void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref);
}
/* Search through datatype IDs to count number of named datatypes, and put their
* IDs on the object list */
if(types & H5F_OBJ_DATATYPE) {
olist.obj_type = H5I_DATATYPE;
- (void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist);
+ (void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref);
}
/* Search through attribute IDs to count number of attributes, and put their
* IDs on the object list */
if(types & H5F_OBJ_ATTR) {
olist.obj_type = H5I_ATTR;
- (void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist);
+ (void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref);
}
/* Set the number of objects currently open */
@@ -1964,7 +1964,7 @@ H5F_try_close(H5F_t *f)
unsigned u; /* Local index variable */
/* Get the list of IDs of open dataset, group, & attribute objects */
- while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs)) != 0) {
+ while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs, FALSE)) != 0) {
/* Try to close all the open objects in this file */
for(u = 0; u < obj_count; u++)
if(H5I_dec_ref(objs[u], FALSE) < 0)
@@ -1976,7 +1976,7 @@ H5F_try_close(H5F_t *f)
* they could be using one of the named datatypes and then the
* open named datatype ID will get closed twice)
*/
- while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs)) != 0) {
+ while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs, FALSE)) != 0) {
/* Try to close all the open objects in this file */
for(u = 0; u < obj_count; u++)
if(H5I_dec_ref(objs[u], FALSE) < 0)
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index cb716fc..d975167 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -471,8 +471,8 @@ H5_DLL unsigned H5F_get_intent(const H5F_t *f);
H5_DLL char *H5F_get_extpath(const H5F_t *f);
H5_DLL herr_t H5F_get_fileno(const H5F_t *f, unsigned long *filenum);
H5_DLL hid_t H5F_get_id(H5F_t *file, hbool_t app_ref);
-H5_DLL size_t H5F_get_obj_count(const H5F_t *f, unsigned types);
-H5_DLL size_t H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list);
+H5_DLL size_t H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref);
+H5_DLL size_t H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref);
H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f);
H5_DLL haddr_t H5F_get_eoa(const H5F_t *f);
#ifdef H5_HAVE_PARALLEL
diff --git a/src/H5Gname.c b/src/H5Gname.c
index d745b87..0634aef 100644
--- a/src/H5Gname.c
+++ b/src/H5Gname.c
@@ -1009,15 +1009,15 @@ H5G_name_replace(const H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file,
/* Search through group IDs */
if(search_group)
- H5I_search(H5I_GROUP, H5G_name_replace_cb, &names);
+ H5I_search(H5I_GROUP, H5G_name_replace_cb, &names, FALSE);
/* Search through dataset IDs */
if(search_dataset)
- H5I_search(H5I_DATASET, H5G_name_replace_cb, &names);
+ H5I_search(H5I_DATASET, H5G_name_replace_cb, &names, FALSE);
/* Search through datatype IDs */
if(search_datatype)
- H5I_search(H5I_DATATYPE, H5G_name_replace_cb, &names);
+ H5I_search(H5I_DATATYPE, H5G_name_replace_cb, &names, FALSE);
} /* end if */
} /* end if */
diff --git a/src/H5I.c b/src/H5I.c
index 8cc2910..40fec88 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -1877,7 +1877,7 @@ H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key)
if(H5I_IS_LIB_TYPE(type))
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
- ret_value = H5I_search(type, func, key);
+ ret_value = H5I_search(type, func, key, TRUE);
done:
FUNC_LEAVE_API(ret_value)
@@ -1905,12 +1905,15 @@ done:
* Programmer: Robb Matzke
* Friday, February 19, 1999
*
- * Modifications:
+ * Modifications: Neil Fortner
+ * Wednesday, October 1, 2008
+ * Added app_ref parameter. When set to TRUE, the function will only
+ * operate on ids that have a nonzero application reference count.
*
*-------------------------------------------------------------------------
*/
void *
-H5I_search(H5I_type_t type, H5I_search_func_t func, void *key)
+H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref)
{
H5I_id_type_t *type_ptr; /*ptr to the type */
void *ret_value = NULL; /*return value */
@@ -1935,7 +1938,7 @@ H5I_search(H5I_type_t type, H5I_search_func_t func, void *key)
id_ptr = type_ptr->id_list[i];
while(id_ptr) {
next_id = id_ptr->next; /* Protect against ID being deleted in callback */
- if((*func)(id_ptr->obj_ptr, id_ptr->id, key))
+ if((!app_ref || id_ptr->app_count) && (*func)(id_ptr->obj_ptr, id_ptr->id, key))
HGOTO_DONE(id_ptr->obj_ptr); /*found the item*/
id_ptr = next_id;
} /* end while */
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index f06bf79..0923af7 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -61,7 +61,7 @@ H5_DLL H5I_type_t H5I_get_type(hid_t id);
H5_DLL hid_t H5I_get_file_id(hid_t obj_id, hbool_t app_ref);
H5_DLL void *H5I_remove(hid_t id);
H5_DLL void *H5I_remove_verify(hid_t id, H5I_type_t id_type);
-H5_DLL void *H5I_search(H5I_type_t type, H5I_search_func_t func, void *key);
+H5_DLL void *H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref);
H5_DLL int H5I_get_ref(hid_t id, hbool_t app_ref);
H5_DLL int H5I_inc_ref(hid_t id, hbool_t app_ref);
H5_DLL int H5I_dec_ref(hid_t id, hbool_t app_ref);
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index 71c59f3..846d2ec 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -684,7 +684,7 @@ htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char*
HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number")
/* Count all opened attributes */
- if((num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL)) < 0)
+ if((num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, FALSE)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "can't get number of opened attributes")
/* Find out whether the attribute has been opened */
@@ -692,7 +692,7 @@ htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char*
attr_id_list = (hid_t*)H5MM_malloc(num_open_attr*sizeof(hid_t));
/* Retrieve the IDs of all opened attributes */
- if(H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list) < 0)
+ if(H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list, FALSE) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't IDs of opened attributes")
for(i=0; i<num_open_attr; i++) {
diff --git a/src/H5Pint.c b/src/H5Pint.c
index a7bad06..e522010 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -4348,7 +4348,7 @@ H5P_open_class_path(const char *path)
check_info.name=curr_name;
/* Find the class with this name & parent by iterating over the open classes */
- if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info)))
+ if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info, FALSE)))
HGOTO_ERROR (H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class");
/* Advance the pointer in the path to the start of the next component */
@@ -4362,7 +4362,7 @@ H5P_open_class_path(const char *path)
check_info.name = curr_name;
/* Find the class with this name & parent by iterating over the open classes */
- if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info)))
+ if(NULL == (curr_class = (H5P_genclass_t *)H5I_search(H5I_GENPROP_CLS, H5P_check_class, &check_info, FALSE)))
HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, NULL, "can't locate class")
/* Copy it */
diff --git a/src/H5T.c b/src/H5T.c
index 293a5c5..ee02016 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -1449,7 +1449,7 @@ H5T_term_interface(void)
H5T_g.nsoft = H5T_g.asoft = 0;
/* Unlock all datatypes, then free them */
- H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL);
+ H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL, FALSE);
H5I_dec_type_ref(H5I_DATATYPE);
/* Reset all the datatype IDs */
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index b02e72a..05277a8 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -884,6 +884,7 @@ typedef struct H5T_conv_struct_t {
hid_t *dst_memb_id; /*destination member type ID's */
H5T_path_t **memb_path; /*conversion path for each member */
H5T_subset_info_t subset_info; /*info related to compound subsets */
+ unsigned src_nmembs; /*needed by free function */
} H5T_conv_struct_t;
/* Conversion data for H5T_conv_enum() */
@@ -1751,6 +1752,48 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5T_conv_struct_free
+ *
+ * Purpose: Free the private data structure used by the compound
+ * conversion functions.
+ *
+ * Return: The result of H5MM_xfree(priv) (NULL)
+ *
+ * Programmer: Neil Fortner
+ * Wednesday, October 1, 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5T_conv_struct_t *
+H5T_conv_struct_free(H5T_conv_struct_t *priv)
+{
+ int *src2dst = priv->src2dst;
+ hid_t *src_memb_id = priv->src_memb_id,
+ *dst_memb_id = priv->dst_memb_id;
+ unsigned i;
+ int status;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_conv_struct_free)
+
+ for (i=0; i<priv->src_nmembs; i++)
+ if (src2dst[i] >= 0) {
+ status = H5I_dec_ref(src_memb_id[i], FALSE);
+ HDassert(status >= 0);
+ status = H5I_dec_ref(dst_memb_id[src2dst[i]], FALSE);
+ HDassert(status >= 0);
+ }
+
+ H5MM_xfree(src2dst);
+ H5MM_xfree(src_memb_id);
+ H5MM_xfree(dst_memb_id);
+ H5MM_xfree(priv->memb_path);
+ FUNC_LEAVE_NOAPI(H5MM_xfree(priv));
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_conv_struct_init
*
* Purpose: Initialize the `priv' field of `cdata' with conversion
@@ -1824,6 +1867,7 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id)
NULL == (priv->dst_memb_id = H5MM_malloc(dst_nmembs * sizeof(hid_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
src2dst = priv->src2dst;
+ priv->src_nmembs = src_nmembs;
/* The flag of special optimization to indicate if source members and destination
* members are a subset of each other. Initialize it to FALSE */
@@ -1885,11 +1929,7 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id)
H5T_path_t *tpath = H5T_path_find(src->shared->u.compnd.memb[i].type, dst->shared->u.compnd.memb[src2dst[i]].type, NULL, NULL, dxpl_id, FALSE);
if(NULL == (priv->memb_path[i] = tpath)) {
- H5MM_xfree(priv->src2dst);
- H5MM_xfree(priv->src_memb_id);
- H5MM_xfree(priv->dst_memb_id);
- H5MM_xfree(priv->memb_path);
- cdata->priv = priv = H5MM_xfree (priv);
+ cdata->priv = priv = H5T_conv_struct_free(priv);
HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member datatype")
} /* end if */
} /* end if */
@@ -2073,11 +2113,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
/*
* Free the private conversion data.
*/
- H5MM_xfree(priv->src2dst);
- H5MM_xfree(priv->src_memb_id);
- H5MM_xfree(priv->dst_memb_id);
- H5MM_xfree(priv->memb_path);
- cdata->priv = priv = H5MM_xfree (priv);
+ cdata->priv = priv = H5T_conv_struct_free(priv);
break;
case H5T_CONV_CONV:
@@ -2346,11 +2382,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
if (dst_memb->size > src_memb->size) {
offset -= src_memb->size;
if (dst_memb->size > src->shared->size-offset) {
- H5MM_xfree(priv->src2dst);
- H5MM_xfree(priv->src_memb_id);
- H5MM_xfree(priv->dst_memb_id);
- H5MM_xfree(priv->memb_path);
- cdata->priv = priv = H5MM_xfree (priv);
+ cdata->priv = priv = H5T_conv_struct_free(priv);
HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "convertion is unsupported by this function");
}
}
@@ -2363,11 +2395,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
* Free the private conversion data.
*/
priv = (H5T_conv_struct_t *)(cdata->priv);
- H5MM_xfree(priv->src2dst);
- H5MM_xfree(priv->src_memb_id);
- H5MM_xfree(priv->dst_memb_id);
- H5MM_xfree(priv->memb_path);
- cdata->priv = priv = H5MM_xfree (priv);
+ cdata->priv = priv = H5T_conv_struct_free(priv);
break;
case H5T_CONV_CONV:
diff --git a/test/dtypes.c b/test/dtypes.c
index 674c42f..f58dc90 100644
--- a/test/dtypes.c
+++ b/test/dtypes.c
@@ -23,6 +23,7 @@
#include <math.h>
#include <time.h>
#include "h5test.h"
+#include "H5Iprivate.h" /* For checking that datatype id's don't leak */
/* Number of times to run each test */
#define NTESTS 1
@@ -57,6 +58,27 @@
#define SET_ALIGNMENT(TYPE,VAL) \
H5T_NATIVE_##TYPE##_ALIGN_g=MAX(H5T_NATIVE_##TYPE##_ALIGN_g, VAL)
+/*
+ * Macro for checking that the correct number of datatype ids are present. Be
+ * careful as the call to H5Tunregister removes *ALL* compound conversions from
+ * the soft conversion list. One must call reset_hdf5() after this.
+ */
+#define CHECK_NMEMBS(NMEMBS,SRC_ID,DST_ID) \
+ if (H5Tunregister(H5T_PERS_SOFT, NULL, SRC_ID, DST_ID, NULL) < 0) { \
+ FAIL_STACK_ERROR \
+ goto error; \
+ } \
+ if (H5Tclose(SRC_ID) < 0 || ((SRC_ID) != (DST_ID) && H5Tclose(DST_ID) < 0)) { \
+ FAIL_STACK_ERROR \
+ goto error; \
+ } \
+ if ((NMEMBS) != H5I_nmembers(H5I_DATATYPE)) { \
+ H5_FAILED(); \
+ printf(" #dtype ids expected: %d; found: %d\n", NMEMBS, \
+ H5I_nmembers(H5I_DATATYPE)); \
+ goto error; \
+ }
+
const char *FILENAME[] = {
"dtypes1",
"dtypes2",
@@ -628,6 +650,7 @@ test_compound_1(void)
} /* end if */
if (H5Tclose (complex_id) < 0) goto error;
+
PASSED();
return 0;
@@ -669,10 +692,13 @@ test_compound_2(void)
unsigned char *buf=NULL, *orig=NULL, *bkg=NULL;
hid_t st=-1, dt=-1;
hid_t array_dt;
- int i;
+ int i, nmembs;
TESTING("compound element reordering");
+ if ((nmembs = H5I_nmembers(H5I_DATATYPE)) < 0)
+ FAIL_STACK_ERROR
+
/* Sizes should be the same, but be careful just in case */
buf = (unsigned char*)malloc(nelmts * MAX(sizeof(struct st), sizeof(struct dt)));
bkg = (unsigned char*)malloc(nelmts * sizeof(struct dt));
@@ -742,13 +768,14 @@ test_compound_2(void)
free(buf);
free(bkg);
free(orig);
- if (H5Tclose(st) < 0 || H5Tclose(dt) < 0) goto error;
+ CHECK_NMEMBS(nmembs , st, dt)
PASSED();
reset_hdf5();
return 0;
error:
+ reset_hdf5();
return 1;
}
@@ -786,10 +813,13 @@ test_compound_3(void)
unsigned char *buf=NULL, *orig=NULL, *bkg=NULL;
hid_t st=-1, dt=-1;
hid_t array_dt;
- int i;
+ int i, nmembs;
TESTING("compound subset conversions");
+ if ((nmembs = H5I_nmembers(H5I_DATATYPE)) < 0)
+ FAIL_STACK_ERROR
+
/* Initialize */
buf = (unsigned char*)malloc(nelmts * MAX(sizeof(struct st), sizeof(struct dt)));
bkg = (unsigned char*)malloc(nelmts * sizeof(struct dt));
@@ -856,13 +886,14 @@ test_compound_3(void)
free(buf);
free(bkg);
free(orig);
- if (H5Tclose(st) < 0 || H5Tclose(dt) < 0) goto error;
+ CHECK_NMEMBS(nmembs, st, dt)
PASSED();
reset_hdf5();
return 0;
error:
+ reset_hdf5();
return 1;
}
@@ -904,10 +935,13 @@ test_compound_4(void)
unsigned char *buf=NULL, *orig=NULL, *bkg=NULL;
hid_t st=-1, dt=-1;
hid_t array_dt;
- int i;
+ int i, nmembs;
TESTING("compound element shrinking & reordering");
+ if ((nmembs = H5I_nmembers(H5I_DATATYPE)) < 0)
+ FAIL_STACK_ERROR
+
/* Sizes should be the same, but be careful just in case */
buf = (unsigned char*)malloc(nelmts * MAX(sizeof(struct st), sizeof(struct dt)));
bkg = (unsigned char*)malloc(nelmts * sizeof(struct dt));
@@ -978,13 +1012,14 @@ test_compound_4(void)
free(buf);
free(bkg);
free(orig);
- if (H5Tclose(st) < 0 || H5Tclose(dt) < 0) goto error;
+ CHECK_NMEMBS(nmembs, st, dt)
PASSED();
reset_hdf5();
return 0;
error:
+ reset_hdf5();
return 1;
}
@@ -1133,10 +1168,13 @@ test_compound_6(void)
const size_t nelmts = NTESTELEM;
unsigned char *buf=NULL, *orig=NULL, *bkg=NULL;
hid_t st=-1, dt=-1;
- int i;
+ int i, nmembs;
TESTING("compound element growing");
+ if ((nmembs = H5I_nmembers(H5I_DATATYPE)) < 0)
+ FAIL_STACK_ERROR
+
/* Sizes should be the same, but be careful just in case */
buf = (unsigned char*)malloc(nelmts * MAX(sizeof(struct st), sizeof(struct dt)));
bkg = (unsigned char*)malloc(nelmts * sizeof(struct dt));
@@ -1189,16 +1227,14 @@ test_compound_6(void)
free(buf);
free(bkg);
free(orig);
- if (H5Tclose(st) < 0 || H5Tclose(dt) < 0) {
- H5_FAILED();
- goto error;
- }
+ CHECK_NMEMBS(nmembs, st, dt)
PASSED();
reset_hdf5();
return 0;
error:
+ reset_hdf5();
return 1;
}
@@ -1337,6 +1373,7 @@ test_compound_7(void)
return 0;
error:
+ reset_hdf5();
return 1;
}
@@ -1955,10 +1992,10 @@ test_compound_10(void)
if(H5Dclose(dset_id) < 0)
goto error;
- if(H5Tclose(cmpd_tid) < 0)
- goto error;
if(H5Tclose(arr_tid) < 0)
goto error;
+ if(H5Tclose(cmpd_tid) < 0)
+ goto error;
if(H5Tclose(cstr_id) < 0)
goto error;
if(H5Tclose(vlstr_id) < 0)
@@ -2400,19 +2437,19 @@ static int
test_compound_14(void)
{
typedef struct cmpd_struct_1 {
- char c1;
- char c2;
- char* str;
+ char c1;
+ char c2;
+ char* str;
} cmpd_struct_1;
typedef struct cmpd_struct_2 {
- char c1;
- char c2;
- char* str;
- long l1;
- long l2;
- long l3;
- long l4;
+ char c1;
+ char c2;
+ char* str;
+ long l1;
+ long l2;
+ long l3;
+ long l4;
} cmpd_struct_2;
cmpd_struct_1 wdata1 = {'A', 'B', "variable-length string"};
@@ -2891,7 +2928,101 @@ test_compound_15(void)
error:
return 1;
-} /* end test_compound_14() */
+} /* end test_compound_15() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_compound_16
+ *
+ * Purpose: Tests that committed types that can be registered during
+ * compound conversion are not visible to the application
+ * with H5Fget_obj_count or H5Fget_obj_ids.
+ *
+ * Return: Success: 0
+ *
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Friday, October 3, 2008
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_compound_16(void)
+{
+ typedef struct cmpd_struct {
+ int i1;
+ int i2;
+ } cmpd_struct;
+
+ cmpd_struct wdata1 = {1254, 5471};
+ cmpd_struct rdata;
+ int wdata2[2] = {1, 2};
+ int obj_count;
+ hid_t file;
+ hid_t cmpd_m_tid, cmpd_f_tid, int_id;
+ hid_t space_id;
+ hid_t dset_id;
+ hid_t open_dtypes[2] = {0, 0};
+ hsize_t dim1[1] = {1};
+ char filename[1024];
+
+ TESTING("visibility of internally registered type ids");
+
+ /* Create File */
+ h5_fixname(FILENAME[3], H5P_DEFAULT, filename, sizeof filename);
+ if((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Copy and commit integer datatype */
+ if((int_id = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if(H5Tcommit (file, "int", int_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Create file compound datatype */
+ if((cmpd_f_tid = H5Tcreate(H5T_COMPOUND, 2 * sizeof(int) + 2)) < 0) TEST_ERROR
+ if(H5Tinsert(cmpd_f_tid, "i1", 0, int_id) < 0) TEST_ERROR
+ if(H5Tinsert(cmpd_f_tid, "i2", sizeof(int) + 1, int_id) < 0) TEST_ERROR
+
+ /* Create memory compound datatype */
+ if((cmpd_m_tid = H5Tcreate(H5T_COMPOUND, sizeof(struct cmpd_struct))) < 0) TEST_ERROR
+ if(H5Tinsert(cmpd_m_tid, "i1", HOFFSET(struct cmpd_struct, i1), int_id) < 0) TEST_ERROR
+ if(H5Tinsert(cmpd_m_tid, "i2", HOFFSET(struct cmpd_struct, i2), int_id) < 0) TEST_ERROR
+
+ /* Create space, dataset, write wdata1 */
+ if((space_id = H5Screate_simple(1, dim1, NULL)) < 0) TEST_ERROR
+ if((dset_id = H5Dcreate2(file, "Dataset", cmpd_f_tid, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Dwrite(dset_id, cmpd_m_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata1) < 0) TEST_ERROR
+
+ /* Check behavior of H5Fget_obj_count */
+ if((obj_count = H5Fget_obj_count(file, H5F_OBJ_DATATYPE)) != 1) {
+ H5_FAILED(); AT();
+ printf(" H5Fget_obj_count returned: %d; expected: 1\n", obj_count);
+ goto error;
+ }
+
+ /* Check behavior of H5Fget_obj_ids */
+ if(H5Fget_obj_ids(file, H5F_OBJ_DATATYPE, 2, open_dtypes) < 0) TEST_ERROR
+ if(open_dtypes[1]) {
+ H5_FAILED(); AT();
+ printf(" H5Fget_obj_ids returned as second id: %d; expected: 0\n", open_dtypes[1]);
+ goto error;
+ }
+
+ /* Close */
+ if(H5Dclose(dset_id) < 0) TEST_ERROR
+ if(H5Sclose(space_id) < 0) TEST_ERROR
+ if(H5Tclose(cmpd_f_tid) < 0) TEST_ERROR
+ if(H5Tclose(cmpd_m_tid) < 0) TEST_ERROR
+ if(H5Tclose(int_id) < 0) TEST_ERROR
+ if(H5Fclose(file) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ return 1;
+} /* end test_compound_16() */
/*-------------------------------------------------------------------------
@@ -5587,6 +5718,7 @@ main(void)
nerrors += test_compound_13();
nerrors += test_compound_14();
nerrors += test_compound_15();
+ nerrors += test_compound_16();
nerrors += test_conv_enum_1();
nerrors += test_conv_enum_2();
nerrors += test_conv_bitfield();