From 1063eb8a1ea0cbdbdc4244f0627b94b3096d65ab Mon Sep 17 00:00:00 2001
From: Robb Matzke <matzke@llnl.gov>
Date: Fri, 9 Jan 1998 12:49:23 -0500
Subject: [svn-r152] Changes since 19980107 ----------------------

./html/Datatypes.html
	Updated to match code.

./src/H5Odtype.c
./src/H5Oprivate.h
./src/H5Tpkg.h
./src/H5detect.c
	Changed H5T_FIXED to H5T_INTEGER.

./src/H5T.c
./src/H5Tprivate.h
./src/H5Tpublic.h
./test/dtypes.c
	Implemented lots of type properties.

./src/H5detect.c
./src/H5Tpublic.h
	It is no longer necessary to call H5init() before using a
	predefined data type.
---
 src/H5Odtype.c   |   18 +-
 src/H5Oprivate.h |    4 -
 src/H5T.c        | 1486 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/H5Tpkg.h     |    4 +-
 src/H5Tprivate.h |   10 +-
 src/H5Tpublic.h  |   93 +++-
 src/H5detect.c   |   12 +-
 test/dtypes.c    |   87 +++-
 8 files changed, 1614 insertions(+), 100 deletions(-)

diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index be401c1..2d830e9 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -90,9 +90,9 @@ H5O_dtype_decode_helper (const uint8 **pp, H5T_t *dt)
    UINT32DECODE (*pp, dt->size);
 
    switch (dt->type) {
-   case H5T_FIXED:
+   case H5T_INTEGER:
       /*
-       * Fixed-point types...
+       * Integer types...
        */
       dt->u.atomic.order = (flags & 0x1) ? H5T_ORDER_BE : H5T_ORDER_LE;
       dt->u.atomic.lo_pad = (flags & 0x2) ? H5T_PAD_ONE : H5T_PAD_ZERO;
@@ -217,9 +217,9 @@ H5O_dtype_encode_helper (uint8 **pp, const H5T_t *dt)
    UINT32ENCODE (*pp, dt->size);
 
    switch (dt->type) {
-   case H5T_FIXED:
+   case H5T_INTEGER:
       /*
-       * Fixed-point data types...
+       * Integer data types...
        */
       switch (dt->u.atomic.order) {
       case H5T_ORDER_LE:
@@ -538,7 +538,7 @@ H5O_dtype_size (H5F_t *f, const void *mesg)
    assert (mesg);
 
    switch (dt->type) {
-   case H5T_FIXED:
+   case H5T_INTEGER:
       ret_value += 4;
       break;
 
@@ -637,13 +637,13 @@ H5O_dtype_debug (H5F_t *f, const void *mesg, FILE *stream,
    assert (fwidth>=0);
 
    switch (dt->type) {
-   case H5T_FIXED:
-      s = "fixed-point";
+   case H5T_INTEGER:
+      s = "integer";
       break;
    case H5T_FLOAT:
       s = "floating-point";
       break;
-   case H5T_DATE:
+   case H5T_TIME:
       s = "date and time";
       break;
    case H5T_STRING:
@@ -838,7 +838,7 @@ H5O_dtype_debug (H5F_t *f, const void *mesg, FILE *stream,
 		  "Mantissa size:",
 		  (unsigned long)(dt->u.atomic.u.f.msize));
 	 
-      } else if (H5T_FIXED==dt->type) {
+      } else if (H5T_INTEGER==dt->type) {
 	 switch (dt->u.atomic.u.i.sign) {
 	 case H5T_SGN_NONE:
 	    s = "none";
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 108fb30..fade4b4 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -52,10 +52,6 @@ typedef struct H5O_class_t {
    size_t	native_size;		/*size of native message	*/
    void		*(*decode)(H5F_t*,size_t,const uint8*);
    herr_t	(*encode)(H5F_t*,size_t,uint8*,const void*);
-#if 0
-   void		*(*fast)(const H5G_cache_t*, void*);/*get from of entry	*/
-   hbool_t	(*cache)(H5G_type_t*, H5G_cache_t*,const void*); /*into entry*/
-#endif
    void		*(*copy)(const void*,void*); /*copy native value	*/
    size_t	(*raw_size)(H5F_t*,const void*); /*sizeof raw val	*/
    herr_t	(*reset)(void*); /*free nested data structures		*/
diff --git a/src/H5T.c b/src/H5T.c
index 414349a..5863a24 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -272,6 +272,909 @@ H5Tequal (hid_t type1_id, hid_t type2_id)
 
 
 /*-------------------------------------------------------------------------
+ * Function:	H5Tget_class
+ *
+ * Purpose:	Returns the data type class identifier for data type TYPE_ID.
+ *
+ * Return:	Success:	One of the non-negative data type class
+ *				constants.
+ *
+ *		Failure:	H5T_NO_CLASS (-1, same as FAIL)
+ *
+ * Programmer:	Robb Matzke
+ *              Monday, December  8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_class_t
+H5Tget_class (hid_t type_id)
+{
+   H5T_t	*dt = NULL;
+   
+   FUNC_ENTER (H5Tget_class, H5T_NO_CLASS);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id))) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a data type");
+   }
+
+   FUNC_LEAVE (dt->type);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tget_size
+ *
+ * Purpose:	Determines the total size of a data type in bytes.
+ *
+ * Return:	Success:	Size of the data type in bytes.  The size of
+ *				data type is the size of an instance of that
+ *				data type.
+ *
+ *		Failure:	0 (valid data types are never zero size)
+ *
+ * Programmer:	Robb Matzke
+ *              Monday, December  8, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5Tget_size (hid_t type_id)
+{
+   H5T_t	*dt = NULL;
+   size_t	size;
+   
+   FUNC_ENTER (H5Tget_size, 0);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id))) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, "not a data type");
+   }
+
+   /* size */
+   size = H5T_get_size (dt);
+
+   FUNC_LEAVE (size);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tset_size
+ *
+ * Purpose:	Sets the total size in bytes for an atomic data type (this
+ *		operation is not permitted on compound data types).  If the
+ *		size is decreased so that the significant bits of the data
+ *		type extend beyond the edge of the new size, then the
+ *		`offset' property is decreased toward zero.  If the `offset'
+ *		becomes zero and the significant bits of the data type still
+ *		hang over the edge of the new size, then the number of
+ *		significant bits is decreased.
+ *
+ * 		All data types have a positive size.
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tset_size (hid_t type_id, size_t size)
+{
+   H5T_t	*dt = NULL;
+   size_t	prec, offset;
+   
+   FUNC_ENTER (H5Tset_size, FAIL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       !H5T_is_atomic (dt)) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
+   }
+   if (dt->locked) {
+      HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
+   }
+   if (size<=0) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "size must be positive");
+   }
+
+   offset = dt->u.atomic.offset;
+   prec = dt->u.atomic.prec;
+   
+   /* Decrement the offset and precision if necessary */
+   if (prec > 8*size) offset = 0;
+   else if (offset + prec > 8*size) offset = 8*size - prec;
+   if (prec > 8*size) prec = 8*size;
+
+   /* Make sure that other values are still okay */
+   switch (dt->type) {
+   case H5T_INTEGER:
+   case H5T_TIME:
+   case H5T_STRING:
+   case H5T_BITFIELD:
+      /* nothing to check */
+      break;
+      
+   case H5T_FLOAT:
+      /*
+       * The sign, mantissa, and exponent fields should be adjusted first
+       * when decreasing the size of a floating point type.
+       */
+      if (dt->u.atomic.u.f.sign >= prec ||
+	  dt->u.atomic.u.f.epos + dt->u.atomic.u.f.esize > prec ||
+	  dt->u.atomic.u.f.mpos + dt->u.atomic.u.f.msize > prec) {
+	 HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+			"adjust sign, mantissa, and exponent fields first");
+      }
+      break;
+
+   case H5T_OPAQUE:
+      /*
+       * The significant bits of an opaque type are not allowed to change
+       * implicitly.
+       */
+      if (prec != dt->u.atomic.prec) {
+	 HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+			"unable to change precision of an opaque type");
+      }
+      break;
+
+   default:
+      assert ("not implemented yet" && 0);
+   }
+
+   /* Commit */
+   dt->size = size;
+   dt->u.atomic.offset = offset;
+   dt->u.atomic.prec = prec;
+
+   FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tget_order
+ *
+ * Purpose:	Returns the byte order of an atomic data type.
+ *
+ * Return:	Success:	A byte order constant
+ *
+ *		Failure:	H5T_ORDER_ERROR (-1, same as FAIL)
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_order_t
+H5Tget_order (hid_t type_id)
+{
+   H5T_t	*dt = NULL;
+   H5T_order_t	order;
+   
+   FUNC_ENTER (H5Tget_order, H5T_ORDER_ERROR);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       !H5T_is_atomic (dt)) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5T_ORDER_ERROR,
+		     "not an atomic data type");
+   }
+
+   /* order */
+   order = dt->u.atomic.order;
+
+   FUNC_LEAVE (order);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tset_order
+ *
+ * Purpose:	Sets the byte order for an atomic data type.
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tset_order (hid_t type_id, H5T_order_t order)
+{
+   H5T_t	*dt = NULL;
+
+   FUNC_ENTER (H5Tset_order, FAIL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       !H5T_is_atomic (dt)) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
+   }
+   if (dt->locked) {
+      HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
+   }
+   if (order<0 || order>H5T_ORDER_NONE) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order");
+   }
+   
+   /* order */
+   dt->u.atomic.order = order;
+   FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tget_precision
+ *
+ * Purpose:	Gets the precision of an atomic data type.  The precision is
+ *		the number of significant bits which, unless padding is
+ *		present, is 8 times larger than the value returned by
+ *		H5Tget_size().
+ *
+ * Return:	Success:	Number of significant bits
+ *
+ *		Failure:	0 (all atomic types have at least one
+ *				significant bit)
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5Tget_precision (hid_t type_id)
+{
+   H5T_t	*dt = NULL;
+   size_t	prec;
+   
+   FUNC_ENTER (H5Tget_precision, 0);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       !H5T_is_atomic (dt)) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, "not an atomic data type");
+   }
+
+   /* precision */
+   prec = dt->u.atomic.prec;
+
+   FUNC_LEAVE (prec);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tset_precision
+ *
+ * Purpose:	Sets the precision of an atomic data type.  The precision is
+ *		the number of significant bits which, unless padding is
+ *		present, is 8 times larger than the value returned by
+ *		H5Tget_size().
+ *
+ *		If the precision is increased then the offset is decreased
+ *		and then the size is increased to insure that significant
+ *		bits do not "hang over" the edge of the data type.
+ *
+ *		When decreasing the precision of a floating point type, set
+ *		the locations and sizes of the sign, mantissa, and exponent
+ *		fields first.
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tset_precision (hid_t type_id, size_t prec)
+{
+   H5T_t	*dt = NULL;
+   size_t	offset, size;
+
+   FUNC_ENTER (H5Tset_prec, FAIL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       !H5T_is_atomic (dt)) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
+   }
+   if (dt->locked) {
+      HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
+   }
+   if (prec<=0) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+		     "precision must be positive");
+   }
+
+   /* Adjust the offset and size */
+   offset = dt->u.atomic.offset;
+   size = dt->size;
+   if (prec > 8*size) offset = 0;
+   else if (offset + prec > 8*size) offset = 8*size - prec;
+   if (prec > 8*size) size = (prec+7)/8;
+
+   /* Check that things are still kosher */
+   switch (dt->type) {
+   case H5T_INTEGER:
+   case H5T_TIME:
+   case H5T_STRING:
+   case H5T_BITFIELD:
+   case H5T_OPAQUE:
+      /* nothing to check */
+      break;
+      
+   case H5T_FLOAT:
+      /*
+       * The sign, mantissa, and exponent fields should be adjusted first
+       * when decreasing the precision of a floating point type.
+       */
+      if (dt->u.atomic.u.f.sign >= prec ||
+	  dt->u.atomic.u.f.epos + dt->u.atomic.u.f.esize > prec ||
+	  dt->u.atomic.u.f.mpos + dt->u.atomic.u.f.msize > prec) {
+	 HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+			"adjust sign, mantissa, and exponent fields first");
+      }
+      break;
+
+   default:
+      assert ("not implemented yet" && 0);
+   }
+   
+   /* Commit */
+   dt->size = size;
+   dt->u.atomic.offset = offset;
+   dt->u.atomic.prec = prec;
+   
+   FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tget_offset
+ *
+ * Purpose:	Retrieves the bit offset of the first significant bit.  The
+ *		signficant bits of an atomic datum can be offset from the
+ *		beginning of the memory for that datum by an amount of
+ *		padding. The `offset' property specifies the number of bits
+ *		of padding that appear to the "right of" the value.  That is,
+ *		if we have a 32-bit datum with 16-bits of precision having
+ *		the value 0x1122 then it will be layed out in memory as (from
+ *		small byte address toward larger byte addresses):
+ *
+ * 		    Big      Big       Little   Little
+ *		    Endian   Endian    Endian   Endian
+ *		    offset=0 offset=16 offset=0 offset=16
+ *
+ * 		0:  [ pad]   [0x11]    [0x22]   [ pad]
+ *		1:  [ pad]   [0x22]    [0x11]   [ pad]
+ *		2:  [0x11]   [ pad]    [ pad]   [0x22]
+ *		3:  [0x22]   [ pad]    [ pad]   [0x11]
+ *
+ * Return:	Success:	The offset
+ *
+ *		Failure:	0
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5Tget_offset (hid_t type_id)
+{
+   H5T_t	*dt = NULL;
+   size_t	offset;
+   
+   FUNC_ENTER (H5Tget_offset, 0);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       !H5T_is_atomic (dt)) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, "not an atomic data type");
+   }
+
+   /* offset */
+   offset = dt->u.atomic.offset;
+
+   FUNC_LEAVE (offset);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tset_offset
+ *
+ * Purpose:	Sets the bit offset of the first significant bit.  The
+ *		signficant bits of an atomic datum can be offset from the
+ *		beginning of the memory for that datum by an amount of
+ *		padding. The `offset' property specifies the number of bits
+ *		of padding that appear to the "right of" the value.  That is,
+ *		if we have a 32-bit datum with 16-bits of precision having
+ *		the value 0x1122 then it will be layed out in memory as (from
+ *		small byte address toward larger byte addresses):
+ *
+ * 		    Big      Big       Little   Little
+ *		    Endian   Endian    Endian   Endian
+ *		    offset=0 offset=16 offset=0 offset=16
+ *
+ * 		0:  [ pad]   [0x11]    [0x22]   [ pad]
+ *		1:  [ pad]   [0x22]    [0x11]   [ pad]
+ *		2:  [0x11]   [ pad]    [ pad]   [0x22]
+ *		3:  [0x22]   [ pad]    [ pad]   [0x11]
+ *
+ *		If the offset is incremented then the total size is
+ *		incremented also if necessary to prevent significant bits of
+ *		the value from hanging over the edge of the data type.
+ *
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tset_offset (hid_t type_id, size_t offset)
+{
+
+   H5T_t	*dt = NULL;
+
+   FUNC_ENTER (H5Tset_offset, FAIL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       !H5T_is_atomic (dt)) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
+   }
+   if (dt->locked) {
+      HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
+   }
+   if (offset<=0) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+		     "precision must be positive");
+   }
+
+   /* Adjust the size */
+   if (offset + dt->u.atomic.prec > 8*dt->size) {
+      dt->size = (offset + dt->u.atomic.prec + 7) / 8;
+   }
+
+   /* Commit */
+   dt->u.atomic.offset = offset;
+   
+   FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tget_sign
+ *
+ * Purpose:	Retrieves the sign type for an integer type.
+ *
+ * Return:	Success:	The sign type.
+ *
+ *		Failure:	H5T_SGN_ERROR (-1, same as FAIL)
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_sign_t
+H5Tget_sign (hid_t type_id)
+{
+   H5T_t	*dt = NULL;
+   H5T_sign_t	sign;
+   
+   FUNC_ENTER (H5Tget_sign, H5T_SGN_ERROR);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_INTEGER!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5T_SGN_ERROR,
+		     "not an integer data type");
+   }
+
+   /* sign */
+   sign = dt->u.atomic.u.i.sign;
+
+   FUNC_LEAVE (sign);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tset_sign
+ *
+ * Purpose:	Sets the sign property for an integer.
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tset_sign (hid_t type_id, H5T_sign_t sign)
+{
+   H5T_t	*dt = NULL;
+
+   FUNC_ENTER (H5Tset_sign, FAIL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_INTEGER!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an integer data type");
+   }
+   if (dt->locked) {
+      HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
+   }
+   if (sign<0 || sign>=H5T_SGN_N) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "illegal sign type");
+   }
+   
+   /* sign */
+   dt->u.atomic.u.i.sign = sign;
+   FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tget_fields
+ *
+ * Purpose:	Returns information about the locations of the various bit
+ *		fields of a floating point data type.  The field positions
+ *		are bit positions in the significant region of the data type.
+ *		Bits are numbered with the least significant bit number zero.
+ *
+ * 		Any (or even all) of the arguments can be null pointers.
+ *
+ * Return:	Success:	SUCCEED, field locations and sizes are
+ *				returned through the arguments.
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tget_fields (hid_t type_id, size_t *spos/*out*/,
+	       size_t *epos/*out*/, size_t *esize/*out*/,
+	       size_t *mpos/*out*/, size_t *msize/*out*/)
+{
+   H5T_t	*dt = NULL;
+
+   FUNC_ENTER (H5Tget_fields, FAIL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_FLOAT!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL,
+		     "not a floating-point data type");
+   }
+
+   /* Get values */
+   if (spos) *spos = dt->u.atomic.u.f.sign;
+   if (epos) *epos = dt->u.atomic.u.f.epos;
+   if (esize) *esize = dt->u.atomic.u.f.esize;
+   if (mpos) *mpos = dt->u.atomic.u.f.mpos;
+   if (msize) *msize = dt->u.atomic.u.f.msize;
+
+   FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tset_fields
+ *
+ * Purpose:	Sets the locations and sizes of the various floating point
+ *		bit fields.  The field positions are bit positions in the
+ *		significant region of the data type.  Bits are numbered with
+ *		the least significant bit number zero.
+ *
+ *		Fields are not allowed to extend beyond the number of bits of
+ *		precision, nor are they allowed to overlap with one another.
+ *		
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tset_fields (hid_t type_id, size_t spos, size_t epos, size_t esize,
+	       size_t mpos, size_t msize)
+{
+   H5T_t	*dt = NULL;
+
+   FUNC_ENTER (H5Tset_fields, FAIL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_FLOAT!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL,
+		     "not a floating-point data type");
+   }
+   if (dt->locked) {
+      HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
+   }
+   if (epos<0 || epos+esize>dt->u.atomic.prec) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+		     "exponent bit field size/location is invalid");
+   }
+   if (mpos<0 || mpos+msize>dt->u.atomic.prec) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+		     "mantissa bit field size/location is invalid");
+   }
+   if (spos<0 || spos>=dt->u.atomic.prec) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+		     "sign location is not valid");
+   }
+
+   /* Check for overlap */
+   if (spos>=epos && spos<epos+esize) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+		     "sign bit appears within exponent field");
+   }
+   if (spos>=mpos && spos<mpos+msize) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+		     "sign bit appears within mantissa field");
+   }
+   if ((mpos<epos && mpos+msize>epos) ||
+       (epos<mpos && epos+esize>mpos)) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+		     "exponent and mantissa fields overlap");
+   }
+
+   /* Commit */
+   dt->u.atomic.u.f.sign = spos;
+   dt->u.atomic.u.f.epos = epos;
+   dt->u.atomic.u.f.mpos = mpos;
+   dt->u.atomic.u.f.esize = esize;
+   dt->u.atomic.u.f.msize = msize;
+
+   FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tget_ebias
+ *
+ * Purpose:	Retrieves the exponent bias of a floating-point type.
+ *
+ * Return:	Success:	The bias
+ *
+ *		Failure:	0
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5Tget_ebias (hid_t type_id)
+{
+   H5T_t	*dt = NULL;
+   size_t	ebias;
+
+   FUNC_ENTER (H5Tget_ebias, 0);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_FLOAT!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0,
+		     "not a floating-point data type");
+   }
+
+   /* bias */
+   ebias = dt->u.atomic.u.f.ebias;
+
+   FUNC_LEAVE (ebias);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tset_ebias
+ *
+ * Purpose:	Sets the exponent bias of a floating-point type.
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tset_ebias (hid_t type_id, size_t ebias)
+{
+   H5T_t	*dt = NULL;
+   
+   FUNC_ENTER (H5Tset_ebias, FAIL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_FLOAT!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL,
+		     "not a floating-point data type");
+   }
+   if (dt->locked) {
+      HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
+   }
+
+   dt->u.atomic.u.f.ebias = ebias;
+
+   FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tget_norm
+ *
+ * Purpose:	Returns the mantisssa normalization of a floating-point data
+ *		type.
+ *
+ * Return:	Success:	Normalization ID
+ *
+ *		Failure:	H5T_NORM_ERROR (-1, same as FAIL)
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_norm_t
+H5Tget_norm (hid_t type_id)
+{
+   H5T_t	*dt = NULL;
+   H5T_norm_t	norm;
+   
+   FUNC_ENTER (H5Tget_norm, H5T_NORM_ERROR);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_FLOAT!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5T_NORM_ERROR,
+		     "not a floating-point data type");
+   }
+
+   /* norm */
+   norm = dt->u.atomic.u.f.norm;
+
+   FUNC_LEAVE (norm);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tset_norm
+ *
+ * Purpose:	Sets the mantissa normalization method for a floating point
+ *		data type.
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tset_norm (hid_t type_id, H5T_norm_t norm)
+{
+   H5T_t	*dt = NULL;
+
+   FUNC_ENTER (H5Tset_norm, FAIL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_FLOAT!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL,
+		     "not a floating-point data type");
+   }
+   if (dt->locked) {
+      HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
+   }
+   if (norm<0 || norm>H5T_NORM_NONE) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "illegal normalization");
+   }
+   
+   /* norm */
+   dt->u.atomic.u.f.norm = norm;
+   FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
  * Function:	H5Tget_nmembers
  *
  * Purpose:	Determines how many members compound data type TYPE_ID has.
