diff options
-rw-r--r-- | release_docs/RELEASE.txt | 7 | ||||
-rw-r--r-- | src/H5Dint.c | 2 | ||||
-rw-r--r-- | src/H5E.c | 2 | ||||
-rw-r--r-- | src/H5F.c | 30 | ||||
-rw-r--r-- | src/H5Fprivate.h | 4 | ||||
-rw-r--r-- | src/H5Gname.c | 6 | ||||
-rw-r--r-- | src/H5I.c | 11 | ||||
-rw-r--r-- | src/H5Iprivate.h | 2 | ||||
-rw-r--r-- | src/H5Oattribute.c | 4 | ||||
-rw-r--r-- | src/H5Pint.c | 4 | ||||
-rw-r--r-- | src/H5T.c | 2 | ||||
-rw-r--r-- | src/H5Tconv.c | 68 | ||||
-rw-r--r-- | test/dtypes.c | 180 |
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) @@ -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) @@ -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 */ @@ -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 */ @@ -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(); |