summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5T.c21
-rw-r--r--src/H5Tcompound.c146
-rw-r--r--test/cmpd_dset.c251
3 files changed, 384 insertions, 34 deletions
diff --git a/src/H5T.c b/src/H5T.c
index ee02016..d6bc1ed 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -2973,8 +2973,10 @@ H5T_create(H5T_class_t type, size_t size)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
dt->shared->type = type;
- if(type==H5T_COMPOUND)
+ if(type==H5T_COMPOUND) {
dt->shared->u.compnd.packed=TRUE; /* Start out packed */
+ dt->shared->u.compnd.sorted=H5T_SORT_VALUE; /* Start out sorted by value */
+ } /* end if */
else if(type==H5T_OPAQUE)
/* Initialize the tag in case it's not set later. A null tag will
* cause problems for later operations. */
@@ -3173,13 +3175,16 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
* name and type fields of each new member with copied values.
* That is, H5T_copy() is a deep copy.
*/
- new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc *
- sizeof(H5T_cmemb_t));
- if (NULL==new_dt->shared->u.compnd.memb)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
-
- HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb,
- new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t));
+ /* Only malloc if space has been allocated for members - NAF */
+ if(new_dt->shared->u.compnd.nalloc > 0) {
+ new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc *
+ sizeof(H5T_cmemb_t));
+ if (NULL==new_dt->shared->u.compnd.memb)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb,
+ new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t));
+ } /* end if */
for(i = 0; i < new_dt->shared->u.compnd.nmembs; i++) {
unsigned j;
diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c
index 68de174..02d6bd1 100644
--- a/src/H5Tcompound.c
+++ b/src/H5Tcompound.c
@@ -45,6 +45,11 @@
/******************/
/* Local Typedefs */
/******************/
+/* "Key" (+ user data) for bsearch callback */
+typedef struct{
+ size_t offset; /* Offset of member to be added */
+ const H5T_cmemb_t *max_under; /* Member with maximum offset seen that is not above "offset" */
+} H5T_insert_compar_t;
/********************/
@@ -416,6 +421,48 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5T_insert_compar
+ *
+ * Purpose: Callback function for bsearch called from H5T_insert.
+ * Reports whether obj has a lower of higher offset than
+ * that stored in key. Also keeps track of the highest
+ * offset seen that is not higher than that in key.
+ *
+ * Return: -1 if key < obj
+ * 0 if key == obj
+ * 1 if key > obj
+ *
+ * Programmer: Neil Fortner
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5T_insert_compar(const void *_key, const void *_obj)
+{
+ H5T_insert_compar_t *key = *(H5T_insert_compar_t * const *)_key; /* User data */
+ const H5T_cmemb_t *memb = (const H5T_cmemb_t *)_obj; /* Compound member being examined */
+ int ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_insert_compar)
+
+ if(key->offset > memb->offset) {
+ if(key->max_under == NULL || memb->offset > key->max_under->offset)
+ key->max_under = memb;
+ ret_value = 1;
+ } /* end if */
+ else if(key->offset < memb->offset)
+ ret_value = -1;
+ else
+ ret_value = 0; /* Should not happen */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_insert_compar() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_insert
*
* Purpose: Adds a new MEMBER to the compound datatype PARENT. The new
@@ -435,6 +482,8 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
{
unsigned idx; /* Index of member to insert */
size_t total_size;
+ H5T_insert_compar_t key; /* Key for bsearch compare function */
+ H5T_insert_compar_t *keyptr = &key; /* Pointer to key */
unsigned i; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -451,20 +500,39 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
if(!HDstrcmp(parent->shared->u.compnd.memb[i].name, name))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member name is not unique")
- /* Does the new member overlap any existing member ? */
total_size = member->shared->size;
- for(i = 0; i < parent->shared->u.compnd.nmembs; i++)
- if((offset <= parent->shared->u.compnd.memb[i].offset &&
- (offset + total_size) > parent->shared->u.compnd.memb[i].offset) ||
- (parent->shared->u.compnd.memb[i].offset <= offset &&
- (parent->shared->u.compnd.memb[i].offset +
- parent->shared->u.compnd.memb[i].size) > offset))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member")
/* Does the new member overlap the end of the compound type? */
if((offset + total_size) > parent->shared->size)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member extends past end of compound type")
+ if(parent->shared->u.compnd.sorted != H5T_SORT_VALUE)
+ if(H5T_sort_value(parent, NULL) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOMPARE, FAIL, "value sort failed")
+
+ /* Find the position to insert the new member */
+ if(parent->shared->u.compnd.nmembs == 0)
+ idx = 0;
+ else {
+ /* Key value (including user data) for compar callback */
+ key.offset = offset;
+ key.max_under = NULL;
+
+ /* Do a binary search on the offsets of the (now sorted) members. We do
+ * not expect to find an exact match (if we do it is an error), rely on
+ * the user data in the key to keep track of the closest member below
+ * the new member. */
+ if(NULL != HDbsearch(&keyptr, parent->shared->u.compnd.memb, parent->shared->u.compnd.nmembs,
+ sizeof(parent->shared->u.compnd.memb[0]), H5T_insert_compar))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member")
+ idx = (key.max_under == NULL) ? 0 : (unsigned) (key.max_under - parent->shared->u.compnd.memb + 1);
+ } /* end else */
+
+ /* Does the new member overlap any existing member ? */
+ if((idx < parent->shared->u.compnd.nmembs && (offset + total_size) > parent->shared->u.compnd.memb[idx].offset) ||
+ (idx && (parent->shared->u.compnd.memb[idx-1].offset + parent->shared->u.compnd.memb[idx-1].size) > offset))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "member overlaps with another member")
+
/* Increase member array if necessary */
if(parent->shared->u.compnd.nmembs >= parent->shared->u.compnd.nalloc) {
unsigned na = MAX(1, parent->shared->u.compnd.nalloc * 2);
@@ -476,38 +544,68 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
parent->shared->u.compnd.memb = x;
} /* end if */
- /* 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);
-
- parent->shared->u.compnd.sorted = H5T_SORT_NONE;
- parent->shared->u.compnd.nmembs++;
-
- /* Determine if the compound datatype stayed packed */
+ /* Determine if the compound datatype stays packed */
if(parent->shared->u.compnd.packed) {
/* Check if the member type is packed */
- if(H5T_is_packed(parent->shared->u.compnd.memb[idx].type) > 0) {
+ if(H5T_is_packed(member) > 0) {
if(idx == 0) {
/* If the is the first member, the datatype is not packed
* if the first member isn't at offset 0
*/
- if(parent->shared->u.compnd.memb[idx].offset > 0)
+ if(offset > 0)
parent->shared->u.compnd.packed = FALSE;
} /* end if */
else {
/* If the is not the first member, the datatype is not
* packed if the new member isn't adjoining the previous member
*/
- if(parent->shared->u.compnd.memb[idx].offset != (parent->shared->u.compnd.memb[idx - 1].offset + parent->shared->u.compnd.memb[idx - 1].size))
+ if(offset != (parent->shared->u.compnd.memb[idx - 1].offset + parent->shared->u.compnd.memb[idx - 1].size))
parent->shared->u.compnd.packed = FALSE;
} /* end else */
} /* end if */
else
parent->shared->u.compnd.packed = FALSE;
} /* end if */
+ else
+ /* Check if inserting this member causes the parent to become packed */
+ /* First check if it completely closes a gap */
+ /* No need to check if it's being appended to the end */
+ if(idx != parent->shared->u.compnd.nmembs
+ && (offset + total_size) == parent->shared->u.compnd.memb[idx].offset
+ && (idx == 0 ? offset == 0 : (parent->shared->u.compnd.memb[idx-1].offset
+ + parent->shared->u.compnd.memb[idx-1].size) == offset)
+ && H5T_is_packed(member) > 0) {
+
+ /* Start out packed */
+ parent->shared->u.compnd.packed = TRUE;
+
+ /* Check if the entire type is now packed */
+ if((idx != 0 && parent->shared->u.compnd.memb[0].offset != 0)
+ || !H5T_is_packed(parent->shared->u.compnd.memb[0].type))
+ parent->shared->u.compnd.packed = FALSE;
+ else
+ for(i = 1; i < parent->shared->u.compnd.nmembs; i++)
+ if((i != idx && parent->shared->u.compnd.memb[i].offset
+ != (parent->shared->u.compnd.memb[i - 1].offset
+ + parent->shared->u.compnd.memb[i - 1].size))
+ || !H5T_is_packed(parent->shared->u.compnd.memb[i].type)) {
+ parent->shared->u.compnd.packed = FALSE;
+ break;
+ } /* end if */
+ } /* end if */
+
+ /* Reshape the memb array to accomodate the new member */
+ if(idx != parent->shared->u.compnd.nmembs)
+ HDmemmove(&parent->shared->u.compnd.memb[idx+1], &parent->shared->u.compnd.memb[idx],
+ (parent->shared->u.compnd.nmembs - idx) * sizeof(parent->shared->u.compnd.memb[0]));
+
+ /* Add member to member array */
+ 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);
+
+ parent->shared->u.compnd.nmembs++;
/* Set the "force conversion" flag if the field's datatype indicates */
if(member->shared->force_conv == TRUE)
@@ -633,11 +731,11 @@ H5T_is_packed(const H5T_t *dt)
/* If this is a compound datatype, check if it is packed */
if(dt->shared->type == H5T_COMPOUND) {
H5T_compnd_t *compnd = &(dt->shared->u.compnd); /* Convenience pointer to compound info */
- ret_value = (htri_t)(compnd->packed
+ ret_value = (htri_t)(compnd->packed && compnd->nmembs > 0
&& compnd->memb[compnd->nmembs - 1].offset
+ compnd->memb[compnd->nmembs - 1].size
== dt->shared->size);
- }
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_is_packed() */
diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c
index c6ba30b..c05844e 100644
--- a/test/cmpd_dset.c
+++ b/test/cmpd_dset.c
@@ -23,6 +23,7 @@
#define H5T_PACKAGE
#include "H5Tpkg.h" /*to turn off hardware conversions*/
+#include "H5Iprivate.h"
#include "h5test.h"
@@ -120,6 +121,7 @@ typedef struct {
#define NX 100u
#define NY 2000u
+#define PACK_NMEMBS 100
/*-------------------------------------------------------------------------
@@ -600,7 +602,7 @@ test_compound (char *filename, hid_t fapl)
if ((s8_m_sid = H5Screate_simple (2, h_size, NULL)) < 0) goto error;
/* Read the dataset */
- s8 = calloc ((size_t)(h_size[0]*h_size[1]), sizeof(s1_t));
+ s8 = (s1_t *) calloc ((size_t)(h_size[0]*h_size[1]), sizeof(s1_t));
assert (s8);
if (H5Dread (dataset, s1_tid, s8_m_sid, s8_f_sid, H5P_DEFAULT, s8) < 0) {
goto error;
@@ -767,7 +769,7 @@ test_compound (char *filename, hid_t fapl)
f_offset[1] = NY/3;
h_size[0] = 2*NX/3 - f_offset[0];
h_size[1] = 2*NY/3 - f_offset[1];
- s11 = malloc ((size_t)h_size[0]*(size_t)h_size[1]*sizeof(s4_t));
+ s11 = (s4_t *) malloc ((size_t)h_size[0]*(size_t)h_size[1]*sizeof(s4_t));
assert (s11);
/* Initialize */
@@ -1717,6 +1719,248 @@ error:
return 1;
}
+/* Error macro that outputs the state of the randomly generated variables so the
+ * failure can be reproduced */
+#define PACK_OOO_ERROR \
+{ \
+ int _i; \
+ H5_FAILED(); AT(); \
+ printf(" Insertion order ="); \
+ for(_i=0; _i<PACK_NMEMBS; _i++) \
+ printf(" %d", order[_i]); \
+ printf("\n Inner compound order = %d, location = %d\n", sub_cmpd_order, order[sub_cmpd_order]); \
+ fflush(stdout); \
+ goto error; \
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_pack_ooo
+ *
+ * Purpose: Test inserting fields into a compound out of offset order.
+ * Verifies that the compound
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Neil Fortner
+ * Thursday, 22 January 2009
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+static int
+test_pack_ooo(void)
+{
+ hid_t cmpd, sub_cmpd; /* Datatype IDs */
+ H5T_t *dt; /* Datatype pointer */
+ unsigned order[PACK_NMEMBS]; /* Order of insertion */
+ unsigned free_order[PACK_NMEMBS]; /* Index of remaining free slots in order */
+ unsigned num_free; /* Number of free slots in order */
+ unsigned sub_cmpd_order; /* Order to insert the inner compound */
+ char name[6]; /* Member name */
+ unsigned i, j; /* Indices */
+
+ HDsrand((unsigned) time(NULL));
+
+ /* Initialize "free_order" array to indicate that all slots in order are
+ * free */
+ for(i=0; i<PACK_NMEMBS; i++)
+ free_order[i] = i;
+
+ /* Create "order" array */
+ for(i=0; i<PACK_NMEMBS; i++) {
+ /* Generate index into free_order array */
+ num_free = PACK_NMEMBS - i;
+ j = HDrand() % num_free;
+
+ /* Update order array at the randomly generated (but guaranteed to be
+ * free) location */
+ order[free_order[j]] = i;
+
+ /* Reshape free_order to remove j (which is no longer free) */
+ if(j < (num_free - 1))
+ HDmemmove(&free_order[j], &free_order[j+1], (num_free - j - 1) * sizeof(free_order[0]));
+ } /* end for */
+
+ /* Generate order to insert inner compound type */
+ sub_cmpd_order = HDrand() % PACK_NMEMBS;
+
+ TESTING("random member insertion with empty compound subtype");
+
+ /* Create inner compound type. It will be empty for the first run */
+ if((sub_cmpd = H5Tcreate(H5T_COMPOUND, 4)) < 0) PACK_OOO_ERROR
+
+ /* Create main compound type, with extra space at the end */
+ if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) PACK_OOO_ERROR
+
+ /* Insert the compound members in the random order previously generated */
+ for(i=0; i<PACK_NMEMBS; i++) {
+ sprintf(name, "%05d", i);
+ if(i == sub_cmpd_order) {
+ if(H5Tinsert(cmpd, name, 4 * order[i], sub_cmpd) < 0) PACK_OOO_ERROR
+ } else
+ if(H5Tinsert(cmpd, name, 4 * order[i], H5T_STD_I32BE) < 0) PACK_OOO_ERROR
+ } /* end for */
+
+ /* Verify that the compound is not packed */
+ if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) PACK_OOO_ERROR
+ if(dt->shared->u.compnd.packed) PACK_OOO_ERROR
+
+ /* Close the main compound */
+ if(H5Tclose(cmpd) < 0) PACK_OOO_ERROR
+
+ PASSED();
+
+ TESTING("random member insertion with full compound subtype");
+
+ /* Complete the inner compound type */
+ if(H5Tinsert(sub_cmpd, "int", 0, H5T_STD_I32LE) < 0) PACK_OOO_ERROR
+
+ /* Recreate main compound type */
+ if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) PACK_OOO_ERROR
+
+ /* Insert the compound members in the random order previously generated */
+ for(i=0; i<PACK_NMEMBS; i++) {
+ sprintf(name, "%05d", i);
+ if(i == sub_cmpd_order) {
+ if(H5Tinsert(cmpd, name, 4 * order[i], sub_cmpd) < 0) PACK_OOO_ERROR
+ } else
+ if(H5Tinsert(cmpd, name, 4 * order[i], H5T_STD_I32BE) < 0) PACK_OOO_ERROR
+ } /* end for */
+
+ /* Verify that the compound is packed */
+ if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) PACK_OOO_ERROR
+ if(!dt->shared->u.compnd.packed) PACK_OOO_ERROR
+
+ /* Close */
+ if(H5Tclose(cmpd) < 0) PACK_OOO_ERROR
+ if(H5Tclose(sub_cmpd) < 0) PACK_OOO_ERROR
+
+ PASSED();
+
+ /* Change to reverse ordering, insert compound last */
+ for(i=0; i<PACK_NMEMBS; i++)
+ order[i] = PACK_NMEMBS - i - 1;
+ sub_cmpd_order = PACK_NMEMBS - 1;
+
+ TESTING("reverse member insertion with empty compound subtype");
+
+ /* Create inner compound type. It will be empty for the first run */
+ if((sub_cmpd = H5Tcreate(H5T_COMPOUND, 4)) < 0) TEST_ERROR
+
+ /* Create main compound type, with extra space at the end */
+ if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) TEST_ERROR
+
+ /* Insert the compound members in the reverse order previously generated */
+ for(i=0; i<PACK_NMEMBS; i++) {
+ sprintf(name, "%05d", i);
+ if(i == sub_cmpd_order) {
+ if(H5Tinsert(cmpd, name, 4 * order[i], sub_cmpd) < 0) TEST_ERROR
+ } else
+ if(H5Tinsert(cmpd, name, 4 * order[i], H5T_STD_I32BE) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Verify that the compound is not packed */
+ if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) TEST_ERROR
+ if(dt->shared->u.compnd.packed) TEST_ERROR
+
+ /* Close the main compound */
+ if(H5Tclose(cmpd) < 0) TEST_ERROR
+
+ PASSED();
+
+ TESTING("reverse member insertion with full compound subtype");
+
+ /* Complete the inner compound type */
+ if(H5Tinsert(sub_cmpd, "int", 0, H5T_STD_I32LE) < 0) TEST_ERROR
+
+ /* Recreate main compound type */
+ if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) TEST_ERROR
+
+ /* Insert the compound members in the reverse order previously generated */
+ for(i=0; i<PACK_NMEMBS; i++) {
+ sprintf(name, "%05d", i);
+ if(i == sub_cmpd_order) {
+ if(H5Tinsert(cmpd, name, 4 * order[i], sub_cmpd) < 0) TEST_ERROR
+ } else
+ if(H5Tinsert(cmpd, name, 4 * order[i], H5T_STD_I32BE) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Verify that the compound is packed */
+ if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) TEST_ERROR
+ if(!dt->shared->u.compnd.packed) TEST_ERROR
+
+ /* Close */
+ if(H5Tclose(cmpd) < 0) TEST_ERROR
+ if(H5Tclose(sub_cmpd) < 0) TEST_ERROR
+
+ PASSED();
+
+ /* Change to forward ordering, insert compound first */
+ sub_cmpd_order = 0;
+
+ TESTING("forward member insertion with empty compound subtype");
+
+ /* Create inner compound type. It will be empty for the first run */
+ if((sub_cmpd = H5Tcreate(H5T_COMPOUND, 4)) < 0) TEST_ERROR
+
+ /* Create main compound type, with extra space at the end */
+ if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) TEST_ERROR
+
+ /* Insert the compound members in forward order */
+ for(i=0; i<PACK_NMEMBS; i++) {
+ sprintf(name, "%05d", i);
+ if(i == sub_cmpd_order) {
+ if(H5Tinsert(cmpd, name, 4 * i, sub_cmpd) < 0) TEST_ERROR
+ } else
+ if(H5Tinsert(cmpd, name, 4 * i, H5T_STD_I32BE) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Verify that the compound is not packed */
+ if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) TEST_ERROR
+ if(dt->shared->u.compnd.packed) TEST_ERROR
+
+ /* Close the main compound */
+ if(H5Tclose(cmpd) < 0) TEST_ERROR
+
+ PASSED();
+
+ TESTING("forward member insertion with full compound subtype");
+
+ /* Complete the inner compound type */
+ if(H5Tinsert(sub_cmpd, "int", 0, H5T_STD_I32LE) < 0) TEST_ERROR
+
+ /* Recreate main compound type */
+ if((cmpd = H5Tcreate(H5T_COMPOUND, (4 * PACK_NMEMBS) + 1)) < 0) TEST_ERROR
+
+ /* Insert the compound members in forward order */
+ for(i=0; i<PACK_NMEMBS; i++) {
+ sprintf(name, "%05d", i);
+ if(i == sub_cmpd_order) {
+ if(H5Tinsert(cmpd, name, 4 * i, sub_cmpd) < 0) TEST_ERROR
+ } else
+ if(H5Tinsert(cmpd, name, 4 * i, H5T_STD_I32BE) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Verify that the compound is packed */
+ if(NULL == (dt = (H5T_t *) H5I_object_verify(cmpd, H5I_DATATYPE))) TEST_ERROR
+ if(!dt->shared->u.compnd.packed) TEST_ERROR
+
+ /* Close */
+ if(H5Tclose(cmpd) < 0) TEST_ERROR
+ if(H5Tclose(sub_cmpd) < 0) TEST_ERROR
+
+ PASSED();
+
+ return 0;
+
+error:
+ puts("*** DATASET TESTS FAILED ***");
+ return 1;
+}
+
/*-------------------------------------------------------------------------
* Function: main
@@ -1768,6 +2012,9 @@ main (int argc, char *argv[])
h5_fixname(FILENAME[2], fapl_id, fname, sizeof(fname));
nerrors += test_hdf5_dst_subset(fname, fapl_id);
+ puts("Testing that compound types can be packed out of order:");
+ nerrors += test_pack_ooo();
+
if (nerrors) {
printf("***** %u FAILURE%s! *****\n",
nerrors, 1==nerrors?"":"S");