@@ -293,100 +1196,216 @@ H5Tequal (hid_t type1_id, hid_t type2_id)
 intn
 H5Tget_nmembers (hid_t type_id)
 {
-   
+   
+   H5T_t	*dt = NULL;
+
+   FUNC_ENTER (H5Tget_num_members, FAIL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_COMPOUND!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type");
+   }
+
+   FUNC_LEAVE (dt->u.compnd.nmembs);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tget_member_name
+ *
+ * Purpose:	Returns the name of a member of a compound data type.
+ *		Members are stored in no particular order with numbers 0
+ *		through N-1 where N is the value returned by
+ *		H5Tget_nmembers().
+ *
+ * Return:	Success:	Ptr to a string allocated with malloc().  The
+ *				caller is responsible for freeing the string.
+ *
+ *		Failure:	NULL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+char *
+H5Tget_member_name (hid_t type_id, int membno)
+{
+   H5T_t	*dt = NULL;
+   char		*s = NULL;
+
+   FUNC_ENTER (H5Tget_member_name, NULL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_COMPOUND!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, NULL, "not a compound data type");
+   }
+   if (membno<0 || membno>=dt->u.compnd.nmembs) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, NULL, "invalid member number");
+   }
+
+   s = H5MM_xstrdup (dt->u.compnd.memb[membno].name);
+   FUNC_LEAVE (s);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tget_member_offset
+ *
+ * Purpose:	Returns the byte offset of the beginning of a member with
+ *		respect to the beginning of the compound data type datum.
+ *
+ * Return:	Success:	Byte offset.
+ *
+ *		Failure:	Zero. Zero is a valid offset, but this
+ *				function will fail only if a call to
+ *				H5Tget_member_dims() fails with the same
+ *				arguments.
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5Tget_member_offset (hid_t type_id, int membno)
+{
    H5T_t	*dt = NULL;
+   size_t	offset = 0;
 
-   FUNC_ENTER (H5Tget_num_members, FAIL);
+   FUNC_ENTER (H5Tget_member_offset, 0);
    H5ECLEAR;
 
    /* Check args */
    if (H5_DATATYPE!=H5Aatom_group (type_id) ||
        NULL==(dt=H5Aatom_object (type_id)) ||
        H5T_COMPOUND!=dt->type) {
-      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type");
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, "not a compound data type");
+   }
+   if (membno<0 || membno>=dt->u.compnd.nmembs) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, 0, "invalid member number");
    }
 
