diff options
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | RELEASE | 78 | ||||
-rw-r--r-- | config/irix5.3 | 2 | ||||
-rw-r--r-- | src/H5.c | 8 | ||||
-rw-r--r-- | src/H5A.c | 14 | ||||
-rw-r--r-- | src/H5AC.c | 2 | ||||
-rw-r--r-- | src/H5D.c | 2 | ||||
-rw-r--r-- | src/H5Distore.c | 2 | ||||
-rw-r--r-- | src/H5Ffamily.c | 4 | ||||
-rw-r--r-- | src/H5Fistore.c | 2 | ||||
-rw-r--r-- | src/H5G.c | 4 | ||||
-rw-r--r-- | src/H5Gprivate.h | 2 | ||||
-rw-r--r-- | src/H5HG.c | 2 | ||||
-rw-r--r-- | src/H5MM.c | 1 | ||||
-rw-r--r-- | src/H5O.c | 10 | ||||
-rw-r--r-- | src/H5T.c | 23 | ||||
-rw-r--r-- | src/H5Tbit.c | 176 | ||||
-rw-r--r-- | src/H5Tconv.c | 500 | ||||
-rw-r--r-- | src/H5Tpkg.h | 9 | ||||
-rw-r--r-- | src/H5detect.c | 9 | ||||
-rw-r--r-- | src/H5private.h | 1 | ||||
-rw-r--r-- | test/.distdep | 248 | ||||
-rw-r--r-- | test/chunk.c | 1 | ||||
-rw-r--r-- | test/dtypes.c | 351 |
24 files changed, 1270 insertions, 182 deletions
@@ -1,3 +1,4 @@ +./CHANGES_API ./INSTALL ./INSTALL.ascired ./INSTALL.ibm.sp.parallel @@ -1,6 +1,84 @@ Release information for hdf5-1.0.0a ----------------------------------- + CHANGES SINCE THE FIRST ALPHA + +* Two of the packages have been renamed. The data space API has been + renamed from `H5P' to `H5S' and the property list (template) API has + been renamed from `H5C' to `H5P'. + +* The new attribute API `H5A' has been added. An attribute is a small + dataset which can be attached to some other object (for instance, a + 4x4 transformation matrix attached to a 3-dimensional dataset, or an + English abstract attached to a group). + +* The error handling API `H5E' has been completed. By default, when an + API function returns failure an error stack is displayed on the + standard error stream. The H5Eset_auto() controls the automatic + printing and H5E_BEGIN_TRY/H5E_END_TRY macros can temporarily + disable the automatic error printing. + +* Support for large files and datasets (>2GB) has been added. There + is an html document that describes how it works. Some of the types + for function arguments have changed to support this: all arguments + pertaining to sizes of memory objects are `size_t' and all arguments + pertaining to file sizes are `hsize_t'. + +* More data type conversions have been added although none of them are + fine tuned for performance. There are new converters from integer + to integer and float to float, but not between integers and floating + points. A bug has been fixed in the converter between compound + types. + +* The numbered types have been removed from the API: int8, uint8, + int16, uint16, int32, uint32, int64, uint64, float32, and float64. + Use standard C types instead. Similarly, the numbered types were + removed from the H5T_NATIVE_* architecture; use unnumbered types + which correspond to the standard C types like H5T_NATIVE_INT. + +* More debugging support was added. If tracing is enabled at + configuration time and the HDF5_TRACE environment variable is set to + a file descriptor then all API calls will emit the function name, + argument names and values, and return value on that file number. + There is an html document that describes this. If appropriate + debugging options are enabled at configuration time, some packages + will display performance information on stderr. + +* Data types can be stored in the file as independent objects and + multiple datasets can share a data type. + +* The raw data I/O stream has been implemented and the application can + control meta and raw data caches, so I/O performance should be + improved from the first alpha release. + +* Group and attribute query functions have been implemented so it is + now possible to find out the contents of a file with no prior + knowledge. + +* External raw data storage allows datasets to be written by other + applications or I/O libraries and described and accessed through + HDF5. + +* Hard and soft (symbolic) links are implemented which allow groups to + share objects. + +* User-defined data compression is implemented although we may + generalize the interface to allow arbitrary user-defined filters + which can be used for compression, checksums, encryption, + performance monitoring, etc. The publicly-available `deflate' + method is predefined if the GNU libz.a can be found at configuration + time. + +* The configuration scripts have been modified to make it easier to + build debugging vs. production versions of the library. + +* The library automatically checks that the application was compiled + with the correct version of header files. + +* Parallel feature changes...(?) + + LIST OF API FUNCTIONS + The following functions are implemented. Errors are returned if an attempt is made to use some feature which is not implemented and printing the error stack will show `not implemented yet'. diff --git a/config/irix5.3 b/config/irix5.3 index acc375e..c0064ef 100644 --- a/config/irix5.3 +++ b/config/irix5.3 @@ -17,7 +17,7 @@ CC=cc RANLIB=: # What must *always* be present for things to compile correctly? -CFLAGS="$CFLAGS -ansi -fullwarn -woff 799" +CFLAGS="$CFLAGS -U_POSIX_SOURCE -ansi -fullwarn -woff 799" #CPPFLAGS="$CPPFLAGS -I." # What compiler flags should be used for code development? @@ -591,7 +591,7 @@ HDfprintf (FILE *stream, const char *fmt, ...) if (prec>0) { sprintf (template+strlen (template), ".%d", prec); } - if (modifier) { + if (*modifier) { sprintf (template+strlen (template), "%s", modifier); } sprintf (template+strlen (template), "%c", conv); @@ -1281,24 +1281,26 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...) case 'M': switch (type[1]) { -#ifdef HAVE_PARALLEL case 'c': if (ptr) { fprintf (out, "0x%lx", (unsigned long)vp); } else { +#ifdef HAVE_PARALLEL MPI_Comm comm = va_arg (ap, MPI_Comm); fprintf (out, "%ld", (long)comm); +#endif } break; case 'i': if (ptr) { fprintf (out, "0x%lx", (unsigned long)vp); } else { +#ifdef HAVE_PARALLEL MPI_Info info = va_arg (ap, MPI_Info); fprintf (out, "%ld", (long)info); +#endif } break; -#endif default: goto error; } @@ -157,7 +157,6 @@ H5Acreate (hid_t loc_id, const char *name, hid_t datatype, hid_t dataspace, 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); @@ -195,14 +194,11 @@ 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 (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, - "not a dataset creation property list"); - } - } else { - create_parms = &H5D_create_dflt; + if (H5P_DEFAULT!=create_plist && + (H5P_DATASET_CREATE != H5Pget_class(create_plist) || + NULL == H5I_object(create_plist))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset creation property list"); } /* Go do the real work for attaching the attribute to the dataset */ @@ -722,7 +722,7 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, const haddr_t *addr, HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - slot->aprots = na; + slot->aprots = (intn)na; slot->prot = x; } slot->prot[slot->nprots].type = type; @@ -972,7 +972,6 @@ H5D_open(H5G_t *loc, const char *name) H5D_t *dataset = NULL; /*the dataset which was found */ H5D_t *ret_value = NULL; /*return value */ intn i; - H5F_t *f = NULL; FUNC_ENTER(H5D_open, NULL); @@ -980,7 +979,6 @@ H5D_open(H5G_t *loc, const char *name) assert (loc); assert (name && *name); - f = H5G_fileof (loc); if (NULL==(dataset = H5MM_calloc(sizeof(H5D_t)))) { HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); diff --git a/src/H5Distore.c b/src/H5Distore.c index 2f23715..4cb808b 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -1086,7 +1086,7 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - rdcc->nslots = na; + rdcc->nslots = (intn)na; rdcc->slot = x; } HDmemmove (rdcc->slot+1, rdcc->slot, diff --git a/src/H5Ffamily.c b/src/H5Ffamily.c index bed381f..fd876c0 100644 --- a/src/H5Ffamily.c +++ b/src/H5Ffamily.c @@ -161,7 +161,7 @@ H5F_fam_open(const char *name, const H5F_access_t *access_parms, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - lf->u.fam.nalloc = na; + lf->u.fam.nalloc = (intn)na; lf->u.fam.memb = x; } lf->u.fam.memb[lf->u.fam.nmemb++] = member; @@ -425,7 +425,7 @@ H5F_fam_write(H5F_low_t *lf, const H5F_access_t *access_parms, HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - lf->u.fam.nalloc = na; + lf->u.fam.nalloc = (intn)na; lf->u.fam.memb = x; } for (i = lf->u.fam.nmemb; i <= membno; i++) { diff --git a/src/H5Fistore.c b/src/H5Fistore.c index 2f23715..4cb808b 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -1086,7 +1086,7 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - rdcc->nslots = na; + rdcc->nslots = (intn)na; rdcc->slot = x; } HDmemmove (rdcc->slot+1, rdcc->slot, @@ -1732,7 +1732,7 @@ H5G_loc (hid_t loc_id) *------------------------------------------------------------------------- */ herr_t -H5G_link (H5G_t *loc, H5G_type_t type, const char *cur_name, +H5G_link (H5G_t *loc, H5G_link_t type, const char *cur_name, const char *new_name) { H5G_entry_t cur_obj; /*entry for the link tail */ @@ -1882,7 +1882,7 @@ H5G_stat (H5G_t *loc, const char *name, hbool_t follow_link, /* * Initialize the stat buf. Symbolic links aren't normal objects and - * therefor don't have much of the normal info. However, the link value + * therefore don't have much of the normal info. However, the link value * length is specific to symbolic links. */ if (statbuf) { diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 7c76f2d..ae3064a 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -110,7 +110,7 @@ herr_t H5G_set (H5G_t *grp); herr_t H5G_push (H5G_t *grp); herr_t H5G_pop (H5F_t *f); H5G_t *H5G_getcwg(H5F_t *f); -herr_t H5G_link (H5G_t *loc, H5G_type_t type, const char *cur_name, +herr_t H5G_link (H5G_t *loc, H5G_link_t type, const char *cur_name, const char *new_name); herr_t H5G_stat (H5G_t *loc, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/); @@ -271,7 +271,7 @@ H5HG_load (H5F_t *f, const haddr_t *addr, const void __unused__ *udata1, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - heap->nalloc = nalloc; + heap->nalloc = (intn)nalloc; while (p<heap->chunk+heap->size) { if (p+H5HG_SIZEOF_OBJHDR(f)>heap->chunk+heap->size) { /* @@ -19,6 +19,7 @@ #include <H5MMprivate.h> /* Interface initialization? */ +#define PABLO_MASK H5MM_mask static hbool_t interface_initialize_g = FALSE; #define INTERFACE_INIT NULL @@ -393,7 +393,7 @@ H5O_load(H5F_t *f, const haddr_t *addr, const void __unused__ *_udata1, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - oh->alloc_nchunks = na; + oh->alloc_nchunks = (intn)na; oh->chunk = x; } @@ -1455,7 +1455,7 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - oh->alloc_nmesgs = na; + oh->alloc_nmesgs = (intn)na; oh->mesg = x; } delta = MAX(H5O_MIN_SIZE, size+H5O_SIZEOF_MSGHDR(f)); @@ -1589,7 +1589,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - oh->alloc_nchunks = na; + oh->alloc_nchunks = (intn)na; oh->chunk = x; } chunkno = oh->nchunks++; @@ -1613,7 +1613,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - oh->alloc_nmesgs = na; + oh->alloc_nmesgs = (intn)na; oh->mesg = x; /* Set new object header info to zeros */ @@ -1770,7 +1770,7 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - oh->alloc_nmesgs = na; + oh->alloc_nmesgs = (intn)na; oh->mesg = x; /* Set new object header info to zeros */ @@ -572,6 +572,11 @@ H5T_init_interface(void) HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to register conversion function"); } + if (H5Tregister_soft ("f_f", H5T_FLOAT, H5T_FLOAT, + H5T_conv_f_f) < 0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to register conversion function"); + } if (H5Tregister_soft("ibo", H5T_INTEGER, H5T_INTEGER, H5T_conv_order) < 0) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, @@ -597,7 +602,16 @@ H5T_init_interface(void) HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to register conversion function"); } - + if (H5Tregister_hard("flt_dbl", H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE, + H5T_conv_float_double)<0) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to register conversion function"); + } + if (H5Tregister_hard("dbl_flt", H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT, + H5T_conv_double_float)<0) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to register conversion function"); + } FUNC_LEAVE(ret_value); } @@ -2879,7 +2893,7 @@ H5Tregister_soft (const char *name, H5T_class_t src_cls, H5T_class_t dst_cls, HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - H5T_asoft_g = na; + H5T_asoft_g = (intn)na; H5T_soft_g = x; } HDstrncpy (H5T_soft_g[H5T_nsoft_g].name, name, H5T_NAMELEN); @@ -3697,7 +3711,7 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - parent->u.compnd.nalloc = na; + parent->u.compnd.nalloc = (intn)na; parent->u.compnd.memb = x; } @@ -4197,7 +4211,7 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst, HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - H5T_apath_g = na; + H5T_apath_g = (intn)na; H5T_path_g = x; } if (cmp > 0) md++; @@ -4266,6 +4280,7 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst, } if ((H5T_soft_g[i].func) (src_id, dst_id, &(path->cdata), H5T_CONV_INIT, NULL, NULL) < 0) { + H5MM_xfree(path->cdata.stats); HDmemset (&(path->cdata), 0, sizeof(H5T_cdata_t)); H5E_clear(); /*ignore the error*/ } else { diff --git a/src/H5Tbit.c b/src/H5Tbit.c index b9a830d..d80c8b3 100644 --- a/src/H5Tbit.c +++ b/src/H5Tbit.c @@ -11,8 +11,15 @@ */ #define H5T_PACKAGE #include <H5private.h> +#include <H5Eprivate.h> +#include <H5Iprivate.h> #include <H5Tpkg.h> +/* Interface initialization */ +#define PABLO_MASK H5Tbit_mask +static intn interface_initialize_g = FALSE; +#define INTERFACE_INIT NULL + /*------------------------------------------------------------------------- * Function: H5T_bit_copy @@ -40,8 +47,8 @@ H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, * Normalize the offset to be a byte number and a bit offset within that * byte. */ - s_idx = src_offset / 8; - d_idx = dst_offset / 8; + s_idx = (intn)src_offset / 8; + d_idx = (intn)dst_offset / 8; src_offset %= 8; dst_offset %= 8; @@ -62,7 +69,7 @@ H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, * dst[d_idx+1] dst[d_idx] */ while (src_offset && size>0) { - unsigned nbits = MIN3 (size, 8-dst_offset, 8-src_offset); + unsigned nbits = (unsigned)MIN3 (size, 8-dst_offset, 8-src_offset); unsigned mask = (1<<nbits) - 1; dst[d_idx] &= ~(mask<<dst_offset); @@ -102,9 +109,9 @@ H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, * bits). SHIFT is three since the source must be shifted right three bits * to line up with the destination. */ - shift = dst_offset; + shift = (intn)dst_offset; mask_lo = (1<<(8-shift))-1; - mask_hi = ~mask_lo; + mask_hi = (~mask_lo) & 0xff; for (/*void*/; size>8; size-=8, d_idx++, s_idx++) { if (shift) { @@ -119,7 +126,7 @@ H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, /* Finish up */ while (size>0) { - unsigned nbits = MIN3 (size, 8-dst_offset, 8-src_offset); + unsigned nbits = (unsigned)MIN3 (size, 8-dst_offset, 8-src_offset); unsigned mask = (1<<nbits) - 1; dst[d_idx] &= ~(mask<<dst_offset); @@ -141,6 +148,94 @@ H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, /*------------------------------------------------------------------------- + * Function: H5T_bit_get_d + * + * Purpose: Return a small bit sequence as a number. + * + * Return: Success: The bit sequence interpretted as an unsigned + * integer. + * + * Failure: 0 + * + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hsize_t +H5T_bit_get_d (uint8 *buf, size_t offset, size_t size) +{ + hsize_t val=0; + size_t i, hs; + + FUNC_ENTER (H5T_bit_get_d, 0); + assert (8*sizeof(val)>=size); + + H5T_bit_copy ((uint8*)&val, 0, buf, offset, size); + switch (((H5T_t*)(H5I_object(H5T_NATIVE_INT_g)))->u.atomic.order) { + case H5T_ORDER_LE: + break; + + case H5T_ORDER_BE: + for (i=0, hs=sizeof(val)/2; i<hs; i++) { + uint8 tmp = ((uint8*)&val)[i]; + ((uint8*)&val)[i] = ((uint8*)&val)[sizeof(val)-(i+1)]; + ((uint8*)&val)[sizeof(val)-(i+1)] = tmp; + } + break; + + default: + abort (); + } + + FUNC_LEAVE (val); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_bit_set_d + * + * Purpose: Sets part of a bit vector to the specified unsigned value. + * + * Return: void + * + * Programmer: Robb Matzke + * Wednesday, June 24, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +H5T_bit_set_d (uint8 *buf, size_t offset, size_t size, hsize_t val) +{ + size_t i, hs; + + assert (8*sizeof(val)>=size); + + switch (((H5T_t*)(H5I_object(H5T_NATIVE_INT_g)))->u.atomic.order) { + case H5T_ORDER_LE: + break; + + case H5T_ORDER_BE: + for (i=0, hs=sizeof(val)/2; i<hs; i++) { + uint8 tmp = ((uint8*)&val)[i]; + ((uint8*)&val)[i] = ((uint8*)&val)[sizeof(val)-(i+1)]; + ((uint8*)&val)[sizeof(val)-(i+1)] = tmp; + } + break; + + default: + abort (); + } + + H5T_bit_copy (buf, offset, (uint8*)&val, 0, size); +} + + +/*------------------------------------------------------------------------- * Function: H5T_bit_set * * Purpose: Sets or clears bits in a contiguous region of a vector @@ -161,7 +256,7 @@ H5T_bit_set (uint8 *buf, size_t offset, size_t size, hbool_t value) intn idx; /* Normalize */ - idx = offset / 8; + idx = (intn)offset / 8; offset %= 8; /* The first partial byte */ @@ -217,7 +312,7 @@ ssize_t H5T_bit_find (uint8 *buf, size_t offset, size_t size, H5T_sdir_t direction, hbool_t value) { - size_t base=offset; + ssize_t base=(ssize_t)offset; ssize_t idx, i; /* Some functions call this with value=TRUE */ @@ -300,3 +395,68 @@ H5T_bit_find (uint8 *buf, size_t offset, size_t size, H5T_sdir_t direction, return -1; } + + +/*------------------------------------------------------------------------- + * Function: H5T_bit_inc + * + * Purpose: Increment part of a bit field by adding 1. + * + * Return: Success: The carry-out value, one if overflow zero + * otherwise. + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, June 26, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hbool_t +H5T_bit_inc(uint8 *buf, size_t start, size_t size) +{ + size_t idx = start / 8; + unsigned carry = 1; + unsigned acc, mask; + + assert(buf); + start %= 8; + + /* The first partial byte */ + if (start) { + if (size+start<8) mask = (1<<size)-1; + else mask = (1<<(8-start))-1; + acc = (buf[idx]>>start) & mask; + acc += 1; + carry = acc & (1<<MIN(size, 8-start)); + buf[idx] &= ~(mask<<start); + buf[idx] |= (acc & mask) << start; + size -= MIN(size, 8-start); + start=0; + idx++; + } + + /* The middle */ + while (carry && size>=8) { + acc = buf[idx]; + acc += 1; + carry = acc & 0x100; + buf[idx] = acc & 0xff; + idx++; + size -= 8; + } + + /* The last bits */ + if (carry && size>0) { + mask = (1<<size)-1; + acc = buf[idx] & mask; + acc += 1; + carry = acc & (1<<size); + buf[idx] &= ~mask; + buf[idx] |= acc & mask; + } + + return carry ? TRUE : FALSE; +} diff --git a/src/H5Tconv.c b/src/H5Tconv.c index f994345..930b330 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -620,12 +620,14 @@ H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, } else if (src->size>=dst->size) { sp = dp = (uint8*)buf; direction = 1; - olap = ceil((double)(src->size)/(src->size-dst->size))-1; + olap = (size_t)(ceil((double)(src->size)/ + (double)(src->size-dst->size))-1); } else { sp = (uint8*)buf + (nelmts-1) * src->size; dp = (uint8*)buf + (nelmts-1) * dst->size; direction = -1; - olap = ceil((double)(dst->size)/(dst->size-src->size))-1; + olap = (size_t)(ceil((double)(dst->size)/ + (double)(dst->size-src->size))-1); } /* The conversion loop */ @@ -871,6 +873,497 @@ H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, /*------------------------------------------------------------------------- + * Function: H5T_conv_f_f + * + * Purpose: Convert one floating point type to another. This is a catch + * all for floating point conversions and is probably not + * particularly fast! + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *buf, void __unused__ *bkg) +{ + /* Traversal-related variables */ + H5T_t *src_p; /*source data type */ + H5T_t *dst_p; /*destination data type */ + H5T_atomic_t src; /*atomic source info */ + H5T_atomic_t dst; /*atomic destination info */ + intn direction; /*forward or backward traversal */ + size_t elmtno; /*element number */ + size_t half_size; /*half the type size */ + size_t olap; /*num overlapping elements */ + ssize_t bitno; /*bit number */ + uint8 *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ + uint8 dbuf[64]; /*temp destination buffer */ + + /* Conversion-related variables */ + hssize_t expo; /*exponent */ + hssize_t expo_max; /*maximum possible dst exponent */ + size_t msize; /*useful size of mantissa in src*/ + size_t mpos; /*offset to useful mant is src */ + size_t mrsh; /*amount to right shift mantissa*/ + hbool_t carry; /*carry after rounding mantissa */ + size_t i; /*miscellaneous counters */ + size_t implied; /*destination implied bits */ + + FUNC_ENTER (H5T_conv_f_f, FAIL); + + switch (cdata->command) { + case H5T_CONV_INIT: + if (H5_DATATYPE!=H5I_group (src_id) || + NULL==(src_p=H5I_object (src_id)) || + H5_DATATYPE!=H5I_group (dst_id) || + NULL==(dst_p=H5I_object (dst_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + src = src_p->u.atomic; + dst = dst_p->u.atomic; + if (H5T_ORDER_LE!=src.order && + H5T_ORDER_BE!=src.order) { + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unsupported byte order"); + } + if (H5T_ORDER_LE!=dst.order && + H5T_ORDER_BE!=dst.order) { + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unsupported byte order"); + } + if (dst_p->size>sizeof(dbuf)) { + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "destination size is too large"); + } + if (8*sizeof(expo)-1<src.u.f.esize || + 8*sizeof(expo)-1<dst.u.f.esize) { + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "exponent field is too large"); + } + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + /* Get the data types */ + if (H5_DATATYPE!=H5I_group (src_id) || + NULL==(src_p=H5I_object (src_id)) || + H5_DATATYPE!=H5I_group (dst_id) || + NULL==(dst_p=H5I_object (dst_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + src = src_p->u.atomic; + dst = dst_p->u.atomic; + expo_max = ((hssize_t)1 << dst.u.f.esize) - 1; + + /* + * Do we process the values from beginning to end or vice versa? Also, + * how many of the elements have the source and destination areas + * overlapping? + */ + if (src_p->size==dst_p->size) { + sp = dp = (uint8*)buf; + direction = 1; + olap = nelmts; + } else if (src_p->size>=dst_p->size) { + sp = dp = (uint8*)buf; + direction = 1; + olap = (size_t)(ceil((double)(src_p->size)/ + (double)(src_p->size-dst_p->size))-1); + } else { + sp = (uint8*)buf + (nelmts-1) * src_p->size; + dp = (uint8*)buf + (nelmts-1) * dst_p->size; + direction = -1; + olap = (size_t)(ceil((double)(dst_p->size)/ + (double)(dst_p->size-src_p->size))-1); + } + + /* The conversion loop */ + for (elmtno=0; elmtno<nelmts; elmtno++) { + /* + * If the source and destination buffers overlap then use a + * temporary buffer for the destination. + */ + if (direction>0) { + s = sp; + d = elmtno<olap ? dbuf : dp; + } else { + s = sp; + d = elmtno >= nelmts-olap ? dbuf : dp; + } +#ifndef NDEBUG + /* I don't quite trust the overlap calculations yet --rpm */ + if (d==dbuf) { + assert ((dp>=sp && dp<sp+src_p->size) || + (sp>=dp && sp<dp+dst_p->size)); + } else { + assert ((dp<sp && dp+dst_p->size<=sp) || + (sp<dp && sp+src_p->size<=dp)); + } +#endif + + /* + * Put the data in little endian order so our loops aren't so + * complicated. We'll do all the conversion stuff assuming + * little endian and then we'll fix the order at the end. + */ + if (H5T_ORDER_BE==src.order) { + half_size = src_p->size/2; + for (i=0; i<half_size; i++) { + uint8 tmp = s[src_p->size-(i+1)]; + s[src_p->size-(i+1)] = s[i]; + s[i] = tmp; + } + } + + /* + * Check for special cases: +0, -0, +Inf, -Inf, NaN + */ + if (H5T_bit_find (s, src.u.f.mpos, src.u.f.msize, + H5T_BIT_LSB, TRUE)<0) { + if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize, + H5T_BIT_LSB, TRUE)<0) { + /* +0 or -0 */ + H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1); + H5T_bit_set (d, dst.u.f.epos, dst.u.f.esize, FALSE); + H5T_bit_set (d, dst.u.f.mpos, dst.u.f.esize, FALSE); + goto padding; + } else if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize, + H5T_BIT_LSB, FALSE)<0) { + /* +Inf or -Inf */ + H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1); + H5T_bit_set (d, dst.u.f.epos, dst.u.f.esize, TRUE); + H5T_bit_set (d, dst.u.f.mpos, dst.u.f.msize, FALSE); + goto padding; + } + } else if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize, + H5T_BIT_LSB, FALSE)<0) { + /* + * NaN. There are many NaN values, so we just set all bits of + * the significand. + */ + H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1); + H5T_bit_set (d, dst.u.f.epos, dst.u.f.esize, TRUE); + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, TRUE); + goto padding; + } + + /* + * Get the exponent as an unsigned quantity from the section of + * the source bit field where it's located. Don't worry about + * the exponent bias yet. + */ + expo = H5T_bit_get_d(s, src.u.f.epos, src.u.f.esize); + + /* + * Set markers for the source mantissa, excluding the leading `1' + * (might be implied). + */ + implied = 1; + mpos = src.u.f.mpos; + mrsh = 0; + if (0==expo || H5T_NORM_NONE==src.u.f.norm) { + if ((bitno=H5T_bit_find(s, src.u.f.mpos, src.u.f.msize, + H5T_BIT_MSB, TRUE))>0) { + msize = bitno; + } else if (0==bitno) { + msize = 1; + H5T_bit_set(s, src.u.f.mpos, 1, FALSE); + } + } else if (H5T_NORM_IMPLIED==src.u.f.norm) { + msize = src.u.f.msize; + } else { + assert("normalization method not implemented yet" && 0); + abort(); + } + + /* + * The sign for the destination is the same as the sign for the + * source in all cases. + */ + H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1); + + /* + * Calculate the true source exponent by adjusting according to + * the source exponent bias. + */ + if (0==expo || H5T_NORM_NONE==src.u.f.norm) { + bitno = H5T_bit_find(s, src.u.f.mpos, src.u.f.msize, + H5T_BIT_MSB, TRUE); + assert(bitno>=0); + expo -= (src.u.f.ebias-1) + (src.u.f.msize-bitno); + } else if (H5T_NORM_IMPLIED==src.u.f.norm) { + expo -= src.u.f.ebias; + } else { + assert("normalization method not implemented yet" && 0); + abort(); + } + + /* + * If the destination is not normalized then right shift the + * mantissa by one. + */ + if (H5T_NORM_NONE==dst.u.f.norm) { + mrsh++; + } + + /* + * Calculate the destination exponent by adding the destination + * bias and clipping by the minimum and maximum possible + * destination exponent values. + */ + expo += dst.u.f.ebias; + if (expo < -(hssize_t)(dst.u.f.msize)) { + /* The exponent is way too small. Result is zero. */ + expo = 0; + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE); + msize = 0; + + } else if (expo<=0) { + /* + * The exponent is too small to fit in the exponent field, + * but by shifting the mantissa to the right we can + * accomodate that value. The mantissa of course is no + * longer normalized. + */ + mrsh += 1-expo; + expo = 0; + + } else if (expo>=expo_max) { + /* + * The exponent is too large to fit in the available region + * or it results in the maximum possible value. Use positive + * or negative infinity instead. + */ + expo = expo_max; + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE); + msize = 0; + + } + + /* + * If the destination mantissa is smaller than the source + * mantissa then round the source mantissa. Rounding may cause a + * carry in which case the exponent has to be re-evaluated for + * overflow. That is, if `carry' is clear then the implied + * mantissa bit is `1', else it is `10' binary. + */ + if (msize>0 && mrsh<=dst.u.f.msize && mrsh+msize>dst.u.f.msize) { + bitno = (ssize_t)(mrsh+msize - dst.u.f.msize); + assert(bitno>=0 && (size_t)bitno<=msize); + carry = H5T_bit_inc(s, mpos+bitno-1, 1+msize-bitno); + if (carry) implied = 2; + } + + /* + * Write the mantissa to the destination + */ + if (mrsh>dst.u.f.msize+1) { + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE); + } else if (mrsh==dst.u.f.msize+1) { + H5T_bit_set(d, dst.u.f.mpos+1, dst.u.f.msize-1, FALSE); + H5T_bit_set(d, dst.u.f.mpos, 1, TRUE); + } else if (mrsh==dst.u.f.msize) { + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE); + H5T_bit_set_d(d, dst.u.f.mpos, MIN(2, dst.u.f.msize), implied); + } else { + if (mrsh>0) { + H5T_bit_set(d, dst.u.f.mpos+dst.u.f.msize-mrsh, mrsh, + FALSE); + H5T_bit_set_d(d, dst.u.f.mpos+dst.u.f.msize-mrsh, 2, + implied); + } + if (mrsh+msize>=dst.u.f.msize) { + H5T_bit_copy(d, dst.u.f.mpos, + s, (mpos+msize+mrsh-dst.u.f.msize), + dst.u.f.msize-mrsh); + } else { + H5T_bit_copy(d, dst.u.f.mpos+dst.u.f.msize-(mrsh+msize), + s, mpos, msize); + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize-(mrsh+msize), + FALSE); + } + } + + /* Write the exponent */ + H5T_bit_set_d(d, dst.u.f.epos, dst.u.f.esize, expo); + + padding: +#ifndef LATER + /* + * Set internal padding areas + */ +#endif + + /* + * Set external padding areas + */ + if (dst.offset>0) { + assert (H5T_PAD_ZERO==dst.lsb_pad || + H5T_PAD_ONE==dst.lsb_pad); + H5T_bit_set (d, 0, dst.offset, + H5T_PAD_ONE==dst.lsb_pad); + } + if (dst.offset+dst.prec!=8*dst_p->size) { + assert (H5T_PAD_ZERO==dst.msb_pad || + H5T_PAD_ONE==dst.msb_pad); + H5T_bit_set (d, dst.offset+dst.prec, + 8*dst_p->size - (dst.offset+dst.prec), + H5T_PAD_ONE==dst.msb_pad); + } + + /* + * Put the destination in the correct byte order. See note at + * beginning of loop. + */ + if (H5T_ORDER_BE==dst.order) { + half_size = dst_p->size/2; + for (i=0; i<half_size; i++) { + uint8 tmp = d[dst_p->size-(i+1)]; + d[dst_p->size-(i+1)] = d[i]; + d[i] = tmp; + } + } + + /* + * If we had used a temporary buffer for the destination then we + * should copy the value to the true destination buffer. + */ + if (d==dbuf) HDmemcpy (dp, d, dst_p->size); + sp += direction * src_p->size; + dp += direction * dst_p->size; + } + + break; + + default: + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unknown conversion command"); + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_conv_float_double + * + * Purpose: Convert native `float' to native `double' using hardware. + * This is a fast special case. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_float_double (hid_t __unused__ src_id, hid_t __unused__ dst_id, + H5T_cdata_t *cdata, size_t nelmts, void *buf, + void __unused__ *bkg) +{ + size_t elmtno; /*element number */ + float *s; /*source buffer */ + double *d; /*destination buffer */ + + FUNC_ENTER (H5T_conv_float_double, FAIL); + + switch (cdata->command) { + case H5T_CONV_INIT: + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + s = (float*)buf + nelmts; + d = (double*)buf + nelmts; + + for (elmtno=0; elmtno<nelmts; elmtno++) { + *--d = *--s; + } + break; + + default: + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unknown conversion command"); + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_conv_double_float + * + * Purpose: Convert native `double' to native `float' using hardware. + * This is a fast special case. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_double_float (hid_t __unused__ src_id, hid_t __unused__ dst_id, + H5T_cdata_t *cdata, size_t nelmts, void *buf, + void __unused__ *bkg) +{ + size_t elmtno; /*element number */ + double *s; /*source buffer */ + float *d; /*destination buffer */ + + FUNC_ENTER (H5T_conv_double_float, FAIL); + + switch (cdata->command) { + case H5T_CONV_INIT: + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + s = (double*)buf; + d = (float*)buf; + + for (elmtno=0; elmtno<nelmts; elmtno++) { + *d++ = *s++; + } + break; + + default: + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unknown conversion command"); + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- * Function: H5T_conv_i32le_f64le * * Purpose: Converts 4-byte little-endian integers (signed or unsigned) @@ -894,7 +1387,6 @@ H5T_conv_i32le_f64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, uint8 *s=NULL, *d=NULL; /*src and dst buf pointers */ uint8 tmp[8]; /*temporary destination buffer */ H5T_t *src = NULL; /*source data type */ - H5T_t *dst = NULL; /*destination data type */ size_t elmtno; /*element counter */ uintn sign; /*sign bit */ uintn cin, cout; /*carry in/out */ @@ -919,7 +1411,7 @@ H5T_conv_i32le_f64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, if (H5_DATATYPE!=H5I_group (src_id) || NULL==(src=H5I_object (src_id)) || H5_DATATYPE!=H5I_group (dst_id) || - NULL==(dst=H5I_object (dst_id))) { + NULL==H5I_object (dst_id)) { HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 4257d52..a411916 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -127,6 +127,12 @@ herr_t H5T_conv_struct (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *_buf, void *bkg); herr_t H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *_buf, void __unused__ *bkg); +herr_t H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *_buf, void __unused__ *bkg); +herr_t H5T_conv_float_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *buf, void __unused__ *bkg); +herr_t H5T_conv_double_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *buf, void __unused__ *bkg); herr_t H5T_conv_i32le_f64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *_buf, void __unused__ *bkg); @@ -134,7 +140,10 @@ herr_t H5T_conv_i32le_f64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, void H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, size_t src_offset, size_t size); void H5T_bit_set (uint8 *buf, size_t offset, size_t size, hbool_t value); +hsize_t H5T_bit_get_d (uint8 *buf, size_t offset, size_t size); +void H5T_bit_set_d (uint8 *buf, size_t offset, size_t size, hsize_t val); ssize_t H5T_bit_find (uint8 *buf, size_t offset, size_t size, H5T_sdir_t direction, hbool_t value); +hbool_t H5T_bit_inc(uint8 *buf, size_t start, size_t size); #endif diff --git a/src/H5detect.c b/src/H5detect.c index b429caf..9e07688 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -71,7 +71,7 @@ static int byte_cmp(int, void *, void *); static int bit_cmp(int, int *, void *, void *); static void fix_order(int, int, int, int *, const char **); static int imp_bit(int, int *, void *, void *); -static unsigned long find_bias(int, int, int, int *, void *); +static unsigned long find_bias(int, int, int *, void *); static void precision (detected_t*); static void print_header(void); @@ -300,7 +300,7 @@ static detected_t Known[] = INFO.esize = INFO.sign - INFO.epos; \ \ _v1 = 1.0; \ - INFO.bias = find_bias (INFO.epos, INFO.esize, INFO.imp, INFO.perm, &_v1); \ + INFO.bias = find_bias (INFO.epos, INFO.esize, INFO.perm, &_v1); \ precision (&(INFO)); \ } @@ -755,7 +755,7 @@ imp_bit(int n, int *perm, void *_a, void *_b) *------------------------------------------------------------------------- */ static unsigned long -find_bias(int epos, int esize, int imp, int *perm, void *_a) +find_bias(int epos, int esize, int *perm, void *_a) { unsigned char *a = (unsigned char *) _a; unsigned char mask; @@ -771,8 +771,7 @@ find_bias(int epos, int esize, int imp, int *perm, void *_a) esize -= nbits; epos += nbits; } - - return bias - (imp ? 0 : 1); + return bias; } diff --git a/src/H5private.h b/src/H5private.h index e079682..82f0add 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -517,7 +517,6 @@ extern char *strdup(const char *s); #define H5TRACE_RETURN(V) /*void*/ #endif -extern FILE *H5_trace_g; void H5_trace (hbool_t returning, const char *func, const char *type, ...); diff --git a/test/.distdep b/test/.distdep index 388026c..a2fcc62 100644 --- a/test/.distdep +++ b/test/.distdep @@ -4,6 +4,30 @@ testhdf5.o: \ ../src/H5private.h \ ../src/H5public.h \ ../src/H5config.h +tattr.o: \ + tattr.c \ + testhdf5.h \ + ../src/H5private.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5Eprivate.h \ + ../src/H5Epublic.h \ + ../src/H5Ipublic.h \ + ../src/hdf5.h \ + ../src/H5Apublic.h \ + ../src/H5ACpublic.h \ + ../src/H5Bpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Fpublic.h \ + ../src/H5Gpublic.h \ + ../src/H5HGpublic.h \ + ../src/H5HLpublic.h \ + ../src/H5MFpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Opublic.h \ + ../src/H5Ppublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Spublic.h tfile.o: \ tfile.c \ testhdf5.h \ @@ -106,29 +130,35 @@ tstab.o: \ ../src/H5Tpublic.h \ ../src/H5Sprivate.h \ ../src/H5Spublic.h -extend.o: \ - extend.c \ - ../src/hdf5.h \ +th5s.o: \ + th5s.c \ + testhdf5.h \ + ../src/H5private.h \ ../src/H5public.h \ ../src/H5config.h \ + ../src/H5Eprivate.h \ + ../src/H5Epublic.h \ ../src/H5Ipublic.h \ - ../src/H5Apublic.h \ - ../src/H5ACpublic.h \ + ../src/H5Bprivate.h \ ../src/H5Bpublic.h \ - ../src/H5Dpublic.h \ - ../src/H5Epublic.h \ + ../src/H5Fprivate.h \ ../src/H5Fpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Sprivate.h \ + ../src/H5Spublic.h \ + ../src/H5Gprivate.h \ ../src/H5Gpublic.h \ - ../src/H5HGpublic.h \ - ../src/H5HLpublic.h \ - ../src/H5MFpublic.h \ - ../src/H5MMpublic.h \ + ../src/H5Oprivate.h \ ../src/H5Opublic.h \ - ../src/H5Ppublic.h \ + ../src/H5HGprivate.h \ + ../src/H5HGpublic.h \ + ../src/H5Tprivate.h \ + ../src/H5Tpublic.h \ + ../src/H5Zprivate.h \ ../src/H5Zpublic.h \ - ../src/H5Spublic.h -iopipe.o: \ - iopipe.c \ + ../src/H5Pprivate.h +dtypes.o: \ + dtypes.c \ ../src/hdf5.h \ ../src/H5public.h \ ../src/H5config.h \ @@ -148,26 +178,44 @@ iopipe.o: \ ../src/H5Ppublic.h \ ../src/H5Zpublic.h \ ../src/H5Spublic.h \ - ../src/H5Tpublic.h -gheap.o: \ - gheap.c \ + ../src/H5Tpublic.h \ + ../src/H5Tpkg.h \ + ../src/H5HGprivate.h \ + ../src/H5Fprivate.h \ + ../src/H5private.h +hyperslab.o: \ + hyperslab.c \ + ../src/H5private.h \ + ../src/H5public.h \ + ../src/H5config.h +istore.o: \ + istore.c \ ../src/H5private.h \ ../src/H5public.h \ ../src/H5config.h \ - ../src/H5Eprivate.h \ - ../src/H5Epublic.h \ + ../src/H5Iprivate.h \ ../src/H5Ipublic.h \ - ../src/H5Fprivate.h \ - ../src/H5Fpublic.h \ + ../src/H5Pprivate.h \ + ../src/H5Ppublic.h \ ../src/H5Dpublic.h \ + ../src/H5Fpublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Fprivate.h \ ../src/H5Gprivate.h \ ../src/H5Gpublic.h \ ../src/H5Bprivate.h \ ../src/H5Bpublic.h \ + ../src/H5MMprivate.h \ + ../src/H5MMpublic.h \ + ../src/H5Oprivate.h \ + ../src/H5Opublic.h \ ../src/H5HGprivate.h \ - ../src/H5HGpublic.h -shtype.o: \ - shtype.c \ + ../src/H5HGpublic.h \ + ../src/H5Tprivate.h \ + ../src/H5Tpublic.h \ + ../src/H5Sprivate.h +dsets.o: \ + dsets.c \ ../src/hdf5.h \ ../src/H5public.h \ ../src/H5config.h \ @@ -186,9 +234,10 @@ shtype.o: \ ../src/H5Opublic.h \ ../src/H5Ppublic.h \ ../src/H5Zpublic.h \ - ../src/H5Spublic.h -big.o: \ - big.c \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h +cmpd_dset.o: \ + cmpd_dset.c \ ../src/hdf5.h \ ../src/H5public.h \ ../src/H5config.h \ @@ -207,11 +256,9 @@ big.o: \ ../src/H5Opublic.h \ ../src/H5Ppublic.h \ ../src/H5Zpublic.h \ - ../src/H5Spublic.h \ - ../src/H5Tpublic.h \ - ../src/H5private.h -links.o: \ - links.c \ + ../src/H5Spublic.h +extend.o: \ + extend.c \ ../src/hdf5.h \ ../src/H5public.h \ ../src/H5config.h \ @@ -230,10 +277,9 @@ links.o: \ ../src/H5Opublic.h \ ../src/H5Ppublic.h \ ../src/H5Zpublic.h \ - ../src/H5Spublic.h \ - ../src/H5Tpublic.h -chunk.o: \ - chunk.c \ + ../src/H5Spublic.h +external.o: \ + external.c \ ../src/hdf5.h \ ../src/H5public.h \ ../src/H5config.h \ @@ -254,25 +300,8 @@ chunk.o: \ ../src/H5Zpublic.h \ ../src/H5Spublic.h \ ../src/H5Tpublic.h -bittests.o: \ - bittests.c \ - ../src/H5Tpkg.h \ - ../src/H5HGprivate.h \ - ../src/H5HGpublic.h \ - ../src/H5public.h \ - ../src/H5config.h \ - ../src/H5Fprivate.h \ - ../src/H5Fpublic.h \ - ../src/H5Ipublic.h \ - ../src/H5private.h \ - ../src/H5Dpublic.h \ - ../src/H5Tprivate.h \ - ../src/H5Tpublic.h \ - ../src/H5Gprivate.h \ - ../src/H5Gpublic.h \ - ../src/H5Bprivate.h -dtypes.o: \ - dtypes.c \ +iopipe.o: \ + iopipe.c \ ../src/hdf5.h \ ../src/H5public.h \ ../src/H5config.h \ @@ -293,8 +322,25 @@ dtypes.o: \ ../src/H5Zpublic.h \ ../src/H5Spublic.h \ ../src/H5Tpublic.h -dsets.o: \ - dsets.c \ +gheap.o: \ + gheap.c \ + ../src/H5private.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5Eprivate.h \ + ../src/H5Epublic.h \ + ../src/H5Ipublic.h \ + ../src/H5Fprivate.h \ + ../src/H5Fpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Gprivate.h \ + ../src/H5Gpublic.h \ + ../src/H5Bprivate.h \ + ../src/H5Bpublic.h \ + ../src/H5HGprivate.h \ + ../src/H5HGpublic.h +shtype.o: \ + shtype.c \ ../src/hdf5.h \ ../src/H5public.h \ ../src/H5config.h \ @@ -313,10 +359,9 @@ dsets.o: \ ../src/H5Opublic.h \ ../src/H5Ppublic.h \ ../src/H5Zpublic.h \ - ../src/H5Spublic.h \ - ../src/H5Tpublic.h -cmpd_dset.o: \ - cmpd_dset.c \ + ../src/H5Spublic.h +big.o: \ + big.c \ ../src/hdf5.h \ ../src/H5public.h \ ../src/H5config.h \ @@ -335,9 +380,11 @@ cmpd_dset.o: \ ../src/H5Opublic.h \ ../src/H5Ppublic.h \ ../src/H5Zpublic.h \ - ../src/H5Spublic.h -external.o: \ - external.c \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h \ + ../src/H5private.h +links.o: \ + links.c \ ../src/hdf5.h \ ../src/H5public.h \ ../src/H5config.h \ @@ -358,20 +405,17 @@ external.o: \ ../src/H5Zpublic.h \ ../src/H5Spublic.h \ ../src/H5Tpublic.h -tattr.o: \ - tattr.c \ - testhdf5.h \ - ../src/H5private.h \ +chunk.o: \ + chunk.c \ + ../src/hdf5.h \ ../src/H5public.h \ ../src/H5config.h \ - ../src/H5Eprivate.h \ - ../src/H5Epublic.h \ ../src/H5Ipublic.h \ - ../src/hdf5.h \ ../src/H5Apublic.h \ ../src/H5ACpublic.h \ ../src/H5Bpublic.h \ ../src/H5Dpublic.h \ + ../src/H5Epublic.h \ ../src/H5Fpublic.h \ ../src/H5Gpublic.h \ ../src/H5HGpublic.h \ @@ -381,62 +425,22 @@ tattr.o: \ ../src/H5Opublic.h \ ../src/H5Ppublic.h \ ../src/H5Zpublic.h \ - ../src/H5Spublic.h -th5s.o: \ - th5s.c \ - testhdf5.h \ - ../src/H5private.h \ - ../src/H5public.h \ - ../src/H5config.h \ - ../src/H5Eprivate.h \ - ../src/H5Epublic.h \ - ../src/H5Ipublic.h \ - ../src/H5Bprivate.h \ - ../src/H5Bpublic.h \ - ../src/H5Fprivate.h \ - ../src/H5Fpublic.h \ - ../src/H5Dpublic.h \ - ../src/H5Sprivate.h \ ../src/H5Spublic.h \ - ../src/H5Gprivate.h \ - ../src/H5Gpublic.h \ - ../src/H5Oprivate.h \ - ../src/H5Opublic.h \ + ../src/H5Tpublic.h +bittests.o: \ + bittests.c \ + ../src/H5Tpkg.h \ ../src/H5HGprivate.h \ ../src/H5HGpublic.h \ - ../src/H5Tprivate.h \ - ../src/H5Tpublic.h \ - ../src/H5Zprivate.h \ - ../src/H5Zpublic.h \ - ../src/H5Pprivate.h -hyperslab.o: \ - hyperslab.c \ - ../src/H5private.h \ - ../src/H5public.h \ - ../src/H5config.h -istore.o: \ - istore.c \ - ../src/H5private.h \ ../src/H5public.h \ ../src/H5config.h \ - ../src/H5Iprivate.h \ + ../src/H5Fprivate.h \ + ../src/H5Fpublic.h \ ../src/H5Ipublic.h \ - ../src/H5Pprivate.h \ - ../src/H5Ppublic.h \ + ../src/H5private.h \ ../src/H5Dpublic.h \ - ../src/H5Fpublic.h \ - ../src/H5Zpublic.h \ - ../src/H5Fprivate.h \ - ../src/H5Gprivate.h \ - ../src/H5Gpublic.h \ - ../src/H5Bprivate.h \ - ../src/H5Bpublic.h \ - ../src/H5MMprivate.h \ - ../src/H5MMpublic.h \ - ../src/H5Oprivate.h \ - ../src/H5Opublic.h \ - ../src/H5HGprivate.h \ - ../src/H5HGpublic.h \ ../src/H5Tprivate.h \ ../src/H5Tpublic.h \ - ../src/H5Sprivate.h + ../src/H5Gprivate.h \ + ../src/H5Gpublic.h \ + ../src/H5Bprivate.h diff --git a/test/chunk.c b/test/chunk.c index 33b4648..592fc73 100644 --- a/test/chunk.c +++ b/test/chunk.c @@ -19,6 +19,7 @@ #include <hdf5.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <H5config.h> #ifndef HAVE_ATTRIBUTE diff --git a/test/dtypes.c b/test/dtypes.c index 1bc58f5..455fd3b 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -7,11 +7,17 @@ * * Purpose: Tests the data type interface (H5T) */ +#include <assert.h> #include <hdf5.h> +#include <math.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#define H5T_PACKAGE +#include <H5Tpkg.h> /*to turn off hardware conversions*/ + #include <H5config.h> #ifndef HAVE_ATTRIBUTE # undef __attribute__ @@ -21,6 +27,11 @@ # define __unused__ __attribute__((unused)) #endif +#ifndef MAX +# define MAX(X,Y) ((X)>(Y)?(X):(Y)) +# define MIN(X,Y) ((X)<(Y)?(X):(Y)) +#endif + #define FILE_NAME_1 "dtypes1.h5" #define FILE_NAME_2 "dtypes2.h5" @@ -29,6 +40,17 @@ typedef struct complex_t { double im; } complex_t; +/* + * Count up or down depending on whether the machine is big endian or little + * endian. If `E' is H5T_ORDER_BE then the result will be I, otherwise the + * result will be Z-(I+1). + */ +#define ENDIAN(E,Z,I) (H5T_ORDER_BE==(E)?(I):(Z)-((I)+1)) + +typedef enum flt_t { + FLT_FLOAT, FLT_DOUBLE, FLT_LDOUBLE, FLT_OTHER +} flt_t; + /*------------------------------------------------------------------------- * Function: cleanup @@ -499,7 +521,7 @@ test_named (void) /*------------------------------------------------------------------------- - * Function: test_conv_num + * Function: test_conv_int * * Purpose: Test atomic number conversions. * @@ -515,7 +537,7 @@ test_named (void) *------------------------------------------------------------------------- */ static herr_t -test_conv_num (void) +test_conv_int (void) { const size_t ntests=100; const size_t nelmts=2000; @@ -528,7 +550,7 @@ test_conv_num (void) * Test some specific overflow/underflow cases. *--------------------------------------------------------------------- */ - printf ("%-70s", "Testing atomic number overflow conversions"); + printf ("%-70s", "Testing integer overflow conversions"); fflush (stdout); /* (unsigned)0x80000000 -> (unsigned)0xffff */ @@ -608,7 +630,7 @@ test_conv_num (void) * Test random cases. *----------------------------------------------------------------------- */ - printf ("%-70s", "Testing atomic number random conversions"); + printf ("%-70s", "Testing random integer conversions"); fflush (stdout); /* Allocate buffers */ @@ -650,7 +672,289 @@ test_conv_num (void) return -1; } - + +/*------------------------------------------------------------------------- + * Function: test_conv_flt_1 + * + * Purpose: Test conversion of random floating point values from SRC to + * DST. These types should be H5T_NATIVE_FLOAT, + * H5T_NATIVE_DOUBLE, or H5T_NATIVE_LDOUBLE. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_conv_flt_1 (const char *name, hid_t src, hid_t dst) +{ + flt_t src_type, dst_type; /*data types */ + const size_t ntests=10; /*number of tests */ + const size_t nelmts=200000; /*num values per test */ + const size_t max_fails=8; /*max number of failures*/ + size_t fails_all_tests=0; /*number of failures */ + size_t fails_this_test; /*fails for this test */ + const char *src_type_name = NULL; /*source type name */ + const char *dst_type_name = NULL; /*destination type name */ + size_t src_size, dst_size; /*type sizes */ + unsigned char *buf = NULL; /*buffer for conversion */ + unsigned char *saved = NULL; /*original values */ + char str[256]; /*hello string */ + float hw_f; /*hardware-converted */ + double hw_d; /*hardware-converted */ + long double hw_ld; /*hardware-converted */ + unsigned char *hw=NULL; /*ptr to hardware-conv'd*/ + size_t i, j, k; /*counters */ + int endian; /*machine endianess */ + + /* What are the names of the source and destination types */ + if (H5Tequal(src, H5T_NATIVE_FLOAT)) { + src_type_name = "float"; + src_type = FLT_FLOAT; + } else if (H5Tequal(src, H5T_NATIVE_DOUBLE)) { + src_type_name = "double"; + src_type = FLT_DOUBLE; + } else if (H5Tequal(src, H5T_NATIVE_LDOUBLE)) { + src_type_name = "long double"; + src_type = FLT_LDOUBLE; + } else { + src_type_name = "UNKNOWN"; + src_type = FLT_OTHER; + } + + if (H5Tequal(dst, H5T_NATIVE_FLOAT)) { + dst_type_name = "float"; + dst_type = FLT_FLOAT; + } else if (H5Tequal(dst, H5T_NATIVE_DOUBLE)) { + dst_type_name = "double"; + dst_type = FLT_DOUBLE; + } else if (H5Tequal(dst, H5T_NATIVE_LDOUBLE)) { + dst_type_name = "long double"; + dst_type = FLT_LDOUBLE; + } else { + dst_type_name = "UNKNOWN"; + dst_type = FLT_OTHER; + } + + /* Sanity checks */ + assert(sizeof(float)!=sizeof(double)); + if (FLT_OTHER==src_type || FLT_OTHER==dst_type) { + sprintf(str, "Testing random %s %s -> %s conversions", + name, src_type_name, dst_type_name); + printf ("%-70s", str); + puts("*FAILED*"); + puts(" Unknown data type."); + goto error; + } + + /* Allocate buffers */ + endian = H5Tget_order(H5T_NATIVE_FLOAT); + src_size = H5Tget_size(src); + dst_size = H5Tget_size(dst); + buf = malloc(nelmts*MAX(src_size, dst_size)); + saved = malloc(nelmts*MAX(src_size, dst_size)); + + for (i=0; i<ntests; i++) { + + /* + * If it looks like it might take a long time then print a progress + * report between each test. + */ + sprintf(str, "Testing random %s %s -> %s conversions (test %d/%d)", + name, src_type_name, dst_type_name, (int)i+1, (int)ntests); + printf ("%-70s", str); + fflush(stdout); + fails_this_test = 0; + + /* + * Initialize the source buffers to random bits. The `buf' buffer + * will be used for the conversion while the `saved' buffer will be + * used for the comparison later. + */ + for (j=0; j<nelmts*src_size; j++) buf[j] = saved[j] = rand(); + + /* Perform the conversion in software */ + if (H5Tconvert(src, dst, nelmts, buf, NULL)<0) goto error; + + /* Check the software results against the hardware */ + for (j=0; j<nelmts; j++) { + + /* The hardware conversion */ + if (FLT_FLOAT==src_type) { + if (FLT_FLOAT==dst_type) { + hw_f = ((float*)saved)[j]; + hw = (unsigned char*)&hw_f; + } else if (FLT_DOUBLE==dst_type) { + hw_d = ((float*)saved)[j]; + hw = (unsigned char*)&hw_d; + } else { + hw_ld = ((float*)saved)[j]; + hw = (unsigned char*)&hw_ld; + } + } else if (FLT_DOUBLE==src_type) { + if (FLT_FLOAT==dst_type) { + hw_f = ((double*)saved)[j]; + hw = (unsigned char*)&hw_f; + } else if (FLT_DOUBLE==dst_type) { + hw_d = ((double*)saved)[j]; + hw = (unsigned char*)&hw_d; + } else { + hw_ld = ((double*)saved)[j]; + hw = (unsigned char*)&hw_ld; + } + } else { + if (FLT_FLOAT==dst_type) { + hw_f = ((long double*)saved)[j]; + hw = (unsigned char*)&hw_f; + } else if (FLT_DOUBLE==dst_type) { + hw_d = ((long double*)saved)[j]; + hw = (unsigned char*)&hw_d; + } else { + hw_ld = ((long double*)saved)[j]; + hw = (unsigned char*)&hw_ld; + } + } + + /* Are the two results the same? */ + for (k=0; k<dst_size; k++) { + if (buf[j*dst_size+k]!=hw[k]) break; + } + if (k==dst_size) continue; /*no error*/ + +#if 1 + /* + * Assume same if both results are NaN. There are many NaN bit + * patterns and the software doesn't attemt to emulate the + * hardware in this regard. Instead, software uses a single bit + * pattern for NaN by setting the significand to all ones. + */ + if (FLT_FLOAT==dst_type && + ((float*)buf)[j]!=((float*)buf)[j] && + ((float*)hw)[0]!=((float*)hw)[0]) { + continue; + } else if (FLT_DOUBLE==dst_type && + ((double*)buf)[j]!=((double*)buf)[j] && + ((double*)hw)[0]!=((double*)hw)[0]) { + continue; + } else if (FLT_LDOUBLE==dst_type && + ((long double*)buf)[j]!=((long double*)buf)[j] && + ((long double*)hw)[0]!=((long double*)hw)[0]) { + continue; + } +#endif + +#if 1 + /* + * Assume same if hardware result is NaN. This is because the + * hardware conversions on some machines return NaN instead of + * overflowing to +Inf or -Inf or underflowing to +0 or -0. + */ + if (FLT_FLOAT==dst_type && + *((float*)hw)!=*((float*)hw)) { + continue; + } else if (FLT_DOUBLE==dst_type && + *((double*)hw)!=*((double*)hw)) { + continue; + } else if (FLT_LDOUBLE==dst_type && + *((long double*)hw)!=*((long double*)hw)) { + continue; + } +#endif + +#if 1 + /* + * Instead of matching down to the bit, just make sure the + * exponents are the same and the mantissa is the same to a + * certain precision. This is needed on machines that don't + * round as expected. + */ + { + double check_mant[2]; + int check_expo[2]; + + if (FLT_FLOAT==dst_type) { + check_mant[0] = frexp(((float*)buf)[j], check_expo+0); + check_mant[1] = frexp(((float*)hw)[0], check_expo+1); + } else if (FLT_DOUBLE==dst_type) { + check_mant[0] = frexp(((double*)buf)[j], check_expo+0); + check_mant[1] = frexp(((double*)hw)[0], check_expo+1); + } else { + check_mant[0] = frexp(((long double*)buf)[j],check_expo+0); + check_mant[1] = frexp(((long double*)hw)[0],check_expo+1); + } + if (check_expo[0]==check_expo[1] && + fabs(check_mant[0]-check_mant[1])<0.000001) { + continue; + } + } +#endif + + if (0==fails_this_test++) puts("*FAILED*"); + printf(" test %u, elmt %u\n", (unsigned)i+1, (unsigned)j); + + printf(" src ="); + for (k=0; k<src_size; k++) { + printf(" %02x", saved[j*src_size+ENDIAN(endian,src_size,k)]); + } + printf("%*s", 3*MAX(0, (ssize_t)dst_size-(ssize_t)src_size), ""); + if (FLT_FLOAT==src_type) { + printf(" %29.20e\n", ((float*)saved)[j]); + } else if (FLT_DOUBLE==src_type) { + printf(" %29.20e\n", ((double*)saved)[j]); + } else { + printf(" %29.20Le\n", ((long double*)saved)[j]); + } + + printf(" dst ="); + for (k=0; k<dst_size; k++) { + printf(" %02x", buf[j*dst_size+ENDIAN(endian,dst_size,k)]); + } + printf("%*s", 3*MAX(0, (ssize_t)src_size-(ssize_t)dst_size), ""); + if (FLT_FLOAT==dst_type) { + printf(" %29.20e\n", ((float*)buf)[j]); + } else if (FLT_DOUBLE==dst_type) { + printf(" %29.20e\n", ((double*)buf)[j]); + } else { + printf(" %29.20Le\n", ((long double*)buf)[j]); + } + + printf(" ans ="); + for (k=0; k<dst_size; k++) { + printf(" %02x", hw[ENDIAN(endian,dst_size,k)]); + } + printf("%*s", 3*MAX(0, (ssize_t)src_size-(ssize_t)dst_size), ""); + if (FLT_FLOAT==dst_type) { + printf(" %29.20e\n", hw_f); + } else if (FLT_DOUBLE==dst_type) { + printf(" %29.20e\n", hw_d); + } else { + printf(" %29.20Le\n", hw_ld); + } + + if (++fails_all_tests>=max_fails) { + puts(" maximum failures reached, aborting test..."); + goto done; + } + } + puts(" PASSED"); + } + + done: + if (buf) free (buf); + if (saved) free (saved); + return (int)fails_all_tests; + + error: + if (buf) free (buf); + if (saved) free (saved); + return (int)MIN(1, fails_all_tests); +} /*------------------------------------------------------------------------- @@ -672,7 +976,11 @@ test_conv_num (void) int main(void) { - int nerrors = 0; + unsigned long nerrors = 0; + +#if 0 + signal(SIGFPE,SIG_IGN); +#endif /* Set the error handler */ H5Eset_auto (display_error_cb, NULL); @@ -683,11 +991,36 @@ main(void) nerrors += test_compound()<0 ? 1 : 0; nerrors += test_transient ()<0 ? 1 : 0; nerrors += test_named ()<0 ? 1 : 0; - nerrors += test_conv_num ()<0 ? 1 : 0; + nerrors += test_conv_int ()<0 ? 1 : 0; + +#ifndef LATER + /* + * NOT READY FOR TESTING YET BECAUSE SOME SYSTEMS GENERATE A SIGFPE WHEN + * AN OVERFLOW OCCURS CASTING A DOUBLE TO A FLOAT. + */ +#else + /* Test degenerate cases */ + nerrors += test_conv_flt_1("noop", H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT); + nerrors += test_conv_flt_1("noop", H5T_NATIVE_DOUBLE, H5T_NATIVE_DOUBLE); + + /* Test hardware conversion functions */ + nerrors += test_conv_flt_1("hw", H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE); + nerrors += test_conv_flt_1("hw", H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT); + + /* Test software conversion functions */ + H5Tunregister(H5T_conv_float_double); + H5Tunregister(H5T_conv_double_float); + nerrors += test_conv_flt_1("sw", H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE); + nerrors += test_conv_flt_1("sw", H5T_NATIVE_FLOAT, H5T_NATIVE_LDOUBLE); + nerrors += test_conv_flt_1("sw", H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT); + nerrors += test_conv_flt_1("sw", H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE); + nerrors += test_conv_flt_1("sw", H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT); + nerrors += test_conv_flt_1("sw", H5T_NATIVE_LDOUBLE, H5T_NATIVE_DOUBLE); +#endif if (nerrors) { - printf("***** %d DATA TYPE TEST%s FAILED! *****\n", - nerrors, 1 == nerrors ? "" : "S"); + printf("***** %lu FAILURE%s! *****\n", + nerrors, 1==nerrors?"":"S"); exit(1); } printf("All data type tests passed.\n"); |