From 1e8ebeecfc67073a3019f9c2084a5977d2b8c62e Mon Sep 17 00:00:00 2001 From: Robb Matzke Date: Fri, 5 Jun 1998 16:03:49 -0500 Subject: [svn-r410] Changes since 19980604 ---------------------- ./src/H5A.c Named data types can have attributes. Fixed bugs where the API functions didn't check the return values of their internal counterparts and thus the automatic error reporting didn't work. Fixed some places where the error stack wasn't cleared after a function returned failure. Data types returned by H5Aget_type() are always read-only. If the `attr_num' argument of H5Aiterate() is null then it acts like H5Giterate() instead of failing -- it begins processing attributes with the first one. ./src/H5D.c We check for allocation overruns when scalar datasets are stored in external files. ./src/H5O.c H5O_modify() will fail if the message is >=16kB. ./src/H5Oattr.c Split some long lines ./src/H5T.c ./src/H5Tprivate.h Added H5T_entof() to support attributes on named types. ./src/h5ls.c Prints the names of attributes and their sizes. ./test/cmpd_dset.c ./test/dsets.c ./test/dtypes.c ./test/extend.c ./test/external.c ./test/gheap.c ./test/istore.c ./test/links.c ./test/shtype.c If the environment variable HDF5_NOCLEANUP is defined then the temporary files are not removed. The testhdf5 program still has the bug that it removes *.h5, clobbering test files from other programs... oh well. ./test/dtypes.c Added attribute tests. --- src/H5A.c | 500 +++++++++++++++++++++++++++++++++---------------------- src/H5Apkg.h | 4 +- src/H5D.c | 49 +++--- src/H5O.c | 5 + src/H5Oattr.c | 6 +- src/H5T.c | 40 +++++ src/H5Tprivate.h | 1 + src/h5ls.c | 43 +++++ test/cmpd_dset.c | 5 +- test/dsets.c | 5 +- test/dtypes.c | 46 +++-- test/extend.c | 6 +- test/external.c | 31 ++-- test/gheap.c | 13 +- test/istore.c | 5 +- test/links.c | 6 +- test/shtype.c | 14 +- 17 files changed, 510 insertions(+), 269 deletions(-) diff --git a/src/H5A.c b/src/H5A.c index fbce35e..efe8b2d 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -1,13 +1,13 @@ /**************************************************************************** -* NCSA HDF * -* Software Development Group * -* National Center for Supercomputing Applications * -* University of Illinois at Urbana-Champaign * -* 605 E. Springfield, Champaign IL 61820 * -* * -* For conditions of distribution and use, see the accompanying * -* hdf/COPYING file. * -* * +* NCSA HDF * +* Software Development Group * +* National Center for Supercomputing Applications * +* University of Illinois at Urbana-Champaign * +* 605 E. Springfield, Champaign IL 61820 * +* * +* For conditions of distribution and use, see the accompanying * +* hdf/COPYING file. * +* * ****************************************************************************/ #ifdef RCSID @@ -16,31 +16,32 @@ static char RcsId[] = "$Revision$"; /* $Id$ */ -#define H5A_PACKAGE /*suppress error about including H5Apkg */ +#define H5A_PACKAGE /*suppress error about including H5Apkg */ /* Private header files */ #include /* Generic Functions */ -#include /* IDs */ +#include /* IDs */ #include /* B-tree subclass names */ -#include /* Datasets */ -#include /* Groups */ -#include /* Datatypes */ +#include /* Datasets */ +#include /* Groups */ +#include /* Datatypes */ #include /* Error handling */ #include /* Memory management */ #include /* Property lists */ -#include /* Object Headers */ -#include /* Attributes */ +#include /* Object Headers */ +#include /* Attributes */ #define PABLO_MASK H5A_mask /* Is the interface initialized? */ static hbool_t interface_initialize_g = FALSE; -#define INTERFACE_INIT H5A_init_interface +#define INTERFACE_INIT H5A_init_interface static herr_t H5A_init_interface(void); /* PRIVATE PROTOTYPES */ -static void H5A_term_interface(void); -static hid_t H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type, const H5S_t *space); +static void H5A_term_interface(void); +static hid_t H5A_create(const H5G_entry_t *ent, const char *name, + const H5T_t *type, const H5S_t *space); static hid_t H5A_open(H5G_entry_t *ent, unsigned idx); static herr_t H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf); static herr_t H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf); @@ -142,23 +143,45 @@ H5A_term_interface(void) attribute is reduced to zero. The location object may be either a group or a dataset, both of which may have any sort of attribute. + * + * Modifications: + * Robb Matzke, 5 Jun 1998 + * The LOC_ID can also be a committed data type. + * --------------------------------------------------------------------------*/ hid_t H5Acreate(hid_t loc_id, const char *name, hid_t datatype, hid_t dataspace, hid_t create_plist) { - void *obj = NULL; - H5G_entry_t *ent = NULL; - H5T_t *type = NULL; - H5S_t *space = NULL; - const H5D_create_t *create_parms = NULL; - hid_t ret_value = FAIL; + void *obj = NULL; + H5G_entry_t *ent = NULL; + H5T_t *type = NULL; + H5S_t *space = NULL; + const H5D_create_t *create_parms = NULL; + hid_t ret_value = FAIL; FUNC_ENTER(H5Acreate, FAIL); /* check arguments */ - if (!(H5_DATASET == H5I_group(loc_id) || H5_GROUP == H5I_group(loc_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute target not a dataset or group"); + if (NULL==(obj=H5I_object (loc_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); + } + switch (H5I_group (loc_id)) { + case H5_DATASET: + ent = H5D_entof ((H5D_t*)obj); + break; + case H5_DATATYPE: + if (NULL==(ent=H5T_entof ((H5T_t*)obj))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "target data type is not committed"); + } + break; + case H5_GROUP: + ent = H5G_entof ((H5G_t*)obj); + break; + default: + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "inappropriate attribute target"); } if (!name || !*name) { HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name"); @@ -171,7 +194,7 @@ H5Acreate(hid_t loc_id, const char *name, hid_t datatype, hid_t dataspace, NULL == (space = H5I_object(dataspace))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space"); } - if (create_plist >= 0) { + if (H5P_DEFAULT!=create_plist) { if (H5P_DATASET_CREATE != H5Pget_class(create_plist) || NULL == (create_parms = H5I_object(create_plist))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, @@ -181,16 +204,11 @@ H5Acreate(hid_t loc_id, const char *name, hid_t datatype, hid_t dataspace, create_parms = &H5D_create_dflt; } - /* Get the dataset or group's pointer */ - if(NULL == (obj = H5I_object(loc_id))) - HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); - if (H5_DATASET == H5I_group(loc_id)) - ent = H5D_entof ((H5D_t*)obj); - else - ent = H5G_entof ((H5G_t*)obj); - /* Go do the real work for attaching the attribute to the dataset */ - ret_value=H5A_create(ent,name,type,space); + if ((ret_value=H5A_create(ent,name,type,space))<0) { + HRETURN_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL, + "unable to create attribute"); + } FUNC_LEAVE(ret_value); } /* H5Acreate() */ @@ -217,7 +235,8 @@ H5Acreate(hid_t loc_id, const char *name, hid_t datatype, hid_t dataspace, *------------------------------------------------------------------------- */ static hid_t -H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type, const H5S_t *space) +H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type, + const H5S_t *space) { H5A_t *attr = NULL; H5A_t found_attr; @@ -269,12 +288,13 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type, const H5 } H5O_reset (H5O_ATTR, &found_attr); seq++; - } /* end while */ + } + H5E_clear (); /* Create the attribute message and save the attribute index */ if (H5O_modify(&(attr->ent), H5O_ATTR, H5O_NEW_MESG, 0, attr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, - "can't update attribute header messages"); + "unable to update attribute header messages"); /* Register the new attribute and get an ID for it */ if ((ret_value = H5I_register(H5_ATTR, attr)) < 0) { @@ -340,7 +360,8 @@ H5A_get_index(H5G_entry_t *ent, const char *name) } H5O_reset (H5O_ATTR, &found_attr); i++; - } /* end while */ + } + H5E_clear (); if(ret_value<0) { HRETURN_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, @@ -372,42 +393,56 @@ H5A_get_index(H5G_entry_t *ent, const char *name) H5Aclose or resource leaks will develop. The location object may be either a group or a dataset, both of which may have any sort of attribute. + * + * Modifications: + * Robb Matzke, 5 Jun 1998 + * The LOC_ID can also be a named (committed) data type. --------------------------------------------------------------------------*/ hid_t H5Aopen_name(hid_t loc_id, const char *name) { - H5G_entry_t *ent = NULL; /* Symbol table entry of object to attribute */ - void *obj = NULL; - intn idx=0; - hid_t ret_value = FAIL; + H5G_entry_t *ent = NULL; /*Symtab entry of object to attribute*/ + void *obj = NULL; + intn idx=0; + hid_t ret_value = FAIL; FUNC_ENTER(H5Aopen_name, FAIL); /* check arguments */ - if (!(H5_DATASET == H5I_group(loc_id) || H5_GROUP == H5I_group(loc_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute target not a dataset or group"); + if(NULL == (obj = H5I_object(loc_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); + } + switch (H5I_group (loc_id)) { + case H5_DATASET: + ent = H5D_entof ((H5D_t*)obj); + break; + case H5_DATATYPE: + if (NULL==(ent=H5T_entof ((H5T_t*)obj))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "target data type is not committed"); + } + break; + case H5_GROUP: + ent = H5G_entof ((H5G_t*)obj); + break; + default: + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "inappropriate attribute target"); } if (!name || !*name) { HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name"); } - /* Get the dataset or group's pointer */ - if(NULL == (obj = H5I_object(loc_id))) - HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); - - /* Copy the object header entry for the object */ - if (H5_DATASET == H5I_group(loc_id)) - ent = H5D_entof ((H5D_t*)obj); - else - ent = H5G_entof ((H5G_t*)obj); - /* Look up the attribute for the object */ if((idx=H5A_get_index(ent,name))<0) HRETURN_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "attribute not found"); /* Go do the real work for opening the attribute */ - ret_value=H5A_open(ent, (unsigned)idx); - + if ((ret_value=H5A_open(ent, (unsigned)idx))<0) { + HRETURN_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL, + "unable to open attribute"); + } + FUNC_LEAVE(ret_value); } /* H5Aopen_name() */ @@ -433,34 +468,49 @@ H5Aopen_name(hid_t loc_id, const char *name) H5Aclose or resource leaks will develop. The location object may be either a group or a dataset, both of which may have any sort of attribute. + * + * Modifications: + * Robb Matzke, 5 Jun 1998 + * The LOC_ID can also be a named (committed) data type. + * --------------------------------------------------------------------------*/ hid_t H5Aopen_idx(hid_t loc_id, unsigned idx) { - H5G_entry_t *ent = NULL; /* Symbol table entry of object to attribute */ - void *obj = NULL; - hid_t ret_value = FAIL; + H5G_entry_t *ent = NULL; /*Symtab entry of object to attribute */ + void *obj = NULL; + hid_t ret_value = FAIL; FUNC_ENTER(H5Aopen_idx, FAIL); /* check arguments */ - if (!(H5_DATASET == H5I_group(loc_id) || H5_GROUP == H5I_group(loc_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute target not a dataset or group"); - } - - /* Get the dataset or group's pointer */ - if(NULL == (obj = H5I_object(loc_id))) + if(NULL == (obj = H5I_object(loc_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); - - /* Copy the object header entry for the object */ - if (H5_DATASET == H5I_group(loc_id)) + } + switch (H5I_group (loc_id)) { + case H5_DATASET: ent = H5D_entof ((H5D_t*)obj); - else + break; + case H5_DATATYPE: + if (NULL==(ent=H5T_entof ((H5T_t*)obj))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "target data type is not committed"); + } + break; + case H5_GROUP: ent = H5G_entof ((H5G_t*)obj); + break; + default: + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "inappropriate attribute target"); + } /* Go do the real work for opening the attribute */ - ret_value=H5A_open(ent, idx); - + if ((ret_value=H5A_open(ent, idx))<0) { + HRETURN_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL, + "unable to open attribute"); + } + FUNC_LEAVE(ret_value); } /* H5Aopen_idx() */ @@ -555,11 +605,11 @@ H5Awrite(hid_t attr_id, hid_t mem_dt, void *buf) /* check arguments */ if (H5_ATTR != H5I_group(attr_id) || - (NULL == (attr = H5I_object(attr_id)))) { + (NULL == (attr = H5I_object(attr_id)))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute"); } if (H5_DATATYPE != H5I_group(mem_dt) || - NULL == (mem_type = H5I_object(mem_dt))) { + NULL == (mem_type = H5I_object(mem_dt))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } if (NULL == buf) { @@ -569,7 +619,7 @@ H5Awrite(hid_t attr_id, hid_t mem_dt, void *buf) /* Go write the actual data to the attribute */ if ((ret_value=H5A_write(attr,mem_type,buf))<0) { HRETURN_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, - "can't write attribute"); + "unable to write attribute"); } FUNC_LEAVE(ret_value); @@ -597,16 +647,16 @@ H5Awrite(hid_t attr_id, hid_t mem_dt, void *buf) static herr_t H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf) { - uint8 *tconv_buf = NULL; /* data type conv buffer */ - size_t nelmts; /* elements in attribute */ + uint8 *tconv_buf = NULL; /* data type conv buffer */ + size_t nelmts; /* elements in attribute */ H5T_conv_t tconv_func = NULL; /* conversion function */ H5T_cdata_t *cdata = NULL; /* type conversion data */ hid_t src_id = -1, dst_id = -1;/* temporary type atoms */ size_t src_type_size; /* size of source type */ size_t dst_type_size; /* size of destination type*/ - size_t buf_size; /* desired buffer size */ - int idx; /* index of attribute in object header */ - herr_t ret_value = FAIL; + size_t buf_size; /* desired buffer size */ + int idx; /* index of attribute in object header */ + herr_t ret_value = FAIL; #ifdef H5T_DEBUG H5_timer_t timer; #endif @@ -626,12 +676,12 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf) /* Get the maximum buffer size needed and allocate it */ buf_size = nelmts*MAX(src_type_size,dst_type_size); - tconv_buf = H5MM_xmalloc (buf_size); + tconv_buf = H5MM_xmalloc (buf_size); /* Copy the user's data into the buffer for conversion */ HDmemcpy(tconv_buf,buf,src_type_size*nelmts); -/* Convert memory buffer into disk buffer */ + /* Convert memory buffer into disk buffer */ /* Set up type conversion function */ if (NULL == (tconv_func = H5T_find(mem_type, attr->dt, H5T_BKG_NO, &cdata))) { @@ -640,22 +690,22 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf) } else if (H5T_conv_noop!=tconv_func) { if ((src_id = H5I_register(H5_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL)))<0 || - (dst_id = H5I_register(H5_DATATYPE, - H5T_copy(attr->dt, H5T_COPY_ALL)))<0) { + (dst_id = H5I_register(H5_DATATYPE, + H5T_copy(attr->dt, H5T_COPY_ALL)))<0) { HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion"); } } - /* Perform data type conversion. */ + /* Perform data type conversion. */ #ifdef H5T_DEBUG H5T_timer_begin (&timer, cdata); #endif - cdata->command = H5T_CONV_CONV; - if ((tconv_func) (src_id, dst_id, cdata, nelmts, tconv_buf, NULL)<0) { - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, - "data type conversion failed"); - } + cdata->command = H5T_CONV_CONV; + if ((tconv_func) (src_id, dst_id, cdata, nelmts, tconv_buf, NULL)<0) { + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, + "data type conversion failed"); + } #ifdef H5T_DEBUG H5T_timer_end (&timer, cdata, nelmts); #endif @@ -672,7 +722,7 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf) attr->data=tconv_buf; /* Set the data pointer temporarily */ if (H5O_modify(&(attr->ent), H5O_ATTR, idx, 0, attr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, - "can't update attribute header messages"); + "unable to update attribute header messages"); attr->data=NULL; /* un-do the data pointer */ /* Indicate the the attribute doesn't need fill-values */ @@ -722,11 +772,11 @@ H5Aread(hid_t attr_id, hid_t mem_dt, void *buf) /* check arguments */ if (H5_ATTR != H5I_group(attr_id) || - (NULL == (attr = H5I_object(attr_id)))) { + (NULL == (attr = H5I_object(attr_id)))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute"); } if (H5_DATATYPE != H5I_group(mem_dt) || - NULL == (mem_type = H5I_object(mem_dt))) { + NULL == (mem_type = H5I_object(mem_dt))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } if (NULL == buf) { @@ -736,7 +786,7 @@ H5Aread(hid_t attr_id, hid_t mem_dt, void *buf) /* Go write the actual data to the attribute */ if ((ret_value=H5A_read(attr,mem_type,buf))<0) { HRETURN_ERROR(H5E_ATTR, H5E_READERROR, FAIL, - "can't read attribute"); + "unable to read attribute"); } FUNC_LEAVE(ret_value); @@ -764,15 +814,15 @@ H5Aread(hid_t attr_id, hid_t mem_dt, void *buf) static herr_t H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf) { - uint8 *tconv_buf = NULL; /* data type conv buffer */ - size_t nelmts; /* elements in attribute */ - H5T_conv_t tconv_func = NULL; /* conversion function */ + uint8 *tconv_buf = NULL; /* data type conv buffer*/ + size_t nelmts; /* elements in attribute*/ + H5T_conv_t tconv_func = NULL; /* conversion function */ H5T_cdata_t *cdata = NULL; /* type conversion data */ - hid_t src_id = -1, dst_id = -1;/* temporary type atoms */ - size_t src_type_size; /* size of source type */ - size_t dst_type_size; /* size of destination type*/ - size_t buf_size; /* desired buffer size */ - herr_t ret_value = FAIL; + hid_t src_id = -1, dst_id = -1;/* temporary type atoms*/ + size_t src_type_size; /* size of source type */ + size_t dst_type_size; /* size of destination type */ + size_t buf_size; /* desired buffer size */ + herr_t ret_value = FAIL; #ifdef H5T_DEBUG H5_timer_t timer; #endif @@ -783,7 +833,6 @@ H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf) assert(mem_type); assert(buf); - /* Create buffer for data to store on disk */ nelmts=H5S_get_npoints (attr->ds); @@ -793,12 +842,12 @@ H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf) /* Get the maximum buffer size needed and allocate it */ buf_size = nelmts*MAX(src_type_size,dst_type_size); - tconv_buf = H5MM_xmalloc (buf_size); + tconv_buf = H5MM_xmalloc (buf_size); /* Copy the attribute data into the buffer for conversion */ HDmemcpy(tconv_buf,attr->data,src_type_size*nelmts); -/* Convert memory buffer into disk buffer */ + /* Convert memory buffer into disk buffer */ /* Set up type conversion function */ if (NULL == (tconv_func = H5T_find(attr->dt, mem_type, H5T_BKG_NO, &cdata))) { @@ -807,22 +856,22 @@ H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf) } else if (H5T_conv_noop!=tconv_func) { if ((src_id = H5I_register(H5_DATATYPE, H5T_copy(attr->dt, H5T_COPY_ALL)))<0 || - (dst_id = H5I_register(H5_DATATYPE, - H5T_copy(mem_type, H5T_COPY_ALL)))<0) { + (dst_id = H5I_register(H5_DATATYPE, + H5T_copy(mem_type, H5T_COPY_ALL)))<0) { HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion"); } } - /* Perform data type conversion. */ + /* Perform data type conversion. */ #ifdef H5T_DEBUG H5T_timer_begin (&timer, cdata); #endif - cdata->command = H5T_CONV_CONV; - if ((tconv_func) (src_id, dst_id, cdata, nelmts, tconv_buf, NULL)<0) { - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, - "data type conversion failed"); - } + cdata->command = H5T_CONV_CONV; + if ((tconv_func) (src_id, dst_id, cdata, nelmts, tconv_buf, NULL)<0) { + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, + "data type conversion failed"); + } #ifdef H5T_DEBUG H5T_timer_end (&timer, cdata, nelmts); #endif @@ -830,7 +879,6 @@ H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf) /* Copy the converted data into the user's buffer */ HDmemcpy(buf,tconv_buf,dst_type_size*nelmts); - ret_value=SUCCEED; done: @@ -867,15 +915,15 @@ done: hid_t H5Aget_space(hid_t attr_id) { - H5A_t *attr = NULL; + H5A_t *attr = NULL; H5S_t *dst = NULL; - hid_t ret_value = FAIL; + hid_t ret_value = FAIL; FUNC_ENTER(H5Aget_space, FAIL); /* check arguments */ if (H5_ATTR != H5I_group(attr_id) || - (NULL == (attr = H5I_object(attr_id)))) { + (NULL == (attr = H5I_object(attr_id)))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute"); } @@ -916,10 +964,9 @@ H5Aget_space(hid_t attr_id) * Modifications: * Robb Matzke, 4 Jun 1998 * The data type is reopened if it's a named type before returning it to - * the application. If the data type of the attribute is read-only then - * it is returned to the application as a read-only type. If an error - * occurs when atomizing the return data type then the data type is - * closed. + * the application. The data types returned by this function are always + * read-only. If an error occurs when atomizing the return data type + * then the data type is closed. --------------------------------------------------------------------------*/ hid_t H5Aget_type(hid_t attr_id) @@ -932,19 +979,25 @@ H5Aget_type(hid_t attr_id) /* check arguments */ if (H5_ATTR != H5I_group(attr_id) || - (NULL == (attr = H5I_object(attr_id)))) { + (NULL == (attr = H5I_object(attr_id)))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute"); } /* * Copy the attribute's data type. If the type is a named type then - * reopen the type before returning it to the user. + * reopen the type before returning it to the user. Make the type + * read-only. */ if (NULL==(dst=H5T_copy (attr->dt, H5T_COPY_REOPEN))) { HRETURN_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy datatype"); } - + if (H5T_lock (dst, FALSE)<0) { + H5T_close (dst); + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to lock transient data type"); + } + /* Atomize */ if ((ret_value=H5I_register (H5_DATATYPE, dst))<0) { H5T_close (dst); @@ -982,15 +1035,15 @@ H5Aget_type(hid_t attr_id) size_t H5Aget_name(hid_t attr_id, char *buf, size_t buf_size) { - H5A_t *attr = NULL; + H5A_t *attr = NULL; size_t copy_len=0; - size_t ret_value = FAIL; + size_t ret_value = FAIL; FUNC_ENTER(H5Aget_name, FAIL); /* check arguments */ if (H5_ATTR != H5I_group(attr_id) || - (NULL == (attr = H5I_object(attr_id)))) { + (NULL == (attr = H5I_object(attr_id)))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute"); } if (!buf || buf_size==0) { @@ -1029,30 +1082,41 @@ H5Aget_name(hid_t attr_id, char *buf, size_t buf_size) DESCRIPTION This function returns the number of attributes attached to a dataset or group, 'location_id'. + * + * Modifications: + * Robb Matzke, 5 Jun 1998 + * The LOC_ID can also be a named (committed) data type. --------------------------------------------------------------------------*/ int H5Anum_attrs(hid_t loc_id) { - H5G_entry_t *ent = NULL; /* Symbol table entry of object to attribute */ - void *obj = NULL; - int ret_value = 0; + H5G_entry_t *ent = NULL; /*symtab ent of object to attribute */ + void *obj = NULL; + int ret_value = 0; FUNC_ENTER(H5Anum_attrs, FAIL); /* check arguments */ - if (!(H5_DATASET == H5I_group(loc_id) || H5_GROUP == H5I_group(loc_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute target not a dataset or group"); - } - - /* Get the dataset or group's pointer */ - if(NULL == (obj = H5I_object(loc_id))) + if(NULL == (obj = H5I_object(loc_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); - - /* Copy the object header entry for the object */ - if (H5_DATASET == H5I_group(loc_id)) + } + switch (H5I_group (loc_id)) { + case H5_DATASET: ent = H5D_entof ((H5D_t*)obj); - else + break; + case H5_DATATYPE: + if (NULL==(ent=H5T_entof ((H5T_t*)obj))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "target data type is not committed"); + } + break; + case H5_GROUP: ent = H5G_entof ((H5G_t*)obj); + break; + default: + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "inappropriate attribute target"); + } /* Look up the attribute for the object */ ret_value=H5O_count(ent, H5O_ATTR); @@ -1097,51 +1161,74 @@ H5Anum_attrs(hid_t loc_id) C. Negative causes the iterator to immediately return that value, indicating failure. The iterator can be restarted at the next attribute. + * + * Modifications: + * Robb Matzke, 5 Jun 1998 + * The LOC_ID can also be a named (committed) data type. + * + * Robb Matzke, 5 Jun 1998 + * Like the group iterator, if ATTR_NUM is the null pointer then all + * attributes are processed. + * --------------------------------------------------------------------------*/ int H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op, void *op_data) { - H5G_entry_t *ent = NULL; /* Symbol table entry of object to attribute */ - void *obj = NULL; - H5A_t found_attr; - int ret_value = 0; + H5G_entry_t *ent = NULL; /*symtab ent of object to attribute */ + void *obj = NULL; + H5A_t found_attr; + intn ret_value = 0; + intn idx; - FUNC_ENTER(H5Anum_attrs, FAIL); + FUNC_ENTER(H5Aiterate, FAIL); /* check arguments */ - if (!(H5_DATASET == H5I_group(loc_id) || H5_GROUP == H5I_group(loc_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute target not a dataset or group"); + if(NULL == (obj = H5I_object(loc_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); } - if (!attr_num) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index"); + switch (H5I_group (loc_id)) { + case H5_DATASET: + ent = H5D_entof ((H5D_t*)obj); + break; + case H5_DATATYPE: + if (NULL==(ent=H5T_entof ((H5T_t*)obj))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "target data type is not committed"); + } + break; + case H5_GROUP: + ent = H5G_entof ((H5G_t*)obj); + break; + default: + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "inappropriate attribute target"); } if (!op) { HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid operator"); } - /* Get the dataset or group's pointer */ - if(NULL == (obj = H5I_object(loc_id))) - HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); - - /* Copy the object header entry for the object */ - if (H5_DATASET == H5I_group(loc_id)) - ent = H5D_entof ((H5D_t*)obj); - else - ent = H5G_entof ((H5G_t*)obj); - /* Look up the attribute for the object */ - if((int)*attr_numdata,old_attr->data,old_attr->data_size); } /* end if */ +#ifndef LATER /* Copy the share info? */ +#endif FUNC_LEAVE(new_attr); } @@ -1336,13 +1438,13 @@ H5A_close(H5A_t *attr) if (NULL == tmp_buf) { HRETURN_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, - "can't allocate attribute fill-value"); + "unable to allocate attribute fill-value"); } /* Go write the fill data to the attribute */ if (H5A_write(attr,attr->dt,tmp_buf)<0) { HRETURN_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, - "can't write attribute"); + "unable to write attribute"); } /* Free temporary buffer */ @@ -1363,7 +1465,9 @@ H5A_close(H5A_t *attr) if(attr->ent_opened) H5O_close(&(attr->ent)); -/* Do something with the shared information? */ +#ifndef LATER + /* Do something with the shared information? */ +#endif H5MM_xfree(attr); diff --git a/src/H5Apkg.h b/src/H5Apkg.h index 780a876..a0af7aa 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -37,8 +37,8 @@ struct H5A_t { size_t ds_size; /* Size of dataspace on disk */ void *data; /* Attribute data (on a temporary basis) */ size_t data_size; /* Size of data on disk */ - H5HG_t sh_heap; /*if defined, attribute is in global heap */ - H5F_t *sh_file; /*file pointer if this is a shared attribute */ + H5HG_t sh_heap; /*if defined, attribute is in global heap */ + H5F_t *sh_file; /*file pointer if this is a shared attribute */ }; /* Function prototypes for H5T package scope */ diff --git a/src/H5D.c b/src/H5D.c index 7c8783d..2141200 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -423,7 +423,7 @@ H5Dget_type (hid_t dataset_id) } if (H5T_lock (copied_type, FALSE)<0) { H5T_close (copied_type); - HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient data type"); } @@ -793,36 +793,31 @@ H5D_create(H5G_t *loc, const char *name, const H5T_t *type, const H5S_t *space, "unable to initialize contiguous storage"); } - /* Don't go through all these checks for scalar dataspaces */ - if(ndims>0) { - for (i=1; inew_dset->layout.dim[i]) { - HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, - "only the first dimension can be extendible"); - } + for (i=1; inew_dset->layout.dim[i]) { + HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, + "only the first dimension can be extendible"); } - if (efl->nused>0) { - hsize_t max_points = H5S_get_npoints_max (space); - hsize_t max_storage = H5O_efl_total_size (efl); - - if (H5S_UNLIMITED==max_points) { - if (H5O_EFL_UNLIMITED!=max_storage) { - HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, - "unlimited data space but finite " - "storage"); - } - } else if (max_points * H5T_get_size (type) < max_points) { - HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, - "data space * type size overflowed"); - } else if (max_points * H5T_get_size (type) > max_storage) { + } + if (efl->nused>0) { + hsize_t max_points = H5S_get_npoints_max (space); + hsize_t max_storage = H5O_efl_total_size (efl); + + if (H5S_UNLIMITED==max_points) { + if (H5O_EFL_UNLIMITED!=max_storage) { HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, - "data space size exceeds external storage " - "size"); + "unlimited data space but finite storage"); } - } else if (max_dim[0]>new_dset->layout.dim[0]) { - HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, NULL, - "extendible contiguous non-external dataset"); + } else if (max_points * H5T_get_size (type) < max_points) { + HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, + "data space * type size overflowed"); + } else if (max_points * H5T_get_size (type) > max_storage) { + HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, + "data space size exceeds external storage size"); } + } else if (ndims>0 && max_dim[0]>new_dset->layout.dim[0]) { + HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, NULL, + "extendible contiguous non-external dataset"); } break; diff --git a/src/H5O.c b/src/H5O.c index cb625c0..e587e40 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -533,6 +533,7 @@ H5O_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, H5O_t *oh) id = oh->mesg[i].type->id; UINT16ENCODE(p, id); + assert (oh->mesg[i].raw_size<65536); UINT16ENCODE(p, oh->mesg[i].raw_size); *p++ = oh->mesg[i].flags; *p++ = 0; /*reserved*/ @@ -1171,6 +1172,10 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite, } if (0==(flags & H5O_FLAG_SHARED)) { size = (type->raw_size) (ent->file, mesg); + if (size>=65536) { + HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, + "object header message is too large (16k max)"); + } } size = H5O_ALIGN(size); idx = H5O_alloc(ent->file, oh, type, size); diff --git a/src/H5Oattr.c b/src/H5Oattr.c index 2e56a75..ed629fd 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -76,9 +76,9 @@ static hbool_t interface_initialize_g = FALSE; static void * H5O_attr_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh) { - H5A_t *attr = NULL; - H5S_simple_t *simple; /*simple dimensionality information */ - size_t name_len; /* Attribute name length */ + H5A_t *attr = NULL; + H5S_simple_t *simple; /*simple dimensionality information */ + size_t name_len; /*attribute name length */ FUNC_ENTER(H5O_attr_decode, NULL); diff --git a/src/H5T.c b/src/H5T.c index 5f6b8ad..e3a1e1d 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -3775,6 +3775,46 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst, /*------------------------------------------------------------------------- + * Function: H5T_entof + * + * Purpose: Returns a pointer to the entry for a named data type. + * + * Return: Success: Ptr directly into named data type + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Friday, June 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5G_entry_t * +H5T_entof (H5T_t *dt) +{ + H5G_entry_t *ret_value = NULL; + + FUNC_ENTER (H5T_entof, NULL); + assert (dt); + + switch (dt->state) { + case H5T_STATE_TRANSIENT: + case H5T_STATE_RDONLY: + case H5T_STATE_IMMUTABLE: + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL, + "not a named data type"); + case H5T_STATE_NAMED: + case H5T_STATE_OPEN: + ret_value = &(dt->ent); + break; + } + + FUNC_LEAVE (ret_value); +} + + +/*------------------------------------------------------------------------- * Function: H5T_timer_begin * * Purpose: Start a timer for a data type conversion. diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 26fe27b..af3e2a3 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -60,6 +60,7 @@ herr_t H5T_pack (H5T_t *dt); herr_t H5T_debug (H5T_t *dt, FILE * stream); H5T_conv_t H5T_find (const H5T_t *src, const H5T_t *dst, H5T_bkg_t need_bkg, H5T_cdata_t **pcdata/*out*/); +H5G_entry_t *H5T_entof (H5T_t *dt); void H5T_timer_begin (H5_timer_t *timer, H5T_cdata_t *cdata); void H5T_timer_end (H5_timer_t *timer, H5T_cdata_t *cdata, size_t nelmts); diff --git a/src/h5ls.c b/src/h5ls.c index 64207be..c1d6965 100644 --- a/src/h5ls.c +++ b/src/h5ls.c @@ -28,6 +28,46 @@ usage (const char *progname) exit (1); } + +/*------------------------------------------------------------------------- + * Function: list_attr + * + * Purpose: Prints information about attributes. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Friday, June 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +list_attr (hid_t obj, const char *attr_name, void __unused__ *op_data) +{ + hid_t attr; + int i; + + printf ("%*s%s", 26, "", attr_name); + if ((attr = H5Aopen_name (obj, attr_name))) { + hid_t space = H5Aget_space (attr); + hsize_t size[64]; + int ndims = H5Sget_dims (space, size); + H5Sclose (space); + printf (" {"); + for (i=0; i=0) { printf ("Group\n"); + H5Aiterate (obj, NULL, list_attr, NULL); H5Gclose (obj); } else if (H5Gget_linkval (group, name, sizeof(buf), buf)>=0) { if (NULL==HDmemchr (buf, 0, sizeof(buf))) { @@ -91,6 +133,7 @@ list (hid_t group, const char *name, void __unused__ *op_data) printf (" -> %s\n", buf); } else if ((obj=H5Topen (group, name))>=0) { printf ("Data type\n"); + H5Aiterate (obj, NULL, list_attr, NULL); H5Tclose (obj); } else { printf ("Unknown Type\n"); diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c index 13d9ca3..1ccbe85 100644 --- a/test/cmpd_dset.c +++ b/test/cmpd_dset.c @@ -81,8 +81,11 @@ typedef struct s5_t { static void cleanup(void) { - remove(TEST_FILE_NAME); + if (!getenv ("HDF5_NOCLEANUP")) { + remove(TEST_FILE_NAME); + } } + /*------------------------------------------------------------------------- * Function: main diff --git a/test/dsets.c b/test/dsets.c index a6d86fa..fac3bdb 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -688,8 +688,11 @@ test_compression(hid_t file) static void cleanup(void) { - remove(TEST_FILE_NAME); + if (!getenv ("HDF5_NOCLEANUP")) { + remove(TEST_FILE_NAME); + } } + /*------------------------------------------------------------------------- * Function: main diff --git a/test/dtypes.c b/test/dtypes.c index 88b0d63..eed8a29 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -9,8 +9,18 @@ */ #include #include +#include #include +#include +#ifndef HAVE_ATTRIBUTE +# undef __attribute__ +# define __attribute__(X) /*void*/ +# define __unused__ /*void*/ +#else +# define __unused__ __attribute__((unused)) +#endif + #define FILE_NAME_1 "dtypes1.h5" #define FILE_NAME_2 "dtypes2.h5" @@ -21,7 +31,7 @@ typedef struct complex_t { /*------------------------------------------------------------------------- - * Function: clean + * Function: cleanup * * Purpose: Removes test files * @@ -35,10 +45,12 @@ typedef struct complex_t { *------------------------------------------------------------------------- */ static void -clean (void) +cleanup (void) { - remove (FILE_NAME_1); - remove (FILE_NAME_2); + if (!getenv ("HDF5_NOCLEANUP")) { + remove (FILE_NAME_1); + remove (FILE_NAME_2); + } } @@ -59,7 +71,7 @@ clean (void) *------------------------------------------------------------------------- */ static herr_t -display_error_cb (void *client_data) +display_error_cb (void __unused__ *client_data) { puts ("*FAILED*"); H5Eprint (stdout); @@ -214,7 +226,7 @@ test_compound(void) static herr_t test_transient (void) { - static hsize_t ds_size[2] = {100, 200}; + static hsize_t ds_size[2] = {10, 20}; hid_t file, type, space, dset, t2; printf ("%-70s", "Testing transient data types"); @@ -239,9 +251,18 @@ test_transient (void) /* Copying a predefined type results in a modifiable copy */ if ((type=H5Tcopy (H5T_NATIVE_INT))<0) goto error; if (H5Tset_precision (type, 256)<0) goto error; - if (H5Tclose (type)<0) goto error; + + /* It should not be possible to create an attribute for a transient type */ + H5E_BEGIN_TRY { + if (H5Acreate (type, "attr1", H5T_NATIVE_INT, space, H5P_DEFAULT)>=0) { + puts ("*FAILED*"); + puts (" Attributes should not be allowed for transient types!"); + goto error; + } + } H5E_END_TRY; /* Create a dataset from a transient data type */ + if (H5Tclose (type)<0) goto error; if ((type = H5Tcopy (H5T_NATIVE_INT))<0) goto error; if ((dset=H5Dcreate (file, "dset1", type, space, H5P_DEFAULT))<0) { goto error; @@ -321,9 +342,9 @@ test_transient (void) static herr_t test_named (void) { - hid_t file, type, space, dset, t2; + hid_t file, type, space, dset, t2, attr1; herr_t status; - static hsize_t ds_size[2] = {100, 200}; + static hsize_t ds_size[2] = {10, 20}; printf ("%-70s", "Testing named data types"); if ((file=H5Fcreate (FILE_NAME_2, H5F_ACC_TRUNC|H5F_ACC_DEBUG, @@ -368,6 +389,11 @@ test_named (void) } } H5E_END_TRY; + /* It should be possible to define an attribute for the named type */ + if ((attr1=H5Acreate (type, "attr1", H5T_NATIVE_INT, space, + H5P_DEFAULT))<0) goto error; + if (H5Aclose (attr1)<0) goto error; + /* * Copying a committed type should result in a transient type which is * not locked. @@ -509,6 +535,6 @@ main(void) exit(1); } printf("All data type tests passed.\n"); - clean (); + cleanup (); return 0; } diff --git a/test/extend.c b/test/extend.c index b582cc4..d1b3d0e 100644 --- a/test/extend.c +++ b/test/extend.c @@ -9,6 +9,7 @@ */ #include #include +#include #define TEST_FILE_NAME "extend.h5" #define NX 100 /* USE AN EVEN NUMBER!*/ @@ -32,8 +33,11 @@ static void cleanup(void) { - remove(TEST_FILE_NAME); + if (!getenv ("HDF5_NOCLEANUP")) { + remove(TEST_FILE_NAME); + } } + /*------------------------------------------------------------------------- * Function: main diff --git a/test/external.c b/test/external.c index 6857129..2c8e8a7 100644 --- a/test/external.c +++ b/test/external.c @@ -787,21 +787,24 @@ test_3 (void) static void cleanup(void) { - remove(TEST_FILE_NAME1); - remove(TEST_FILE_NAME2); - remove(TEST_FILE_NAME3); - /* not sure if the following file names can be #defined */ - /* because some of them are created during runtime. */ - /* List them out this way for now. */ - remove("extern_1.raw"); - remove("extern_1b.raw"); - remove("extern_2.raw"); - remove("extern_2b.raw"); - remove("extern_3.raw"); - remove("extern_3b.raw"); - remove("extern_4.raw"); - remove("extern_4b.raw"); + if (!getenv ("HDF5_NOCLEANUP")) { + remove(TEST_FILE_NAME1); + remove(TEST_FILE_NAME2); + remove(TEST_FILE_NAME3); + /* not sure if the following file names can be #defined */ + /* because some of them are created during runtime. */ + /* List them out this way for now. */ + remove("extern_1.raw"); + remove("extern_1b.raw"); + remove("extern_2.raw"); + remove("extern_2b.raw"); + remove("extern_3.raw"); + remove("extern_3b.raw"); + remove("extern_4.raw"); + remove("extern_4b.raw"); + } } + /*------------------------------------------------------------------------- * Function: main diff --git a/test/gheap.c b/test/gheap.c index 208f5e4..d6c6768 100644 --- a/test/gheap.c +++ b/test/gheap.c @@ -386,12 +386,15 @@ test_4 (void) static void cleanup(void) { - remove(TEST_FILE_NAME0); - remove(TEST_FILE_NAME1); - remove(TEST_FILE_NAME2); - remove(TEST_FILE_NAME3); - remove(TEST_FILE_NAME4); + if (!getenv ("HDF5_NOCLEANUP")) { + remove(TEST_FILE_NAME0); + remove(TEST_FILE_NAME1); + remove(TEST_FILE_NAME2); + remove(TEST_FILE_NAME3); + remove(TEST_FILE_NAME4); + } } + /*------------------------------------------------------------------------- * Function: main diff --git a/test/istore.c b/test/istore.c index fb02e20..15753a8 100644 --- a/test/istore.c +++ b/test/istore.c @@ -543,8 +543,11 @@ test_sparse(H5F_t *f, const char *prefix, size_t nblocks, static void cleanup(void) { - remove(FILENAME); + if (!getenv ("HDF5_NOCLEANUP")) { + remove(FILENAME); + } } + /*------------------------------------------------------------------------- * Function: main diff --git a/test/links.c b/test/links.c index 81c185d..006bf37 100644 --- a/test/links.c +++ b/test/links.c @@ -8,6 +8,7 @@ * Purpose: Tests hard and soft (symbolic) links. */ #include +#include #define TEST_FILE_NAME "links.h5" @@ -29,8 +30,11 @@ static void cleanup(void) { - remove(TEST_FILE_NAME); + if (!getenv ("HDF5_NOCLEANUP")) { + remove(TEST_FILE_NAME); + } } + /*------------------------------------------------------------------------- * Function: main diff --git a/test/shtype.c b/test/shtype.c index ba6c32d..c86998d 100644 --- a/test/shtype.c +++ b/test/shtype.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #ifndef HAVE_ATTRIBUTE @@ -286,12 +287,15 @@ test_3 (void) static void cleanup(void) { - remove(TEST_FILE_NAME0); - remove(TEST_FILE_NAME1); - remove(TEST_FILE_NAME2A); - remove(TEST_FILE_NAME2B); - remove(TEST_FILE_NAME3); + if (!getenv ("HDF5_NOCLEANUP")) { + remove(TEST_FILE_NAME0); + remove(TEST_FILE_NAME1); + remove(TEST_FILE_NAME2A); + remove(TEST_FILE_NAME2B); + remove(TEST_FILE_NAME3); + } } + /*------------------------------------------------------------------------- * Function: main -- cgit v0.12