-   FUNC_LEAVE (dt->u.compnd.nmembs);
+   offset = dt->u.compnd.memb[membno].offset;
+   FUNC_LEAVE (offset);
 }
 
 
 /*-------------------------------------------------------------------------
- * Function:	H5Tget_class
+ * Function:	H5Tget_member_dims
  *
- * Purpose:	Returns the data type class identifier for data type TYPE_ID.
+ * Purpose:	Returns the dimensionality of the member.  The dimensions and
+ *		permuation vector are returned through arguments DIMS and
+ *		PERM, both arrays of at least four elements.  Either (or even
+ *		both) may be null pointers.
  *
- * Return:	Success:	One of the non-negative data type class
- *				constants.
+ * Return:	Success:	A value between zero and four, inclusive.
  *
- *		Failure:	H5T_NO_CLASS (-1)
+ *		Failure:	-1
  *
  * Programmer:	Robb Matzke
- *              Monday, December  8, 1997
+ *              Wednesday, January  7, 1998
  *
  * Modifications:
  *
  *-------------------------------------------------------------------------
  */
-H5T_class_t
-H5Tget_class (hid_t type_id)
+int
+H5Tget_member_dims (hid_t type_id, int membno,
+		    int dims[]/*out*/, int perm[]/*out*/)
 {
    H5T_t	*dt = NULL;
-   
-   FUNC_ENTER (H5Tget_class, FAIL);
+   intn		ndims, i;
+
+   FUNC_ENTER (H5Tget_member_dims, FAIL);
    H5ECLEAR;
 
    /* Check args */
    if (H5_DATATYPE!=H5Aatom_group (type_id) ||
-       NULL==(dt=H5Aatom_object (type_id))) {
-      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_COMPOUND!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type");
+   }
+   if (membno<0 || membno>=dt->u.compnd.nmembs) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number");
    }
 
