summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2005-09-03 17:11:00 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2005-09-03 17:11:00 (GMT)
commit01a3d9d780f255373e5e563152ac47aed6b049bc (patch)
treecf551eaefc4f02c2cd6e9efb781160d816687ad2
parent4aa86e2297e05687820d9cd8211c217184d06ae4 (diff)
downloadhdf5-01a3d9d780f255373e5e563152ac47aed6b049bc.zip
hdf5-01a3d9d780f255373e5e563152ac47aed6b049bc.tar.gz
hdf5-01a3d9d780f255373e5e563152ac47aed6b049bc.tar.bz2
[svn-r11345] Purpose:
Bug fix & code cleanup Description: Address most of datatype conversion exception handling bug that Ed Hartnett reported. (He's reported a different problem now, but we're closer at least). Also, condense exception handling #ifdef's into one location instead of spread out in so many places. Platforms tested: FreeBSD 4.11 (sleipnir) Too minor to require h5committest
-rw-r--r--src/H5Tconv.c167
-rw-r--r--test/dt_arith.c2
-rw-r--r--test/dtypes.c175
3 files changed, 290 insertions, 54 deletions
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 8745892..688eb60 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -190,7 +190,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
* equal. In this case, do not return exception but make sure the maximum is assigned
* to the destination. SLU - 2005/06/29
*/
-#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_Xx_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) > (DT)(D_MAX)) { \
if(cb_struct.func) { \
@@ -207,8 +206,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} \
else \
*((DT*)D) = (D_MAX); \
- } else if (*((ST*)S) == (DT)(D_MAX)) { \
- *((DT*)D) = (D_MAX); \
} else if (*((ST*)S) < (DT)(D_MIN)) { \
if(cb_struct.func) { \
H5T_conv_ret_t except_ret; /*callback return*/ \
@@ -227,13 +224,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
-#else
-#define H5T_CONV_Xx_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
- *((DT*)D) = (DT)(*((ST*)S)); \
-}
-#endif
-#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_Ux_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) > (DT)(D_MAX)) { \
if(cb_struct.func) { \
@@ -253,18 +244,12 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
-#else
-#define H5T_CONV_Ux_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
- *((DT*)D) = (DT)(*((ST*)S)); \
-}
-#endif
#define H5T_CONV_sS(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)<=sizeof(DT)); \
H5T_CONV(H5T_CONV_xX, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
-#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_sU_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) < 0) { \
if(cb_struct.func) { \
@@ -284,18 +269,12 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
-#else
-#define H5T_CONV_sU_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
- *((DT*)D) = (DT)(*((ST*)S)); \
-}
-#endif
#define H5T_CONV_sU(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)<=sizeof(DT)); \
H5T_CONV(H5T_CONV_sU, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
-#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_uS_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (sizeof(ST)==sizeof(DT) && *((ST*)S) > (D_MAX)) { \
if(cb_struct.func) { \
@@ -315,11 +294,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
-#else
-#define H5T_CONV_uS_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
- *((DT*)D) = (DT)(*((ST*)S)); \
-}
-#endif
#define H5T_CONV_uS(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)<=sizeof(DT)); \
@@ -336,7 +310,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
H5T_CONV(H5T_CONV_Xx, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
-#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_Su_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) < 0) { \
if(cb_struct.func) { \
@@ -371,11 +344,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
-#else
-#define H5T_CONV_Su_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
- *((DT*)D) = (DT)(*((ST*)S)); \
-}
-#endif
#define H5T_CONV_Su(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)>=sizeof(DT)); \
@@ -392,7 +360,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
H5T_CONV(H5T_CONV_Ux, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
-#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_su_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
/* Assumes memory format of unsigned & signed integers is same */ \
if (*((ST*)S) < 0) { \
@@ -413,18 +380,12 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
-#else
-#define H5T_CONV_su_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
- *((DT*)D) = (DT)(*((ST*)S)); \
-}
-#endif
#define H5T_CONV_su(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)==sizeof(DT)); \
H5T_CONV(H5T_CONV_su, long_long, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
-#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_us_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
/* Assumes memory format of unsigned & signed integers is same */ \
if (*((ST*)S) > (DT)(D_MAX)) { \
@@ -445,11 +406,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
-#else
-#define H5T_CONV_us_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
- *((DT*)D) = (DT)(*((ST*)S)); \
-}
-#endif
#define H5T_CONV_us(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)==sizeof(DT)); \
@@ -464,7 +420,6 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
/* Same as H5T_CONV_Xx_CORE, except that instead of using D_MAX and D_MIN
* when an overflow occurs, use the 'float' infinity values.
*/
-#ifdef H5_WANT_DCONV_EXCEPTION
#define H5T_CONV_Ff_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
if (*((ST*)S) > (DT)(D_MAX)) { \
if(cb_struct.func) { \
@@ -499,23 +454,119 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
} else \
*((DT*)D) = (DT)(*((ST*)S)); \
}
-#else
-#define H5T_CONV_Ff_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
- *((DT*)D) = (DT)(*((ST*)S)); \
-}
-#endif
#define H5T_CONV_Ff(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
assert(sizeof(ST)>=sizeof(DT)); \
H5T_CONV(H5T_CONV_Ff, long double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
}
+/* Note: this is a relative fragile hack (to use the temporary variable of the
+ * destination type) - it may get optimized out by the compiler. QAK - 2005/08/19
+ *
+ * A better solution would be to find the bit position of the highest 1 bit
+ * in the source and the bit position of the lowest 1 bit in the source and
+ * determine if the number of bits between them is greater than the mantissa
+ * of the floating point number (including the leading "implied" 1 bit), then
+ * issue a precision exception. However, that's probably too slow, so we'll
+ * try to use this solution for now. QAK - 2005/19/08
+ */
+#define H5T_CONV_xF_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
+ DT t_s = *((ST*)S); \
+ if (*((ST*)S) != (ST)t_s) { \
+ if(cb_struct.func) { \
+ H5T_conv_ret_t except_ret; /*callback return*/ \
+ \
+ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_PRECISION, \
+ src_id, dst_id, S, D, cb_struct.user_data); \
+ if(except_ret == H5T_CONV_UNHANDLED) \
+ /* Let compiler convert if case is ignored by user handler*/ \
+ *((DT*)D) = (DT)(*((ST*)S)); \
+ else if(except_ret == H5T_CONV_ABORT) \
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
+ /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
+ } \
+ else \
+ *((DT*)D) = (DT)(*((ST*)S)); \
+ } \
+ else \
+ *((DT*)D) = (DT)(*((ST*)S)); \
+}
+
#define H5T_CONV_xF(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
- H5T_CONV(H5T_CONV_xX, long double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_xF, long double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+}
+
+/* Added a condition branch(else if (*((ST*)S) == (DT)(D_MAX))) which seems redundant.
+ * It handles a special situation when the source is "float" and assigned the value
+ * of "INT_MAX". A compiler may do roundup making this value "INT_MAX+1". However,
+ * when do comparison "if (*((ST*)S) > (DT)(D_MAX))", the compiler may consider them
+ * equal. In this case, do not return exception but make sure the maximum is assigned
+ * to the destination. SLU - 2005/06/29
+ *
+ * Modified Ray's change to just check for the source >= the DT_MAX, so that
+ * the exception handling routine gets called. QAK - 2005/08/08
+ */
+#define H5T_CONV_Fx_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
+ if (*((ST*)S) >= (DT)(D_MAX)) { \
+ if(cb_struct.func) { \
+ H5T_conv_ret_t except_ret; /*callback return*/ \
+ \
+ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, \
+ src_id, dst_id, S, D, cb_struct.user_data); \
+ if(except_ret == H5T_CONV_UNHANDLED) \
+ /* Let compiler convert if case is ignored by user handler*/ \
+ *((DT*)D) = (D_MAX); \
+ else if(except_ret == H5T_CONV_ABORT) \
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
+ /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
+ } \
+ else \
+ *((DT*)D) = (D_MAX); \
+ } else if (*((ST*)S) < (DT)(D_MIN)) { \
+ if(cb_struct.func) { \
+ H5T_conv_ret_t except_ret; /*callback return*/ \
+ \
+ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW, \
+ src_id, dst_id, S, D, cb_struct.user_data); \
+ if(except_ret == H5T_CONV_UNHANDLED) \
+ /* Let compiler convert if case is ignored by user handler*/ \
+ *((DT*)D) = (D_MIN); \
+ else if(except_ret == H5T_CONV_ABORT) \
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
+ /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
+ } \
+ else \
+ *((DT*)D) = (D_MIN); \
+ } else if (*((ST*)S) != (ST)((DT)(*((ST*)S)))) { \
+ if(cb_struct.func) { \
+ H5T_conv_ret_t except_ret; /*callback return*/ \
+ \
+ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_TRUNCATE, \
+ src_id, dst_id, S, D, cb_struct.user_data); \
+ if(except_ret == H5T_CONV_UNHANDLED) \
+ /* Let compiler convert if case is ignored by user handler*/ \
+ *((DT*)D) = (DT)(*((ST*)S)); \
+ else if(except_ret == H5T_CONV_ABORT) \
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") \
+ /* if(except_ret==H5T_CONV_HANDLED): Fall through, user handled it */ \
+ } \
+ else \
+ *((DT*)D) = (DT)(*((ST*)S)); \
+ } \
+ else \
+ *((DT*)D) = (DT)(*((ST*)S)); \
}
#define H5T_CONV_Fx(STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
- H5T_CONV(H5T_CONV_Xx, long double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+ H5T_CONV(H5T_CONV_Fx, long double, STYPE, DTYPE, ST, DT, D_MIN, D_MAX) \
+}
+
+/* Since all "no exception" cores do the same thing (assign the value in the
+ * source location to the destination location, using casting), use one "core"
+ * to do them all.
+ */
+#define H5T_CONV_NO_EXCEPT_CORE(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) { \
+ *((DT*)D) = (DT)(*((ST*)S)); \
}
/* The main part of every integer hardware conversion macro */
@@ -686,7 +737,7 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
H5_GLUE(H5T_CONV_LOOP_,PRE_DALIGN_GUTS)(DT) \
\
/* ... user-defined stuff here -- the conversion ... */ \
- H5_GLUE(GUTS,_CORE)(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
+ H5T_CONV_LOOP_GUTS(GUTS,S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
\
/* Handle source post-alignment */ \
H5_GLUE(H5T_CONV_LOOP_,POST_SALIGN_GUTS)(ST) \
@@ -699,6 +750,16 @@ H5FL_BLK_DEFINE_STATIC(array_seq);
dst += d_stride; \
}
+/* Macro to call the actual "guts" of the type conversion, or call the "no exception" guts */
+#ifdef H5_WANT_DCONV_EXCEPTION
+#define H5T_CONV_LOOP_GUTS(GUTS,S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
+ /* ... user-defined stuff here -- the conversion ... */ \
+ H5_GLUE(GUTS,_CORE)(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX)
+#else /* H5_WANT_DCONV_EXCEPTION */
+#define H5T_CONV_LOOP_GUTS(GUTS,S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX) \
+ H5_GLUE(H5T_CONV_NO_EXCEPT,_CORE)(S,D,STYPE,DTYPE,ST,DT,D_MIN,D_MAX)
+#endif /* H5_WANT_DCONV_EXCEPTION */
+
#ifdef H5T_DEBUG
diff --git a/test/dt_arith.c b/test/dt_arith.c
index a760c00..0944524 100644
--- a/test/dt_arith.c
+++ b/test/dt_arith.c
@@ -4749,7 +4749,7 @@ run_fp_int_conv(const char *name)
* Modifications:
* Raymond Lu
* Monday, April 4, 2005
- * These tests were slitted from dtypes.c because dtypes.c
+ * These tests were split from dtypes.c because dtypes.c
* has grown too big.
*
*-------------------------------------------------------------------------
diff --git a/test/dtypes.c b/test/dtypes.c
index 9f366f3..92b7c33 100644
--- a/test/dtypes.c
+++ b/test/dtypes.c
@@ -86,6 +86,9 @@ typedef enum dtype_t {
FLT_LDOUBLE, OTHER
} dtype_t;
+/* Constant for size of conversion buffer for int <-> float exception test */
+#define CONVERT_SIZE 4
+
/* Count opaque conversions */
static int num_opaque_conversions_g = 0;
@@ -3832,6 +3835,177 @@ test_encode(void)
return 1;
}
+typedef struct {
+ unsigned num_range_hi; /* Number of H5T_CONV_EXCEPT_RANGE_HI exceptions seen */
+ unsigned num_range_low; /* Number of H5T_CONV_EXCEPT_RANGE_LOW exceptions seen */
+ unsigned num_precision; /* Number of H5T_CONV_EXCEPT_PRECISION exceptions seen */
+ unsigned num_truncate; /* Number of H5T_CONV_EXCEPT_TRUNCATE exceptions seen */
+ unsigned num_other; /* Number of other exceptions seen */
+} except_info_t;
+
+static H5T_conv_ret_t
+conv_except(H5T_conv_except_t except_type, hid_t UNUSED src_id, hid_t UNUSED dst_id,
+ void UNUSED *src_buf, void UNUSED *dst_buf, void *_user_data)
+{
+ except_info_t *user_data = (except_info_t *)_user_data;
+
+ if(except_type == H5T_CONV_EXCEPT_RANGE_HI)
+ user_data->num_range_hi++;
+ else if(except_type == H5T_CONV_EXCEPT_RANGE_LOW)
+ user_data->num_range_low++;
+ else if(except_type == H5T_CONV_EXCEPT_PRECISION)
+ user_data->num_precision++;
+ else if(except_type == H5T_CONV_EXCEPT_TRUNCATE)
+ user_data->num_truncate++;
+ else
+ user_data->num_other++;
+
+ return(H5T_CONV_UNHANDLED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_int_float_except
+ *
+ * Purpose: Tests exception handling behavior of int <-> float
+ * conversions.
+ *
+ * Return: Success: 0
+ *
+ * Failure: number of errors
+ *
+ * Programmer: Quincey Koziol
+ * August 18, 2005
+ *
+ * Notes: This routine is pretty specific to 4 byte integers and 4 byte
+ * floats and I can't think of a particularly good way to
+ * make it portable to other architectures, but further
+ * input and changes are welcome. -QAK
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_int_float_except(void)
+{
+#if H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4
+ float buf[CONVERT_SIZE] = {(float)INT_MIN - 172.0, (float)INT_MAX - 32.0,
+ (float)INT_MAX - 68.0, (float)4.5};
+ int buf_int[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX-127, 4};
+ float buf_float[CONVERT_SIZE] = {INT_MIN, INT_MAX + 1.0, INT_MAX - 127.0, 4};
+ int *intp; /* Pointer to buffer, as integers */
+ int buf2[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 72, 0};
+ float buf2_float[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 127.0, 0.0};
+ int buf2_int[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 127, 0};
+ float *floatp; /* Pointer to buffer #2, as floats */
+ hid_t dxpl; /* Dataset transfer property list */
+ except_info_t e; /* Exception information */
+ unsigned u; /* Local index variables */
+#endif /* H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4 */
+
+ TESTING("exceptions for int <-> float conversions");
+
+#if H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4
+ /* Create dataset transfer property list */
+ if((dxpl = H5Pcreate(H5P_DATASET_XFER) ) < 0) TEST_ERROR
+
+ /* Set the conversion exception handler in the DXPL */
+ if(H5Pset_type_conv_cb(dxpl, conv_except, &e) < 0) TEST_ERROR
+
+ /* Convert buffer */
+ HDmemset(&e, 0, sizeof(except_info_t));
+ if(H5Tconvert(H5T_NATIVE_FLOAT, H5T_NATIVE_INT, (size_t)CONVERT_SIZE, buf, NULL, dxpl) < 0) TEST_ERROR
+
+ /* Check the buffer after conversion, as integers */
+ for(u = 0; u < CONVERT_SIZE; u++) {
+ intp = (int *)&buf[u];
+ if(*intp != buf_int[u]) TEST_ERROR
+ } /* end for */
+
+ /* Check for proper exceptions */
+ if(e.num_range_hi != 1) TEST_ERROR
+ if(e.num_range_low != 1) TEST_ERROR
+ if(e.num_precision != 0) TEST_ERROR
+ if(e.num_truncate != 1) TEST_ERROR
+ if(e.num_other != 0) TEST_ERROR
+
+ /* Convert buffer */
+ HDmemset(&e, 0, sizeof(except_info_t));
+ if(H5Tconvert(H5T_NATIVE_INT, H5T_NATIVE_FLOAT, (size_t)CONVERT_SIZE,
+ buf, NULL, dxpl) < 0) TEST_ERROR
+
+ /* Check the buffer after conversion, as floats */
+ for(u = 0; u < CONVERT_SIZE; u++) {
+ floatp = (float *)&buf[u];
+ if(*floatp != buf_float[u]) TEST_ERROR
+ } /* end for */
+
+ /* Check for proper exceptions */
+ if(e.num_range_hi != 0) TEST_ERROR
+ if(e.num_range_low != 0) TEST_ERROR
+ if(e.num_precision != 1) TEST_ERROR
+ if(e.num_truncate != 0) TEST_ERROR
+ if(e.num_other != 0) TEST_ERROR
+
+
+ /* Work on second buffer */
+
+ /* Convert second buffer */
+ HDmemset(&e, 0, sizeof(except_info_t));
+ if(H5Tconvert(H5T_NATIVE_INT, H5T_NATIVE_FLOAT, (size_t)CONVERT_SIZE,
+ buf2, NULL, dxpl) < 0) TEST_ERROR
+
+ /* Check the buffer after conversion, as floats */
+ for(u = 0; u < CONVERT_SIZE; u++) {
+ floatp = (float *)&buf2[u];
+ if(*floatp != buf2_float[u]) TEST_ERROR
+ } /* end for */
+
+ /* Check for proper exceptions */
+ if(e.num_range_hi != 0) TEST_ERROR
+ if(e.num_range_low != 0) TEST_ERROR
+ if(e.num_precision != 2) TEST_ERROR
+ if(e.num_truncate != 0) TEST_ERROR
+ if(e.num_other != 0) TEST_ERROR
+
+ /* Convert buffer */
+ HDmemset(&e, 0, sizeof(except_info_t));
+ if(H5Tconvert(H5T_NATIVE_FLOAT, H5T_NATIVE_INT, (size_t)CONVERT_SIZE,
+ buf2, NULL, dxpl) < 0) TEST_ERROR
+
+ /* Check the buffer after conversion, as integers */
+ for(u = 0; u < CONVERT_SIZE; u++) {
+ intp = (int *)&buf2[u];
+ if(*intp != buf2_int[u]) TEST_ERROR
+ } /* end for */
+
+ /* Check for proper exceptions */
+ if(e.num_range_hi != 1) TEST_ERROR
+ if(e.num_range_low != 0) TEST_ERROR
+ if(e.num_precision != 0) TEST_ERROR
+ if(e.num_truncate != 0) TEST_ERROR
+ if(e.num_other != 0) TEST_ERROR
+
+ /* Close DXPL */
+ if(H5Pclose(dxpl) < 0) TEST_ERROR
+
+ PASSED();
+#else /* H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4 */
+ SKIPPED();
+ HDputs(" Test skipped due to int or float not 4 bytes.");
+#endif /* H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4 */
+ return 0;
+
+#if H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4
+error:
+ H5E_BEGIN_TRY {
+ H5Pclose (dxpl);
+ } H5E_END_TRY;
+ return 1;
+#endif /* H5_SIZEOF_INT==4 && H5_SIZEOF_FLOAT==4 */
+} /* end test_int_float_except() */
+
/*-------------------------------------------------------------------------
* Function: main
@@ -3873,6 +4047,7 @@ main(void)
nerrors += test_transient (fapl);
nerrors += test_named (fapl);
nerrors += test_encode();
+ nerrors += test_int_float_except();
h5_cleanup(FILENAME, fapl); /*must happen before first reset*/
reset_hdf5();