From 82c0cb122f468c0d8d684da64a08acf50534bd02 Mon Sep 17 00:00:00 2001 From: jwsblokland Date: Wed, 2 Dec 2020 05:27:24 +0100 Subject: (fix) H5Z_xform_create function and scientific notation (#144) * (fix) H5Z_xform_create function and scientific notation Implemented a more sophisticated check to support scientific notation in the expression of the H5Zset_data_transform function. * (fix) H5Z_xform_create and scientific notation: Added test. Added a test to demonstrate that the parsing of expression which includes scientific notation works correctly. Improved inline comment. Co-authored-by: Jan-Willem Blokland --- src/H5Ztrans.c | 42 ++++++++++++++++++++++++++---------------- test/dtransform.c | 24 ++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/src/H5Ztrans.c b/src/H5Ztrans.c index cde1862..8a702fd 100644 --- a/src/H5Ztrans.c +++ b/src/H5Ztrans.c @@ -13,12 +13,12 @@ #include "H5Zmodule.h" /* This source code file is part of the H5Z module */ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5VMprivate.h" /* H5VM_array_fill */ -#include "H5Zpkg.h" /* Data filters */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5VMprivate.h" /* H5VM_array_fill */ +#include "H5Zpkg.h" /* Data filters */ /* Token types */ typedef enum { @@ -994,12 +994,12 @@ done: /*------------------------------------------------------------------------- * Function: H5Z_xform_eval - * Purpose: If the transform is trivial, this function applies it. - * Otherwise, it calls H5Z__xform_eval_full to do the full - * transform. + * Purpose: If the transform is trivial, this function applies it. + * Otherwise, it calls H5Z__xform_eval_full to do the full + * transform. * Return: SUCCEED if transform applied successfully, FAIL otherwise * Programmer: Leon Arber - * 5/1/04 + * 5/1/04 * *------------------------------------------------------------------------- */ @@ -1110,8 +1110,8 @@ done: /*------------------------------------------------------------------------- * Function: H5Z__xform_eval_full * - * Purpose: Does a full evaluation of the parse tree contained in tree - * and applies this transform to array. + * Purpose: Does a full evaluation of the parse tree contained in tree + * and applies this transform to array. * * Notes: In the case of a polynomial data transform (ie, the left and right * subtree are both of type H5Z_XFORM_SYMBOL), the convention is @@ -1121,7 +1121,7 @@ done: * Return: Nothing * * Programmer: Leon Arber - * 5/1/04 + * 5/1/04 * *------------------------------------------------------------------------- */ @@ -1539,10 +1539,20 @@ H5Z_xform_create(const char *expr) "unable to allocate memory for data transform expression") /* Find the number of times "x" is used in this equation, and allocate room for storing that many points + * A more sophisticated check is needed to support scientific notation. */ - for (i = 0; i < HDstrlen(expr); i++) - if (HDisalpha(expr[i])) + for (i = 0; i < HDstrlen(expr); i++) { + if (HDisalpha(expr[i])) { + if ((i > 0) && (i < (HDstrlen(expr) - 1))) { + if (((expr[i] == 'E') || (expr[i] == 'e')) && + (HDisdigit(expr[i - 1]) || (expr[i - 1] == '.')) && + (HDisdigit(expr[i + 1]) || (expr[i + 1] == '-') || (expr[i + 1] == '+'))) + continue; + } + count++; + } + } /* When there are no "x"'s in the equation (ie, simple transform case), * we don't need to allocate any space since no array will have to be @@ -1753,7 +1763,7 @@ H5Z_xform_noop(const H5Z_data_xform_t *data_xform_prop) * Function: H5Z_xform_extract_xform_str * * Purpose: Extracts the pointer to the data transform strings from the - * data transform property.` + * data transform property.` * Return: * Pointer to a copy of the string in the data_xform property. * diff --git a/test/dtransform.c b/test/dtransform.c index 191cc73..ab568da 100644 --- a/test/dtransform.c +++ b/test/dtransform.c @@ -581,6 +581,7 @@ test_specials(hid_t file) const char *special3 = "1000/x"; const char *special4 = "-x"; const char *special5 = "+x"; + const char *special6 = "2e+1*x"; TESTING("data transform of some special cases") @@ -705,6 +706,29 @@ test_specials(hid_t file) if (H5Dclose(dset_id) < 0) TEST_ERROR + /*----------------------------- + * Operation 6: 2e+1*x + *----------------------------*/ + if (H5Pset_data_transform(dxpl_id, special6) < 0) + TEST_ERROR; + + for (row = 0; row < ROWS; row++) + for (col = 0; col < COLS; col++) + data_res[row][col] = transformData[row][col] * 20; + + if ((dset_id = H5Dcreate2(file, "/special6", 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) -- cgit v0.12