summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST1
-rw-r--r--RELEASE78
-rw-r--r--config/irix5.32
-rw-r--r--src/H5.c8
-rw-r--r--src/H5A.c14
-rw-r--r--src/H5AC.c2
-rw-r--r--src/H5D.c2
-rw-r--r--src/H5Distore.c2
-rw-r--r--src/H5Ffamily.c4
-rw-r--r--src/H5Fistore.c2
-rw-r--r--src/H5G.c4
-rw-r--r--src/H5Gprivate.h2
-rw-r--r--src/H5HG.c2
-rw-r--r--src/H5MM.c1
-rw-r--r--src/H5O.c10
-rw-r--r--src/H5T.c23
-rw-r--r--src/H5Tbit.c176
-rw-r--r--src/H5Tconv.c500
-rw-r--r--src/H5Tpkg.h9
-rw-r--r--src/H5detect.c9
-rw-r--r--src/H5private.h1
-rw-r--r--test/.distdep248
-rw-r--r--test/chunk.c1
-rw-r--r--test/dtypes.c351
24 files changed, 1270 insertions, 182 deletions
diff --git a/MANIFEST b/MANIFEST
index 6ea1e83..0ddf81b 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,3 +1,4 @@
+./CHANGES_API
./INSTALL
./INSTALL.ascired
./INSTALL.ibm.sp.parallel
diff --git a/RELEASE b/RELEASE
index 09df2a6..c0d3b27 100644
--- a/RELEASE
+++ b/RELEASE
@@ -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?
diff --git a/src/H5.c b/src/H5.c
index 71defe7..8f770b9 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -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;
}
diff --git a/src/H5A.c b/src/H5A.c
index d7014b6..b07bf37 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -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 */
diff --git a/src/H5AC.c b/src/H5AC.c
index 0e4b325..c34d7c2 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -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;
diff --git a/src/H5D.c b/src/H5D.c
index d696f92..6cbcf2c 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -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,
diff --git a/src/H5G.c b/src/H5G.c
index c885655..f1e65fb 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -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*/);
diff --git a/src/H5HG.c b/src/H5HG.c
index f2fe211..eaca1f9 100644
--- a/src/H5HG.c
+++ b/src/H5HG.c
@@ -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) {
/*
diff --git a/src/H5MM.c b/src/H5MM.c
index af38125..bc2a7ef 100644
--- a/src/H5MM.c
+++ b/src/H5MM.c
@@ -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
diff --git a/src/H5O.c b/src/H5O.c
index 29eb583..dde5917 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -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 */
diff --git a/src/H5T.c b/src/H5T.c
index 9297634..4fe6078 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -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");