diff options
author | Raymond Lu <songyulu@hdfgroup.org> | 2012-03-15 20:53:14 (GMT) |
---|---|---|
committer | Raymond Lu <songyulu@hdfgroup.org> | 2012-03-15 20:53:14 (GMT) |
commit | b337ae979dad938f1ef72df4f67b612a883040b1 (patch) | |
tree | 97bbd651a366c406bb7a22bde36f37f7448dc550 | |
parent | 207c05e2e9f1c2844416c19fe5b74b2d71610fd1 (diff) | |
download | hdf5-b337ae979dad938f1ef72df4f67b612a883040b1.zip hdf5-b337ae979dad938f1ef72df4f67b612a883040b1.tar.gz hdf5-b337ae979dad938f1ef72df4f67b612a883040b1.tar.bz2 |
[svn-r22076] #Issue 7922 - H5Pset_data_transform had seg fault with some operations like x*-100.
The parser mistaked "-" as substraction. I fixed it and also fixed another problem
with some special cases like 100-x and 2/x.
Tested on jam, koala, and ostrich.
-rw-r--r-- | release_docs/RELEASE.txt | 4 | ||||
-rw-r--r-- | src/H5HF.c | 1 | ||||
-rw-r--r-- | src/H5Ztrans.c | 187 | ||||
-rw-r--r-- | test/dtransform.c | 180 |
4 files changed, 338 insertions, 34 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 8055516..63ae2d7 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -364,7 +364,9 @@ Bug Fixes since HDF5-1.8.0 release Library ------- - + - H5Pset_data_transform had seg fault in some cases like x*-100. It + works correctly now and handles other cases like 100-x or 2/x. + (SLU - 2012/3/15. Issue 7922) - Fixed rare corruption bugs that could occur when using the new object header format. (NAF - 2012/3/15 - HDFFV-7879) - Creating a dataset in a read-only file caused seg fault when the file @@ -361,6 +361,7 @@ H5HF_insert(H5HF_t *fh, hid_t dxpl_id, size_t size, const void *obj, herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) + #ifdef QAK HDfprintf(stderr, "%s: size = %Zu\n", FUNC, size); #endif /* QAK */ diff --git a/src/H5Ztrans.c b/src/H5Ztrans.c index 5a707b5..2a2796d 100644 --- a/src/H5Ztrans.c +++ b/src/H5Ztrans.c @@ -94,6 +94,8 @@ static H5Z_node *H5Z_parse_term(H5Z_token *current, H5Z_datval_ptrs* dat_val_poi static H5Z_node *H5Z_parse_factor(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers); static H5Z_node *H5Z_new_node(H5Z_token_type type); static void H5Z_do_op(H5Z_node* tree); +static hbool_t H5Z_op_is_numbs(H5Z_node* _tree); +static hbool_t H5Z_op_is_numbs2(H5Z_node* _tree); static hid_t H5Z_xform_find_type(const H5T_t* type); static herr_t H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_type, H5Z_result* res); static void H5Z_xform_destroy_parse_tree(H5Z_node *tree); @@ -105,41 +107,46 @@ static void H5Z_XFORM_DEBUG(H5Z_node *tree); static void H5Z_print(H5Z_node *tree, FILE *stream); #endif /* H5Z_XFORM_DEBUG */ - #define H5Z_XFORM_DO_OP1(RESL,RESR,TYPE,OP,SIZE) \ { \ - if( (((RESL).type == H5Z_XFORM_SYMBOL) && ((RESR).type != H5Z_XFORM_SYMBOL)) || (((RESR).type == H5Z_XFORM_SYMBOL) && ((RESL).type != H5Z_XFORM_SYMBOL))) \ + size_t u; \ + \ + if(((RESL).type == H5Z_XFORM_SYMBOL) && ((RESR).type != H5Z_XFORM_SYMBOL)) \ + { \ + TYPE* p; \ + double tree_val; \ + \ + tree_val = ((RESR).type==H5Z_XFORM_INTEGER ? (double)(RESR).value.int_val : (RESR).value.float_val); \ + p = (TYPE*)(RESL).value.dat_val; \ + \ + for(u=0; u<(SIZE); u++) \ + *p++ = *p OP tree_val; \ + } \ + else if(((RESR).type == H5Z_XFORM_SYMBOL) && ((RESL).type != H5Z_XFORM_SYMBOL)) \ { \ - size_t u; \ TYPE* p; \ double tree_val; \ \ - if((RESL).type == H5Z_XFORM_SYMBOL) \ - { \ - tree_val = ((RESR).type==H5Z_XFORM_INTEGER ? (double)(RESR).value.int_val : (RESR).value.float_val); \ - p = (TYPE*)(RESL).value.dat_val; \ - } \ + /* The case that the left operand is nothing, like -x or +x */ \ + if((RESL).type == H5Z_XFORM_ERROR) \ + tree_val = 0; \ else \ - { \ tree_val = ((RESL).type==H5Z_XFORM_INTEGER ? (double)(RESL).value.int_val : (RESL).value.float_val); \ - p = (TYPE*)(RESR).value.dat_val; \ - } \ - \ + \ + p = (TYPE*)(RESR).value.dat_val; \ for(u=0; u<(SIZE); u++) \ - *p++ OP tree_val; \ - } \ + *p++ = tree_val OP *p; \ + } \ else if( ((RESL).type == H5Z_XFORM_SYMBOL) && ((RESR).type==H5Z_XFORM_SYMBOL)) \ { \ - size_t u; \ TYPE* pl = (TYPE*)(RESL).value.dat_val; \ TYPE* pr = (TYPE*)(RESR).value.dat_val; \ \ for(u=0; u<(SIZE); u++) \ - *pl++ OP *pr++; \ + *pl++ = *pl OP *pr++; \ } \ else \ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unexpected type conversion operation") \ - \ } /* Due to the undefined nature of embedding macros/conditionals within macros, we employ @@ -235,6 +242,7 @@ static void H5Z_print(H5Z_node *tree, FILE *stream); } #endif /*H5_SIZEOF_LONG_DOUBLE */ + #define H5Z_XFORM_DO_OP3(OP) \ { \ if((tree->lchild->type == H5Z_XFORM_INTEGER) && (tree->rchild->type==H5Z_XFORM_INTEGER)) \ @@ -259,6 +267,48 @@ static void H5Z_print(H5Z_node *tree, FILE *stream); } \ } +/* The difference of this macro from H5Z_XFORM_DO_OP3 is that it handles the operations when the left operand is empty, like -x or +x. + * The reason that it's seperated from H5Z_XFORM_DO_OP3 is because compilers don't accept operations like *x or /x. So in H5Z_do_op, + * these two macros are called in different ways. + */ +#define H5Z_XFORM_DO_OP6(OP) \ +{ \ + if(!tree->lchild && (tree->rchild->type==H5Z_XFORM_INTEGER)) \ + { \ + tree->type = H5Z_XFORM_INTEGER; \ + tree->value.int_val = OP tree->rchild->value.int_val; \ + H5MM_xfree(tree->rchild); \ + tree->rchild = NULL; \ + } \ + else if(!tree->lchild && (tree->rchild->type==H5Z_XFORM_FLOAT)) \ + { \ + tree->type = H5Z_XFORM_FLOAT; \ + tree->value.float_val = OP tree->rchild->value.float_val; \ + H5MM_xfree(tree->rchild); \ + tree->rchild = NULL; \ + } \ + else if((tree->lchild->type == H5Z_XFORM_INTEGER) && (tree->rchild->type==H5Z_XFORM_INTEGER)) \ + { \ + tree->type = H5Z_XFORM_INTEGER; \ + tree->value.int_val = tree->lchild->value.int_val OP tree->rchild->value.int_val; \ + H5MM_xfree(tree->lchild); \ + H5MM_xfree(tree->rchild); \ + tree->lchild = NULL; \ + tree->rchild = NULL; \ + } \ + else if( ( (tree->lchild->type == H5Z_XFORM_FLOAT) || (tree->lchild->type == H5Z_XFORM_INTEGER)) && \ + ( (tree->rchild->type == H5Z_XFORM_FLOAT) || (tree->rchild->type == H5Z_XFORM_INTEGER))) \ + { \ + tree->type = H5Z_XFORM_FLOAT; \ + tree->value.float_val = ((tree->lchild->type == H5Z_XFORM_FLOAT) ? tree->lchild->value.float_val : (double)tree->lchild->value.int_val) OP \ + ((tree->rchild->type == H5Z_XFORM_FLOAT) ? tree->rchild->value.float_val : (double)tree->rchild->value.int_val); \ + H5MM_xfree(tree->lchild); \ + H5MM_xfree(tree->rchild); \ + tree->lchild = NULL; \ + tree->rchild = NULL; \ + } \ +} + #define H5Z_XFORM_DO_OP4(TYPE) \ { \ if ((ret_value = (H5Z_node*) H5MM_malloc(sizeof(H5Z_node))) == NULL) \ @@ -1027,6 +1077,9 @@ H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_ /* check args */ HDassert(tree); + HDmemset(&resl, 0, sizeof(H5Z_result)); + HDmemset(&resr, 0, sizeof(H5Z_result)); + if (tree->type == H5Z_XFORM_INTEGER) { res->type = H5Z_XFORM_INTEGER; res->value.int_val = tree->value.int_val; @@ -1044,7 +1097,7 @@ H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_ res->value.dat_val = *((void**)(tree->value.dat_val)); } /* end if */ else { - if(H5Z_xform_eval_full(tree->lchild, array_size, array_type, &resl) < 0) + if(tree->lchild && H5Z_xform_eval_full(tree->lchild, array_size, array_type, &resl) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "error while performing data transform") if(H5Z_xform_eval_full(tree->rchild, array_size, array_type, &resr) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "error while performing data transform") @@ -1059,19 +1112,19 @@ H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_ switch (tree->type) { case H5Z_XFORM_PLUS: - H5Z_XFORM_TYPE_OP(resl, resr, array_type, +=, array_size) + H5Z_XFORM_TYPE_OP(resl, resr, array_type, +, array_size) break; case H5Z_XFORM_MINUS: - H5Z_XFORM_TYPE_OP(resl, resr, array_type, -=, array_size) + H5Z_XFORM_TYPE_OP(resl, resr, array_type, -, array_size) break; case H5Z_XFORM_MULT: - H5Z_XFORM_TYPE_OP(resl, resr, array_type, *=, array_size) + H5Z_XFORM_TYPE_OP(resl, resr, array_type, *, array_size) break; case H5Z_XFORM_DIVIDE: - H5Z_XFORM_TYPE_OP(resl, resr, array_type, /=, array_size) + H5Z_XFORM_TYPE_OP(resl, resr, array_type, /, array_size) break; default: @@ -1274,22 +1327,37 @@ H5Z_xform_reduce_tree(H5Z_node* tree) FUNC_ENTER_NOAPI_NOINIT_NOERR if(tree) { - if((tree->type == H5Z_XFORM_PLUS) || (tree->type == H5Z_XFORM_DIVIDE) ||(tree->type == H5Z_XFORM_MULT) ||(tree->type == H5Z_XFORM_MINUS)) + if((tree->type == H5Z_XFORM_DIVIDE) || (tree->type == H5Z_XFORM_MULT)) { - if(((tree->lchild->type == H5Z_XFORM_INTEGER) || (tree->lchild->type == H5Z_XFORM_FLOAT)) && ((tree->rchild->type == H5Z_XFORM_INTEGER) || (tree->rchild->type == H5Z_XFORM_FLOAT))) + if(H5Z_op_is_numbs(tree)) H5Z_do_op(tree); else { H5Z_xform_reduce_tree(tree->lchild); - if(((tree->lchild->type == H5Z_XFORM_INTEGER) || (tree->lchild->type == H5Z_XFORM_FLOAT)) && ((tree->rchild->type == H5Z_XFORM_INTEGER) || (tree->rchild->type == H5Z_XFORM_FLOAT))) + if(H5Z_op_is_numbs(tree)) H5Z_do_op(tree); else { H5Z_xform_reduce_tree(tree->rchild); - if(((tree->lchild->type == H5Z_XFORM_INTEGER) || (tree->lchild->type == H5Z_XFORM_FLOAT)) && ((tree->rchild->type == H5Z_XFORM_INTEGER) || (tree->rchild->type == H5Z_XFORM_FLOAT))) + if(H5Z_op_is_numbs(tree)) + H5Z_do_op(tree); + } + } + } else if((tree->type == H5Z_XFORM_PLUS) || (tree->type == H5Z_XFORM_MINUS)) { + if(H5Z_op_is_numbs2(tree)) + H5Z_do_op(tree); + else + { + H5Z_xform_reduce_tree(tree->lchild); + if(H5Z_op_is_numbs2(tree)) + H5Z_do_op(tree); + else { + H5Z_xform_reduce_tree(tree->rchild); + if(H5Z_op_is_numbs2(tree)) H5Z_do_op(tree); } } } + } FUNC_LEAVE_NOAPI_VOID; @@ -1297,6 +1365,63 @@ H5Z_xform_reduce_tree(H5Z_node* tree) /*------------------------------------------------------------------------- + * Function: H5Z_op_is_numbs + * Purpose: Internal function to facilitate the condition check in + * H5Z_xform_reduce_tree to reduce the bulkiness of the code. + * Return: TRUE or FALSE + * Programmer: Raymond Lu + * 15 March 2012 + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +H5Z_op_is_numbs(H5Z_node* _tree) +{ + hbool_t ret_value = FALSE; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + assert(_tree); + + if(((_tree->lchild->type == H5Z_XFORM_INTEGER) || (_tree->lchild->type == H5Z_XFORM_FLOAT)) && ((_tree->rchild->type == H5Z_XFORM_INTEGER) || (_tree->rchild->type == H5Z_XFORM_FLOAT))) + ret_value = TRUE; + + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5Z_op_is_numbs2 + * Purpose: Internal function to facilitate the condition check in + * H5Z_xform_reduce_tree to reduce the bulkiness of the code. + * The difference from H5Z_op_is_numbs is that the left child + * can be empty, like -x or +x. + * Return: TRUE or FALSE + * Programmer: Raymond Lu + * 15 March 2012 + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +H5Z_op_is_numbs2(H5Z_node* _tree) +{ + hbool_t ret_value = FALSE; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + assert(_tree); + + if((!_tree->lchild && ((_tree->rchild->type == H5Z_XFORM_INTEGER) || (_tree->rchild->type == H5Z_XFORM_FLOAT))) || + ((_tree->lchild && ((_tree->lchild->type == H5Z_XFORM_INTEGER) || (_tree->lchild->type == H5Z_XFORM_FLOAT))) && (_tree->rchild && ((_tree->rchild->type == H5Z_XFORM_INTEGER) || (_tree->rchild->type == H5Z_XFORM_FLOAT))))) + ret_value = TRUE; + + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- * Function: H5Z_do_op * Purpose: If the root of the tree passed in points to a simple * arithmetic operation and the left and right subtrees are both @@ -1307,7 +1432,11 @@ H5Z_xform_reduce_tree(H5Z_node* tree) * Programmer: Leon Arber * April 1, 2004. * Modifications: -* + * Raymond Lu + * 15 March 2012 + * I added a new macro H5Z_XFORM_DO_OP6 to handle the special + * operations like -x or +x when the left operand is empty. + * *------------------------------------------------------------------------- */ static void @@ -1320,9 +1449,9 @@ H5Z_do_op(H5Z_node* tree) else if(tree->type == H5Z_XFORM_MULT) H5Z_XFORM_DO_OP3(*) else if(tree->type == H5Z_XFORM_PLUS) - H5Z_XFORM_DO_OP3(+) + H5Z_XFORM_DO_OP6(+) else if(tree->type == H5Z_XFORM_MINUS) - H5Z_XFORM_DO_OP3(-) + H5Z_XFORM_DO_OP6(-) FUNC_LEAVE_NOAPI_VOID; } diff --git a/test/dtransform.c b/test/dtransform.c index 5d5cefe..2bcbe8c 100644 --- a/test/dtransform.c +++ b/test/dtransform.c @@ -23,6 +23,7 @@ static int init_test(hid_t file_id); static int test_copy(const hid_t dxpl_id_c_to_f_copy, const hid_t dxpl_id_polynomial_copy); static int test_trivial(const hid_t dxpl_id_simple); static int test_poly(const hid_t dxpl_id_polynomial); +static int test_specials(hid_t file); static int test_set(void); static int test_getset(const hid_t dxpl_id_simple); @@ -50,14 +51,14 @@ const float windchillFfloat[ROWS][COLS] = const int transformData[ROWS][COLS] = { {36, 31, 25, 19, 13, 7, 1, 5, 11, 16, 22, 28, 34, 40, 46, 52, 57, 63 }, - {34, 27, 21, 15, 9, 3, 4, 10, 16, 22, 28, 35, 41, 47, 53, 59, 66, 0 } , - {32, 25, 19, 13, 6, 0, 7, 13, 19, 26, 32, 39, 45, 51, 58, 64, 71, 5 }, + {34, 27, 21, 15, 9, 3, 4, 10, 16, 22, 28, 35, 41, 47, 53, 59, 66, 1 } , + {32, 25, 19, 13, 6, 2, 7, 13, 19, 26, 32, 39, 45, 51, 58, 64, 71, 5 }, {30, 24, 17, 11, 4, 2, 9, 15, 22, 29, 35, 42, 48, 55, 61, 68, 2, 9 }, {29, 23, 16, 9, 3, 4, 11, 17, 24, 31, 37, 44, 51, 58, 64, 71, 6, 12 }, {28, 22, 15, 8, 1, 5, 12, 19, 26, 33, 39, 46, 53, 60, 67, 1, 8, 15 }, - {28, 21, 14, 7, 0, 7, 14, 21, 27, 34, 41, 48, 55, 62, 69, 4, 10, 17 }, + {28, 21, 14, 7, 6, 7, 14, 21, 27, 34, 41, 48, 55, 62, 69, 4, 10, 17 }, {27, 20, 13, 6, 1, 8, 15, 22, 29, 36, 43, 50, 57, 64, 71, 6, 12, 19 }, - {26, 19, 12, 5, 2, 9, 16, 23, 30, 37, 44, 51, 58, 65, 0, 7, 14, 21 }, + {26, 19, 12, 5, 2, 9, 16, 23, 30, 37, 44, 51, 58, 65, 5, 7, 14, 21 }, {26, 19, 12, 4, 3, 10, 17, 24, 31, 38, 45, 52, 60, 67, 2, 9, 16, 23}, {25, 18, 11, 4, 3, 11, 18, 25, 32, 39, 46, 54, 61, 68, 3, 10, 17, 25}, {25, 17, 10, 3, 4, 11, 19, 26, 33, 40, 48, 55, 62, 69, 4, 12, 19, 26} @@ -97,6 +98,22 @@ const int transformData[ROWS][COLS] = PASSED(); \ } +#define COMPARE_INT(VAR1,VAR2) \ +{ \ + size_t i,j; \ + \ + for(i=0; i<ROWS; i++) \ + for(j=0; j<COLS; j++) \ + { \ + if( (VAR1)[i][j] != (VAR2)[i][j] ) \ + { \ + H5_FAILED(); \ + fprintf(stderr, " ERROR: data failed to match computed data\n"); \ + goto error; \ + } \ + } \ +} + #define TEST_TYPE_CONTIG(XFORM, TYPE, HDF_TYPE, TEST_STR, COMPARE_DATA, SIGNED) \ { \ TYPE array[ROWS][COLS]; \ @@ -332,6 +349,7 @@ int main(void) if(test_trivial(dxpl_id_simple) < 0) TEST_ERROR; if(test_poly(dxpl_id_polynomial) < 0) TEST_ERROR; if(test_getset(dxpl_id_c_to_f) < 0) TEST_ERROR; + if(test_specials(file_id) < 0) TEST_ERROR; /* Close the objects we opened/created */ if(H5Dclose(dset_id_int) < 0) TEST_ERROR; @@ -502,6 +520,160 @@ error: } static int +test_specials(hid_t file) +{ + hid_t dxpl_id, dset_id, dataspace; + hsize_t dim[2] = { ROWS, COLS }; + int read_buf[ROWS][COLS]; + int data_res[ROWS][COLS]; + int row, col; + const char* special1 = "x*-100"; + const char* special2 = "100-x"; + const char* special3 = "1000/x"; + const char* special4 = "-x"; + const char* special5 = "+x"; + + TESTING("data transform of some special cases") + + if((dataspace = H5Screate_simple(2, dim, NULL)) < 0) + TEST_ERROR + + if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR; + + /*----------------------------- + * Operation 1: x*-100 + *----------------------------*/ + if(H5Pset_data_transform(dxpl_id, special1) < 0) TEST_ERROR; + + for(row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + data_res[row][col] = transformData[row][col] * -100; + + if((dset_id = H5Dcreate2(file, "/special1", H5T_NATIVE_INT, + dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl_id, transformData) < 0) + TEST_ERROR + if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if(H5Dclose(dset_id) < 0) + TEST_ERROR + + /*----------------------------- + * Operation 2: 100-x + *----------------------------*/ + if(H5Pset_data_transform(dxpl_id, special2) < 0) TEST_ERROR; + + for(row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + data_res[row][col] = 100 - transformData[row][col]; + + if((dset_id = H5Dcreate2(file, "/special2", H5T_NATIVE_INT, + dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl_id, transformData) < 0) + TEST_ERROR + if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if(H5Dclose(dset_id) < 0) + TEST_ERROR + + /*----------------------------- + * Operation 3: 1000/x + *----------------------------*/ + if(H5Pset_data_transform(dxpl_id, special3) < 0) TEST_ERROR; + + for(row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + data_res[row][col] = 1000 / transformData[row][col]; + + if((dset_id = H5Dcreate2(file, "/special3", H5T_NATIVE_INT, + dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl_id, transformData) < 0) + TEST_ERROR + if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if(H5Dclose(dset_id) < 0) + TEST_ERROR + + /*----------------------------- + * Operation 4: -x + *----------------------------*/ + if(H5Pset_data_transform(dxpl_id, special4) < 0) TEST_ERROR; + + for(row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + data_res[row][col] = -1 * transformData[row][col]; + + if((dset_id = H5Dcreate2(file, "/special4", H5T_NATIVE_INT, + dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl_id, transformData) < 0) + TEST_ERROR + if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if(H5Dclose(dset_id) < 0) + TEST_ERROR + + /*----------------------------- + * Operation 5: +x + *----------------------------*/ + if(H5Pset_data_transform(dxpl_id, special5) < 0) TEST_ERROR; + + for(row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + data_res[row][col] = transformData[row][col]; + + if((dset_id = H5Dcreate2(file, "/special5", H5T_NATIVE_INT, + dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl_id, transformData) < 0) + TEST_ERROR + if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if(H5Dclose(dset_id) < 0) + TEST_ERROR + + + if(H5Pclose(dxpl_id) < 0) + TEST_ERROR + if(H5Sclose(dataspace) < 0) + TEST_ERROR + + PASSED(); + return 0; + +error: + return -1; +} + +static int test_copy(const hid_t dxpl_id_c_to_f_copy, const hid_t dxpl_id_polynomial_copy) { int windchillC; |