diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/COPYING | 2 | ||||
-rw-r--r-- | src/H5.c | 2 | ||||
-rw-r--r-- | src/H5C.c | 179 | ||||
-rw-r--r-- | src/H5Lexternal.c | 4 | ||||
-rw-r--r-- | src/H5T.c | 21 | ||||
-rw-r--r-- | src/H5Tcompound.c | 151 | ||||
-rw-r--r-- | src/H5private.h | 15 | ||||
-rw-r--r-- | src/H5public.h | 4 | ||||
-rw-r--r-- | src/H5system.c | 28 | ||||
-rw-r--r-- | src/Makefile.in | 2 |
10 files changed, 265 insertions, 143 deletions
diff --git a/src/COPYING b/src/COPYING index ef0cbaf..6903daf 100755 --- a/src/COPYING +++ b/src/COPYING @@ -1,5 +1,5 @@ - Copyright by The HDF Group (THG) and + Copyright by The HDF Group and The Board of Trustees of the University of Illinois. All rights reserved. @@ -600,6 +600,8 @@ done: "The HDF5 header files used to compile this application do not match\n" \ "the version used by the HDF5 library to which this application is linked.\n" \ "Data corruption or segmentation faults may occur if the application continues.\n" \ + "This can happen when an application was compiled by one version of HDF5 but\n" \ + "linked with a different version of static or shared HDF5 library.\n" \ "You should recompile the application or check your shared library related\n" \ "settings such as 'LD_LIBRARY_PATH'.\n" @@ -541,6 +541,11 @@ if ( ( (entry_ptr) == NULL ) || \ * Updated H5C__UPDATE_STATS_FOR_PROTECT() to keep stats on * read and write protects. * + * MAM -- 1/15/09 + * Created H5C__UPDATE_MAX_INDEX_SIZE_STATS to contain + * common code within macros that update the maximum + * index, clean_index, and dirty_index statistics fields. + * ***********************************************************************/ #define H5C__UPDATE_CACHE_HIT_RATE_STATS(cache_ptr, hit) \ @@ -551,6 +556,18 @@ if ( ( (entry_ptr) == NULL ) || \ #if H5C_COLLECT_CACHE_STATS +#define H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ + if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \ + (cache_ptr)->max_index_size = (cache_ptr)->index_size; \ + if ( (cache_ptr)->clean_index_size > \ + (cache_ptr)->max_clean_index_size ) \ + (cache_ptr)->max_clean_index_size = \ + (cache_ptr)->clean_index_size; \ + if ( (cache_ptr)->dirty_index_size > \ + (cache_ptr)->max_dirty_index_size ) \ + (cache_ptr)->max_dirty_index_size = \ + (cache_ptr)->dirty_index_size; + #define H5C__UPDATE_STATS_FOR_DIRTY_PIN(cache_ptr, entry_ptr) \ (((cache_ptr)->dirty_pins)[(entry_ptr)->type->id])++; @@ -582,16 +599,7 @@ if ( ( (entry_ptr) == NULL ) || \ } \ if ( (entry_ptr)->size < (new_size) ) { \ ((cache_ptr)->size_increases[(entry_ptr)->type->id])++; \ - if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \ - (cache_ptr)->max_index_size = (cache_ptr)->index_size; \ - if ( (cache_ptr)->clean_index_size > \ - (cache_ptr)->max_clean_index_size ) \ - (cache_ptr)->max_clean_index_size = \ - (cache_ptr)->clean_index_size; \ - if ( (cache_ptr)->dirty_index_size > \ - (cache_ptr)->max_dirty_index_size ) \ - (cache_ptr)->max_dirty_index_size = \ - (cache_ptr)->dirty_index_size; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \ (cache_ptr)->max_slist_size = (cache_ptr)->slist_size; \ if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \ @@ -686,16 +694,7 @@ if ( ( (entry_ptr) == NULL ) || \ } \ if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \ - (cache_ptr)->max_index_size = (cache_ptr)->index_size; \ - if ( (cache_ptr)->clean_index_size > \ - (cache_ptr)->max_clean_index_size ) \ - (cache_ptr)->max_clean_index_size = \ - (cache_ptr)->clean_index_size; \ - if ( (cache_ptr)->dirty_index_size > \ - (cache_ptr)->max_dirty_index_size ) \ - (cache_ptr)->max_dirty_index_size = \ - (cache_ptr)->dirty_index_size; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ if ( (cache_ptr)->slist_len > (cache_ptr)->max_slist_len ) \ (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \ @@ -723,16 +722,7 @@ if ( ( (entry_ptr) == NULL ) || \ } \ if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \ - (cache_ptr)->max_index_size = (cache_ptr)->index_size; \ - if ( (cache_ptr)->clean_index_size > \ - (cache_ptr)->max_clean_index_size ) \ - (cache_ptr)->max_clean_index_size = \ - (cache_ptr)->clean_index_size; \ - if ( (cache_ptr)->dirty_index_size > \ - (cache_ptr)->max_dirty_index_size ) \ - (cache_ptr)->max_dirty_index_size = \ - (cache_ptr)->dirty_index_size; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ if ( (cache_ptr)->pl_len > (cache_ptr)->max_pl_len ) \ (cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \ if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \ @@ -783,16 +773,7 @@ if ( ( (entry_ptr) == NULL ) || \ } \ if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \ - (cache_ptr)->max_index_size = (cache_ptr)->index_size; \ - if ( (cache_ptr)->clean_index_size > \ - (cache_ptr)->max_clean_index_size ) \ - (cache_ptr)->max_clean_index_size = \ - (cache_ptr)->clean_index_size; \ - if ( (cache_ptr)->dirty_index_size > \ - (cache_ptr)->max_dirty_index_size ) \ - (cache_ptr)->max_dirty_index_size = \ - (cache_ptr)->dirty_index_size; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ if ( (cache_ptr)->slist_len > (cache_ptr)->max_slist_len ) \ (cache_ptr)->max_slist_len = (cache_ptr)->slist_len; \ if ( (cache_ptr)->slist_size > (cache_ptr)->max_slist_size ) \ @@ -815,16 +796,7 @@ if ( ( (entry_ptr) == NULL ) || \ } \ if ( (cache_ptr)->index_len > (cache_ptr)->max_index_len ) \ (cache_ptr)->max_index_len = (cache_ptr)->index_len; \ - if ( (cache_ptr)->index_size > (cache_ptr)->max_index_size ) \ - if ( (cache_ptr)->clean_index_size > \ - (cache_ptr)->max_clean_index_size ) \ - (cache_ptr)->max_clean_index_size = \ - (cache_ptr)->clean_index_size; \ - if ( (cache_ptr)->dirty_index_size > \ - (cache_ptr)->max_dirty_index_size ) \ - (cache_ptr)->max_dirty_index_size = \ - (cache_ptr)->dirty_index_size; \ - (cache_ptr)->max_index_size = (cache_ptr)->index_size; \ + H5C__UPDATE_MAX_INDEX_SIZE_STATS(cache_ptr) \ if ( (cache_ptr)->pl_len > (cache_ptr)->max_pl_len ) \ (cache_ptr)->max_pl_len = (cache_ptr)->pl_len; \ if ( (cache_ptr)->pl_size > (cache_ptr)->max_pl_size ) \ @@ -901,7 +873,6 @@ if ( ( (cache_ptr) == NULL ) || \ ( (cache_ptr)->index_size != \ ((cache_ptr)->clean_index_size + \ (cache_ptr)->dirty_index_size) ) ) { \ - HDassert(0); /* JRM */ \ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, fail_val, \ "Pre HT insert SC failed") \ } @@ -927,7 +898,6 @@ if ( ( (cache_ptr) == NULL ) || \ ( (cache_ptr)->index_size != \ ((cache_ptr)->clean_index_size + \ (cache_ptr)->dirty_index_size) ) ) { \ - HDassert(0); /* JRM */ \ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Pre HT remove SC failed") \ } @@ -983,18 +953,18 @@ if ( ( (cache_ptr) == NULL ) || \ ( (new_size) <= 0 ) || \ ( ( (cache_ptr)->index_len == 1 ) && \ ( (cache_ptr)->index_size != (old_size) ) ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + \ + (cache_ptr)->dirty_index_size) ) || \ + ( (entry_ptr == NULL) ) || \ + ( ( !( was_clean ) || \ + ( (cache_ptr)->clean_index_size < (old_size) ) ) && \ + ( ( (was_clean) ) || \ + ( (cache_ptr)->dirty_index_size < (old_size) ) ) ) \ ( (entry_ptr) == NULL ) ) { \ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ "Pre HT entry size change SC failed") \ -} \ -HDassert( (cache_ptr)->index_size == \ - ((cache_ptr)->clean_index_size + \ - (cache_ptr)->dirty_index_size) ); \ -HDassert( (entry_ptr) != NULL ); \ -HDassert( ( ( was_clean ) && \ - ( (cache_ptr)->clean_index_size >= (old_size) ) ) || \ - ( ( ! (was_clean) ) && \ - ( (cache_ptr)->dirty_index_size >= (old_size) ) ) ); +} #define H5C__POST_HT_ENTRY_SIZE_CHANGE_SC(cache_ptr, old_size, new_size, \ entry_ptr) \ @@ -1002,57 +972,62 @@ if ( ( (cache_ptr) == NULL ) || \ ( (cache_ptr)->index_len <= 0 ) || \ ( (cache_ptr)->index_size <= 0 ) || \ ( (new_size) > (cache_ptr)->index_size ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + \ + (cache_ptr)->dirty_index_size) ) || \ + ( ( !((entry_ptr)->is_dirty ) || \ + ( (cache_ptr)->dirty_index_size < (new_size) ) ) && \ + ( ( ((entry_ptr)->is_dirty) ) || \ + ( (cache_ptr)->clean_index_size < (new_size) ) ) ) \ ( ( (cache_ptr)->index_len == 1 ) && \ ( (cache_ptr)->index_size != (new_size) ) ) ) { \ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ "Post HT entry size change SC failed") \ -} \ -HDassert( (cache_ptr)->index_size == \ - ((cache_ptr)->clean_index_size + \ - (cache_ptr)->dirty_index_size) ); \ -HDassert( ( ( (entry_ptr)->is_dirty ) && \ - ( (cache_ptr)->dirty_index_size >= (new_size) ) ) || \ - ( ( ! ((entry_ptr)->is_dirty) ) && \ - ( (cache_ptr)->clean_index_size >= (new_size) ) ) ); - -#define H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) \ -{ \ - HDassert( (cache_ptr) != NULL ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (cache_ptr)->index_len > 0 ); \ - HDassert( (entry_ptr) != NULL ); \ - HDassert( (entry_ptr)->is_dirty == FALSE ); \ - HDassert( (cache_ptr)->index_size >= (entry_ptr)->size ); \ - HDassert( (cache_ptr)->dirty_index_size >= (entry_ptr)->size ); \ - HDassert( (cache_ptr)->index_size == \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ); \ -} -/* JRM */ -#define H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) \ -{ \ - HDassert( (cache_ptr) != NULL ); \ - HDassert( (cache_ptr)->magic == H5C__H5C_T_MAGIC ); \ - HDassert( (cache_ptr)->index_len > 0 ); \ - HDassert( (entry_ptr) != NULL ); \ - HDassert( (entry_ptr)->is_dirty == TRUE ); \ - HDassert( (cache_ptr)->index_size >= (entry_ptr)->size ); \ - HDassert( (cache_ptr)->clean_index_size >= (entry_ptr)->size ); \ - HDassert( (cache_ptr)->index_size == \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ); \ +} + +#define H5C__PRE_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) \ +if ( \ + ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( (cache_ptr)->index_len <= 0 ) || \ + ( (entry_ptr) == NULL ) || \ + ( (entry_ptr)->is_dirty != FALSE ) || \ + ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ + ( (cache_ptr)->dirty_index_size < (entry_ptr)->size ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Pre HT update for entry clean SC failed") \ } -#define H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) \ -{ \ - HDassert( (cache_ptr)->index_size == \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ); \ +#define H5C__PRE_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) \ +if ( \ + ( (cache_ptr) == NULL ) || \ + ( (cache_ptr)->magic != H5C__H5C_T_MAGIC ) || \ + ( (cache_ptr)->index_len <= 0 ) || \ + ( (entry_ptr) == NULL ) || \ + ( (entry_ptr)->is_dirty != TRUE ) || \ + ( (cache_ptr)->index_size < (entry_ptr)->size ) || \ + ( (cache_ptr)->clean_index_size < (entry_ptr)->size ) || \ + ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Pre HT update for entry dirty SC failed") \ } -#define H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) \ -{ \ - HDassert( (cache_ptr)->index_size == \ - ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ); \ +#define H5C__POST_HT_UPDATE_FOR_ENTRY_CLEAN_SC(cache_ptr, entry_ptr) \ +if ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Post HT update for entry clean SC failed") \ } +#define H5C__POST_HT_UPDATE_FOR_ENTRY_DIRTY_SC(cache_ptr, entry_ptr) \ +if ( (cache_ptr)->index_size != \ + ((cache_ptr)->clean_index_size + (cache_ptr)->dirty_index_size) ) { \ + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Post HT update for entry dirty SC failed") \ +} #else /* H5C_DO_SANITY_CHECKS */ diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index 2c6b3a3..8637429 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -121,6 +121,8 @@ H5L_getenv_prefix_name(char **env_prefix/*in,out*/) * * Programmer: Vailin Choi, April 2, 2008 * + * Modification: Raymond Lu, 14 Jan. 2009 + * Added support for OpenVMS pathname --------------------------------------------------------------------------*/ static herr_t H5L_build_name(char *prefix, char *file_name, char **full_name/*out*/) @@ -140,8 +142,10 @@ H5L_build_name(char *prefix, char *file_name, char **full_name/*out*/) /* Copy the prefix into the buffer */ HDstrcpy(*full_name, prefix); +#ifndef H5_VMS if (!CHECK_DELIMITER(prefix[prefix_len-1])) HDstrcat(*full_name, DIR_SEPS); +#endif /* Add the external link's filename to the prefix supplied */ HDstrcat(*full_name, file_name); @@ -2973,8 +2973,10 @@ H5T_create(H5T_class_t type, size_t size) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); dt->shared->type = type; - if(type==H5T_COMPOUND) + if(type==H5T_COMPOUND) { dt->shared->u.compnd.packed=TRUE; /* Start out packed */ + dt->shared->u.compnd.sorted=H5T_SORT_VALUE; /* Start out sorted by value */ + } /* end if */ else if(type==H5T_OPAQUE) /* Initialize the tag in case it's not set later. A null tag will * cause problems for later operations. */ @@ -3173,13 +3175,16 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) * name and type fields of each new member with copied values. * That is, H5T_copy() is a deep copy. */ - new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc * - sizeof(H5T_cmemb_t)); - if (NULL==new_dt->shared->u.compnd.memb) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - - HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb, - new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t)); + /* Only malloc if space has been allocated for members - NAF */ + if(new_dt->shared->u.compnd.nalloc > 0) { + new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc * + sizeof(H5T_cmemb_t)); + if (NULL==new_dt->shared->u.compnd.memb) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb, + new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t)); + } /* end if */ for(i = 0; i < new_dt->shared->u.compnd.nmembs; i++) { unsigned j; diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c index d9b5974..02d6bd1 100644 --- a/src/H5Tcompound.c +++ b/src/H5Tcompound.c @@ -45,6 +45,11 @@ /******************/ /* Local Typedefs */ /******************/ +/* "Key" (+ user data) for bsearch callback */ +typedef struct{ + size_t offset; /* Offset of member to be added */ + const H5T_cmemb_t *max_under; /* Member with maximum offset seen that is not above "offset" */ +} H5T_insert_compar_t; /********************/ @@ -416,6 +421,48 @@ done: /*------------------------------------------------------------------------- + * Function: H5T_insert_compar + * + * Purpose: Callback function for bsearch called from H5T_insert. + * Reports whether obj has a lower of higher offset than + * that stored in key. Also keeps track of the highest + * offset seen that is not higher than that in key. + * + * Return: -1 if key < obj + * 0 if key == obj + * 1 if key > obj + * + * Programmer: Neil Fortner + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +H5T_insert_compar(const void *_key, const void *_obj) +{ + H5T_insert_compar_t *key = *(H5T_insert_compar_t * const *)_key; /* User data */ + const H5T_cmemb_t *memb = (const H5T_cmemb_t *)_obj; /* Compound member being examined */ + int ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_insert_compar) + + if(key->offset > memb->offset) { + if(key->max_under == NULL || memb->offset > key->max_under->offset) + key->max_under = memb; + ret_value = 1; + } /* end if */ + else if(key->offset < memb->offset) + ret_value = -1; + else + ret_value = 0; /* Should not happen */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_insert_compar() */ + + +/*------------------------------------------------------------------------- * Function: H5T_insert * * Purpose: Adds a new MEMBER to the compound datatype PARENT. The new @@ -435,6 +482,8 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) { unsigned idx; /* Index of member to insert */ size_t total_size; + H5T_insert_compar_t key; /* Key for bsearch compare function */ + H5T_insert_compar_t *keyptr = &key; /* Pointer to key */ unsigned i; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -451,20 +500,39 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) if(!HDstrcmp(parent->shared->u.compnd.memb[i].name, name)) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member name is not unique") - /* Does the new member overlap any existing member ? */ total_size = member->shared->size; - for(i = 0; i < parent->shared->u.compnd.nmembs; i++) - if((offset <= parent->shared->u.compnd.memb[i].offset && - (offset + total_size) > parent->shared->u.compnd.memb[i].offset) || - (parent->shared->u.compnd.memb[i].offset <= offset && - (parent->shared->u.compnd.memb[i].offset + - parent->shared->u.compnd.memb[i].size) > offset)) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member") /* Does the new member overlap the end of the compound type? */ if((offset + total_size) > parent->shared->size) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member extends past end of compound type") + if(parent->shared->u.compnd.sorted != H5T_SORT_VALUE) + if(H5T_sort_value(parent, NULL) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOMPARE, FAIL, "value sort failed") + + /* Find the position to insert the new member */ + if(parent->shared->u.compnd.nmembs == 0) + idx = 0; + else { + /* Key value (including user data) for compar callback */ + key.offset = offset; + key.max_under = NULL; + + /* Do a binary search on the offsets of the (now sorted) members. We do + * not expect to find an exact match (if we do it is an error), rely on + * the user data in the key to keep track of the closest member below + * the new member. */ + if(NULL != HDbsearch(&keyptr, parent->shared->u.compnd.memb, parent->shared->u.compnd.nmembs, + sizeof(parent->shared->u.compnd.memb[0]), H5T_insert_compar)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member") + idx = (key.max_under == NULL) ? 0 : (unsigned) (key.max_under - parent->shared->u.compnd.memb + 1); + } /* end else */ + + /* Does the new member overlap any existing member ? */ + if((idx < parent->shared->u.compnd.nmembs && (offset + total_size) > parent->shared->u.compnd.memb[idx].offset) || + (idx && (parent->shared->u.compnd.memb[idx-1].offset + parent->shared->u.compnd.memb[idx-1].size) > offset)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member") + /* Increase member array if necessary */ if(parent->shared->u.compnd.nmembs >= parent->shared->u.compnd.nalloc) { unsigned na = MAX(1, parent->shared->u.compnd.nalloc * 2); @@ -476,38 +544,68 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) parent->shared->u.compnd.memb = x; } /* end if */ - /* Add member to end of member array */ - idx = parent->shared->u.compnd.nmembs; - parent->shared->u.compnd.memb[idx].name = H5MM_xstrdup(name); - parent->shared->u.compnd.memb[idx].offset = offset; - parent->shared->u.compnd.memb[idx].size = total_size; - parent->shared->u.compnd.memb[idx].type = H5T_copy(member, H5T_COPY_ALL); - - parent->shared->u.compnd.sorted = H5T_SORT_NONE; - parent->shared->u.compnd.nmembs++; - - /* Determine if the compound datatype stayed packed */ + /* Determine if the compound datatype stays packed */ if(parent->shared->u.compnd.packed) { /* Check if the member type is packed */ - if(H5T_is_packed(parent->shared->u.compnd.memb[idx].type) > 0) { + if(H5T_is_packed(member) > 0) { if(idx == 0) { /* If the is the first member, the datatype is not packed * if the first member isn't at offset 0 */ - if(parent->shared->u.compnd.memb[idx].offset > 0) + if(offset > 0) parent->shared->u.compnd.packed = FALSE; } /* end if */ else { /* If the is not the first member, the datatype is not * packed if the new member isn't adjoining the previous member */ - if(parent->shared->u.compnd.memb[idx].offset != (parent->shared->u.compnd.memb[idx - 1].offset + parent->shared->u.compnd.memb[idx - 1].size)) + if(offset != (parent->shared->u.compnd.memb[idx - 1].offset + parent->shared->u.compnd.memb[idx - 1].size)) parent->shared->u.compnd.packed = FALSE; } /* end else */ } /* end if */ else parent->shared->u.compnd.packed = FALSE; } /* end if */ + else + /* Check if inserting this member causes the parent to become packed */ + /* First check if it completely closes a gap */ + /* No need to check if it's being appended to the end */ + if(idx != parent->shared->u.compnd.nmembs + && (offset + total_size) == parent->shared->u.compnd.memb[idx].offset + && (idx == 0 ? offset == 0 : (parent->shared->u.compnd.memb[idx-1].offset + + parent->shared->u.compnd.memb[idx-1].size) == offset) + && H5T_is_packed(member) > 0) { + + /* Start out packed */ + parent->shared->u.compnd.packed = TRUE; + + /* Check if the entire type is now packed */ + if((idx != 0 && parent->shared->u.compnd.memb[0].offset != 0) + || !H5T_is_packed(parent->shared->u.compnd.memb[0].type)) + parent->shared->u.compnd.packed = FALSE; + else + for(i = 1; i < parent->shared->u.compnd.nmembs; i++) + if((i != idx && parent->shared->u.compnd.memb[i].offset + != (parent->shared->u.compnd.memb[i - 1].offset + + parent->shared->u.compnd.memb[i - 1].size)) + || !H5T_is_packed(parent->shared->u.compnd.memb[i].type)) { + parent->shared->u.compnd.packed = FALSE; + break; + } /* end if */ + } /* end if */ + + /* Reshape the memb array to accomodate the new member */ + if(idx != parent->shared->u.compnd.nmembs) + HDmemmove(&parent->shared->u.compnd.memb[idx+1], &parent->shared->u.compnd.memb[idx], + (parent->shared->u.compnd.nmembs - idx) * sizeof(parent->shared->u.compnd.memb[0])); + + /* Add member to member array */ + parent->shared->u.compnd.memb[idx].name = H5MM_xstrdup(name); + parent->shared->u.compnd.memb[idx].offset = offset; + parent->shared->u.compnd.memb[idx].size = total_size; + parent->shared->u.compnd.memb[idx].type = H5T_copy(member, H5T_COPY_ALL); + + parent->shared->u.compnd.nmembs++; /* Set the "force conversion" flag if the field's datatype indicates */ if(member->shared->force_conv == TRUE) @@ -631,8 +729,13 @@ H5T_is_packed(const H5T_t *dt) dt = dt->shared->parent; /* If this is a compound datatype, check if it is packed */ - if(dt->shared->type == H5T_COMPOUND) - ret_value = (htri_t)dt->shared->u.compnd.packed; + if(dt->shared->type == H5T_COMPOUND) { + H5T_compnd_t *compnd = &(dt->shared->u.compnd); /* Convenience pointer to compound info */ + ret_value = (htri_t)(compnd->packed && compnd->nmembs > 0 + && compnd->memb[compnd->nmembs - 1].offset + + compnd->memb[compnd->nmembs - 1].size + == dt->shared->size); + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_is_packed() */ diff --git a/src/H5private.h b/src/H5private.h index 63bbcf4..2f75f86 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -1375,8 +1375,7 @@ extern char *strdup(const char *s); #define HDpthread_self_ulong() ((unsigned long)pthread_self()) #endif /* HDpthread_self_ulong */ - -#ifdef H5_HAVE_WINDOW_PATH +#if defined(H5_HAVE_WINDOW_PATH) /* directory delimiter for Windows: slash and backslash are acceptable on Windows */ #define DIR_SLASH_SEPC '/' @@ -1397,6 +1396,18 @@ extern char *strdup(const char *s); (ptr = slash); \ } +#elif defined(H5_HAVE_VMS_PATH) + +/* OpenVMS pathname: <disk name>$<partition>:[path]<file name> + * i.g. SYS$SYSUSERS:[LU.HDF5.SRC]H5system.c */ +#define DIR_SEPC '.' +#define DIR_SEPS "." +#define CHECK_DELIMITER(SS) (SS == DIR_SEPC) +#define CHECK_ABSOLUTE(NAME) (strrchr(NAME, ':') && strrchr(NAME, '[')) +#define CHECK_ABS_DRIVE(NAME) (0) +#define CHECK_ABS_PATH(NAME) (0) +#define GET_LAST_DELIMITER(NAME, ptr) ptr = strrchr(NAME, ']'); + #else #define DIR_SEPC '/' diff --git a/src/H5public.h b/src/H5public.h index cf9ff14..c1a8449 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -71,10 +71,10 @@ extern "C" { /* Version numbers */ #define H5_VERS_MAJOR 1 /* For major interface/format changes */ #define H5_VERS_MINOR 9 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 27 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_RELEASE 29 /* For tweaks, bug-fixes, or development */ #define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */ /* Empty string for real releases. */ -#define H5_VERS_INFO "HDF5 library version: 1.9.27" /* Full version string */ +#define H5_VERS_INFO "HDF5 library version: 1.9.29" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \ H5_VERS_RELEASE) diff --git a/src/H5system.c b/src/H5system.c index 8f91e2f..8956e9b 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -597,9 +597,12 @@ HDremove_all(const char *fname) * * Programmer: Vailin Choi * April 2, 2008 - * Modifications: 2nd Oct, 2008; Vailin Choi + * Modifications: 2nd Oct, 2008; Vailin Choi * Remove compiler warning for "if condition" - * + * + * Raymond Lu + * 14 Jan. 2009 + * Add support for OpenVMS pathname *------------------------------------------------------------------------- */ #define MAX_PATH_LEN 1024 @@ -620,6 +623,8 @@ H5_build_extpath(const char *name, char **extpath/*out*/) /* * Unix: name[0] is a "/" * Windows: name[0-2] is "<drive letter>:\" or "<drive-letter>:/" + * OpenVMS: <disk name>$<partition>:[path]<file name> + * i.g. SYS$SYSUSERS:[LU.HDF5.SRC]H5system.c */ if (CHECK_ABSOLUTE(name)) { if ((full_path=H5MM_strdup(name)) == NULL) @@ -634,6 +639,7 @@ H5_build_extpath(const char *name, char **extpath/*out*/) * Windows: name[0-1] is "<drive-letter>:" * Get current working directory on the drive specified in NAME * Unix: does not apply + * OpenVMS: does not apply */ if (CHECK_ABS_DRIVE(name)) { drive = name[0] - 'A' + 1; @@ -643,12 +649,13 @@ H5_build_extpath(const char *name, char **extpath/*out*/) * Windows: name[0] is a '/' or '\' * Get current drive * Unix: does not apply + * OpenVMS: does not apply */ } else if (CHECK_ABS_PATH(name) && ((drive=HDgetdrive()) != 0)) { sprintf(cwdpath, "%c:%c", (drive+'A'-1), name[0]); retcwd = cwdpath; HDstrcpy(new_name, &name[1]); - } else /* totally relative for both Unix and Windows: get current working directory */ + } else /* totally relative for Unix, Windows, and OpenVMS: get current working directory */ retcwd = HDgetcwd(cwdpath, MAX_PATH_LEN); if (retcwd != NULL) { @@ -659,9 +666,24 @@ H5_build_extpath(const char *name, char **extpath/*out*/) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") HDstrcpy(full_path, cwdpath); +#ifdef H5_VMS + /* If the file name contains relative path, cut off the beginning bracket. Also cut off the + * ending bracket of CWDPATH to combine the full path name. i.g. + * cwdpath = SYS$SYSUSERS:[LU.HDF5.TEST] + * new_name = [.tmp]extlinks.h5 + * full_path = SYS$SYSUSERS:[LU.HDF5.TEST.tmp]extlinks.h5 + */ + if(new_name[0] == '[') { + char *tmp = new_name; + full_path[cwdlen-1] = '\0'; + HDstrcat(full_path, ++tmp); + } else + HDstrcat(full_path, new_name); +#else if (!CHECK_DELIMITER(cwdpath[cwdlen-1])) HDstrcat(full_path, DIR_SEPS); HDstrcat(full_path, new_name); +#endif } } diff --git a/src/Makefile.in b/src/Makefile.in index 8d71154..0a08832 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -408,7 +408,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 17 +LT_VERS_REVISION = 19 LT_VERS_AGE = 0 H5detect_CFLAGS = -g |