-   FUNC_LEAVE (dt->type);
+   ndims = dt->u.compnd.memb[membno].ndims;
+   for (i=0; i<ndims; i++) {
+      if (dims[i]) dims[i] = dt->u.compnd.memb[membno].dim[i];
+      if (perm[i]) perm[i] = dt->u.compnd.memb[membno].perm[i];
+   }
+   
+   FUNC_LEAVE (ndims);
 }
 
 
 /*-------------------------------------------------------------------------
- * Function:	H5Tget_size
+ * Function:	H5Tget_member_type
  *
- * Purpose:	Determines the total size of a data type in bytes.
+ * Purpose:	Returns the data type of the specified member.  The caller
+ *		should invoke H5Tclose() to release resources associated with
+ *		the type.
  *
- * Return:	Success:	Size of the data type in bytes.  The size of
- *				data type is the size of an instance of that
- *				data type.
+ * Return:	Success:	An OID of a copy of the member data type;
+ *				modifying the returned data type does not
+ *				modify the member type.
  *
- *		Failure:	0 (valid data types are never zero size)
+ *		Failure:	FAIL
  *
  * Programmer:	Robb Matzke
- *              Monday, December  8, 1997
+ *              Wednesday, January  7, 1998
  *
  * Modifications:
  *
  *-------------------------------------------------------------------------
  */
-size_t
-H5Tget_size (hid_t type_id)
+hid_t
+H5Tget_member_type (hid_t type_id, int membno)
 {
-   H5T_t	*dt = NULL;
-   size_t	size;
-   
-   FUNC_ENTER (H5Tget_size, 0);
+   H5T_t	*dt = NULL, *memb_dt = NULL;
+   hid_t	memb_type_id;
+
+   FUNC_ENTER (H5Tget_member_type, FAIL);
    H5ECLEAR;
 
    /* Check args */
    if (H5_DATATYPE!=H5Aatom_group (type_id) ||
-       NULL==(dt=H5Aatom_object (type_id))) {
-      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_COMPOUND!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type");
+   }
+   if (membno<0 || membno>=dt->u.compnd.nmembs) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number");
+   }
+   
+   /* Copy data type into an atom */
+   if (NULL==(memb_dt=H5T_copy (&(dt->u.compnd.memb[membno].type)))) {
+      HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+		     "unable to copy member data type");
+   }
+   if ((memb_type_id=H5Aregister_atom (H5_DATATYPE, memb_dt))<0) {
+      H5T_close (memb_dt);
+      HRETURN_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
+		     "can't register data type atom");
    }
 
-   /* size */
-   size = H5T_get_size (dt);
-
-   FUNC_LEAVE (size);
+   FUNC_LEAVE (memb_type_id);
 }
 
 
 /*-------------------------------------------------------------------------
- * Function:	H5Tinsert_member
+ * Function:	H5Tinsert
  *
  * Purpose:	Adds another member to the compound data type PARENT_ID.  The
  *		new member has a NAME which must be unique within the
@@ -414,13 +1433,12 @@ H5Tget_size (hid_t type_id)
  *-------------------------------------------------------------------------
  */
 herr_t
