summaryrefslogtreecommitdiffstats
path: root/src/H5T.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5T.c')
-rw-r--r--src/H5T.c771
1 files changed, 484 insertions, 287 deletions
diff --git a/src/H5T.c b/src/H5T.c
index 8648a4e..1e10135 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -12,6 +12,7 @@ static char RcsId[] = "@(#)$Revision$";
#define H5T_PACKAGE /*suppress error about including H5Tpkg */
#include <H5private.h> /*generic functions */
+#include <H5Dprivate.h> /*datasets (for H5Tcopy) */
#include <H5Iprivate.h> /*ID functions */
#include <H5Eprivate.h> /*error handling */
#include <H5Gprivate.h> /*groups */
@@ -94,6 +95,7 @@ H5T_init_interface(void)
(herr_t (*)(void *)) H5T_close)) != FAIL) {
ret_value = H5_add_exit(&H5T_term_interface);
}
+
/*
* Initialize pre-defined data types that depend on the architecture.
*/
@@ -158,7 +160,8 @@ H5T_init_interface(void)
/* TIME */
dt = H5MM_xcalloc(1, sizeof(H5T_t));
- dt->locked = TRUE;
+ dt->state = H5T_STATE_IMMUTABLE;
+ H5F_addr_undef (&(dt->ent.header));
dt->type = H5T_TIME;
dt->size = 1;
dt->u.atomic.order = H5Tget_order(H5T_NATIVE_INT_g);
@@ -173,7 +176,8 @@ H5T_init_interface(void)
/* STRING */
dt = H5MM_xcalloc(1, sizeof(H5T_t));
- dt->locked = TRUE;
+ dt->state = H5T_STATE_IMMUTABLE;
+ H5F_addr_undef (&(dt->ent.header));
dt->type = H5T_STRING;
dt->size = 1;
dt->u.atomic.order = H5T_ORDER_NONE;
@@ -190,7 +194,8 @@ H5T_init_interface(void)
/* BITFIELD */
dt = H5MM_xcalloc(1, sizeof(H5T_t));
- dt->locked = TRUE;
+ dt->state = H5T_STATE_IMMUTABLE;
+ H5F_addr_undef (&(dt->ent.header));
dt->type = H5T_BITFIELD;
dt->size = 1;
dt->u.atomic.order = H5Tget_order(H5T_NATIVE_INT_g);
@@ -205,7 +210,8 @@ H5T_init_interface(void)
/* OPAQUE */
dt = H5MM_xcalloc(1, sizeof(H5T_t));
- dt->locked = TRUE;
+ dt->state = H5T_STATE_IMMUTABLE;
+ H5F_addr_undef (&(dt->ent.header));
dt->type = H5T_OPAQUE;
dt->size = 1;
dt->u.atomic.order = H5T_ORDER_NONE;
@@ -254,7 +260,7 @@ H5T_init_interface(void)
/*-------------------------------------------------------------------------
* Function: H5T_unlock_cb
*
- * Purpose: Clear the locked flag for a data type. This function is
+ * Purpose: Clear the immutable flag for a data type. This function is
* called when the library is closing in order to unlock all
* registered data types and thus make them free-able.
*
@@ -270,11 +276,15 @@ H5T_init_interface(void)
*-------------------------------------------------------------------------
*/
static intn
-H5T_unlock_cb (void *dt, const void __unused__ *key)
+H5T_unlock_cb (void *_dt, const void __unused__ *key)
{
+ H5T_t *dt = (H5T_t *)_dt;
+
FUNC_ENTER (H5T_unlock_cb, FAIL);
assert (dt);
- ((H5T_t*)dt)->locked = FALSE;
+ if (H5T_STATE_IMMUTABLE==dt->state) {
+ dt->state = H5T_STATE_RDONLY;
+ }
FUNC_LEAVE (0);
}
@@ -420,6 +430,136 @@ H5Tcreate(H5T_class_t type, size_t size)
/*-------------------------------------------------------------------------
+ * Function: H5Topen
+ *
+ * Purpose: Opens a named data type.
+ *
+ * Return: Success: Object ID of the named data type.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Monday, June 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Topen (hid_t loc_id, const char *name)
+{
+ H5G_t *loc = NULL;
+ H5T_t *type = NULL;
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER (H5Topen, FAIL);
+
+ /* Check args */
+ if (NULL==(loc=H5G_loc (loc_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
+ }
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
+ }
+
+ /* Open it */
+ if (NULL==(type=H5T_open (loc, name))) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL,
+ "unable to open named data type");
+ }
+
+ /* Register the type and return the ID */
+ if ((ret_value=H5I_register (H5_DATATYPE, type))<0) {
+ H5T_close (type);
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
+ "unable to register named data type");
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tcommit
+ *
+ * Purpose: Save a transient data type to a file and turn the type handle
+ * into a named, immutable type.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Monday, June 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tcommit (hid_t loc_id, const char *name, hid_t type_id)
+{
+ H5G_t *loc = NULL;
+ H5T_t *type = NULL;
+
+ FUNC_ENTER (H5Tcommit, FAIL);
+
+ /* Check arguments */
+ if (NULL==(loc=H5G_loc (loc_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
+ }
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
+ }
+ if (H5_DATATYPE!=H5I_group (type_id) ||
+ NULL==(type=H5I_object (type_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+
+ /* Commit the type */
+ if (H5T_commit (loc, name, type)<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to commit data type");
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tcommitted
+ *
+ * Purpose: Determines if a data type is committed or not.
+ *
+ * Return: Success: TRUE if committed, FALSE otherwise.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, June 4, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5Tcommitted (hid_t type_id)
+{
+ H5T_t *type = NULL;
+
+ FUNC_ENTER (H5Tcommitted, FAIL);
+
+ /* Check arguments */
+ if (H5_DATATYPE!=H5I_group (type_id) ||
+ NULL==(type=H5I_object (type_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+
+ FUNC_LEAVE (H5T_STATE_OPEN==type->state || H5T_STATE_NAMED==type->state);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5Tcopy
*
* Purpose: Copies a data type. The resulting data type is not locked.
@@ -435,6 +575,12 @@ H5Tcreate(H5T_class_t type, size_t size)
*
* Modifications:
*
+ * Robb Matzke, 4 Jun 1998
+ * The returned type is always transient and unlocked. If the TYPE_ID
+ * argument is a dataset instead of a data type then this function
+ * returns a transient, modifiable data type which is a copy of the
+ * dataset's data type.
+ *
*-------------------------------------------------------------------------
*/
hid_t
@@ -442,18 +588,37 @@ H5Tcopy(hid_t type_id)
{
H5T_t *dt = NULL;
H5T_t *new_dt = NULL;
+ H5D_t *dset = NULL;
hid_t ret_value = FAIL;
FUNC_ENTER(H5Tcopy, FAIL);
- /* Check args */
- if (H5_DATATYPE != H5I_group(type_id) ||
- NULL == (dt = H5I_object(type_id))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ switch (H5I_group (type_id)) {
+ case H5_DATATYPE:
+ /* The argument is a data type handle */
+ if (NULL==(dt=H5I_object (type_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+ break;
+
+ case H5_DATASET:
+ /* The argument is a dataset handle */
+ if (NULL==(dset=H5I_object (type_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+ }
+ if (NULL==(dt=H5D_typeof (dset))) {
+ HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to get the dataset data type");
+ }
+ break;
+
+ default:
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a data type or dataset");
}
/* Copy */
- if (NULL == (new_dt = H5T_copy(dt))) {
+ if (NULL == (new_dt = H5T_copy(dt, H5T_COPY_TRANSIENT))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't copy");
}
@@ -496,8 +661,8 @@ H5Tclose(hid_t type_id)
NULL == (dt = H5I_object(type_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
- if (dt->locked) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "predefined data type");
+ if (H5T_STATE_IMMUTABLE==dt->state) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable data type");
}
/* When the reference count reaches zero the resources are freed */
@@ -557,7 +722,8 @@ H5Tequal(hid_t type1_id, hid_t type2_id)
* the application doesn't inadvertently change or delete a
* predefined type.
*
- * Once a data type is locked it can never be unlocked.
+ * Once a data type is locked it can never be unlocked unless
+ * the entire library is closed.
*
* Return: Success: SUCCEED
*
@@ -568,6 +734,10 @@ H5Tequal(hid_t type1_id, hid_t type2_id)
*
* Modifications:
*
+ * Robb Matzke, 1 Jun 1998
+ * It is illegal to lock a named data type since we must allow named
+ * types to be closed (to release file resources) but locking a type
+ * prevents that.
*-------------------------------------------------------------------------
*/
herr_t
@@ -582,7 +752,14 @@ H5Tlock(hid_t type_id)
NULL == (dt = H5I_object(type_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
- dt->locked = TRUE;
+ if (H5T_STATE_NAMED==dt->state || H5T_STATE_OPEN==dt->state) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "unable to lock named data type");
+ }
+ if (H5T_lock (dt, TRUE)<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to lock transient data type");
+ }
FUNC_LEAVE(SUCCEED);
}
@@ -703,7 +880,7 @@ H5Tset_size(hid_t type_id, size_t size)
!H5T_is_atomic(dt)) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (size <= 0) {
@@ -762,7 +939,6 @@ H5Tset_size(hid_t type_id, size_t size)
}
/* Commit */
- H5T_unshare (dt);
dt->size = size;
dt->u.atomic.offset = offset;
dt->u.atomic.prec = prec;
@@ -839,7 +1015,7 @@ H5Tset_order(hid_t type_id, H5T_order_t order)
!H5T_is_atomic(dt)) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (order < 0 || order > H5T_ORDER_NONE) {
@@ -847,7 +1023,6 @@ H5Tset_order(hid_t type_id, H5T_order_t order)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.order = order;
FUNC_LEAVE(SUCCEED);
}
@@ -939,7 +1114,7 @@ H5Tset_precision(hid_t type_id, size_t prec)
!H5T_is_atomic(dt)) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (prec <= 0) {
@@ -993,7 +1168,6 @@ H5Tset_precision(hid_t type_id, size_t prec)
}
/* Commit */
- H5T_unshare (dt);
dt->size = size;
dt->u.atomic.offset = offset;
dt->u.atomic.prec = prec;
@@ -1108,7 +1282,7 @@ H5Tset_offset(hid_t type_id, size_t offset)
!H5T_is_atomic(dt)) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (H5T_STRING == dt->type && offset != 0) {
@@ -1122,7 +1296,6 @@ H5Tset_offset(hid_t type_id, size_t offset)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.offset = offset;
FUNC_LEAVE(SUCCEED);
@@ -1198,7 +1371,7 @@ H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb)
!H5T_is_atomic(dt)) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (lsb < 0 || lsb >= H5T_NPAD || msb < 0 || msb >= H5T_NPAD) {
@@ -1206,7 +1379,6 @@ H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.lsb_pad = lsb;
dt->u.atomic.msb_pad = msb;
@@ -1282,7 +1454,7 @@ H5Tset_sign(hid_t type_id, H5T_sign_t sign)
H5T_INTEGER != dt->type) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an integer data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (sign < 0 || sign >= H5T_NSGN) {
@@ -1290,7 +1462,6 @@ H5Tset_sign(hid_t type_id, H5T_sign_t sign)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.i.sign = sign;
FUNC_LEAVE(SUCCEED);
}
@@ -1383,7 +1554,7 @@ H5Tset_fields(hid_t type_id, size_t spos, size_t epos, size_t esize,
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
"not a floating-point data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (epos + esize > dt->u.atomic.prec) {
@@ -1415,7 +1586,6 @@ H5Tset_fields(hid_t type_id, size_t spos, size_t epos, size_t esize,
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.f.sign = spos;
dt->u.atomic.u.f.epos = epos;
dt->u.atomic.u.f.mpos = mpos;
@@ -1495,12 +1665,11 @@ H5Tset_ebias(hid_t type_id, size_t ebias)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
"not a floating-point data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.f.ebias = ebias;
FUNC_LEAVE(SUCCEED);
@@ -1578,7 +1747,7 @@ H5Tset_norm(hid_t type_id, H5T_norm_t norm)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
"not a floating-point data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (norm < 0 || norm > H5T_NORM_NONE) {
@@ -1586,7 +1755,6 @@ H5Tset_norm(hid_t type_id, H5T_norm_t norm)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.f.norm = norm;
FUNC_LEAVE(SUCCEED);
}
@@ -1667,7 +1835,7 @@ H5Tset_inpad(hid_t type_id, H5T_pad_t pad)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
"not a floating-point data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (pad < 0 || pad >= H5T_NPAD) {
@@ -1676,7 +1844,6 @@ H5Tset_inpad(hid_t type_id, H5T_pad_t pad)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.f.pad = pad;
FUNC_LEAVE(SUCCEED);
}
@@ -1754,7 +1921,7 @@ H5Tset_cset(hid_t type_id, H5T_cset_t cset)
H5T_STRING != dt->type) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a string data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (cset < 0 || cset >= H5T_NCSET) {
@@ -1763,7 +1930,6 @@ H5Tset_cset(hid_t type_id, H5T_cset_t cset)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.s.cset = cset;
FUNC_LEAVE(SUCCEED);
}
@@ -1843,7 +2009,7 @@ H5Tset_strpad(hid_t type_id, H5T_str_t strpad)
H5T_STRING != dt->type) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a string data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (strpad < 0 || strpad >= H5T_NSTR) {
@@ -1851,7 +2017,6 @@ H5Tset_strpad(hid_t type_id, H5T_str_t strpad)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.s.pad = strpad;
FUNC_LEAVE(SUCCEED);
}
@@ -2051,6 +2216,10 @@ H5Tget_member_dims(hid_t type_id, int membno,
*
* Modifications:
*
+ * Robb Matzke, 4 Jun 1998
+ * If the member type is a named type then this function returns a
+ * handle to the re-opened named type.
+ *
*-------------------------------------------------------------------------
*/
hid_t
@@ -2072,7 +2241,8 @@ H5Tget_member_type(hid_t type_id, int membno)
}
/* Copy data type into an atom */
- if (NULL == (memb_dt = H5T_copy(dt->u.compnd.memb[membno].type))) {
+ if (NULL == (memb_dt = H5T_copy(dt->u.compnd.memb[membno].type,
+ H5T_COPY_REOPEN))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to copy member data type");
}
@@ -2128,7 +2298,7 @@ H5Tinsert(hid_t parent_id, const char *name, size_t offset, hid_t member_id)
H5T_COMPOUND != parent->type) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type");
}
- if (parent->locked) {
+ if (H5T_STATE_TRANSIENT!=parent->state) {
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent type read-only");
}
if (!name || !*name) {
@@ -2179,7 +2349,7 @@ H5Tpack(hid_t type_id)
H5T_COMPOUND != dt->type) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data type is read-only");
}
@@ -2194,98 +2364,6 @@ H5Tpack(hid_t type_id)
/*-------------------------------------------------------------------------
- * Function: H5Tshare
- *
- * Purpose: Marks a data type as sharable. Using the type during the
- * creation of a dataset will cause the dataset object header to
- * point to the type in the global heap instead of containing
- * the type directly in its object header. Subsequent
- * modifications to a shared type cause the type to become
- * unshared.
- *
- * Return: Success: SUCCEED
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * Tuesday, March 31, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Tshare (hid_t loc_id, hid_t type_id)
-{
- H5G_t *loc = NULL;
- H5T_t *dt = NULL;
-
- FUNC_ENTER (H5Tshare, FAIL);
-
- /* Check arguments */
- if (NULL==(loc=H5G_loc (loc_id))) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- }
- if (H5_DATATYPE!=H5I_group (type_id) ||
- NULL==(dt=H5I_object (type_id))) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- }
-
- /* Make it sharable */
- if (H5T_share (H5G_fileof (loc), dt)<0) {
- HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
- "unable to make data type sharable");
- }
-
- FUNC_LEAVE (SUCCEED);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Tis_shared
- *
- * Purpose: Determines if a data type is shared in the specified file.
- * The TYPE_ID is the type in question and LOC_ID is a file id
- * or group id (a group id is used only to identify the file).
- *
- * Return: Success: TRUE or FALSE
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * Friday, April 3, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-hbool_t
-H5Tis_shared (hid_t loc_id, hid_t type_id)
-{
- H5G_t *loc = NULL;
- H5T_t *dt = NULL;
- hbool_t ret_value = FAIL;
-
- FUNC_ENTER (H5Tis_shared, FAIL);
-
- /* Check arguments */
- if (NULL==(loc=H5G_loc (loc_id))) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- }
- if (H5_DATATYPE!=H5I_group (type_id) ||
- NULL==(dt=H5I_object (type_id))) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- }
-
- /* Is it sharable */
- ret_value = (H5HG_defined (&(dt->sh_heap)) &&
- dt->sh_file->shared==H5G_fileof(loc)->shared) ? TRUE : FALSE;
-
- FUNC_LEAVE (ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5Tregister_hard
*
* Purpose: Register a hard conversion function for a data type
@@ -2425,8 +2503,10 @@ H5Tregister_soft(const char *name, H5T_class_t src_cls, H5T_class_t dst_cls,
* data type temporarily to an object id before we query the functions
* capabilities.
*/
- if ((src_id = H5I_register(H5_DATATYPE, H5T_copy(path->src))) < 0 ||
- (dst_id = H5I_register(H5_DATATYPE, H5T_copy(path->dst))) < 0) {
+ if ((src_id = H5I_register(H5_DATATYPE,
+ H5T_copy(path->src, H5T_COPY_ALL))) < 0 ||
+ (dst_id = H5I_register(H5_DATATYPE,
+ H5T_copy(path->dst, H5T_COPY_ALL))) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
"unable to register data types for conv query");
}
@@ -2545,9 +2625,11 @@ H5Tunregister(H5T_conv_t func)
* object id's for the data types.
*/
if ((src_id = H5I_register(H5_DATATYPE,
- H5T_copy(path->src))) < 0 ||
+ H5T_copy(path->src,
+ H5T_COPY_ALL))) < 0 ||
(dst_id = H5I_register(H5_DATATYPE,
- H5T_copy(path->dst))) < 0) {
+ H5T_copy(path->dst,
+ H5T_COPY_ALL))) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
"unable to register conv types for query");
}
@@ -2679,16 +2761,68 @@ H5T_create(H5T_class_t type, size_t size)
"unknown data type class");
}
+ H5F_addr_undef (&(dt->ent.header));
dt->size = size;
FUNC_LEAVE(dt);
}
/*-------------------------------------------------------------------------
+ * Function: H5T_open
+ *
+ * Purpose: Open a named data type.
+ *
+ * Return: Success: Ptr to a new data type.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Monday, June 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_t *
+H5T_open (H5G_t *loc, const char *name)
+{
+ H5T_t *dt = NULL;
+ H5G_entry_t ent;
+
+ FUNC_ENTER (H5T_open, NULL);
+ assert (loc);
+ assert (name && *name);
+
+ /*
+ * Find the named data type object header and read the data type message
+ * from it.
+ */
+ if (H5G_find (loc, name, NULL, &ent/*out*/)<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_NOTFOUND, NULL, "not found");
+ }
+ if (H5O_open (&ent)<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, NULL,
+ "unable to open named data type");
+ }
+ if (NULL==(dt=H5O_read (&ent, H5O_DTYPE, 0, NULL))) {
+ H5O_close (&ent);
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL,
+ "unable to load type message from object header");
+ }
+
+ /* Mark the type as named and open */
+ dt->state = H5T_STATE_OPEN;
+ dt->ent = ent;
+
+ FUNC_LEAVE (dt);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_copy
*
* Purpose: Copies datatype OLD_DT. The resulting data type is not
- * locked.
+ * locked and is a transient type.
*
* Return: Success: Pointer to a new copy of the OLD_DT argument.
*
@@ -2699,10 +2833,20 @@ H5T_create(H5T_class_t type, size_t size)
*
* Modifications:
*
+ * Robb Matzke, 4 Jun 1998
+ * Added the METHOD argument. If it's H5T_COPY_TRANSIENT then the
+ * result will be an unlocked transient type. Otherwise if it's
+ * H5T_COPY_ALL then the result is a named type if the original is a
+ * named type, but the result is not opened. Finally, if it's
+ * H5T_COPY_REOPEN and the original type is a named type then the result
+ * is a named type and the type object header is opened again. The
+ * H5T_COPY_REOPEN method is used when returning a named type to the
+ * application.
+ *
*-------------------------------------------------------------------------
*/
H5T_t *
-H5T_copy(const H5T_t *old_dt)
+H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
{
H5T_t *new_dt=NULL, *tmp=NULL;
intn i;
@@ -2716,8 +2860,43 @@ H5T_copy(const H5T_t *old_dt)
/* copy */
new_dt = H5MM_xcalloc(1, sizeof(H5T_t));
*new_dt = *old_dt;
- new_dt->locked = FALSE;
+ switch (method) {
+ case H5T_COPY_TRANSIENT:
+ /*
+ * Return an unlocked transient type.
+ */
+ new_dt->state = H5T_STATE_TRANSIENT;
+ HDmemset (&(new_dt->ent), 0, sizeof(new_dt->ent));
+ H5F_addr_undef (&(new_dt->ent.header));
+ break;
+
+ case H5T_COPY_ALL:
+ /*
+ * Return a transient type (locked or unlocked) or an unopened named
+ * type.
+ */
+ if (H5T_STATE_OPEN==new_dt->state) {
+ new_dt->state = H5T_STATE_NAMED;
+ }
+ break;
+
+ case H5T_COPY_REOPEN:
+ /*
+ * Return a transient type (locked or unlocked) or an opened named
+ * type.
+ */
+ if (H5F_addr_defined (&(new_dt->ent.header))) {
+ if (H5O_open (&(new_dt->ent))<0) {
+ H5MM_xfree (new_dt);
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, NULL,
+ "unable to reopen named data type");
+ }
+ new_dt->state = H5T_STATE_OPEN;
+ }
+ break;
+ }
+
if (H5T_COMPOUND == new_dt->type) {
/*
* Copy all member fields to new type, then overwrite the
@@ -2732,7 +2911,7 @@ H5T_copy(const H5T_t *old_dt)
for (i = 0; i < new_dt->u.compnd.nmembs; i++) {
s = new_dt->u.compnd.memb[i].name;
new_dt->u.compnd.memb[i].name = H5MM_xstrdup(s);
- tmp = H5T_copy (old_dt->u.compnd.memb[i].type);
+ tmp = H5T_copy (old_dt->u.compnd.memb[i].type, method);
new_dt->u.compnd.memb[i].type = tmp;
}
}
@@ -2742,179 +2921,178 @@ H5T_copy(const H5T_t *old_dt)
/*-------------------------------------------------------------------------
- * Function: H5T_close
+ * Function: H5T_commit
*
- * Purpose: Frees a data type and all associated memory. If the data
- * type is locked then nothing happens.
+ * Purpose: Commit a type, giving it a name and causing it to become
+ * immutable.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
- * Monday, December 8, 1997
+ * Monday, June 1, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
-H5T_close(H5T_t *dt)
+H5T_commit (H5G_t *loc, const char *name, H5T_t *type)
{
- intn i;
-
- FUNC_ENTER(H5T_close, FAIL);
-
- assert(dt);
+ herr_t ret_value = FAIL;
+
+ FUNC_ENTER (H5T_commit, FAIL);
/*
- * Don't free locked datatypes unless we are shutting the interface
- * down.
+ * Check arguments. We cannot commit an immutable type because H5Tclose()
+ * normally fails on such types (try H5Tclose(H5T_NATIVE_INT)) but closing
+ * a named type should always succeed.
*/
- if (!dt->locked) {
- if (dt && H5T_COMPOUND == dt->type) {
- for (i = 0; i < dt->u.compnd.nmembs; i++) {
- H5MM_xfree(dt->u.compnd.memb[i].name);
- H5T_close (dt->u.compnd.memb[i].type);
- }
- H5MM_xfree(dt->u.compnd.memb);
- H5MM_xfree(dt);
+ assert (loc);
+ assert (name && *name);
+ assert (type);
+ if (H5T_STATE_NAMED==type->state || H5T_STATE_OPEN==type->state) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "data type is already committed");
+ }
+ if (H5T_STATE_IMMUTABLE==type->state) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "data type is immutable");
+ }
- } else if (dt) {
- H5MM_xfree(dt);
+ /*
+ * Create the object header and open it for write access. Insert the data
+ * type message and then give the object header a name.
+ */
+ if (H5O_create (H5G_fileof (loc), 64, &(type->ent))<0) {
+ HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to create data type object header");
+ }
+ if (H5O_modify (&(type->ent), H5O_DTYPE, 0, H5O_FLAG_CONSTANT, type)<0) {
+ HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to update type header message");
+ }
+ if (H5G_insert (loc, name, &(type->ent))<0) {
+ HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to name data type");
+ }
+ type->state = H5T_STATE_OPEN;
+ ret_value = SUCCEED;
+
+ done:
+ if (ret_value<0) {
+ if (H5F_addr_defined (&(type->ent.header))) {
+ H5O_close (&(type->ent));
+ H5F_addr_undef (&(type->ent.header));
}
}
-
- FUNC_LEAVE(SUCCEED);
+ FUNC_LEAVE (ret_value);
}
/*-------------------------------------------------------------------------
- * Function: H5T_share
+ * Function: H5T_lock
+ *
+ * Purpose: Lock a transient data type making it read-only. If IMMUTABLE
+ * is set then the type cannot be closed except when the library
+ * itself closes.
*
- * Purpose: Causes a data type to be marked as sharable. If the data
- * type isn't already marked sharable in the specified file then
- * it is written to the global heap of that file and the heap
- * location information is added to the sh_file and sh_heap
- * fields of the data type.
+ * This function is a no-op if the type is not transient or if
+ * the type is already read-only or immutable.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
- * Tuesday, March 31, 1998
+ * Thursday, June 4, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
-H5T_share (H5F_t *f, H5T_t *dt)
+H5T_lock (H5T_t *dt, hbool_t immutable)
{
- FUNC_ENTER (H5T_share, FAIL);
-
- /* Check args */
- assert (f);
+ FUNC_ENTER (H5T_lock, FAIL);
assert (dt);
- /*
- * If the type is sharable in some other file then unshare it first. A
- * type can only be sharable in one file at a time.
- */
- if (H5HG_defined (&(dt->sh_heap)) && f->shared!=dt->sh_file->shared) {
- H5T_unshare (dt);
- H5E_clear (); /*don't really care if it fails*/
+ switch (dt->state) {
+ case H5T_STATE_TRANSIENT:
+ dt->state = immutable ? H5T_STATE_IMMUTABLE : H5T_STATE_RDONLY;
+ break;
+ case H5T_STATE_RDONLY:
+ if (immutable) dt->state = H5T_STATE_IMMUTABLE;
+ break;
+ case H5T_STATE_IMMUTABLE:
+ case H5T_STATE_NAMED:
+ case H5T_STATE_OPEN:
+ /*void*/
+ break;
}
- /*
- * Write the message to the global heap if it isn't already shared in
- * this file.
- */
- if (!H5HG_defined (&(dt->sh_heap))) {
- if (H5O_share (f, H5O_DTYPE, dt, &(dt->sh_heap))<0) {
- HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
- "unable to store data type message in global heap");
- }
- dt->sh_file = f;
- }
-
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5T_unshare
+ * Function: H5T_close
*
- * Purpose: If a data type is in the global heap then this function
- * removes that information from the H5T_t struct.
+ * Purpose: Frees a data type and all associated memory. If the data
+ * type is locked then nothing happens.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
- * Tuesday, March 31, 1998
+ * Monday, December 8, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
-H5T_unshare (H5T_t *dt)
+H5T_close(H5T_t *dt)
{
- FUNC_ENTER (H5T_unshare, FAIL);
+ intn i;
- /* Check args */
- assert (dt);
+ FUNC_ENTER(H5T_close, FAIL);
- H5HG_undef (&(dt->sh_heap));
- dt->sh_file = NULL;
+ assert(dt);
- FUNC_LEAVE (SUCCEED);
-}
+ /*
+ * If a named type is being closed then close the object header also.
+ */
+ if (H5T_STATE_OPEN==dt->state) {
+ assert (H5F_addr_defined (&(dt->ent.header)));
+ if (H5O_close (&(dt->ent))<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to close data type object header");
+ }
+ dt->state = H5T_STATE_NAMED;
+ }
-
-/*-------------------------------------------------------------------------
- * Function: H5T_invalidate_cb
- *
- * Purpose: This is a callback function for H5I_search(). When a file is
- * closed we scan through the data type list and invalidate
- * shared info for all types that have sharing enabled for the
- * specified file. This insures that we don't having dangling
- * pointers from data types to files. We have to do this with
- * data types but not datasets because a dataset_id always
- * corresponds to an open object header which prevents the file
- * from closing in the first place, but a data type can exist
- * independent of a file and doesn't have an object header.
- *
- * Return: Success: 0, this function never returns a non-zero
- * value because that would terminate
- * H5I_search().
- *
- * Failure: 0
- *
- * Programmer: Robb Matzke
- * Friday, April 3, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-intn
-H5T_invalidate_cb (void *obj, const void *call_data)
-{
- H5T_t *dt = (H5T_t *)obj;
- const H5F_t *f = (const H5F_t*)call_data; /*used only for comparison*/
-
- FUNC_ENTER (H5T_invalidate, 0);
+ /*
+ * Don't free locked datatypes unless we are shutting down the
+ * interface.
+ */
+ if (H5T_STATE_IMMUTABLE!=dt->state) {
+ if (dt && H5T_COMPOUND == dt->type) {
+ for (i = 0; i < dt->u.compnd.nmembs; i++) {
+ H5MM_xfree(dt->u.compnd.memb[i].name);
+ H5T_close (dt->u.compnd.memb[i].type);
+ }
+ H5MM_xfree(dt->u.compnd.memb);
+ H5MM_xfree(dt);
- if (H5HG_defined (&(dt->sh_heap)) && dt->sh_file->shared==f->shared) {
- H5T_unshare (dt);
- H5E_clear ();
+ } else if (dt) {
+ H5MM_xfree(dt);
+ }
}
-
- FUNC_LEAVE (0);
+
+ FUNC_LEAVE(SUCCEED);
}
@@ -3003,7 +3181,7 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
/* check args */
assert(parent && H5T_COMPOUND == parent->type);
- assert(!parent->locked);
+ assert(H5T_STATE_TRANSIENT==parent->state);
assert(member);
assert(name && *name);
@@ -3036,12 +3214,11 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
}
/* Add member to end of member array */
- H5T_unshare (parent);
i = parent->u.compnd.nmembs;
parent->u.compnd.memb[i].name = H5MM_xstrdup(name);
parent->u.compnd.memb[i].offset = offset;
parent->u.compnd.memb[i].ndims = 0; /*defaults to scalar */
- parent->u.compnd.memb[i].type = H5T_copy (member);
+ parent->u.compnd.memb[i].type = H5T_copy (member, H5T_COPY_ALL);
parent->u.compnd.nmembs++;
FUNC_LEAVE(SUCCEED);
@@ -3074,9 +3251,8 @@ H5T_pack(H5T_t *dt)
FUNC_ENTER(H5T_pack, FAIL);
assert(dt);
- assert(!dt->locked);
+ assert(H5T_STATE_TRANSIENT==dt->state);
- H5T_unshare (dt);
if (H5T_COMPOUND == dt->type) {
/* Recursively pack the members */
for (i = 0; i < dt->u.compnd.nmembs; i++) {
@@ -3534,8 +3710,8 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst,
/* insert */
path = H5T_path_g + md;
HDmemset(path, 0, sizeof(H5T_path_t));
- path->src = H5T_copy(src);
- path->dst = H5T_copy(dst);
+ path->src = H5T_copy(src, H5T_COPY_ALL);
+ path->dst = H5T_copy(dst, H5T_COPY_ALL);
/* Associate a function with the path if possible */
if (func) {
@@ -3545,8 +3721,10 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst,
path->is_hard = TRUE;
path->cdata.command = H5T_CONV_INIT;
path->cdata.stats = H5MM_xcalloc (1, sizeof(H5T_stats_t));
- if ((src_id=H5I_register(H5_DATATYPE, H5T_copy(path->src))) < 0 ||
- (dst_id=H5I_register(H5_DATATYPE, H5T_copy(path->dst))) < 0) {
+ if ((src_id=H5I_register(H5_DATATYPE,
+ H5T_copy(path->src, H5T_COPY_ALL))) < 0 ||
+ (dst_id=H5I_register(H5_DATATYPE,
+ H5T_copy(path->dst, H5T_COPY_ALL))) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL,
"unable to register conv types for query");
}
@@ -3567,9 +3745,11 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst,
continue;
}
if ((src_id=H5I_register(H5_DATATYPE,
- H5T_copy(path->src))) < 0 ||
+ H5T_copy(path->src,
+ H5T_COPY_ALL))) < 0 ||
(dst_id=H5I_register(H5_DATATYPE,
- H5T_copy(path->dst))) < 0) {
+ H5T_copy(path->dst,
+ H5T_COPY_ALL))) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL,
"unable to register conv types for query");
}
@@ -3665,7 +3845,7 @@ H5T_timer_end (H5_timer_t *timer, H5T_cdata_t *cdata, size_t nelmts)
herr_t
H5T_debug(H5T_t *dt, FILE * stream)
{
- const char *s = "";
+ const char *s1="", *s2="";
int i, j;
uint64 tmp;
@@ -3677,53 +3857,70 @@ H5T_debug(H5T_t *dt, FILE * stream)
switch (dt->type) {
case H5T_INTEGER:
- s = "int";
+ s1 = "int";
break;
case H5T_FLOAT:
- s = "float";
+ s1 = "float";
break;
case H5T_TIME:
- s = "time";
+ s1 = "time";
break;
case H5T_STRING:
- s = "str";
+ s1 = "str";
break;
case H5T_BITFIELD:
- s = "bits";
+ s1 = "bits";
break;
case H5T_OPAQUE:
- s = "opaque";
+ s1 = "opaque";
break;
case H5T_COMPOUND:
- s = "struct";
+ s1 = "struct";
break;
default:
- s = "";
+ s1 = "";
+ break;
+ }
+
+ switch (dt->state) {
+ case H5T_STATE_TRANSIENT:
+ s2 = "[transient]";
+ break;
+ case H5T_STATE_RDONLY:
+ s2 = "[constant]";
+ break;
+ case H5T_STATE_IMMUTABLE:
+ s2 = "[predefined]";
+ break;
+ case H5T_STATE_NAMED:
+ s2 = "[named,closed]";
+ break;
+ case H5T_STATE_OPEN:
+ s2 = "[named,open]";
break;
}
- fprintf(stream, "%s%s {nbytes=%lu",
- s, dt->locked ? "[!]" : "", (unsigned long)(dt->size));
+ fprintf(stream, "%s%s {nbytes=%lu", s1, s2, (unsigned long)(dt->size));
if (H5T_is_atomic(dt)) {
switch (dt->u.atomic.order) {
case H5T_ORDER_BE:
- s = "BE";
+ s1 = "BE";
break;
case H5T_ORDER_LE:
- s = "LE";
+ s1 = "LE";
break;
case H5T_ORDER_VAX:
- s = "VAX";
+ s1 = "VAX";
break;
case H5T_ORDER_NONE:
- s = "NONE";
+ s1 = "NONE";
break;
default:
- s = "order?";
+ s1 = "order?";
break;
}
- fprintf(stream, ", %s", s);
+ fprintf(stream, ", %s", s1);
if (dt->u.atomic.offset) {
fprintf(stream, ", offset=%lu",
@@ -3737,39 +3934,39 @@ H5T_debug(H5T_t *dt, FILE * stream)
case H5T_INTEGER:
switch (dt->u.atomic.u.i.sign) {
case H5T_SGN_NONE:
- s = "unsigned";
+ s1 = "unsigned";
break;
case H5T_SGN_2:
- s = NULL;
+ s1 = NULL;
break;
default:
- s = "sign?";
+ s1 = "sign?";
break;
}
- if (s)
- fprintf(stream, ", %s", s);
+ if (s1)
+ fprintf(stream, ", %s", s1);
break;
case H5T_FLOAT:
switch (dt->u.atomic.u.f.norm) {
case H5T_NORM_IMPLIED:
- s = "implied";
+ s1 = "implied";
break;
case H5T_NORM_MSBSET:
- s = "msbset";
+ s1 = "msbset";
break;
case H5T_NORM_NONE:
- s = "no-norm";
+ s1 = "no-norm";
break;
default:
- s = "norm?";
+ s1 = "norm?";
break;
}
fprintf(stream, ", sign=%lu+1",
(unsigned long) (dt->u.atomic.u.f.sign));
fprintf(stream, ", mant=%lu+%lu (%s)",
(unsigned long) (dt->u.atomic.u.f.mpos),
- (unsigned long) (dt->u.atomic.u.f.msize), s);
+ (unsigned long) (dt->u.atomic.u.f.msize), s1);
fprintf(stream, ", exp=%lu+%lu",
(unsigned long) (dt->u.atomic.u.f.epos),
(unsigned long) (dt->u.atomic.u.f.esize));