From 01a3d9d780f255373e5e563152ac47aed6b049bc Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 3 Sep 2005 12:11:00 -0500 Subject: [PATCH] [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 --- src/H5Tconv.c | 167 ++++++++++++++++++++++++++++++--------------- test/dt_arith.c | 2 +- test/dtypes.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 290 insertions(+), 54 deletions(-) diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 8745892231..688eb606bd 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 a760c00fdc..0944524613 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 9f366f3414..92b7c33eb7 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();