-H5Tinsert_member (hid_t parent_id, const char *name, off_t offset,
-		  hid_t member_id)
+H5Tinsert (hid_t parent_id, const char *name, off_t offset, hid_t member_id)
 {
    H5T_t	*parent = NULL;		/*the compound parent data type	*/
    H5T_t	*member = NULL;		/*the atomic member type	*/
    
-   FUNC_ENTER (H5Tinsert_member, FAIL);
+   FUNC_ENTER (H5Tinsert, FAIL);
    H5ECLEAR;
 
    /* Check args */
@@ -430,18 +1448,17 @@ H5Tinsert_member (hid_t parent_id, const char *name, off_t offset,
       HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type");
    }
    if (parent->locked) {
-      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "parent is locked");
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "parent type read-only");
    }
    if (!name || !*name) {
       HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no member name");
    }
    if (H5_DATATYPE!=H5Aatom_group (member_id) ||
-       NULL==(member=H5Aatom_object (member_id)) ||
-       H5T_COMPOUND==member->type) {
-      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
+       NULL==(member=H5Aatom_object (member_id))) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
    }
 
-   if (H5T_insert_member (parent, name, offset, member)<0) {
+   if (H5T_insert (parent, name, offset, member)<0) {
       HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINSERT, FAIL,
 		     "can't insert member");
    }
@@ -449,6 +1466,51 @@ H5Tinsert_member (hid_t parent_id, const char *name, off_t offset,
    FUNC_LEAVE (SUCCEED);
 }
 
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Tpack
+ *
+ * Purpose:	Recursively removes padding from within a compound data type
+ *		to make it more efficient (space-wise) to store that data.
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tpack (hid_t type_id)
+{
+   H5T_t	*dt = NULL;
+   
+   FUNC_ENTER (H5Tpack, FAIL);
+   H5ECLEAR;
+
+   /* Check args */
+   if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+       NULL==(dt=H5Aatom_object (type_id)) ||
+       H5T_COMPOUND!=dt->type) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type");
+   }
+   if (dt->locked) {
+      HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "data type is read-only");
+   }
+
+   if (H5T_pack (dt)<0) {
+      HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+		     "unable to pack compound data type");
+   }
+
+   FUNC_LEAVE (SUCCEED);
+}
+
+   
 
 
 /*-------------------------------------------------------------------------
@@ -490,7 +1552,7 @@ H5T_create (H5T_class_t type, size_t size)
    assert (size>0);
 
    switch (type) {
-   case H5T_FIXED:
+   case H5T_INTEGER:
       /* Default type is a native `int' */
       if (NULL==(dt=H5T_copy (H5Aatom_object (H5T_NATIVE_INT)))) {
 	 HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL,
@@ -506,7 +1568,7 @@ H5T_create (H5T_class_t type, size_t size)
       }
       break;
 
-   case H5T_DATE:
+   case H5T_TIME:
    case H5T_STRING:
    case H5T_BITFIELD:
    case H5T_OPAQUE:
@@ -620,6 +1682,33 @@ H5T_close (H5T_t *dt)
 
 
 /*-------------------------------------------------------------------------
+ * Function:	H5T_is_atomic
+ *
+ * Purpose:	Determines if a data type is an atomic type.
+ *
+ * Return:	Success:	TRUE, FALSE
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5T_is_atomic (const H5T_t *dt)
+{
+   FUNC_ENTER (H5T_is_atomic, FAIL);
+
+   assert (dt);
+
+   FUNC_LEAVE (H5T_COMPOUND==dt->type ? FALSE : TRUE);
+}
+
+
+/*-------------------------------------------------------------------------
  * Function:	H5T_get_size
  *
  * Purpose:	Determines the total size of a data type in bytes.
@@ -650,7 +1739,7 @@ H5T_get_size (const H5T_t *dt)
 
 
 /*-------------------------------------------------------------------------
- * Function:	H5T_insert_member
+ * Function:	H5T_insert
  *
  * Purpose:	Adds a new MEMBER to the compound data type PARENT.  The new
  *		member will have a NAME that is unique within PARENT and an
@@ -669,18 +1758,17 @@ H5T_get_size (const H5T_t *dt)
  *-------------------------------------------------------------------------
  */
 herr_t
-H5T_insert_member (H5T_t *parent, const char *name, off_t offset,
-		   const H5T_t *member)
+H5T_insert (H5T_t *parent, const char *name, off_t offset, const H5T_t *member)
 {
    intn		i;
    H5T_t	*tmp = NULL;
    
-   FUNC_ENTER (H5T_insert_member, FAIL);
+   FUNC_ENTER (H5T_insert, FAIL);
 
    /* check args */
    assert (parent && H5T_COMPOUND==parent->type);
    assert (!parent->locked);
-   assert (member && H5T_COMPOUND!=member->type);
+   assert (member);
    assert (name && *name);
 
    /* Does NAME already exist in PARENT? */
@@ -690,7 +1778,19 @@ H5T_insert_member (H5T_t *parent, const char *name, off_t offset,
 			"member name is not unique");
       }
    }
