From f2d67b4864424bc52e876f709304604352055cd3 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 7 Oct 2002 12:55:55 -0500 Subject: [svn-r5962] Purpose: Bug fix Description: H5Pequal's algorithm for comparing property lists wasn't allowing property lists that are equal but had the properties inserted in a different order in the list's hash table. Solution: Re-did the algorithm a bit to compare the properties better. Platforms tested: FreeBSD 4.6 (sleipnir) (minor enough to not need triple testing) --- src/H5P.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++--------- test/tgenprop.c | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 13 deletions(-) diff --git a/src/H5P.c b/src/H5P.c index bfa1fe7..8713b4e 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -53,6 +53,14 @@ hid_t H5P_LST_DATASET_CREATE_g = FAIL; hid_t H5P_LST_DATASET_XFER_g = FAIL; hid_t H5P_LST_MOUNT_g = FAIL; +/* Local typedefs */ + +/* Typedef for checking for duplicate class names in parent class */ +typedef struct { + const H5P_genclass_t *parent; /* Pointer to parent class */ + const char *name; /* Pointer to name to check */ +} H5P_check_class_t; + /* Local static functions */ static H5P_genclass_t *H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned hashsize, unsigned internal, @@ -1022,6 +1030,51 @@ H5P_access_class(H5P_genclass_t *pclass, H5P_class_mod_t mod) /*-------------------------------------------------------------------------- NAME + H5P_check_class + PURPOSE + Internal callback routine to check for duplicated names in parent class. + USAGE + int H5P_check_class(obj, id, key) + H5P_genclass_t *obj; IN: Pointer to class + hid_t id; IN: ID of object being looked at + const void *key; IN: Pointer to information used to compare + classes. + RETURNS + Returns >0 on match, 0 on no match and <0 on failure. + DESCRIPTION + Checks whether a property list class has the same parent and name as a + new class being created. This is a callback routine for H5I_search() + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static int +H5P_check_class(void *_obj, hid_t id, const void *_key) +{ + H5P_genclass_t *obj=(H5P_genclass_t *)_obj; /* Pointer to the class for this ID */ + const H5P_check_class_t *key=(const H5P_check_class_t *)_key; /* Pointer to key information for comparison */ + int ret_value=0; /* Return value */ + + FUNC_ENTER_NOINIT(H5P_check_class); + + assert(obj); + assert(H5I_GENPROP_CLS==H5I_get_type(id)); + assert(key); + + /* Check if the class object has the same parent as the new class */ + if(obj->parent!=NULL && obj->parent==key->parent) { + /* Check if they have the same name */ + if(HDstrcmp(obj->name,key->name)==0) + ret_value=1; /* Indicate a match */ + } /* end if */ + + FUNC_LEAVE(ret_value); +} /* end H5P_check_class() */ + + +/*-------------------------------------------------------------------------- + NAME H5P_create_class PURPOSE Internal routine to create a new property list class. @@ -1061,7 +1114,7 @@ H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned hashsize, H5P_cls_close_func_t cls_close, void *close_data ) { - H5P_genclass_t *pclass; /* Property list class created */ + H5P_genclass_t *pclass=NULL; /* Property list class created */ H5P_genclass_t *ret_value; /* return value */ FUNC_ENTER_NOINIT(H5P_create_class); @@ -1074,6 +1127,19 @@ H5P_create_class(H5P_genclass_t *par_class, const char *name, unsigned hashsize, assert(hashsize>0); } + /* Check that the class name is unique in the parent class */ + if(par_class!=NULL) { + H5P_check_class_t check_info; /* Structure to hold the information for checking duplicate names */ + + /* Set up the search structure */ + check_info.parent=par_class; + check_info.name=name; + + /* Iterate over the open class IDs and fail if any have the same parent and name */ + if(H5I_search(H5I_GENPROP_CLS,H5P_check_class,&check_info)!=NULL) + HGOTO_ERROR (H5E_PLIST, H5E_DUPCLASS, NULL, "duplicated class name in parent class"); + } /* end if */ + /* Allocate room for the class & it's hash table of properties */ if (NULL==(pclass = H5MM_calloc (sizeof(H5P_genclass_t)+((hashsize-1)*sizeof(H5P_genprop_t *))))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,"memory allocation failed"); @@ -2992,25 +3058,19 @@ H5P_cmp_plist(H5P_genplist_t *plist1, H5P_genplist_t *plist2) /* Cycle through the properties and compare them also */ for(u=0; upclass->hashsize; u++) { tprop1=plist1->props[u]; - tprop2=plist2->props[u]; - - /* Check if they both have properties in this hash location */ - if(tprop1==NULL && tprop2!=NULL) HGOTO_DONE(-1); - if(tprop1!=NULL && tprop2==NULL) HGOTO_DONE(1); /* Check the actual properties */ - while(tprop1!=NULL && tprop2!=NULL) { + while(tprop1!=NULL) { + /* Find a property with the same name in the second property list */ + if((tprop2=H5P_find_prop(plist2->props,plist2->pclass->hashsize,tprop1->name))==NULL) + HGOTO_DONE(1); + /* Compare the two properties */ if((cmp_value=H5P_cmp_prop(tprop1,tprop2))!=0) HGOTO_DONE(cmp_value); - /* Advance the pointers */ + /* Advance to next property */ tprop1=tprop1->next; - tprop2=tprop2->next; - - /* Check if they both have properties in this location */ - if(tprop1==NULL && tprop2!=NULL) HGOTO_DONE(-1); - if(tprop1!=NULL && tprop2==NULL) HGOTO_DONE(1); } /* end while */ } /* end for */ diff --git a/test/tgenprop.c b/test/tgenprop.c index 4f97322..93cc3ff 100644 --- a/test/tgenprop.c +++ b/test/tgenprop.c @@ -519,6 +519,10 @@ test_genprop_basic_list(void) cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL); CHECK_I(cid1, "H5Pcreate_class"); + /* Create a the generic class again, should fail */ + cid2 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,CLASS1_HASHSIZE,NULL,NULL,NULL,NULL,NULL,NULL); + VERIFY(cid2, FAIL, "H5Pcreate_class"); + /* Add several properties (w/default values) */ /* Insert first property into class (with no callbacks) */ @@ -1367,6 +1371,54 @@ test_genprop_class_addprop(void) /**************************************************************** ** +** test_genprop_list_equal(): Test basic generic property list code. +** More tests for H5Pequal() +** +****************************************************************/ +static void +test_genprop_equal(void) +{ + hid_t cid1; /* Generic Property class ID */ + hid_t lid1; /* Generic Property list ID */ + hid_t lid2; /* Generic Property list ID */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Basic Generic Property List Equal Functionality\n")); + + /* Create a new generic class, derived from the root of the class hierarchy */ + /* (Use a hash size of 1 to force the properties into the same hash chain) */ + cid1 = H5Pcreate_class(H5P_NO_CLASS,CLASS1_NAME,1,NULL,NULL,NULL,NULL,NULL,NULL); + CHECK_I(cid1, "H5Pcreate_class"); + + /* Insert first property into class (with no callbacks) */ + ret = H5Pregister(cid1,PROP1_NAME,PROP1_SIZE,PROP1_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); + CHECK_I(ret, "H5Pregister"); + + /* Insert second property into class (with no callbacks) */ + ret = H5Pregister(cid1,PROP2_NAME,PROP2_SIZE,PROP2_DEF_VALUE,NULL,NULL,NULL,NULL,NULL,NULL); + CHECK_I(ret, "H5Pregister"); + + /* Create a property list from the class */ + lid1 = H5Pcreate(cid1); + CHECK_I(lid1, "H5Pcreate"); + + /* Copy the property list */ + lid2 = H5Pcopy(lid1); + CHECK_I(lid2, "H5Pcopy"); + + /* Check that the lists are equal */ + ret = H5Pequal(lid1,lid2); + VERIFY(ret, 1, "H5Pequal"); + + /* Close class */ + ret = H5Pclose_class(cid1); + CHECK_I(ret, "H5Pclose_class"); + +} /* ent test_genprop_equal() */ + +/**************************************************************** +** ** test_genprop(): Main generic property testing routine. ** ****************************************************************/ @@ -1390,6 +1442,8 @@ test_genprop(void) test_genprop_list_addprop(); /* Test adding properties to HDF5 property list */ test_genprop_class_addprop(); /* Test adding properties to HDF5 property class */ + test_genprop_equal(); /* Tests for more H5Pequal verification */ + } /* test_genprop() */ -- cgit v0.12