From bab8acbe8238a5c4b10a5ecc08eef1d260f11b2b Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Fri, 28 Jul 2023 07:09:09 -0700 Subject: Brings an enum fix from develop (#3304) --- release_docs/RELEASE.txt | 11 + src/H5T.c | 64 +-- src/H5Tcompound.c | 6 +- test/enum.c | 1006 ++++++++++++++++++++++++---------------------- 4 files changed, 568 insertions(+), 519 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 91bc939..0f407f4 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -127,6 +127,17 @@ Bug Fixes since HDF5-1.14.1 release that an error message is displayed in this situation rather than causing an assertion failure. + - Fixed a potential bug when copying empty enum datatypes + + Copying an empty enum datatype (including implicitly, as when an enum + is a part of a compound datatype) would fail in an assert in debug + mode and could fail in release mode depending on how the platform + handles undefined behavior regarding size 0 memory allocations and + using memcpy with a NULL src pointer. + + The library is now more careful about using memory operations when + copying empty enum datatypes and will not error or raise an assert. + - Added an AAPL check to H5Acreate A check was added to H5Acreate to ensure that a failure is correctly diff --git a/src/H5T.c b/src/H5T.c index 3ed0a5a..666c159 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -1417,7 +1417,7 @@ done: (void)H5T_close_real(dt); else { if (dt->shared->owned_vol_obj && H5VL_free_object(dt->shared->owned_vol_obj) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close owned VOL object") + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close owned VOL object"); dt->shared = H5FL_FREE(H5T_shared_t, dt->shared); dt = H5FL_FREE(H5T_t, dt); } /* end else */ @@ -1867,7 +1867,7 @@ done: /* Close the new datatype on errors */ if (H5I_INVALID_HID == ret_value) if (new_dt && H5T_close_real(new_dt) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, H5I_INVALID_HID, "unable to release datatype info") + HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, H5I_INVALID_HID, "unable to release datatype info"); FUNC_LEAVE_API(ret_value) } /* end H5Tcopy() */ @@ -1959,7 +1959,7 @@ H5Tclose_async(const char *app_file, const char *app_func, unsigned app_line, hi done: if (connector && H5VL_conn_dec_rc(connector) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement ref count on connector") + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement ref count on connector"); FUNC_LEAVE_API(ret_value) } /* end H5Tclose_async() */ @@ -2713,8 +2713,7 @@ H5T__unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5T_c if (func && func != soft->conv.u.app_func) continue; - HDmemmove(H5T_g.soft + i, H5T_g.soft + i + 1, - (size_t)(H5T_g.nsoft - (i + 1)) * sizeof(H5T_soft_t)); + memmove(H5T_g.soft + i, H5T_g.soft + i + 1, (size_t)(H5T_g.nsoft - (i + 1)) * sizeof(H5T_soft_t)); --H5T_g.nsoft; } /* end for */ } /* end if */ @@ -2739,8 +2738,8 @@ H5T__unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5T_c } /* end if */ else { /* Remove from table */ - HDmemmove(H5T_g.path + i, H5T_g.path + i + 1, - (size_t)(H5T_g.npaths - (i + 1)) * sizeof(H5T_path_t *)); + memmove(H5T_g.path + i, H5T_g.path + i + 1, + (size_t)(H5T_g.npaths - (i + 1)) * sizeof(H5T_path_t *)); --H5T_g.npaths; /* Shut down path */ @@ -3122,7 +3121,7 @@ H5T_encode(H5T_t *obj, unsigned char *buf, size_t *nalloc) done: /* Release fake file structure */ if (f && H5F_fake_free(f) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release fake file struct") + HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "unable to release fake file struct"); FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_encode() */ @@ -3172,7 +3171,7 @@ H5T_decode(size_t buf_size, const unsigned char *buf) done: /* Release fake file structure */ if (f && H5F_fake_free(f) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, NULL, "unable to release fake file struct") + HDONE_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, NULL, "unable to release fake file struct"); FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_decode() */ @@ -3290,7 +3289,7 @@ done: if (NULL == ret_value) { if (dt) { if (dt->shared->owned_vol_obj && H5VL_free_object(dt->shared->owned_vol_obj) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object") + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object"); dt->shared = H5FL_FREE(H5T_shared_t, dt->shared); dt = H5FL_FREE(H5T_t, dt); } @@ -3345,7 +3344,7 @@ done: if (new_dt) { if (new_dt->shared) { if (new_dt->shared->owned_vol_obj && H5VL_free_object(new_dt->shared->owned_vol_obj) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object") + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object"); new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared); } /* end if */ new_dt = H5FL_FREE(H5T_t, new_dt); @@ -3520,21 +3519,28 @@ H5T__complete_copy(H5T_t *new_dt, const H5T_t *old_dt, H5T_shared_t *reopened_fo * of each new member with copied values. That is, H5T_copy() is a * deep copy. */ - if (NULL == (new_dt->shared->u.enumer.name = - H5MM_malloc(new_dt->shared->u.enumer.nalloc * sizeof(char *)))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "enam name array memory allocation failed") - if (NULL == (new_dt->shared->u.enumer.value = - H5MM_malloc(new_dt->shared->u.enumer.nalloc * new_dt->shared->size))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, - "enam value array memory allocation failed") - H5MM_memcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value, - new_dt->shared->u.enumer.nmembs * new_dt->shared->size); - for (i = 0; i < new_dt->shared->u.enumer.nmembs; i++) { - if (NULL == (s = H5MM_xstrdup(old_dt->shared->u.enumer.name[i]))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, - "can't copy string for enum value's name") - new_dt->shared->u.enumer.name[i] = s; - } /* end for */ + if (old_dt->shared->u.enumer.nalloc > 0) { + if (NULL == (new_dt->shared->u.enumer.name = + H5MM_malloc(new_dt->shared->u.enumer.nalloc * sizeof(char *)))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, + "enam name array memory allocation failed") + if (NULL == (new_dt->shared->u.enumer.value = + H5MM_malloc(new_dt->shared->u.enumer.nalloc * new_dt->shared->size))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, + "enam value array memory allocation failed") + H5MM_memcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value, + new_dt->shared->u.enumer.nmembs * new_dt->shared->size); + for (i = 0; i < new_dt->shared->u.enumer.nmembs; i++) { + if (NULL == (s = H5MM_xstrdup(old_dt->shared->u.enumer.name[i]))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, + "can't copy string for enum value's name") + new_dt->shared->u.enumer.name[i] = s; + } + } + else { + /* Empty enum */ + memset(&new_dt->shared->u.enumer, 0, sizeof(H5T_enum_t)); + } break; case H5T_VLEN: @@ -3665,7 +3671,7 @@ done: if (new_dt) { assert(new_dt->shared); if (new_dt->shared->owned_vol_obj && H5VL_free_object(new_dt->shared->owned_vol_obj) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object") + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object"); new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared); new_dt = H5FL_FREE(H5T_t, new_dt); } /* end if */ @@ -3769,7 +3775,7 @@ done: if (new_dt) { assert(new_dt->shared); if (new_dt->shared->owned_vol_obj && H5VL_free_object(new_dt->shared->owned_vol_obj) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object") + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object"); new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared); new_dt = H5FL_FREE(H5T_t, new_dt); } /* end if */ @@ -5117,7 +5123,7 @@ H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_co } /* end if */ if (cmp > 0) md++; - HDmemmove(H5T_g.path + md + 1, H5T_g.path + md, (size_t)(H5T_g.npaths - md) * sizeof(H5T_path_t *)); + memmove(H5T_g.path + md + 1, H5T_g.path + md, (size_t)(H5T_g.npaths - md) * sizeof(H5T_path_t *)); H5T_g.npaths++; H5T_g.path[md] = path; table = path; diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c index dff699f..be0a111 100644 --- a/src/H5Tcompound.c +++ b/src/H5Tcompound.c @@ -439,10 +439,12 @@ H5T__insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) /* Add member to end of member array */ idx = parent->shared->u.compnd.nmembs; - parent->shared->u.compnd.memb[idx].name = H5MM_xstrdup(name); parent->shared->u.compnd.memb[idx].offset = offset; parent->shared->u.compnd.memb[idx].size = total_size; - parent->shared->u.compnd.memb[idx].type = H5T_copy(member, H5T_COPY_ALL); + if (NULL == (parent->shared->u.compnd.memb[idx].name = H5MM_xstrdup(name))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "couldn't duplicate name string") + if (NULL == (parent->shared->u.compnd.memb[idx].type = H5T_copy(member, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "couldn't copy datatype") parent->shared->u.compnd.sorted = H5T_SORT_NONE; parent->shared->u.compnd.nmembs++; diff --git a/test/enum.c b/test/enum.c index 3aa2855..4b8d7c7 100644 --- a/test/enum.c +++ b/test/enum.c @@ -11,103 +11,101 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Programmer: Robb Matzke - * Tuesday, December 22, 1998 + * Test enum datatypes */ + #include "h5test.h" + +/* Convenience macro for inserting enum values */ #define CPTR(VAR, CONST) ((VAR) = (CONST), &(VAR)) -const char *FILENAME[] = {"enum1", NULL}; +static const char *FILENAME[] = {"enum1", NULL}; typedef enum { E1_RED, E1_GREEN, E1_BLUE, E1_WHITE, E1_BLACK } c_e1; /*------------------------------------------------------------------------- - * Function: test_named - * - * Purpose: Create an enumeration data type and store it in the file. - * - * Return: Success: 0 + * Function: test_named * - * Failure: number of errors - * - * Programmer: Robb Matzke - * Wednesday, December 23, 1998 + * Purpose: Create an enumeration data type and store it in the file * + * Return: Success: 0 + * Failure: 1 *------------------------------------------------------------------------- */ static int test_named(hid_t file) { - hid_t type = -1, cwg = -1; + hid_t tid = H5I_INVALID_HID; + hid_t gid = H5I_INVALID_HID; c_e1 val; signed char val8; TESTING("named enumeration types"); - if ((cwg = H5Gcreate2(file, "test_named", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; + if ((gid = H5Gcreate2(file, "test_named", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; /* A native integer */ - if ((type = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "RED", CPTR(val, E1_RED)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "GREEN", CPTR(val, E1_GREEN)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "BLUE", CPTR(val, E1_BLUE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "WHITE", CPTR(val, E1_WHITE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "BLACK", CPTR(val, E1_BLACK)) < 0) - FAIL_STACK_ERROR; - if (H5Tcommit2(cwg, "e1_a", type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) - FAIL_STACK_ERROR; - if (H5Tclose(type) < 0) - FAIL_STACK_ERROR; + if ((tid = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "RED", CPTR(val, E1_RED)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "GREEN", CPTR(val, E1_GREEN)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "BLUE", CPTR(val, E1_BLUE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "WHITE", CPTR(val, E1_WHITE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "BLACK", CPTR(val, E1_BLACK)) < 0) + TEST_ERROR; + if (H5Tcommit2(gid, "e1_a", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR; + if (H5Tclose(tid) < 0) + TEST_ERROR; /* A smaller type */ - if ((type = H5Tcreate(H5T_ENUM, (size_t)1)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "RED", CPTR(val8, E1_RED)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "GREEN", CPTR(val8, E1_GREEN)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "BLUE", CPTR(val8, E1_BLUE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "WHITE", CPTR(val8, E1_WHITE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "BLACK", CPTR(val8, E1_BLACK)) < 0) - FAIL_STACK_ERROR; - if (H5Tcommit2(cwg, "e1_b", type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) - FAIL_STACK_ERROR; - if (H5Tclose(type) < 0) - FAIL_STACK_ERROR; + if ((tid = H5Tcreate(H5T_ENUM, (size_t)1)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "RED", CPTR(val8, E1_RED)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "GREEN", CPTR(val8, E1_GREEN)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "BLUE", CPTR(val8, E1_BLUE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "WHITE", CPTR(val8, E1_WHITE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "BLACK", CPTR(val8, E1_BLACK)) < 0) + TEST_ERROR; + if (H5Tcommit2(gid, "e1_b", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR; + if (H5Tclose(tid) < 0) + TEST_ERROR; /* A non-native type */ if (H5T_ORDER_BE == H5Tget_order(H5T_NATIVE_INT)) { - if ((type = H5Tenum_create(H5T_STD_U8LE)) < 0) - FAIL_STACK_ERROR; + if ((tid = H5Tenum_create(H5T_STD_U8LE)) < 0) + TEST_ERROR; } else { - if ((type = H5Tenum_create(H5T_STD_U8BE)) < 0) - FAIL_STACK_ERROR; + if ((tid = H5Tenum_create(H5T_STD_U8BE)) < 0) + TEST_ERROR; } - if (H5Tenum_insert(type, "RED", CPTR(val8, E1_RED)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "GREEN", CPTR(val8, E1_GREEN)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "BLUE", CPTR(val8, E1_BLUE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "WHITE", CPTR(val8, E1_WHITE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "BLACK", CPTR(val8, E1_BLACK)) < 0) - FAIL_STACK_ERROR; - if (H5Tcommit2(cwg, "e1_c", type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) - FAIL_STACK_ERROR; - if (H5Tclose(type) < 0) - FAIL_STACK_ERROR; - - if (H5Gclose(cwg) < 0) - FAIL_STACK_ERROR; + if (H5Tenum_insert(tid, "RED", CPTR(val8, E1_RED)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "GREEN", CPTR(val8, E1_GREEN)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "BLUE", CPTR(val8, E1_BLUE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "WHITE", CPTR(val8, E1_WHITE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "BLACK", CPTR(val8, E1_BLACK)) < 0) + TEST_ERROR; + if (H5Tcommit2(gid, "e1_c", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR; + if (H5Tclose(tid) < 0) + TEST_ERROR; + + if (H5Gclose(gid) < 0) + TEST_ERROR; PASSED(); return 0; @@ -115,173 +113,167 @@ test_named(hid_t file) error: H5E_BEGIN_TRY { - H5Tclose(type); - H5Gclose(cwg); + H5Tclose(tid); + H5Gclose(gid); } - H5E_END_TRY; + H5E_END_TRY return 1; } /*------------------------------------------------------------------------- - * Function: test_conv - * - * Purpose: Tests writing and read data + * Function: test_conv * - * Return: Success: 0 + * Purpose: Tests writing and read data * - * Failure: number of errors - * - * Programmer: Robb Matzke - * Monday, January 4, 1999 - * - * Raymond Lu - * 12 October 2012 - * I added tests for enum-integer and enum-float conversions + * Return: Success: 0 + * Failure: 1 *------------------------------------------------------------------------- */ static int test_conv(hid_t file) { - hid_t cwg = -1, type = -1, space = -1, dset = -1; + hid_t gid = H5I_INVALID_HID; + hid_t tid = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; c_e1 val; /* Some values are out of range for testing. The library should accept them */ - static c_e1 data1[] = {E1_RED, E1_GREEN, E1_BLUE, E1_GREEN, E1_WHITE, E1_WHITE, E1_BLACK, - E1_GREEN, E1_BLUE, E1_RED, E1_RED, E1_BLUE, E1_GREEN, E1_BLACK, - E1_WHITE, E1_RED, E1_WHITE, (c_e1)0, (c_e1)-1, (c_e1)-2}; - c_e1 data2[NELMTS(data1)]; - short data_short[NELMTS(data1)]; - int data_int[NELMTS(data1)]; - double data_double[NELMTS(data1)]; - hsize_t ds_size[1] = {NELMTS(data1)}; - size_t i; + c_e1 data1[] = {E1_RED, E1_GREEN, E1_BLUE, E1_GREEN, E1_WHITE, E1_WHITE, E1_BLACK, + E1_GREEN, E1_BLUE, E1_RED, E1_RED, E1_BLUE, E1_GREEN, E1_BLACK, + E1_WHITE, E1_RED, E1_WHITE, (c_e1)0, (c_e1)-1, (c_e1)-2}; + c_e1 data2[NELMTS(data1)]; + short data_short[NELMTS(data1)]; + int data_int[NELMTS(data1)]; + double data_double[NELMTS(data1)]; + hsize_t ds_size = NELMTS(data1); + size_t i; TESTING("enumeration conversions"); - if ((cwg = H5Gcreate2(file, "test_conv", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; - - if ((type = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "RED", CPTR(val, E1_RED)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "GREEN", CPTR(val, E1_GREEN)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "BLUE", CPTR(val, E1_BLUE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "WHITE", CPTR(val, E1_WHITE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "BLACK", CPTR(val, E1_BLACK)) < 0) - FAIL_STACK_ERROR; - - if ((space = H5Screate_simple(1, ds_size, NULL)) < 0) - FAIL_STACK_ERROR; + if ((gid = H5Gcreate2(file, "test_conv", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if ((tid = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "RED", CPTR(val, E1_RED)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "GREEN", CPTR(val, E1_GREEN)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "BLUE", CPTR(val, E1_BLUE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "WHITE", CPTR(val, E1_WHITE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "BLACK", CPTR(val, E1_BLACK)) < 0) + TEST_ERROR; + + if ((sid = H5Screate_simple(1, &ds_size, NULL)) < 0) + TEST_ERROR; /*************************************** * Dataset of enumeration type ***************************************/ /* Create a dataset of enum type and write enum data to it */ - if ((dset = H5Dcreate2(cwg, "color_table1", type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; - if (H5Dwrite(dset, type, space, space, H5P_DEFAULT, data1) < 0) - FAIL_STACK_ERROR; + if ((did = H5Dcreate2(gid, "color_table1", tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + if (H5Dwrite(did, tid, sid, sid, H5P_DEFAULT, data1) < 0) + TEST_ERROR; /* Test reading back the data with no conversion */ - if (H5Dread(dset, type, space, space, H5P_DEFAULT, data2) < 0) - FAIL_STACK_ERROR; + if (H5Dread(did, tid, sid, sid, H5P_DEFAULT, data2) < 0) + TEST_ERROR; - for (i = 0; i < (size_t)ds_size[0]; i++) + for (i = 0; i < ds_size; i++) if (data1[i] != data2[i]) { H5_FAILED(); - printf(" 1. data1[%lu]=%d, data2[%lu]=%d (should be same)\n", (unsigned long)i, - (int)(data1[i]), (unsigned long)i, (int)(data2[i])); + printf(" 1. data1[%zu]=%d, data2[%zu]=%d (should be same)\n", i, (int)data1[i], i, + (int)data2[i]); goto error; - } /* end if */ + } /* Test converting the data to integer. Read enum data back as integer */ - if (H5Dread(dset, H5T_NATIVE_SHORT, space, space, H5P_DEFAULT, data_short) < 0) - FAIL_STACK_ERROR; + if (H5Dread(did, H5T_NATIVE_SHORT, sid, sid, H5P_DEFAULT, data_short) < 0) + TEST_ERROR; - for (i = 0; i < (size_t)ds_size[0]; i++) - if ((short)data1[i] != data_short[i]) { + for (i = 0; i < ds_size; i++) + if ((int)data1[i] != (int)data_short[i]) { H5_FAILED(); - printf(" 2. data1[%lu]=%d, data_short[%lu]=%d (should be same)\n", (unsigned long)i, - (int)(data1[i]), (unsigned long)i, (int)(data_short[i])); + printf(" 2. data1[%zu]=%d, data_short[%zu]=%d (should be same)\n", i, (int)data1[i], i, + (int)data_short[i]); goto error; - } /* end if */ + } /* Test converting the data to floating number. Read enum data back as floating number */ - if (H5Dread(dset, H5T_NATIVE_DOUBLE, space, space, H5P_DEFAULT, data_double) < 0) - FAIL_STACK_ERROR; + if (H5Dread(did, H5T_NATIVE_DOUBLE, sid, sid, H5P_DEFAULT, data_double) < 0) + TEST_ERROR; - for (i = 0; i < (size_t)ds_size[0]; i++) + for (i = 0; i < ds_size; i++) if ((int)data1[i] != (int)data_double[i]) { H5_FAILED(); - printf(" 3. data1[%lu]=%d, data_double[%lu]=%d (should be same)\n", (unsigned long)i, - (int)(data1[i]), (unsigned long)i, (int)(data_double[i])); + printf(" 3. data1[%zu]=%d, data_double[%zu]=%d (should be same)\n", i, (int)data1[i], i, + (int)data_double[i]); goto error; - } /* end if */ + } - if (H5Dclose(dset) < 0) - FAIL_STACK_ERROR; + if (H5Dclose(did) < 0) + TEST_ERROR; /*************************************** * Dataset of integer type ***************************************/ /* Create a dataset of native integer and write enum data to it */ - if ((dset = H5Dcreate2(cwg, "color_table2", H5T_NATIVE_INT, space, H5P_DEFAULT, H5P_DEFAULT, - H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; + if ((did = H5Dcreate2(gid, "color_table2", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < + 0) + TEST_ERROR; - if (H5Dwrite(dset, type, space, space, H5P_DEFAULT, data1) < 0) - FAIL_STACK_ERROR; + if (H5Dwrite(did, tid, sid, sid, H5P_DEFAULT, data1) < 0) + TEST_ERROR; /* Test reading back the data with no conversion */ - if (H5Dread(dset, H5T_NATIVE_INT, space, space, H5P_DEFAULT, data_int) < 0) - FAIL_STACK_ERROR; + if (H5Dread(did, H5T_NATIVE_INT, sid, sid, H5P_DEFAULT, data_int) < 0) + TEST_ERROR; - for (i = 0; i < (size_t)ds_size[0]; i++) + for (i = 0; i < ds_size; i++) if ((int)data1[i] != data_int[i]) { H5_FAILED(); - printf(" 4. data1[%lu]=%d, data_int[%lu]=%d (should be same)\n", (unsigned long)i, - (int)(data1[i]), (unsigned long)i, (int)(data_int[i])); + printf(" 4. data1[%zu]=%d, data_int[%zu]=%d (should be same)\n", i, (int)data1[i], i, + data_int[i]); goto error; - } /* end if */ + } - if (H5Dclose(dset) < 0) - FAIL_STACK_ERROR; + if (H5Dclose(did) < 0) + TEST_ERROR; /*************************************** * Dataset of double type ***************************************/ /* Create a dataset of native double and write enum data to it */ - if ((dset = H5Dcreate2(cwg, "color_table3", H5T_NATIVE_DOUBLE, space, H5P_DEFAULT, H5P_DEFAULT, - H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; + if ((did = H5Dcreate2(gid, "color_table3", H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) + TEST_ERROR; - if (H5Dwrite(dset, type, space, space, H5P_DEFAULT, data1) < 0) - FAIL_STACK_ERROR; + if (H5Dwrite(did, tid, sid, sid, H5P_DEFAULT, data1) < 0) + TEST_ERROR; /* Test reading back the data with no conversion */ - if (H5Dread(dset, H5T_NATIVE_DOUBLE, space, space, H5P_DEFAULT, data_double) < 0) - FAIL_STACK_ERROR; + if (H5Dread(did, H5T_NATIVE_DOUBLE, sid, sid, H5P_DEFAULT, data_double) < 0) + TEST_ERROR; - for (i = 0; i < (size_t)ds_size[0]; i++) + for (i = 0; i < ds_size; i++) if ((int)data1[i] != (int)data_double[i]) { H5_FAILED(); - printf(" 5. data1[%lu]=%d, data_double[%lu]=%d (should be same)\n", (unsigned long)i, - (int)(data1[i]), (unsigned long)i, (int)(data_double[i])); + printf(" 5. data1[%zu]=%d, data_double[%zu]=%d (should be same)\n", i, (int)data1[i], i, + (int)data_double[i]); goto error; - } /* end if */ - - if (H5Dclose(dset) < 0) - FAIL_STACK_ERROR; + } - if (H5Sclose(space) < 0) - FAIL_STACK_ERROR; - if (H5Tclose(type) < 0) - FAIL_STACK_ERROR; - if (H5Gclose(cwg) < 0) - FAIL_STACK_ERROR; + if (H5Dclose(did) < 0) + TEST_ERROR; + if (H5Sclose(sid) < 0) + TEST_ERROR; + if (H5Tclose(tid) < 0) + TEST_ERROR; + if (H5Gclose(gid) < 0) + TEST_ERROR; PASSED(); return 0; @@ -289,102 +281,99 @@ test_conv(hid_t file) error: H5E_BEGIN_TRY { - H5Dclose(dset); - H5Sclose(space); - H5Tclose(type); - H5Gclose(cwg); + H5Dclose(did); + H5Sclose(sid); + H5Tclose(tid); + H5Gclose(gid); } - H5E_END_TRY; + H5E_END_TRY return 1; } /*------------------------------------------------------------------------- - * Function: test_tr1 - * - * Purpose: Writes enumerated data to a dataset which requires - * translation. Both memory and file data types use native - * integers but the file type has a different mapping between - * the integers and symbols. - * - * Return: Success: 0 + * Function: test_tr1 * - * Failure: number of errors - * - * Programmer: Robb Matzke - * Monday, January 4, 1999 + * Purpose: Writes enumerated data to a dataset which requires + * translation. Both memory and file data types use native + * integers but the file type has a different mapping between + * the integers and symbols. * + * Return: Success: 0 + * Failure: 1 *------------------------------------------------------------------------- */ static int test_tr1(hid_t file) { - hid_t cwg = -1, m_type = -1, f_type = -1, space = -1, dset = -1; - hsize_t ds_size[1] = {10}; - size_t i; - c_e1 eval; - int ival; - static c_e1 data1[10] = {E1_RED, E1_GREEN, E1_BLUE, E1_GREEN, E1_WHITE, - E1_WHITE, E1_BLACK, E1_GREEN, E1_BLUE, E1_RED}; - c_e1 data2[10]; + hid_t gid = H5I_INVALID_HID; + hid_t m_tid = H5I_INVALID_HID; + hid_t f_tid = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hsize_t ds_size = 10; + c_e1 eval; + int ival; + c_e1 data1[10] = {E1_RED, E1_GREEN, E1_BLUE, E1_GREEN, E1_WHITE, + E1_WHITE, E1_BLACK, E1_GREEN, E1_BLUE, E1_RED}; + c_e1 data2[10]; TESTING("O(1) conversions"); - if ((cwg = H5Gcreate2(file, "test_tr1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; - - if ((m_type = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(m_type, "RED", CPTR(eval, E1_RED)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(m_type, "GREEN", CPTR(eval, E1_GREEN)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(m_type, "BLUE", CPTR(eval, E1_BLUE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(m_type, "WHITE", CPTR(eval, E1_WHITE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(m_type, "BLACK", CPTR(eval, E1_BLACK)) < 0) - FAIL_STACK_ERROR; - - if ((f_type = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(f_type, "RED", CPTR(ival, 105)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(f_type, "GREEN", CPTR(ival, 104)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(f_type, "BLUE", CPTR(ival, 103)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(f_type, "WHITE", CPTR(ival, 102)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(f_type, "BLACK", CPTR(ival, 101)) < 0) - FAIL_STACK_ERROR; - - if ((space = H5Screate_simple(1, ds_size, NULL)) < 0) - FAIL_STACK_ERROR; - if ((dset = H5Dcreate2(cwg, "color_table", f_type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; - if (H5Dwrite(dset, m_type, space, space, H5P_DEFAULT, data1) < 0) - FAIL_STACK_ERROR; - if (H5Dread(dset, m_type, space, space, H5P_DEFAULT, data2) < 0) - FAIL_STACK_ERROR; - - for (i = 0; i < (size_t)ds_size[0]; i++) + if ((gid = H5Gcreate2(file, "test_tr1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if ((m_tid = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) + TEST_ERROR; + if (H5Tenum_insert(m_tid, "RED", CPTR(eval, E1_RED)) < 0) + TEST_ERROR; + if (H5Tenum_insert(m_tid, "GREEN", CPTR(eval, E1_GREEN)) < 0) + TEST_ERROR; + if (H5Tenum_insert(m_tid, "BLUE", CPTR(eval, E1_BLUE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(m_tid, "WHITE", CPTR(eval, E1_WHITE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(m_tid, "BLACK", CPTR(eval, E1_BLACK)) < 0) + TEST_ERROR; + + if ((f_tid = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) + TEST_ERROR; + if (H5Tenum_insert(f_tid, "RED", CPTR(ival, 105)) < 0) + TEST_ERROR; + if (H5Tenum_insert(f_tid, "GREEN", CPTR(ival, 104)) < 0) + TEST_ERROR; + if (H5Tenum_insert(f_tid, "BLUE", CPTR(ival, 103)) < 0) + TEST_ERROR; + if (H5Tenum_insert(f_tid, "WHITE", CPTR(ival, 102)) < 0) + TEST_ERROR; + if (H5Tenum_insert(f_tid, "BLACK", CPTR(ival, 101)) < 0) + TEST_ERROR; + + if ((sid = H5Screate_simple(1, &ds_size, NULL)) < 0) + TEST_ERROR; + if ((did = H5Dcreate2(gid, "color_table", f_tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + if (H5Dwrite(did, m_tid, sid, sid, H5P_DEFAULT, data1) < 0) + TEST_ERROR; + if (H5Dread(did, m_tid, sid, sid, H5P_DEFAULT, data2) < 0) + TEST_ERROR; + + for (size_t i = 0; i < ds_size; i++) if (data1[i] != data2[i]) { H5_FAILED(); - printf(" data1[%lu]=%d, data2[%lu]=%d (should be same)\n", (unsigned long)i, (int)(data1[i]), - (unsigned long)i, (int)(data2[i])); + printf(" data1[%zu]=%d, data2[%zu]=%d (should be same)\n", i, (int)data1[i], i, (int)data2[i]); goto error; } - if (H5Dclose(dset) < 0) - FAIL_STACK_ERROR; - if (H5Sclose(space) < 0) - FAIL_STACK_ERROR; - if (H5Tclose(m_type) < 0) - FAIL_STACK_ERROR; - if (H5Tclose(f_type) < 0) - FAIL_STACK_ERROR; - if (H5Gclose(cwg) < 0) - FAIL_STACK_ERROR; + if (H5Dclose(did) < 0) + TEST_ERROR; + if (H5Sclose(sid) < 0) + TEST_ERROR; + if (H5Tclose(m_tid) < 0) + TEST_ERROR; + if (H5Tclose(f_tid) < 0) + TEST_ERROR; + if (H5Gclose(gid) < 0) + TEST_ERROR; PASSED(); @@ -393,100 +382,98 @@ test_tr1(hid_t file) error: H5E_BEGIN_TRY { - H5Dclose(dset); - H5Sclose(space); - H5Tclose(m_type); - H5Tclose(f_type); - H5Gclose(cwg); + H5Dclose(did); + H5Sclose(sid); + H5Tclose(m_tid); + H5Tclose(f_tid); + H5Gclose(gid); } - H5E_END_TRY; + H5E_END_TRY return 1; } /*------------------------------------------------------------------------- - * Function: test_tr2 - * - * Purpose: Tests conversions that use the O(log N) lookup function. + * Function: test_tr2 * - * Return: Success: 0 - * - * Failure: number of errors - * - * Programmer: Robb Matzke - * Tuesday, January 5, 1999 + * Purpose: Tests conversions that use the O(log N) lookup function * + * Return: Success: 0 + * Failure: 1 *------------------------------------------------------------------------- */ static int test_tr2(hid_t file) { - hid_t cwg = -1, m_type = -1, f_type = -1, space = -1, dset = -1; - hsize_t ds_size[1] = {10}; - size_t i; - c_e1 val1; - int val2; - static c_e1 data1[10] = {E1_RED, E1_GREEN, E1_BLUE, E1_GREEN, E1_WHITE, - E1_WHITE, E1_BLACK, E1_GREEN, E1_BLUE, E1_RED}; - c_e1 data2[10]; + hid_t gid = H5I_INVALID_HID; + hid_t m_tid = H5I_INVALID_HID; + hid_t f_tid = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hsize_t ds_size = 10; + size_t i; + c_e1 val1; + int val2; + c_e1 data1[10] = {E1_RED, E1_GREEN, E1_BLUE, E1_GREEN, E1_WHITE, + E1_WHITE, E1_BLACK, E1_GREEN, E1_BLUE, E1_RED}; + c_e1 data2[10]; TESTING("O(log N) conversions"); - if ((cwg = H5Gcreate2(file, "test_tr2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; - - if ((m_type = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(m_type, "RED", CPTR(val1, E1_RED)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(m_type, "GREEN", CPTR(val1, E1_GREEN)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(m_type, "BLUE", CPTR(val1, E1_BLUE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(m_type, "WHITE", CPTR(val1, E1_WHITE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(m_type, "BLACK", CPTR(val1, E1_BLACK)) < 0) - FAIL_STACK_ERROR; - - if ((f_type = H5Tcreate(H5T_ENUM, sizeof(int))) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(f_type, "RED", CPTR(val2, 1050)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(f_type, "GREEN", CPTR(val2, 1040)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(f_type, "BLUE", CPTR(val2, 1030)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(f_type, "WHITE", CPTR(val2, 1020)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(f_type, "BLACK", CPTR(val2, 1010)) < 0) - FAIL_STACK_ERROR; - - if ((space = H5Screate_simple(1, ds_size, NULL)) < 0) - FAIL_STACK_ERROR; - if ((dset = H5Dcreate2(cwg, "color_table", f_type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) - FAIL_STACK_ERROR; - if (H5Dwrite(dset, m_type, space, space, H5P_DEFAULT, data1) < 0) - FAIL_STACK_ERROR; - if (H5Dread(dset, m_type, space, space, H5P_DEFAULT, data2) < 0) - FAIL_STACK_ERROR; - - for (i = 0; i < (size_t)ds_size[0]; i++) + if ((gid = H5Gcreate2(file, "test_tr2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if ((m_tid = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) + TEST_ERROR; + if (H5Tenum_insert(m_tid, "RED", CPTR(val1, E1_RED)) < 0) + TEST_ERROR; + if (H5Tenum_insert(m_tid, "GREEN", CPTR(val1, E1_GREEN)) < 0) + TEST_ERROR; + if (H5Tenum_insert(m_tid, "BLUE", CPTR(val1, E1_BLUE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(m_tid, "WHITE", CPTR(val1, E1_WHITE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(m_tid, "BLACK", CPTR(val1, E1_BLACK)) < 0) + TEST_ERROR; + + if ((f_tid = H5Tcreate(H5T_ENUM, sizeof(int))) < 0) + TEST_ERROR; + if (H5Tenum_insert(f_tid, "RED", CPTR(val2, 1050)) < 0) + TEST_ERROR; + if (H5Tenum_insert(f_tid, "GREEN", CPTR(val2, 1040)) < 0) + TEST_ERROR; + if (H5Tenum_insert(f_tid, "BLUE", CPTR(val2, 1030)) < 0) + TEST_ERROR; + if (H5Tenum_insert(f_tid, "WHITE", CPTR(val2, 1020)) < 0) + TEST_ERROR; + if (H5Tenum_insert(f_tid, "BLACK", CPTR(val2, 1010)) < 0) + TEST_ERROR; + + if ((sid = H5Screate_simple(1, &ds_size, NULL)) < 0) + TEST_ERROR; + if ((did = H5Dcreate2(gid, "color_table", f_tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + if (H5Dwrite(did, m_tid, sid, sid, H5P_DEFAULT, data1) < 0) + TEST_ERROR; + if (H5Dread(did, m_tid, sid, sid, H5P_DEFAULT, data2) < 0) + TEST_ERROR; + + for (i = 0; i < ds_size; i++) if (data1[i] != data2[i]) { H5_FAILED(); - printf(" data1[%lu]=%d, data2[%lu]=%d (should be same)\n", (unsigned long)i, (int)(data1[i]), - (unsigned long)i, (int)(data2[i])); + printf(" data1[%zu]=%d, data2[%zu]=%d (should be same)\n", i, (int)data1[i], i, (int)data2[i]); goto error; } - if (H5Dclose(dset) < 0) - FAIL_STACK_ERROR; - if (H5Sclose(space) < 0) - FAIL_STACK_ERROR; - if (H5Tclose(m_type) < 0) - FAIL_STACK_ERROR; - if (H5Tclose(f_type) < 0) - FAIL_STACK_ERROR; - if (H5Gclose(cwg) < 0) - FAIL_STACK_ERROR; + if (H5Dclose(did) < 0) + TEST_ERROR; + if (H5Sclose(sid) < 0) + TEST_ERROR; + if (H5Tclose(m_tid) < 0) + TEST_ERROR; + if (H5Tclose(f_tid) < 0) + TEST_ERROR; + if (H5Gclose(gid) < 0) + TEST_ERROR; PASSED(); @@ -495,20 +482,20 @@ test_tr2(hid_t file) error: H5E_BEGIN_TRY { - H5Dclose(dset); - H5Sclose(space); - H5Tclose(m_type); - H5Tclose(f_type); - H5Gclose(cwg); + H5Dclose(did); + H5Sclose(sid); + H5Tclose(m_tid); + H5Tclose(f_tid); + H5Gclose(gid); } - H5E_END_TRY; + H5E_END_TRY return 1; } /*------------------------------------------------------------------------- - * Function: test_value_dsnt_exist + * Function: test_value_dsnt_exist * - * Purpose: Create an enumeration datatype with "gaps in values" + * Purpose: Create an enumeration datatype with "gaps in values" * and then request a name of non-existing value within * an existing range by calling H5Tenum_nameof function. * Function should fail instead of succeeding and returning @@ -516,211 +503,201 @@ error: * Request a value by supplying non-existing name by calling * H5Tenum_nameof function. Function should fail. * - * - * Return: Success: 0 - * - * Failure: number of errors - * - * Programmer: Elena Pourmal - * Wednesday, June 7, 2002 - * + * Return: Success: 0 + * Failure: 1 *------------------------------------------------------------------------- */ static int test_value_dsnt_exist(void) { - hid_t datatype_id = (-1); /* identifiers */ - int val; - char name[100]; - size_t size = 100; + hid_t tid = H5I_INVALID_HID; + int val; + char name[32]; + size_t size = 32; + const int BAD_VALUES[] = {0, 3, 11}; + const int N_BAD_VALUES = 3; + const char *BAD_NAMES[] = {"SAX", "TEEN", "A"}; + const int N_BAD_NAMES = 3; + herr_t ret; + TESTING("for non-existing name and value"); - /* Turn off error reporting since we expect failure in this test */ - if (H5Eset_auto2(H5E_DEFAULT, NULL, NULL) < 0) - goto error; - - if ((datatype_id = H5Tenum_create(H5T_NATIVE_INT)) < 0) - goto error; + /* Create an empty enum datatype */ + if ((tid = H5Tenum_create(H5T_NATIVE_INT)) < 0) + TEST_ERROR; /* These calls should fail, since no members exist yet */ - if (H5Tenum_valueof(datatype_id, "SAX", &val) >= 0) - goto error; + H5E_BEGIN_TRY + { + ret = H5Tenum_valueof(tid, "SAX", &val); + } + H5E_END_TRY; + if (ret >= 0) + FAIL_PUTS_ERROR("H5Tenum_valueof should not pass with a non-existing name"); + val = 3; - if (H5Tenum_nameof(datatype_id, &val, name, size) >= 0) - goto error; + H5E_BEGIN_TRY + { + ret = H5Tenum_nameof(tid, &val, name, size); + } + H5E_END_TRY; + if (ret >= 0) + FAIL_PUTS_ERROR("H5Tenum_nameof should not pass with a non-existing value"); + /* Insert some enum values */ val = 2; - if (H5Tenum_insert(datatype_id, "TWO", (int *)&val) < 0) - goto error; + if (H5Tenum_insert(tid, "TWO", (int *)&val) < 0) + TEST_ERROR; val = 6; - if (H5Tenum_insert(datatype_id, "SIX", (int *)&val) < 0) - goto error; + if (H5Tenum_insert(tid, "SIX", (int *)&val) < 0) + TEST_ERROR; val = 10; - if (H5Tenum_insert(datatype_id, "TEN", (int *)&val) < 0) - goto error; - - /* This call should fail since we did not create a member with value = 3*/ - val = 3; - if (H5Tenum_nameof(datatype_id, &val, name, size) >= 0) - goto error; - - /* This call should fail since we did not create a member with value = 11*/ - val = 11; - if (H5Tenum_nameof(datatype_id, &val, name, size) >= 0) - goto error; - - /* This call should fail since we did not create a member with value = 0*/ - val = 0; - if (H5Tenum_nameof(datatype_id, &val, name, size) >= 0) - goto error; - - /* This call should fail since we do not have SAX name in the type */ - if (H5Tenum_valueof(datatype_id, "SAX", &val) >= 0) - goto error; + if (H5Tenum_insert(tid, "TEN", (int *)&val) < 0) + TEST_ERROR; + + /* Check that H5Tenum_nameof() fails with non-existing values */ + for (int i = 0; i < N_BAD_VALUES; i++) { + H5E_BEGIN_TRY + { + ret = H5Tenum_nameof(tid, &BAD_VALUES[i], name, size); + } + H5E_END_TRY; + if (ret >= 0) { + H5_FAILED(); + printf("Bad value: %d -- ", BAD_VALUES[i]); + PUTS_ERROR("H5Tenum_nameof should not pass with a non-existing value"); + } + } - /* This call should fail since we do not have TEEN name in the type */ - if (H5Tenum_valueof(datatype_id, "TEEN", &val) >= 0) - goto error; + /* Check that H5Tenum_valueof() fails with non-existing names */ + for (int i = 0; i < N_BAD_NAMES; i++) { + H5E_BEGIN_TRY + { + ret = H5Tenum_valueof(tid, BAD_NAMES[i], &val); + } + H5E_END_TRY; + if (ret >= 0) { + H5_FAILED(); + printf("Bad name: %s -- ", BAD_NAMES[i]); + PUTS_ERROR("H5Tenum_valueof should not pass with a non-existing name"); + } + } - /* This call should fail since we do not have A name in the type */ - if (H5Tenum_valueof(datatype_id, "A", &val) >= 0) - goto error; + if (H5Tclose(tid) < 0) + TEST_ERROR; - if (H5Tclose(datatype_id) < 0) - goto error; PASSED(); return 0; error: H5E_BEGIN_TRY { - H5Tclose(datatype_id); + H5Tclose(tid); } - H5E_END_TRY; + H5E_END_TRY return 1; } /*------------------------------------------------------------------------- - * Function: test_funcs - * - * Purpose: Create an enumeration data type and test some functions - * that are or aren't supposed to work with it. + * Function: test_funcs * - * Return: Success: 0 - * - * Failure: number of errors - * - * Programmer: Raymond Lu - * Tuesday, April 4, 2006 + * Purpose: Create an enumeration data type and test whether setters + * and getters work appropriately * + * Return: Success: 0 + * Failure: 1 *------------------------------------------------------------------------- */ static int test_funcs(void) { - hid_t type = -1; + hid_t tid = H5I_INVALID_HID; c_e1 val; size_t size; H5T_pad_t inpad; H5T_cset_t cset; herr_t ret; - TESTING("some functions with enumeration types"); - - /* A native integer */ - if ((type = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "RED", CPTR(val, E1_RED)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "GREEN", CPTR(val, E1_GREEN)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "BLUE", CPTR(val, E1_BLUE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "WHITE", CPTR(val, E1_WHITE)) < 0) - FAIL_STACK_ERROR; - if (H5Tenum_insert(type, "BLACK", CPTR(val, E1_BLACK)) < 0) - FAIL_STACK_ERROR; - - if (H5Tget_precision(type) == 0) - FAIL_STACK_ERROR; - if (H5Tget_size(type) == 0) - FAIL_STACK_ERROR; - if (H5Tget_offset(type) < 0) - FAIL_STACK_ERROR; - if (H5Tget_sign(type) < 0) - FAIL_STACK_ERROR; - if (H5Tget_super(type) < 0) - FAIL_STACK_ERROR; - + TESTING("setters and getters with enumeration types"); + + /* Create an enum type for testing */ + if ((tid = H5Tcreate(H5T_ENUM, sizeof(c_e1))) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "RED", CPTR(val, E1_RED)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "GREEN", CPTR(val, E1_GREEN)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "BLUE", CPTR(val, E1_BLUE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "WHITE", CPTR(val, E1_WHITE)) < 0) + TEST_ERROR; + if (H5Tenum_insert(tid, "BLACK", CPTR(val, E1_BLACK)) < 0) + TEST_ERROR; + + /* These functions should work with enum datatypes */ + if (H5Tget_precision(tid) == 0) + TEST_ERROR; + if (H5Tget_size(tid) == 0) + TEST_ERROR; + if (H5Tget_offset(tid) < 0) + TEST_ERROR; + if (H5Tget_sign(tid) < 0) + TEST_ERROR; + if (H5Tget_super(tid) < 0) + TEST_ERROR; + + /* These functions should FAIL with enum datatypes */ H5E_BEGIN_TRY { - ret = H5Tset_pad(type, H5T_PAD_ZERO, H5T_PAD_ONE); + ret = H5Tset_pad(tid, H5T_PAD_ZERO, H5T_PAD_ONE); } H5E_END_TRY; - if (ret >= 0) { - H5_FAILED(); - printf("Operation not allowed for this type.\n"); - goto error; - } /* end if */ + if (ret >= 0) + FAIL_PUTS_ERROR("H5Tset_pad should not work with enum types"); H5E_BEGIN_TRY { - size = H5Tget_ebias(type); + size = H5Tget_ebias(tid); } - H5E_END_TRY; - if (size > 0) { - H5_FAILED(); - printf("Operation not allowed for this type.\n"); - goto error; - } /* end if */ + H5E_END_TRY + if (size > 0) + FAIL_PUTS_ERROR("H5Tget_ebias should not work with enum types"); H5E_BEGIN_TRY { - inpad = H5Tget_inpad(type); + inpad = H5Tget_inpad(tid); } - H5E_END_TRY; - if (inpad > -1) { - H5_FAILED(); - printf("Operation not allowed for this type.\n"); - goto error; - } /* end if */ + H5E_END_TRY + if (inpad > -1) + FAIL_PUTS_ERROR("H5Tget_inpad should not work with enum types"); H5E_BEGIN_TRY { - cset = H5Tget_cset(type); + cset = H5Tget_cset(tid); } - H5E_END_TRY; - if (cset > -1) { - H5_FAILED(); - printf("Operation not allowed for this type.\n"); - goto error; - } /* end if */ + H5E_END_TRY + if (cset > -1) + FAIL_PUTS_ERROR("H5Tget_cset should not work with enum types"); size = 16; H5E_BEGIN_TRY { - ret = H5Tset_offset(type, (size_t)size); + ret = H5Tset_offset(tid, size); } - H5E_END_TRY; - if (ret >= 0) { - H5_FAILED(); - printf("Operation not allowed for this type.\n"); - goto error; - } /* end if */ + H5E_END_TRY + if (ret >= 0) + FAIL_PUTS_ERROR("H5Tset_offset should not work with enum types"); H5E_BEGIN_TRY { - ret = H5Tset_order(type, H5T_ORDER_BE); + ret = H5Tset_order(tid, H5T_ORDER_BE); } - H5E_END_TRY; - if (ret >= 0) { - H5_FAILED(); - printf("Operation not allowed for this type.\n"); - goto error; - } /* end if */ + H5E_END_TRY + if (ret >= 0) + FAIL_PUTS_ERROR("H5Tset_order should not work with enum types"); - if (H5Tclose(type) < 0) + if (H5Tclose(tid) < 0) goto error; PASSED(); @@ -729,61 +706,114 @@ test_funcs(void) error: H5E_BEGIN_TRY { - H5Tclose(type); + H5Tclose(tid); } - H5E_END_TRY; + H5E_END_TRY return 1; } /*------------------------------------------------------------------------- - * Function: main - * - * Purpose: - * - * Return: Success: - * - * Failure: + * Function: test_copying_empty_enum * - * Programmer: Robb Matzke - * Tuesday, December 22, 1998 + * Purpose: Test that copying an empty enum works, including implicitly + * when copying compound datatypes containing empty enums * + * Return: Success: 0 + * Failure: 1 *------------------------------------------------------------------------- */ +static int +test_compound_insert_empty_enum(void) +{ + hid_t enum_id = H5I_INVALID_HID; + hid_t cmpd_id = H5I_INVALID_HID; + hid_t copy_id = H5I_INVALID_HID; + size_t size; + + TESTING("copying empty enums works"); + + /* Create an empty enum */ + if ((enum_id = H5Tenum_create(H5T_NATIVE_INT)) < 0) + TEST_ERROR; + + /* Copy the empty enum */ + if ((copy_id = H5Tcopy(enum_id)) < 0) + TEST_ERROR; + if (H5Tclose(copy_id) < 0) + TEST_ERROR; + + /* Create a compound datatype containing the empty enum */ + size = H5Tget_size(H5T_NATIVE_LONG); + if ((cmpd_id = H5Tcreate(H5T_COMPOUND, size)) < 0) + TEST_ERROR; + if (H5Tinsert(cmpd_id, "empty_enum", 0, enum_id)) + TEST_ERROR; + + /* Create a copy of the compound datatype */ + if ((copy_id = H5Tcopy(cmpd_id)) < 0) + TEST_ERROR; + if (H5Tclose(copy_id) < 0) + TEST_ERROR; + + if (H5Tclose(enum_id) < 0) + TEST_ERROR; + if (H5Tclose(cmpd_id) < 0) + TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY + { + H5Tclose(enum_id); + H5Tclose(cmpd_id); + H5Tclose(copy_id); + } + H5E_END_TRY; + return 1; +} + int main(void) { - hid_t fapl = -1, file = -1; + hid_t fapl_id = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; char name[1024]; int nerrors = 0; h5_reset(); - fapl = h5_fileaccess(); + fapl_id = h5_fileaccess(); /* Create the file */ - h5_fixname(FILENAME[0], fapl, name, sizeof name); - if ((file = H5Fcreate(name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + h5_fixname(FILENAME[0], fapl_id, name, sizeof name); + if ((fid = H5Fcreate(name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0) goto error; /* Tests */ - nerrors += test_named(file); - nerrors += test_conv(file); - nerrors += test_tr1(file); - nerrors += test_tr2(file); + nerrors += test_named(fid); + nerrors += test_conv(fid); + nerrors += test_tr1(fid); + nerrors += test_tr2(fid); nerrors += test_value_dsnt_exist(); nerrors += test_funcs(); + nerrors += test_compound_insert_empty_enum(); - H5Fclose(file); + if (H5Fclose(fid) < 0) + goto error; /* Verify symbol table messages are cached */ - nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0); + nerrors += (h5_verify_cached_stabs(FILENAME, fapl_id) < 0 ? 1 : 0); if (nerrors) goto error; + HDputs("All enum tests passed."); - h5_cleanup(FILENAME, fapl); - return 0; + h5_cleanup(FILENAME, fapl_id); + + return EXIT_SUCCESS; error: HDputs("*** ENUM TESTS FAILED ***"); - return 1; + return EXIT_FAILURE; } -- cgit v0.12