-
+   
+   /* Does the new member overlap any existing member ? */
+   for (i=0; i<parent->u.compnd.nmembs; i++) {
+      if ((offset<parent->u.compnd.memb[i].offset &&
+	   offset+member->size>parent->u.compnd.memb[i].offset) ||
+	  (parent->u.compnd.memb[i].offset<offset &&
+	   parent->u.compnd.memb[i].offset+
+	   parent->u.compnd.memb[i].type.size > offset)) {
+	 HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINSERT, FAIL,
+			"member overlaps with another member");
+      }
+   }
+   
    /* Increase member array if necessary */
    if (parent->u.compnd.nmembs>=parent->u.compnd.nalloc) {
       parent->u.compnd.nalloc += H5T_COMPND_INC;
@@ -709,9 +1809,117 @@ H5T_insert_member (H5T_t *parent, const char *name, off_t offset,
    parent->u.compnd.memb[i].type = *tmp;
    H5MM_xfree (tmp);
 
+   parent->u.compnd.nmembs++;
+   FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5T_pack
+ *
+ * Purpose:	Recursively packs a compound data type by removing padding
+ *		bytes. This is done in place (that is, destructively).
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_pack (H5T_t *dt)
+{
+   int		i;
+   size_t	offset;
+   
+   FUNC_ENTER (H5T_pack, FAIL);
+
+   assert (dt);
+   assert (!dt->locked);
+
+   if (H5T_COMPOUND==dt->type) {
+      /* Recursively pack the members */
+      for (i=0; i<dt->u.compnd.nmembs; i++) {
+	 if (H5T_pack (&(dt->u.compnd.memb[i].type))<0) {
+	    HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+			   "unable to pack part of a compound data type");
+	 }
+      }
+
+      /* Remove padding between members */
+      H5T_sort_by_offset (dt);
+      for (i=0, offset=0; i<dt->u.compnd.nmembs; i++) {
+	 dt->u.compnd.memb[i].offset = offset;
+	 offset += dt->u.compnd.memb[i].type.size;
+      }
+
+      /* Change total size */
+      dt->size = MAX (1, offset);
+   }
+
+   FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5T_sort_by_offset
+ *
+ * Purpose:	Sorts the members of a compound data type by their offsets.
+ *		This even works for locked data types since it doesn't change
+ *		the value of the type.
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_sort_by_offset (H5T_t *dt)
+{
+   int		i, j, nmembs;
+   hbool_t	swapped;
+   
+   FUNC_ENTER (H5T_sort_by_offset, FAIL);
+
+   /* Check args */
+   assert (dt);
+   assert (H5T_COMPOUND==dt->type);
+
+   /* Use a bubble sort because we can short circuit */
+   nmembs = dt->u.compnd.nmembs;
+   for (i=nmembs-1, swapped=TRUE; i>0 && swapped; --i) {
+      for (j=0, swapped=FALSE; j<i; j++) {
+	 if (dt->u.compnd.memb[j].offset>dt->u.compnd.memb[j+1].offset) {
+	    H5T_member_t tmp = dt->u.compnd.memb[j];
+	    dt->u.compnd.memb[j] = dt->u.compnd.memb[j+1];
+	    dt->u.compnd.memb[j+1] = tmp;
+	    swapped = 1;
+	 }
+      }
+   }
+
+#ifndef NDEBUG
+   /* I never trust a sort :-) */
+   for (i=0; i<dt->u.compnd.nmembs-1; i++) {
+      assert (dt->u.compnd.memb[i].offset<dt->u.compnd.memb[i+1].offset);
+   }
+#endif
+
    FUNC_LEAVE (SUCCEED);
 }
 
+
 
 /*-------------------------------------------------------------------------
  * Function:	H5T_cmp
@@ -856,7 +2064,7 @@ H5T_cmp (const H5T_t *dt1, const H5T_t *dt2)
       if (dt1->u.atomic.hi_pad > dt2->u.atomic.hi_pad) HGOTO_DONE (1);
 
       switch (dt1->type) {
-      case H5T_FIXED:
+      case H5T_INTEGER:
 	 if (dt1->u.atomic.u.i.sign < dt2->u.atomic.u.i.sign) HGOTO_DONE (-1);
 	 if (dt1->u.atomic.u.i.sign > dt2->u.atomic.u.i.sign) HGOTO_DONE (1);
 	 break;
@@ -894,7 +2102,7 @@ H5T_cmp (const H5T_t *dt1, const H5T_t *dt2)
 
 	 break;
 
-      case H5T_DATE:
+      case H5T_TIME:
 	 /*void*/
 	 break;
 
@@ -927,3 +2135,171 @@ H5T_cmp (const H5T_t *dt1, const H5T_t *dt2)
    FUNC_LEAVE (ret_value);
 }
       
+
+/*-------------------------------------------------------------------------
+ * Function:	H5T_debug
+ *
+ * Purpose:	Prints information about a data type.
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_debug (H5T_t *dt, FILE *stream)
+{
+   const char	*s = "";
+   int		i, j;
+   uint64	tmp;
+
+   FUNC_ENTER (H5T_debug, FAIL);
+
+   /* Check args */
+   assert (dt);
+   assert (stream);
+
+   switch (dt->type) {
+   case H5T_INTEGER:
+      s = "int";
+      break;
+   case H5T_FLOAT:
+      s = "float";
+      break;
+   case H5T_TIME:
+      s = "time";
+      break;
+   case H5T_STRING:
+      s = "str";
+      break;
+   case H5T_BITFIELD:
+      s = "bits";
+      break;
+   case H5T_OPAQUE:
+      s = "opaque";
+      break;
+   case H5T_COMPOUND:
+      s = "struct";
+      break;
+   default:
+      s = "";
+      break;
+   }
+
+   fprintf (stream, "%s%s {nbytes=%d",
+	    s, dt->locked?"[!]":"", dt->size);
+
+   if (H5T_is_atomic (dt)) {
+      switch (dt->u.atomic.order) {
+      case H5T_ORDER_BE:
+	 s = "BE";
+	 break;
+      case H5T_ORDER_LE:
+	 s = "LE";
+	 break;
+      case H5T_ORDER_VAX:
+	 s = "VAX";
+	 break;
+      case H5T_ORDER_NONE:
+	 s = "NONE";
+	 break;
+      default:
+	 s = "order?";
+	 break;
+      }
+      fprintf (stream, ", %s", s);
+
+      if (dt->u.atomic.offset) {
+	 fprintf (stream, ", offset=%lu",
+		  (unsigned long)(dt->u.atomic.offset));
+      }
+      if (dt->u.atomic.prec!=8*dt->size) {
+	 fprintf (stream, ", prec=%lu",
+		  (unsigned long)(dt->u.atomic.prec));
+      }
+
+      switch (dt->type) {
+      case H5T_INTEGER:
+	 switch (dt->u.atomic.u.i.sign) {
+	 case H5T_SGN_NONE:
+	    s = "unsigned";
+	    break;
+	 case H5T_SGN_2:
+	    s = NULL;
+	    break;
+	 default:
+	    s = "sign?";
+	    break;
+	 }
+	 if (s) fprintf (stream, ", %s", s);
+	 break;
+
+      case H5T_FLOAT:
+	 switch (dt->u.atomic.u.f.norm) {
+	 case H5T_NORM_IMPLIED:
+	    s = "implied";
+	    break;
+	 case H5T_NORM_MSBSET:
+	    s = "msbset";
+	    break;
+	 case H5T_NORM_NONE:
+	    s = "no-norm";
+	    break;
+	 default:
+	    s = "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);
+	 fprintf (stream, ", exp=%lu+%lu",
+		  (unsigned long)(dt->u.atomic.u.f.epos),
+		  (unsigned long)(dt->u.atomic.u.f.esize));
+	 tmp = dt->u.atomic.u.f.ebias >> 32;
+	 if (tmp) {
+	    uintn hi = tmp;
+	    uintn lo = dt->u.atomic.u.f.ebias & 0xffffffff;
+	    fprintf (stream, " bias=0x%08x%08x", hi, lo);
+	 } else {
+	    uintn lo = dt->u.atomic.u.f.ebias & 0xffffffff;
+	    fprintf (stream, " bias=0x%08x", lo);
+	 }
+	 break;
+
+      default:
+	 /* No additional info */
+	 break;
+      }
+   } else {
+      for (i=0; i<dt->u.compnd.nmembs; i++) {
+	 fprintf (stream, "\n\"%s\" @%lu",
+		  dt->u.compnd.memb[i].name,
+		  (unsigned long)(dt->u.compnd.memb[i].offset));
+	 if (dt->u.compnd.memb[i].ndims) {
+	    fprintf (stream, "[");
+	    for (j=0; j<dt->u.compnd.memb[i].ndims; j++) {
+	       fprintf (stream, "%s%d", j?", ":"",
+			dt->u.compnd.memb[i].dim[j]);
+	    }
+	    fprintf (stream, "]");
+	 }
+	 fprintf (stream, " ");
+	 H5T_debug (&(dt->u.compnd.memb[i].type), stream);
+      }
+      fprintf (stream, "\n");
+   }
+   fprintf (stream, "}");
+
+   FUNC_LEAVE (SUCCEED);
+}
+
+	 
+
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 1267e83..1a75c59 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -26,8 +26,8 @@ typedef struct H5T_atomic_t {
    intn			hi_pad;	/*type of msb padding			*/
    union {
       struct {
-	 H5T_sign_t	sign;	/*type of fixed-point sign		*/
-      } i;			/*integer; fixed-point types		*/
+	 H5T_sign_t	sign;	/*type of integer sign			*/
+      } i;			/*integer; integer types		*/
 
       struct {
 	 size_t		sign;	/*bit position of sign bit		*/
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 5a9fbcb..f92dba5 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -38,7 +38,13 @@ H5T_t *H5T_copy (const H5T_t *old_dt);
 herr_t H5T_close (H5T_t *dt);
 size_t H5T_get_size (const H5T_t *dt);
 intn H5T_cmp (const H5T_t *dt1, const H5T_t *dt2);
+hbool_t H5T_is_atomic (const H5T_t *dt);
+
+herr_t H5T_insert (H5T_t *parent, const char *name, off_t offset,
+		   const H5T_t *member);
+herr_t H5T_sort_by_offset (H5T_t *dt);
+herr_t H5T_pack (H5T_t *dt);
+herr_t H5T_debug (H5T_t *dt, FILE *stream);
+
 
-herr_t H5T_insert_member (H5T_t *parent, const char *name, off_t offset,
-			  const H5T_t *member);
 #endif
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index e2c1163..907aff1 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -26,9 +26,9 @@
 /* These are the various classes of data types */
 typedef enum H5T_class_t {
    H5T_NO_CLASS		=-1,	/*error					*/
-   H5T_FIXED		=0,	/*fixed-point types			*/
+   H5T_INTEGER		=0,	/*integer types				*/
    H5T_FLOAT		=1,	/*floating-point types			*/
-   H5T_DATE		=2,	/*date and time	types			*/
+   H5T_TIME		=2,	/*date and time	types			*/
    H5T_STRING		=3,	/*character string types		*/
    H5T_BITFIELD		=4,	/*bit field types			*/
    H5T_OPAQUE		=5, 	/*opaque types				*/
@@ -42,13 +42,16 @@ typedef enum H5T_order_t {
    H5T_ORDER_BE		=1, 	/*bit endian				*/
    H5T_ORDER_VAX	=2, 	/*VAX mixed endian			*/
    H5T_ORDER_NONE	=3	/*no particular order (strings, bits,..)*/
+   /*H5T_ORDER_NONE must be last*/
 } H5T_order_t;
 
-/* Types of fixed-point sign schemes */
+/* Types of integer sign schemes */
 typedef enum H5T_sign_t {
    H5T_SGN_ERROR	=-1, 	/*error					*/
    H5T_SGN_NONE		=0, 	/*this is an unsigned type		*/
-   H5T_SGN_2		=1 	/*two's complement			*/
+   H5T_SGN_2		=1,  	/*two's complement			*/
+   
+   H5T_SGN_N		=2	/*this must be last			*/
 } H5T_sign_t;
 
 /* Floating-point normalization schemes */
@@ -57,6 +60,7 @@ typedef enum H5T_norm_t {
    H5T_NORM_IMPLIED	=0,	/*msb of mantissa isn't stored, always 1*/
    H5T_NORM_MSBSET	=1, 	/*msb of mantissa is always 1		*/
    H5T_NORM_NONE	=2	/*not normalized			*/
+   /*H5T_NORM_NONE must be last*/
 } H5T_norm_t;
 
 /* Character set to use for text strings */
@@ -72,39 +76,86 @@ typedef enum H5T_str_t {
    H5T_STR_SPACE	=1 	/*pad with spaces like in Fortran	*/
 } H5T_str_t;
 
+/* Type of padding to use in other atomic types */
+typedef enum H5T_pad_t {
+   H5T_PAD_ERROR	=-1, 	/*error					*/
+   H5T_PAD_ZERO		=0, 	/*always set to zero			*/
+   H5T_PAD_ONE		=1, 	/*always set to one			*/
+   H5T_PAD_BACKGROUND	=2, 	/*set to background value		*/
+   
+   H5T_NPAD		=3	/*THIS MUST BE LAST			*/
+} H5T_pad_t;
 
-
-#define H5T_PAD_ZERO	(-1)	/*pad with all zeros			*/
-#define H5T_PAD_ONE	(-2)	/*pad with all ones			*/
-#define H5T_PAD_FROM(X)	(X)	/*pad with value of bit X		*/
+#define HOFFSET(S,M)	((const char*)&S.M-(const char*)&S)
+#define HPOFFSET(P,M)	((const char*)&(P->M)-(const char*)P)
 
 /* The predefined types */
-extern hid_t H5T_NATIVE_CHAR;
-extern hid_t H5T_NATIVE_UCHAR;
-extern hid_t H5T_NATIVE_SHORT;
-extern hid_t H5T_NATIVE_USHORT;
-extern hid_t H5T_NATIVE_INT;
-extern hid_t H5T_NATIVE_UINT;
-extern hid_t H5T_NATIVE_LONG;
-extern hid_t H5T_NATIVE_ULONG;
-extern hid_t H5T_NATIVE_FLOAT;
-extern hid_t H5T_NATIVE_DOUBLE;
+#define H5T_NATIVE_CHAR		(H5init(), H5T_NATIVE_CHAR_g)
+#define H5T_NATIVE_UCHAR	(H5init(), H5T_NATIVE_UCHAR_g)
+#define H5T_NATIVE_SHORT	(H5init(), H5T_NATIVE_SHORT_g)
+#define H5T_NATIVE_USHORT	(H5init(), H5T_NATIVE_USHORT_g)
+#define H5T_NATIVE_INT		(H5init(), H5T_NATIVE_INT_g)
+#define H5T_NATIVE_UINT		(H5init(), H5T_NATIVE_UINT_g)
+#define H5T_NATIVE_LONG		(H5init(), H5T_NATIVE_LONG_g)
+#define H5T_NATIVE_ULONG	(H5init(), H5T_NATIVE_ULONG_g)
+#define H5T_NATIVE_FLOAT	(H5init(), H5T_NATIVE_FLOAT_g)
+#define H5T_NATIVE_DOUBLE	(H5init(), H5T_NATIVE_DOUBLE_g)
+
+extern hid_t H5T_NATIVE_CHAR_g;
+extern hid_t H5T_NATIVE_UCHAR_g;
+extern hid_t H5T_NATIVE_SHORT_g;
+extern hid_t H5T_NATIVE_USHORT_g;
+extern hid_t H5T_NATIVE_INT_g;
+extern hid_t H5T_NATIVE_UINT_g;
+extern hid_t H5T_NATIVE_LONG_g;
+extern hid_t H5T_NATIVE_ULONG_g;
+extern hid_t H5T_NATIVE_FLOAT_g;
+extern hid_t H5T_NATIVE_DOUBLE_g;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/* Operations defined on all data types */
 hid_t H5Tcreate (H5T_class_t type, size_t size);
 hid_t H5Tcopy (hid_t type_id);
 herr_t H5Tclose (hid_t type_id);
 hbool_t H5Tequal (hid_t type1_id, hid_t type2_id);
 
+/* Operations defined on compound data types */
+herr_t H5Tinsert (hid_t parent_id, const char *name, off_t offset,
+		  hid_t member_id);
+herr_t H5Tpack (hid_t type_id);
+
+/* Querying property values */
 H5T_class_t H5Tget_class (hid_t type_id);
 size_t H5Tget_size (hid_t type_id);
+H5T_order_t H5Tget_order (hid_t type_id);
+size_t H5Tget_precision (hid_t type_id);
+size_t H5Tget_offset (hid_t type_id);
+H5T_sign_t H5Tget_sign (hid_t type_id);
+herr_t H5Tget_fields (hid_t type_id, size_t *spos/*out*/,
+		      size_t *epos/*out*/, size_t *esize/*out*/,
+		      size_t *mpos/*out*/, size_t *msize/*out*/);
+size_t H5Tget_ebias (hid_t type_id);
+H5T_norm_t H5Tget_norm (hid_t type_id);
 intn H5Tget_nmembers (hid_t type_id);
-
-herr_t H5Tinsert_member (hid_t parent_id, const char *name, off_t offset,
-			 hid_t member_id);
+char *H5Tget_member_name (hid_t type_id, int membno);
+size_t H5Tget_member_offset (hid_t type_id, int membno);
+int H5Tget_member_dims (hid_t type_id, int membno,
+			int dims[]/*out*/, int perm[]/*out*/);
+hid_t H5Tget_member_type (hid_t type_id, int membno);
+
+/* Setting property values */
+herr_t H5Tset_size (hid_t type_id, size_t size);
+herr_t H5Tset_order (hid_t type_id, H5T_order_t order);
+herr_t H5Tset_precision (hid_t type_id, size_t prec);
+herr_t H5Tset_offset (hid_t type_id, size_t offset);
+herr_t H5Tset_sign (hid_t type_id, H5T_sign_t sign);
+herr_t H5Tset_fields (hid_t type_id, size_t spos, size_t epos, size_t esize,
+		      size_t mpos, size_t msize);
+herr_t H5Tset_ebias (hid_t type_id, size_t ebias);
+herr_t H5Tset_norm (hid_t type_id, H5T_norm_t norm);
 
 
 #ifdef __cplusplus
diff --git a/src/H5detect.c b/src/H5detect.c
index 43464c4..82b662f 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -98,13 +98,13 @@ static detected_t Known[] = {
    {"Byte addressable",
     1, 0, LE_1, INTEGER},
 
-   /* Little-endian fixed-point */
+   /* Little-endian integer */
    {"Little-endian",
     2, 0, LE_2, INTEGER},
    {"Little-endian",
     4, 0, LE_4, INTEGER},
 
-   /* Big-endian fixed-point */
+   /* Big-endian integer */
    {"Big-endian",
     2, 0, BE_2, INTEGER},
    {"Big-endian",
@@ -284,7 +284,7 @@ static hbool_t interface_initialize_g = FALSE;\n\
 
    /* Global definitions for each type */
    for (i=0; i<nd; i++) {
-      printf ("hid_t H5T_NATIVE_%s;\n", d[i].varname);
+      printf ("hid_t H5T_NATIVE_%s_g = FAIL;\n", d[i].varname);
    }
    
    /* Function declaration */
@@ -318,7 +318,7 @@ H5T_init (void)\n\
    dt->u.atomic.prec = %d;\n\
    dt->u.atomic.lo_pad = H5T_PAD_ZERO;\n\
    dt->u.atomic.hi_pad = H5T_PAD_ZERO;\n",
-	      d[i].msize?"FLOAT":"FIXED", 		/*class		*/
+	      d[i].msize?"FLOAT":"INTEGER", 		/*class		*/
 	      d[i].size+abs (d[i].padding), 		/*size		*/
 	      d[i].perm[0]?"BE":"LE", 			/*byte order	*/
 	      8*d[i].size); 				/*precision	*/
@@ -350,7 +350,7 @@ H5T_init (void)\n\
 
       /* Atomize the type */
       printf ("\
-   if ((H5T_NATIVE_%s = H5Aregister_atom (H5_DATATYPE, dt))<0) {\n\
+   if ((H5T_NATIVE_%s_g = H5Aregister_atom (H5_DATATYPE, dt))<0) {\n\
       HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,\n\
                      \"can't initialize type system (atom registration \"\n\
                      \"failure\");\n\
@@ -829,7 +829,7 @@ true exponent.	The radix point is assumed\n\
 to be before the first `M' bit.	 Any bit\n\
 of a floating-point value not falling into one\n\
 of these categories is printed as a question\n\
-mark.  Bits of fixed-point types are printed as\n\
+mark.  Bits of integer types are printed as\n\
 `I' for 2's complement and `U' for magnitude.\n\
 \n\
 If the most significant bit of the normalized\n\
diff --git a/test/dtypes.c b/test/dtypes.c
index 6ff118f..bd180e0 100644
--- a/test/dtypes.c
+++ b/test/dtypes.c
@@ -11,6 +11,8 @@
 #include <stdio.h>
 #include <unistd.h>
 
+#include <H5Tprivate.h>
+
 
 #ifndef HAVE_FUNCTION
 #define __FUNCTION__ ""
@@ -18,6 +20,10 @@
 #define AT() printf ("   at %s:%d in %s()...\n",			    \
 		     __FILE__, __LINE__, __FUNCTION__);
 
+typedef struct complex_t {
+   double	re;
+   double	im;
+} complex_t;
 
 
 /*-------------------------------------------------------------------------
@@ -43,7 +49,7 @@ test_classes (void)
 
    printf ("%-70s", "Testing H5Tget_class()");
 
-   if (H5T_FIXED!=(type_class=H5Tget_class (H5T_NATIVE_INT))) {
+   if (H5T_INTEGER!=(type_class=H5Tget_class (H5T_NATIVE_INT))) {
       puts ("*FAILED*");
       if (!isatty (1)) {
 	 AT ();
@@ -131,6 +137,82 @@ test_copy (void)
 
 
 /*-------------------------------------------------------------------------
+ * Function:	test_compound
+ *
+ * Purpose:	Tests various things about compound data types.
+ *
+ * Return:	Success:	SUCCEED
+ *
+ *		Failure:	FAIL
+ *
+ * Programmer:	Robb Matzke
+ *              Wednesday, January  7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_compound (void)
+{
+   complex_t	tmp;
+   hid_t 	complex_id;
+   herr_t	status;
+
+   printf ("%-70s", "Testing compound data types");
+
+   /* Create the empty type */
+   complex_id = H5Tcreate (H5T_COMPOUND, sizeof tmp);
+   if (complex_id<0) {
+      puts ("*FAILED*");
+      if (!isatty (1)) {
+	 AT ();
+	 printf ("   Cannot create empty compound data type.\n");
+      }
+      goto error;
+   }
+
+   /* Add a coupld fields */
+   status = H5Tinsert (complex_id, "real", HOFFSET (tmp, re),
+		       H5T_NATIVE_DOUBLE);
+   if (status<0) {
+      puts ("*FAILED*");
+      if (!isatty (1)) {
+	 AT ();
+	 printf ("   Cannot insert real component.\n");
+      }
+      goto error;
+   }
+
+   status = H5Tinsert (complex_id, "imaginary", HOFFSET (tmp, im),
+		       H5T_NATIVE_DOUBLE);
+   if (status<0) {
+      puts ("*FAILED*");
+      if (!isatty (1)) {
+	 AT ();
+	 printf ("   Cannot insert imaginary component.\n");
+      }
+      goto error;
+   }
+
+   puts (" PASSED");
+
+   /* Just for debugging... */
+   H5T_debug (H5Aatom_object (complex_id), stdout);
+   printf ("\n");
+   
+   
+   return SUCCEED;
+
+ error:
+   return FAIL;
+}
+
+	 
+
+
+
+/*-------------------------------------------------------------------------
  * Function:	main
  *
  * Purpose:	Test the data type interface.
@@ -159,6 +241,9 @@ main (void)
 
    status = test_copy ();
    nerrors += status<0 ? 1 : 0;
+
+   status = test_compound ();
+   nerrors += status<0 ? 1 : 0;
    
 
    if (nerrors) {
-- 
cgit v0.12