mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-27 02:10:55 +08:00
[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
This commit is contained in:
parent
4aa86e2297
commit
01a3d9d780
167
src/H5Tconv.c
167
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
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
|
175
test/dtypes.c
175
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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user