summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1997-12-16 21:08:26 (GMT)
committerRobb Matzke <matzke@llnl.gov>1997-12-16 21:08:26 (GMT)
commite615fc7a982c1817cf7d4c24adf9323604692310 (patch)
tree5dab77c6c1a4476ab5b5953c45f1ea6a1b5d994e
parentfaca6fbaa8c557b18d6b264841fc8717d1e73816 (diff)
downloadhdf5-e615fc7a982c1817cf7d4c24adf9323604692310.zip
hdf5-e615fc7a982c1817cf7d4c24adf9323604692310.tar.gz
hdf5-e615fc7a982c1817cf7d4c24adf9323604692310.tar.bz2
[svn-r146] ./src/H5.c
Changes to error handling. ./src/H5B.c Increased size of internal static buffers. ./src/H5C.c Fixed syntax error when NDEBUG is defined. ./src/H5E.c ./src/H5Eprivate.h ./src/H5Epublic.h Errors can now be printed with H5Eprint(). Other minor changes to names and arg types. ./src/H5F.c The base address is now stored in the boot block. The user block size and the base address are synonyms. ./src/H5Fstdio.c Fixed a bug with a return value from fseek(). ./src/H5H.c Added alignment constraints to get rid of unaligned access errors on the DEC alpha having to do with the heap free list. ./src/H5P.c ./src/H5Ppublic.h Changed some size arguments from int to size_t and fixed memory allocation calls. ./src/H5T.c ./src/H5Tpublic.h Changed the order of functions so all the public ones are at the top of the file. Other minor changes. ./src/H5detect.c Added a newline to a string constant.
-rw-r--r--src/H5.c4
-rw-r--r--src/H5B.c2
-rw-r--r--src/H5C.c5
-rw-r--r--src/H5Cpublic.h2
-rw-r--r--src/H5E.c792
-rw-r--r--src/H5Eprivate.h90
-rw-r--r--src/H5Epublic.h24
-rw-r--r--src/H5F.c23
-rw-r--r--src/H5Fstdio.c2
-rw-r--r--src/H5H.c35
-rw-r--r--src/H5P.c22
-rw-r--r--src/H5Ppublic.h2
-rw-r--r--src/H5T.c447
-rw-r--r--src/H5Tpublic.h4
-rw-r--r--src/H5detect.c2
15 files changed, 805 insertions, 651 deletions
diff --git a/src/H5.c b/src/H5.c
index 555645e..faef9f8 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -189,7 +189,7 @@ herr_t H5_init_thread(void)
FUNC_ENTER_INIT (H5_init_thread, NULL, FAIL);
/* Create/initialize this thread's error stack */
- if((thrderrid=H5Enew_err_stack(16))==FAIL)
+ if((H5E_thrdid_g=H5Ecreate(16))==FAIL)
HRETURN_ERROR (H5E_FUNC, H5E_CANTINIT, FAIL,
"unable to create thread error stack");
@@ -222,7 +222,7 @@ herr_t H5_init_thread(void)
void
H5_term_thread (void)
{
- H5Edelete_err_stack(thrderrid);
+ H5Eclose (H5E_thrdid_g);
} /* end H5_term_thread() */
/*--------------------------------------------------------------------------
diff --git a/src/H5B.c b/src/H5B.c
index be64ccf..6adf671 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -762,7 +762,7 @@ herr_t
H5B_insert (H5F_t *f, const H5B_class_t *type, const haddr_t *addr,
void *udata)
{
- uint8 lt_key[512], md_key[512], rt_key[512];
+ uint8 lt_key[1024], md_key[1024], rt_key[1024];
hbool_t lt_key_changed=FALSE, rt_key_changed=FALSE;
haddr_t child, old_root;
intn level;
diff --git a/src/H5C.c b/src/H5C.c
index 2d5ebe5..05686dd 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -269,7 +269,10 @@ H5Cget_class (hid_t template)
FUNC_ENTER (H5Cget_class, H5C_NO_CLASS);
if ((group = H5Aatom_group (template))<0 ||
- group<H5_TEMPLATE_0 || group>=H5_TEMPLATE_MAX) {
+#ifndef NDEBUG
+ group>=H5_TEMPLATE_MAX ||
+#endif
+ group<H5_TEMPLATE_0) {
HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, H5C_NO_CLASS, "not a template");
}
diff --git a/src/H5Cpublic.h b/src/H5Cpublic.h
index c0bc55d..c4188f9 100644
--- a/src/H5Cpublic.h
+++ b/src/H5Cpublic.h
@@ -60,7 +60,7 @@ typedef enum H5C_prop_t {
H5D_CHUNK_SIZE, /* Chunk size vector */
H5D_COMPRESS, /* Raw data compression */
H5D_PRE_OFFSET, /* Precompression offset */
- H5D_PRE_SCALE, /* Precompression scale */
+ H5D_PRE_SCALE /* Precompression scale */
/* Dataset Transfer Properties */
/* None defined yet */
diff --git a/src/H5E.c b/src/H5E.c
index f738caa..f7d9fd2 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -1,13 +1,22 @@
/****************************************************************************
-* NCSA HDF *
-* Software Development Group *
-* National Center for Supercomputing Applications *
-* University of Illinois at Urbana-Champaign *
-* 605 E. Springfield, Champaign IL 61820 *
-* *
-* For conditions of distribution and use, see the accompanying *
-* hdf/COPYING file. *
-* *
+* NCSA HDF *
+* Software Development Group *
+* National Center for Supercomputing Applications *
+* University of Illinois at Urbana-Champaign *
+* 605 E. Springfield, Champaign IL 61820 *
+* *
+* For conditions of distribution and use, see the accompanying *
+* hdf/COPYING file. *
+ *
+ * Notes: It is safe to call HRETURN_ERROR(), HGOTO_ERROR(), HERROR(), and
+ * H5ECLEAR within any of these functions except H5E_push() (see
+ * comments in H5E_push()). However, some of the H5E API functions
+ * don't call H5ECLEAR the the error stack on which they're operating
+ * is the thread's global error stack. If the thread's global error
+ * stack isn't defined yet, then HRETURN_ERROR(), HGOTO_ERROR(), and
+ * HERROR() don't push an error message and H5ECLEAR just returns
+ * without doing anything.
+* *
****************************************************************************/
#ifdef RCSID
@@ -16,82 +25,65 @@ static char RcsId[] = "@(#)$Revision$";
/* $Id$ */
-/*LINTLIBRARY */
-/*+
- FILE
- hdf5err.c
- HDF error reporting routines
-
- EXPORTED ROUTINES
- H5Enew_err_stack -- Create a new error stack to push values on
- H5Epush -- Push an error value on an error stack
-
- LIBRARY-SCOPED ROUTINES
-
- LOCAL ROUTINES
- H5E_init_interface -- initialize the H5E interface
- + */
-
-#include <H5private.h> /* Generic Functions */
-#include <H5Aprivate.h> /* Atoms */
-#include <H5Eprivate.h> /* Private error routines */
+#include <H5private.h> /* Generic Functions */
+#include <H5Aprivate.h> /* Atoms */
+#include <H5Eprivate.h> /* Private error routines */
+#include <H5MMprivate.h> /* Memory management */
#define PABLO_MASK H5E_mask
/*-------------------- Locally scoped variables -----------------------------*/
-static const hdf_maj_error_messages_t hdf_maj_error_messages[] =
-{
- {H5E_NONE_MAJOR, "No error"},
- {H5E_ARGS, "Invalid arguments to routine"},
- {H5E_RESOURCE, "Resource unavailable"},
- {H5E_INTERNAL, "Internal HDF5 error (too specific to document in detail)"},
- {H5E_FILE, "File Accessability"},
- {H5E_IO, "Low-level I/O"},
- {H5E_FUNC, "Function Entry/Exit"},
- {H5E_ATOM, "Object Atom"},
+static const H5E_major_mesg_t H5E_major_mesg_g[] = {
+ {H5E_NONE_MAJOR, "No error"},
+ {H5E_ARGS, "Invalid arguments to routine"},
+ {H5E_RESOURCE, "Resource unavailable"},
+ {H5E_INTERNAL, "Internal HDF5 error"},
+ {H5E_FILE, "File Accessability"},
+ {H5E_IO, "Low-level I/O"},
+ {H5E_FUNC, "Function Entry/Exit"},
+ {H5E_ATOM, "Object Atom"},
{H5E_CACHE, "Object Cache"},
{H5E_BTREE, "B-Tree Node"},
{H5E_SYM, "Symbol Table"},
{H5E_HEAP, "Heap"},
{H5E_OHDR, "Object Header"},
- {H5E_DATATYPE, "Datatype"},
+ {H5E_DATATYPE, "Datatype"},
{H5E_DATASPACE, "Dataspace"},
- {H5E_DATASET, "Dataset"},
- {H5E_STORAGE, "Data Storage"},
- {H5E_TEMPLATE, "Template"},
+ {H5E_DATASET, "Dataset"},
+ {H5E_STORAGE, "Data Storage"},
+ {H5E_TEMPLATE, "Template"},
};
-static const hdf_min_error_messages_t hdf_min_error_messages[] =
-{
- {H5E_NONE_MINOR, "No error"},
+static const H5E_minor_mesg_t H5E_minor_mesg_g[] = {
+ {H5E_NONE_MINOR, "No error"},
{H5E_UNINITIALIZED, "Information is uninitialized"},
- {H5E_UNSUPPORTED, "Feature is unsupported"},
- {H5E_BADTYPE, "Incorrect type found"},
- {H5E_BADRANGE, "Argument out of range"},
- {H5E_BADVALUE, "Bad value for argument"},
- {H5E_NOSPACE, "No space available for allocation"},
- {H5E_FILEEXISTS, "File already exists"},
- {H5E_FILEOPEN, "File already open"},
- {H5E_CANTCREATE, "Can't create file"},
- {H5E_CANTOPENFILE, "Can't open file"},
- {H5E_CANTOPENOBJ, "Can't open object"},
- {H5E_NOTHDF5, "Not an HDF5 format file"},
- {H5E_BADFILE, "Bad file ID accessed"},
+ {H5E_UNSUPPORTED, "Feature is unsupported"},
+ {H5E_BADTYPE, "Incorrect type found"},
+ {H5E_BADRANGE, "Argument out of range"},
+ {H5E_BADVALUE, "Bad value for argument"},
+ {H5E_NOSPACE, "No space available for allocation"},
+ {H5E_FILEEXISTS, "File already exists"},
+ {H5E_FILEOPEN, "File already open"},
+ {H5E_CANTCREATE, "Can't create file"},
+ {H5E_CANTOPENFILE, "Can't open file"},
+ {H5E_CANTOPENOBJ, "Can't open object"},
+ {H5E_NOTHDF5, "Not an HDF5 format file"},
+ {H5E_BADFILE, "Bad file ID accessed"},
{H5E_TRUNCATED, "File has been truncated"},
- {H5E_SEEKERROR, "Seek failed"},
- {H5E_READERROR, "Read failed"},
- {H5E_WRITEERROR, "Write failed"},
- {H5E_CLOSEERROR, "Close failed"},
- {H5E_CANTINIT, "Can't initialize interface"},
- {H5E_ALREADYINIT, "Object already initialized"},
- {H5E_BADATOM, "Can't find atom information"},
- {H5E_CANTREGISTER, "Can't register new atom"},
+ {H5E_SEEKERROR, "Seek failed"},
+ {H5E_READERROR, "Read failed"},
+ {H5E_WRITEERROR, "Write failed"},
+ {H5E_CLOSEERROR, "Close failed"},
+ {H5E_CANTINIT, "Can't initialize interface"},
+ {H5E_ALREADYINIT, "Object already initialized"},
+ {H5E_BADATOM, "Can't find atom information"},
+ {H5E_CANTREGISTER, "Can't register new atom"},
{H5E_CANTFLUSH, "Can't flush object from cache"},
{H5E_CANTLOAD, "Can't load object into cache"},
{H5E_PROTECT, "Protected object error"},
- {H5E_NOTCACHED, "Object not currently cached"},
+ {H5E_NOTCACHED, "Object not currently cached"},
{H5E_NOTFOUND, "Object not found"},
{H5E_EXISTS, "Object already exists"},
{H5E_CANTENCODE, "Can't encode value"},
@@ -104,7 +96,7 @@ static const hdf_min_error_messages_t hdf_min_error_messages[] =
{H5E_ALIGNMENT, "Alignment error"},
{H5E_BADMESG, "Unrecognized message"},
{H5E_COMPLEN, "Name component is too long"},
- {H5E_CWG, "Problem with current working group"},
+ {H5E_CWG, "Problem with current working group"},
{H5E_LINK, "Link count failure"},
};
@@ -112,9 +104,9 @@ static const hdf_min_error_messages_t hdf_min_error_messages[] =
static intn interface_initialize_g = FALSE;
#define INTERFACE_INIT H5E_init_interface
static herr_t H5E_init_interface(void);
+static void H5E_term_interface (void);
-
-int32 thrderrid; /* Thread-specific "global" error-handler ID */
+hid_t H5E_thrdid_g = FAIL; /* Thread-specific "global" error-handler ID */
/*--------------------------------------------------------------------------
@@ -133,17 +125,21 @@ Modifications:
Changed the pablo mask from H5_mask to H5E_mask
--------------------------------------------------------------------------*/
-static herr_t H5E_init_interface(void)
+static herr_t
+H5E_init_interface (void)
{
- herr_t ret_value = SUCCEED;
- FUNC_ENTER (H5E_init_interface, FAIL);
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER (H5E_init_interface, FAIL);
- /* Initialize the atom group for the error stacks */
- if((ret_value=H5Ainit_group(H5_ERR,H5A_ERRSTACK_HASHSIZE,0,NULL))!=FAIL)
- ret_value=H5_add_exit(&H5E_term_interface);
+ /* Initialize the atom group for the error stacks */
+ if ((ret_value=H5Ainit_group (H5_ERR, H5A_ERRSTACK_HASHSIZE, 0,
+ (herr_t (*)(void*))H5E_close))!=FAIL) {
+ ret_value = H5_add_exit (H5E_term_interface);
+ }
- FUNC_LEAVE(ret_value);
-} /* H5E_init_interface */
+ FUNC_LEAVE (ret_value);
+}
/*--------------------------------------------------------------------------
NAME
@@ -162,17 +158,18 @@ static herr_t H5E_init_interface(void)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-void H5E_term_interface (void)
+static void
+H5E_term_interface (void)
{
- H5Adestroy_group(H5_ERR);
-} /* end H5E_term_interface() */
+ H5Adestroy_group(H5_ERR);
+}
/*--------------------------------------------------------------------------
NAME
- H5Enew_err_stack -- Create a new error stack
+ H5Ecreate -- Create a new error stack
USAGE
- int32 H5Enew_err_stack(initial_stack_size);
- uintn initial_stack_size; IN: Starting size of the error stack
+ hid_t H5Ecreate (initial_stack_size);
+ uintn initial_stack_size; IN: Starting size of the error stack
RETURNS
The ID of the error stack created on success, FAIL on failure.
@@ -181,47 +178,42 @@ DESCRIPTION
Dynamically creates a new error stack to push error values onto.
--------------------------------------------------------------------------*/
-int32 H5Enew_err_stack(uintn initial_stack_size)
+hid_t
+H5Ecreate (uintn initial_stack_nelmts)
{
- H5E_errstack_t *new_stack=NULL; /* Pointer to the new error stack */
- int32 ret_value = FAIL;
-
- FUNC_ENTER(H5Enew_err_stack, FAIL);
+ H5E_t *new_stack=NULL; /* Pointer to the new error stack */
+ hid_t ret_value = FAIL;
- /* Allocate the stack header */
- if((new_stack=HDmalloc(sizeof(H5E_errstack_t)))==NULL)
- HGOTO_DONE(FAIL);
+ FUNC_ENTER (H5Ecreate, FAIL);
+ H5ECLEAR;
- /* Initialize the stack header */
- new_stack->stack_size=initial_stack_size;
- new_stack->stack_top=0;
- if((new_stack->err_stack=HDcalloc(initial_stack_size,sizeof(H5E_error_t)))==NULL)
- {
- HDfree(new_stack);
- HGOTO_DONE(FAIL);
- } /* end if */
- new_stack->push=H5E_store; /* Set the default error handler */
+ /* check args */
+ initial_stack_nelmts = MAX (10, MIN (initial_stack_nelmts, 1000));
- /* Get an atom for the error stack */
- ret_value=H5Aregister_atom(H5_ERR, new_stack);
+ /* Allocate the stack header */
+ new_stack = H5MM_xmalloc (sizeof(H5E_t));
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
+ /* Initialize the stack header */
+ new_stack->nelmts = initial_stack_nelmts;
+ new_stack->top = 0;
+ new_stack->stack = H5MM_xcalloc (initial_stack_nelmts, sizeof(H5E_error_t));
+ new_stack->push = H5E_push; /* Set the default error handler */
- } /* end if */
+ /* Get an atom for the error stack */
+ if ((ret_value = H5Aregister_atom (H5_ERR, new_stack))<0) {
+ HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL,
+ "unable to register error stack");
+ }
- /* Normal function cleanup */
-
- FUNC_LEAVE(ret_value);
-} /* H5Enew_err_stack */
+ FUNC_LEAVE (ret_value);
+}
/*--------------------------------------------------------------------------
NAME
- H5Edelete_err_stack -- Destroy an error stack
+ H5Eclose -- Destroy an error stack
USAGE
- intn H5Edelete_err_stack(err_stack);
- int32 err_stack; IN: Error stack to delete
+ herr_t H5Eclose (err_stack);
+ hid_t err_stack; IN: Error stack to delete
RETURNS
SUCCEED/FAIL
@@ -230,51 +222,108 @@ DESCRIPTION
Destroys an error stack, releasing memory allocated, etc.
--------------------------------------------------------------------------*/
-intn H5Edelete_err_stack(int32 err_stack)
+herr_t
+H5Eclose (hid_t estack_id)
{
- H5E_errstack_t *old_stack=NULL; /* Pointer to the new error stack */
- intn ret_value = SUCCEED;
-
- FUNC_ENTER(H5Edelete_err_stack, FAIL);
-
- /* Clear errors and check args and all the boring stuff. */
- if (H5Aatom_group(err_stack)!=H5_ERR)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error stack");
-
- /* Get the error stack to put the error on */
- if((old_stack=H5Aremove_atom(err_stack))==NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't remove atom");
-
- /* Clear the error descriptions and reset the stack top */
- for(; old_stack->stack_top>0; old_stack->stack_top--)
- {
- if (old_stack->err_stack[old_stack->stack_top-1].desc)
- {
- HDfree(old_stack->err_stack[old_stack->stack_top-1].desc);
- old_stack->err_stack[old_stack->stack_top-1].desc=NULL;
- } /* end if */
- } /* end if */
-
- HDfree(old_stack->err_stack);
- HDfree(old_stack);
-
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
-
- FUNC_LEAVE(ret_value);
-} /* H5Edelete_err_stack */
+ FUNC_ENTER (H5Eclose, FAIL);
+ H5ECLEAR;
+
+ /* check args */
+ if (H5_ERR!=H5Aatom_group (estack_id)) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an error stack");
+ }
+
+ /*
+ * Decrement the reference count. When it reaches zero the error stack
+ * will be freed.
+ */
+ H5A_dec_ref (estack_id);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Epush
+ *
+ * Purpose: Pushes a new error record onto error stack ESTACK_ID. The
+ * error has major and minor numbers MAJ_NUM and MIN_NUM, the
+ * name of a function where the error was detected, the name of
+ * the file where the error was detected, and the line within
+ * that file. An error description string is also passed to
+ * this function.
+ *
+ * The FUNCTION_NAME is copied (and possibly truncated) into a
+ * fixed length character buffer; the FILE_NAME is pointed to
+ * without copying it (we assume it's statically allocated from
+ * __FILE__); and the DESC argument is strdup'd.
+ *
+ * It is safe to call this function before the thread global
+ * error stack is initialized.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, December 12, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Epush (hid_t estack_id, H5E_major_t maj_num, H5E_minor_t min_num,
+ const char *function_name, const char *file_name, intn line,
+ const char *desc)
+{
+
+ H5E_t *estack = NULL; /* Ptr to the stack to put value on */
+
+ /*
+ * WARNING WARNING WARNING: We cannot call HERROR() from within this
+ * function if ESTACK_ID is the thread global error stack or else we may
+ * enter infinite recursion. Furthermore, we also cannot call any other
+ * HDF5 macro or function which might call HERROR(). HERROR() is called
+ * by HRETURN_ERROR() which could be called by FUNC_ENTER().
+ */
+
+ /*
+ * Clear the thread global error stack only if it isn't the error stack on
+ * which we're pushing the new error.
+ */
+ if (estack_id!=H5E_thrdid_g) H5ECLEAR;
+
+ /*
+ * check args, but don't call error functions if ESTACK_ID is the thread
+ * global error handler.
+ */
+ if (H5_ERR!=H5Aatom_group (estack_id) ||
+ NULL==(estack=H5Aatom_object (estack_id))) {
+ HRETURN (FAIL);
+ }
+ if (!function_name || !file_name || !desc) {
+ HRETURN (FAIL);
+ }
+ if (!estack->push) {
+ HRETURN (FAIL);
+ }
+
+ /* Push the new error. It must be safe to call the push function. */
+ if ((estack->push)(estack, maj_num, min_num, function_name, file_name,
+ line, desc)<0) {
+ HRETURN (FAIL);
+ }
+
+ return SUCCEED; /*don't use FUNC_LEAVE() here*/
+}
/*--------------------------------------------------------------------------
NAME
H5Eclear -- Clear an error stack for later error entries
USAGE
void H5Eclear(int32 err_hand)
- int32 err_hand; IN: The ID of the error stack to push the error onto.
+ int32 err_hand; IN: The ID of the error stack to push the error onto.
RETURNS
SUCCEED/FAIL
@@ -283,200 +332,275 @@ DESCRIPTION
--------------------------------------------------------------------------*/
herr_t
-H5Eclear (int32 err_hand)
+H5Eclear (hid_t estack_id)
{
- H5E_errstack_t *err_stack=NULL; /* Pointer to the error stack to put value on */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER (H5Eclear, FAIL);
-
- /* Get the error stack for this error handler, initialized earlier in H5Enew_err_stack */
- if (H5Aatom_group(err_hand)!=H5_ERR)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error stack");
-
- /* Get the error stack to put the error on */
- if((err_stack=H5Aatom_object(err_hand))==NULL)
- HGOTO_ERROR(H5E_BADATOM, H5E_BADATOM, FAIL, "not an error stack");
-
- /* Clear the error descriptions and reset the stack top */
- for(; err_stack->stack_top>0; err_stack->stack_top--)
- {
- if (err_stack->err_stack[err_stack->stack_top-1].desc)
- {
- HDfree(err_stack->err_stack[err_stack->stack_top-1].desc);
- err_stack->err_stack[err_stack->stack_top-1].desc=NULL;
- } /* end if */
- } /* end if */
-
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
-
- FUNC_LEAVE (ret_value);
-} /* H5Eclear */
-
-/*--------------------------------------------------------------------------
-NAME
- H5E_store -- Push an error value on an error stack
-USAGE
- void H5E_store(hdf_err_code_t err, const char *function_name, const char *file_name, intn line)
- hdf_err_code_t err; IN: The error code which occurred.
- const char *function_name; IN: Name of the function the error occurred within.
- const char *file_name; IN: Name of the file the error occurred within.
- intn line; IN: Line # in the file the error occurred on.
+ H5E_t *estack = NULL;
+
+ FUNC_ENTER (H5Eclear, FAIL);
+
+ /*
+ * Normally we would clear the thread error stack since we're entering an
+ * API function, but we have to be careful here to not get into an
+ * infinite recursion.
+ */
+ if (estack_id != H5E_thrdid_g) H5ECLEAR;
+
+ /* check args */
+ if (H5_ERR!=H5Aatom_group (estack_id) ||
+ NULL==(estack=H5Aatom_object (estack_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an error stack");
+ }
+
+ if (H5E_clear (estack)<0) {
+ HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL,
+ "unable to clear error stack");
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Eprint
+ *
+ * Purpose: Prints the current contents of error stack ESTACK_ID to the
+ * stream FILE.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, December 12, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Eprint (hid_t estack_id, FILE *file)
+{
+ H5E_t *estack = NULL;
-RETURNS
- SUCCESS/FAIL
-DESCRIPTION
- Pushes an error onto an error stack for this thread. (This is the default
- action when errors occur, but can be overridden by user's code)
-
---------------------------------------------------------------------------*/
+ FUNC_ENTER (H5Eprint, FAIL);
+ /*
+ * Don't clear the thread error stack if it's the one we're about to
+ * print.
+ */
+ if (estack_id!=H5E_thrdid_g) H5ECLEAR;
+
+ /* check args */
+ if (H5_ERR!=H5Aatom_group (estack_id) ||
+ NULL==(estack=H5Aatom_object (estack_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an error stack");
+ }
+ if (!file) file = stderr;
+
+ /* print it */
+ if (H5E_print (estack, file)<0) {
+ HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL,
+ "can't print error stack");
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_close
+ *
+ * Purpose: Frees resources associated with an error stack.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, December 12, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
herr_t
-H5E_store(int32 errid, H5E_major_t maj, H5E_minor_t min, const char *function_name, const char *file_name, intn line)
+H5E_close (H5E_t *estack)
{
- H5E_errstack_t *err_stack=NULL; /* Pointer to the error stack to put value on */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER(H5E_store, FAIL);
-
- /* Clear errors and check args and all the boring stuff. */
- H5Eclear(errid);
-
- /* Get the error stack to put the error on */
- if((err_stack=H5Aatom_object(errid))==NULL)
- HGOTO_ERROR(H5E_BADATOM, H5E_BADATOM, FAIL, "not an error stack");
-
- /* Check if we need to expand the stack */
- if(err_stack->stack_top>=err_stack->stack_size)
- {
- H5E_error_t *old_stack=err_stack->err_stack; /* in case realloc fails */
-
- /* Ask for new stack that's twice as large */
- if((err_stack->err_stack=HDrealloc(old_stack,2*err_stack->stack_size))==NULL)
- {
- err_stack->err_stack=old_stack;
- HGOTO_DONE(FAIL);
- } /* end if */
- err_stack->stack_size *= 2; /* increase the size of the stack */
- } /* end if */
-
- /* Push the error onto the error stack */
- err_stack->err_stack[err_stack->stack_top].maj=maj;
- err_stack->err_stack[err_stack->stack_top].min=min;
- HDstrncpy(err_stack->err_stack[err_stack->stack_top].function_name,function_name,MAX_FUNC_NAME_LEN);
- err_stack->err_stack[err_stack->stack_top].file_name=file_name;
- err_stack->err_stack[err_stack->stack_top].line=line;
-
- /* Increment the top of the error stack */
- err_stack->stack_top++;
-
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
+ FUNC_ENTER (H5E_close, FAIL);
+
+ /* check args */
+ assert (estack);
+
+ /* clear error stack, then free it */
+ H5E_clear (estack);
+ H5MM_xfree (estack->stack);
+ H5MM_xfree (estack);
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_clear
+ *
+ * Purpose: Clears an error stack but does not release the stack.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, December 12, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5E_clear (H5E_t *estack)
+{
+ int i;
+
+ FUNC_ENTER (H5E_clear, FAIL);
- FUNC_LEAVE (ret_value);
-} /* H5E_store */
+ /* check args */
+ assert (estack);
-/*--------------------------------------------------------------------------
-NAME
- H5Epush -- Push an error value on an error stack
-USAGE
- void H5Epush(hdf_err_code_t err, const char *function_name, const char *file_name, intn line)
- hdf_err_code_t err; IN: The error code which occurred.
- const char *function_name; IN: Name of the function the error occurred within.
- const char *file_name; IN: Name of the file the error occurred within.
- intn line; IN: Line # in the file the error occurred on.
+ /* Clear the error descriptions and reset the stack top */
+ for (i=0; i<estack->top; i++) {
+ H5MM_xfree (estack->stack[i].desc);
+ estack->stack[i].desc = NULL;
+ }
+ estack->top = 0;
-RETURNS
- SUCCEED/FAIL
-DESCRIPTION
- Pushes an error onto an error stack for this thread.
-
---------------------------------------------------------------------------*/
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_push
+ *
+ * Purpose: Push an error onto an error stack. The FUNCTION_NAME is
+ * copied (and possibly truncated) into the error record. The
+ * FILE_NAME pointer is used directly since we assume it came
+ * from the __FILE__ construct and is thus static data. The
+ * description, DESC, is strdup'd into the error record.
+ *
+ * Note: Warning: to prevent infinite recursivion this function must
+ * not call any other HDF5 function and especially not
+ * the HDF5 error handling macros.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, December 12, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
herr_t
-H5Epush(H5E_major_t maj, H5E_minor_t min, const char *function_name, const char *file_name, intn line)
+H5E_push (H5E_t *estack, H5E_major_t maj_num, H5E_minor_t min_num,
+ const char *function_name, const char *file_name, intn line,
+ const char *desc)
{
- H5E_errstack_t *err_stack=NULL; /* Pointer to the error stack to put value on */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER(H5Epush, FAIL);
-
- /* Clear errors and check args and all the boring stuff. */
- if (function_name==NULL || file_name==NULL || H5Aatom_group(thrderrid)!=H5_ERR)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "wrong arguments");
-
- /* Get the error stack to put the error on */
- if((err_stack=H5Aatom_object(thrderrid))==NULL)
- HGOTO_ERROR(H5E_BADATOM, H5E_BADATOM, FAIL, "not an error stack");
- (err_stack->push)(thrderrid, maj, min, function_name, file_name, line);
-
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
-
- FUNC_LEAVE (ret_value);
-} /* H5Epush */
-
-#ifdef H5_ERROR_DEBUG
-/*--------------------------------------------------------------------------
-NAME
- H5Eset_push -- Set the function to call when an error value is reported
-USAGE
- H5E_push_func_t H5Eset_push(H5E_push_func_t func)
- H5E_push_func_t func; IN: New function to call when an error occurs.
+ /* FUNC_ENTER (H5E_push, FAIL); -- can't do this here! */
+
+ /* check args */
+ assert (estack);
+ assert (function_name);
+ assert (file_name);
+
+ /* Check if we need to expand the stack */
+ if (estack->top >= estack->nelmts) {
+ /*
+ * Ask for new stack that's twice as large. Do not use hdf5 functions
+ * to allocate the memory!
+ */
+ estack->nelmts *= 2;
+ estack->stack = realloc (estack->stack,
+ estack->nelmts * sizeof(H5E_error_t));
+ assert (estack->stack);
+ }
-RETURNS
- The function pointer to the previous error function on success, NULL on
- failure.
-DESCRIPTION
- Changes the function which is called for errors on this thread. The thread
- ID is implicit, ie. this function must be called within each thread whose
- error function is to be changed.
-
---------------------------------------------------------------------------*/
-H5E_push_func_t H5Eset_push(H5E_push_func_t func)
+ /* Push the error onto the error stack */
+ estack->stack[estack->top].maj_num = maj_num;
+ estack->stack[estack->top].min_num = min_num;
+ HDstrncpy (estack->stack[estack->top].func_name, function_name,
+ MAX_FUNC_NAME);
+ estack->stack[estack->top].func_name[MAX_FUNC_NAME-1] = '\0';
+ estack->stack[estack->top].file_name = file_name;
+ estack->stack[estack->top].line = line;
+
+ /* strdup the description but don't use H5MM_xstrdup() */
+ estack->stack[estack->top].desc = malloc (strlen (desc) + 1);
+ assert (estack->stack[estack->top].desc);
+ strcpy (estack->stack[estack->top].desc, desc);
+
+ /* Increment the top of the error stack */
+ estack->top++;
+
+ return SUCCEED; /*don't use FUNC_LEAVE() here*/
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_print
+ *
+ * Purpose: Prints an error stack ESTACK to the stream FILE.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, December 12, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5E_print (H5E_t *estack, FILE *file)
{
- CONSTR(FUNC, "H5Eset_push"); /* For HERROR */
- H5E_errstack_t *err_stack=NULL; /* Pointer to the error stack to put value on */
- H5E_push_func_t ret_value = NULL;
-
- FUNC_ENTER(H5Eset_push, NULL);
-
- /* Clear errors and check args and all the boring stuff. */
- H5ECLEAR;
- if (func==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL);
-
- /* Get the error stack to put the error on */
- if((err_stack=H5Aatom_object(thrderrid))==NULL)
- HGOTO_ERROR(H5E_BADATOM, H5E_BADATOM, NULL);
-
- ret_value=err_stack->push;
- err_stack->push=func;
-
-done:
- if(ret_value == NULL)
- { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
+ intn i, j;
+ const char *maj_str = NULL;
+ const char *min_str = NULL;
+
+ FUNC_ENTER (H5E_print, FAIL);
- FUNC_LEAVE(ID_H5Eset_push, ret_value);
-} /* H5Eset_push */
-#endif /* H5_ERROR_DEBUG */
+ /* check args */
+ assert (estack);
+ assert (file);
+ if (0==estack->top) HRETURN (SUCCEED);
+
+ fprintf (file, "HDF5-DIAG: error stack:\n");
+ for (i=0; i<estack->top; i++) {
+
+ /* Find major and minor error strings */
+ for (j=0, maj_str="??"; j<NELMTS (H5E_major_mesg_g); j++) {
+ if (H5E_major_mesg_g[j].error_code==estack->stack[i].maj_num) {
+ maj_str = H5E_major_mesg_g[j].str;
+ break;
+ }
+ }
+ for (j=0, min_str="??"; j<NELMTS (H5E_minor_mesg_g); j++) {
+ if (H5E_minor_mesg_g[j].error_code==estack->stack[i].min_num) {
+ min_str = H5E_minor_mesg_g[j].str;
+ break;
+ }
+ }
+
+ /* Print error message */
+ fprintf (file, " #%03d: %s:%d in %s() error %02d/%02d: %s\n",
+ i, estack->stack[i].file_name, estack->stack[i].line,
+ estack->stack[i].func_name, estack->stack[i].maj_num,
+ estack->stack[i].min_num, estack->stack[i].desc);
+ fprintf (file, " %s (%s)\n", maj_str, min_str);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h
index 47d3631..8e809c4 100644
--- a/src/H5Eprivate.h
+++ b/src/H5Eprivate.h
@@ -36,7 +36,8 @@
Assume that func and file are both stored in static space, or at
least be not corrupted in the meanwhile. */
-#define HERROR(maj, min, str) H5Epush(maj, min, FUNC, __FILE__, __LINE__)
+#define HERROR(maj, min, str) H5Epush (H5E_thrdid_g, maj, min, \
+ FUNC, __FILE__, __LINE__, str)
/* HRETURN_ERROR macro, used to facilitate error reporting. Makes
same assumptions as HERROR. IN ADDITION, this macro causes
@@ -76,62 +77,67 @@
This macro is just a wrapper to clear the error stack with the thread
error ID */
-#define H5ECLEAR H5Eclear(thrderrid)
+#define H5ECLEAR H5Eclear(H5E_thrdid_g)
/* Maximum length of function name to push onto error stack */
-#define MAX_FUNC_NAME_LEN 32
+#define MAX_FUNC_NAME 32
/*
* error_messages is the list of error messages in the system, kept as
* error_code-message pairs.
*/
-typedef struct
- {
- H5E_major_t error_code;
- const char *str;
- }
-hdf_maj_error_messages_t;
+typedef struct H5E_major_mesg_t {
+ H5E_major_t error_code;
+ const char *str;
+} H5E_major_mesg_t;
+
+typedef struct H5E_minor_mesg_t {
+ H5E_minor_t error_code;
+ const char *str;
+} H5E_minor_mesg_t;
+
+/* Function pointer to report errors through */
+struct H5E_t; /*forward decl*/
+typedef herr_t (*H5E_push_t)(struct H5E_t *estack, H5E_major_t maj_num,
+ H5E_minor_t min_num, const char *function_name,
+ const char *file_name, intn line,
+ const char *desc);
-
-typedef struct
- {
- H5E_minor_t error_code;
- const char *str;
- }
-hdf_min_error_messages_t;
-
-
-/* We use a stack to hold the errors plus we keep track of the function,
- file and line where the error occurs. */
+/*
+ * We use a stack to hold the errors plus we keep track of the function, file
+ * and line where the error occurs.
+ */
/* the structure of the error stack element */
-typedef struct error_t
- {
- H5E_major_t maj; /* Major error number */
- H5E_minor_t min; /* Minor error number */
- char function_name[MAX_FUNC_NAME_LEN]; /* function where error occur */
- const char *file_name; /* file where error occur */
- intn line; /* line in file where error occurs */
- char *desc; /* optional supplied description */
- }
-H5E_error_t;
+typedef struct H5E_error_t {
+ H5E_major_t maj_num; /* Major error number */
+ H5E_minor_t min_num; /* Minor error number */
+ char func_name[MAX_FUNC_NAME]; /* function where error occur */
+ const char *file_name; /* file where error occur */
+ intn line; /* line in file where error occurs */
+ char *desc; /* optional supplied description */
+} H5E_error_t;
/* Structure to store error information for a thread */
-typedef struct errstack_t
- {
- uintn stack_size; /* Number of elements allocated in the stack */
- uintn stack_top; /* Offset of the next open stack element */
- H5E_error_t *err_stack; /* Pointer to the error stack */
- H5E_push_func_t push; /* Function to call when an error is to be reported */
- } H5E_errstack_t;
-
-
+typedef struct H5E_t {
+ uintn nelmts; /* Num elements allocated in the stack */
+ uintn top; /* Index of the next open stack element */
+ H5E_error_t *stack; /* Pointer to the error stack */
+ H5E_push_t push; /* Func that pushes new error on stack */
+} H5E_t;
/* Private global variables in H5E.c */
-extern int32 thrderrid; /* Thread-specific "global" error-handler ID */
+extern hid_t H5E_thrdid_g; /* Thread-specific "global" error-handler ID */
extern hbool_t install_atexit; /* Whether to install the atexit routine */
-/* Private functions in H5E.c */
-herr_t H5E_store(int32 errid, H5E_major_t maj, H5E_minor_t min, const char *function_name, const char *file_name, intn line);
+herr_t H5E_close (H5E_t *estack);
+herr_t H5E_clear (H5E_t *estack);
+herr_t H5E_print (H5E_t *estack, FILE *file);
+herr_t H5E_push (H5E_t *estack, H5E_major_t maj_num, H5E_minor_t min_num,
+ const char *function_name, const char *file_name, intn line,
+ const char *desc);
+
+
+
#endif
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index 57f40e5..f11a900 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -19,8 +19,11 @@
#ifndef _H5Epublic_H
#define _H5Epublic_H
+#include <stdio.h> /*FILE arg of H5Eprint() */
+
/* Public headers needed by this file */
#include <H5public.h>
+#include <H5Apublic.h>
/*
* Declare an enumerated type which holds all the valid major HDF error codes.
@@ -114,25 +117,18 @@ typedef enum H5E_minor_t {
H5E_LINK /* Link count failure */
} H5E_minor_t;
-/* Function pointer to report errors through */
-typedef herr_t (*H5E_push_func_t)(int32 errid, H5E_major_t maj,
- H5E_minor_t min, const char *function_name,
- const char *file_name, intn line);
#ifdef __cplusplus
extern "C" {
#endif
-/* Functions in H5E.c */
-int32 H5Enew_err_stack (uintn initial_stack_size);
-intn H5Edelete_err_stack (int32 err_hand);
-#ifdef H5_ERROR_DEBUG
-H5E_push_func_t H5Eset_push (H5E_push_func_t func);
-#endif
-herr_t H5Epush (H5E_major_t maj, H5E_minor_t min, const char *function_name,
- const char *file_name, intn line);
-herr_t H5Eclear(int32 err_hand);
-void H5E_term_interface(void);
+hid_t H5Ecreate (uintn initial_stack_nelmts);
+herr_t H5Eclose (hid_t estack_id);
+herr_t H5Epush (hid_t estack_id, H5E_major_t maj_num, H5E_minor_t min_num,
+ const char *function_name, const char *file_name, intn line,
+ const char *desc);
+herr_t H5Eclear (hid_t estack_id);
+herr_t H5Eprint (hid_t estack_id, FILE *file);
#ifdef __cplusplus
}
diff --git a/src/H5F.c b/src/H5F.c
index fff101c..af3892b 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -792,16 +792,6 @@ H5F_open (const H5F_low_class_t *type, const char *name, uintn flags,
}
/*
- * All addresses are relative to a base address. Eventually, the base
- * address will be able to be set independently of the boot block
- * address, but for now, all addresses are relative to the beginning of
- * the boot block. Anything before the base address is assumed to be
- * user-defined data.
- */
- f->shared->base_addr = f->shared->boot_addr;
- f->shared->create_parms.userblock_size=f->shared->base_addr.offset;
-
- /*
* Decode the fixed size part of the boot block. For each of the
* version parameters, check that the library is able to handle that
* version.
@@ -879,9 +869,10 @@ H5F_open (const H5F_low_class_t *type, const char *name, uintn flags,
assert (p-buf == fixed_size);
/* Read the variable length part of the boot block... */
- variable_size = H5F_SIZEOF_ADDR (f) + /*global small obj heap*/
+ variable_size = H5F_SIZEOF_ADDR (f) + /*base address*/
+ H5F_SIZEOF_ADDR (f) + /*global small obj heap*/
H5F_SIZEOF_ADDR (f) + /*global free list addr*/
- H5F_SIZEOF_SIZE (f) + /*logical file size*/
+ H5F_SIZEOF_ADDR (f) + /*logical file size*/
H5G_SIZEOF_ENTRY (f);
assert (variable_size <= sizeof buf);
addr1 = f->shared->boot_addr;
@@ -892,6 +883,7 @@ H5F_open (const H5F_low_class_t *type, const char *name, uintn flags,
}
p = buf;
+ H5F_addr_decode (f, &p, &(f->shared->base_addr));
H5F_addr_decode (f, &p, &(f->shared->smallobj_addr));
H5F_addr_decode (f, &p, &(f->shared->freespace_addr));
H5F_addr_decode (f, &p, &(f->shared->hdf5_eof));
@@ -899,6 +891,12 @@ H5F_open (const H5F_low_class_t *type, const char *name, uintn flags,
HGOTO_ERROR (H5E_FILE, H5E_CANTOPENFILE, NULL,
"can't read root symbol entry");
}
+
+ /*
+ * The userdefined data is the area of the file before the base
+ * address.
+ */
+ f->shared->create_parms.userblock_size=f->shared->base_addr.offset;
}
/*
@@ -1205,6 +1203,7 @@ H5F_flush (H5F_t *f, hbool_t invalidate)
UINT16ENCODE (p, f->shared->create_parms.sym_leaf_k);
UINT16ENCODE (p, f->shared->create_parms.btree_k[H5B_SNODE_ID]);
UINT32ENCODE (p, f->shared->consist_flags);
+ H5F_addr_encode (f, &p, &(f->shared->base_addr));
H5F_addr_encode (f, &p, &(f->shared->smallobj_addr));
H5F_addr_encode (f, &p, &(f->shared->freespace_addr));
H5F_addr_encode (f, &p, &(f->shared->hdf5_eof));
diff --git a/src/H5Fstdio.c b/src/H5Fstdio.c
index b610a7a..169e3e2 100644
--- a/src/H5Fstdio.c
+++ b/src/H5Fstdio.c
@@ -103,7 +103,7 @@ H5F_stdio_open (const char *name, uintn flags, H5F_search_t *key/*out*/)
lf->u.stdio.op = H5F_OP_SEEK;
lf->u.stdio.cur = 0;
H5F_addr_reset (&(lf->eof));
- if (fseek (lf->u.stdio.f, 0, SEEK_END)<=0) {
+ if (fseek (lf->u.stdio.f, 0, SEEK_END)<0) {
lf->u.stdio.op = H5F_OP_UNKNOWN;
} else {
H5F_addr_inc (&(lf->eof), ftell (lf->u.stdio.f));
diff --git a/src/H5H.c b/src/H5H.c
index 62aedc3..0cc8477 100644
--- a/src/H5H.c
+++ b/src/H5H.c
@@ -27,6 +27,7 @@
#define H5H_FREE_NULL 1 /*end of free list on disk */
#define PABLO_MASK H5H_mask
+#define H5H_ALIGN(X) (((X)+7)&~0x03) /*align on 8-byte boundary */
typedef struct H5H_free_t {
size_t offset; /*offset of free block */
@@ -113,6 +114,7 @@ H5H_create (H5F_t *f, H5H_type_t heap_type, size_t size_hint,
if (size_hint && size_hint<H5H_SIZEOF_FREE(f)) {
size_hint = H5H_SIZEOF_FREE(f);
}
+ size_hint = H5H_ALIGN (size_hint);
/* allocate file version */
total_size = H5H_SIZEOF_HDR(f) + size_hint;
@@ -547,7 +549,7 @@ H5H_insert (H5F_t *f, const haddr_t *addr, size_t buf_size, const void *buf)
H5H_t *heap=NULL;
H5H_free_t *fl=NULL, *max_fl=NULL;
size_t offset = 0;
- size_t old_size, need_more;
+ size_t need_size, old_size, need_more;
hbool_t found;
#ifndef NDEBUG
static nmessages = 0;
@@ -569,18 +571,25 @@ H5H_insert (H5F_t *f, const haddr_t *addr, size_t buf_size, const void *buf)
heap->dirty += 1;
/*
+ * In order to keep the free list descriptors aligned on word boundaries,
+ * whatever that might mean, we round the size up to the next multiple of
+ * a word.
+ */
+ need_size = H5H_ALIGN (buf_size);
+
+ /*
* Look for a free slot large enough for this object and which would
* leave zero or at least H5G_SIZEOF_FREE bytes left over.
*/
for (fl=heap->freelist,found=FALSE; fl; fl=fl->next) {
- if (fl->size>buf_size && fl->size-buf_size>=H5H_SIZEOF_FREE(f)) {
+ if (fl->size>need_size && fl->size-need_size>=H5H_SIZEOF_FREE(f)) {
/* a bigger free block was found */
offset = fl->offset;
- fl->offset += buf_size;
- fl->size -= buf_size;
+ fl->offset += need_size;
+ fl->size -= need_size;
found = TRUE;
break;
- } else if (fl->size==buf_size) {
+ } else if (fl->size==need_size) {
/* free block of exact size found */
offset = fl->offset;
fl = H5H_remove_free (heap, fl);
@@ -601,15 +610,15 @@ H5H_insert (H5F_t *f, const haddr_t *addr, size_t buf_size, const void *buf)
*/
if (!found) {
- need_more = MAX3 (buf_size, heap->mem_alloc, H5H_SIZEOF_FREE(f));
+ need_more = MAX3 (need_size, heap->mem_alloc, H5H_SIZEOF_FREE(f));
if (max_fl && max_fl->offset+max_fl->size==heap->mem_alloc) {
/*
* Increase the size of the maximum free block.
*/
offset = max_fl->offset;
- max_fl->offset += buf_size;
- max_fl->size += need_more - buf_size;
+ max_fl->offset += need_size;
+ max_fl->size += need_more - need_size;
if (max_fl->size < H5H_SIZEOF_FREE(f)) {
#ifndef NDEBUG
@@ -631,18 +640,18 @@ H5H_insert (H5F_t *f, const haddr_t *addr, size_t buf_size, const void *buf)
* take some space out of it right away.
*/
offset = heap->mem_alloc;
- if (need_more-buf_size >= H5H_SIZEOF_FREE(f)) {
+ if (need_more-need_size >= H5H_SIZEOF_FREE(f)) {
fl = H5MM_xmalloc (sizeof(H5H_free_t));
- fl->offset = heap->mem_alloc + buf_size;
- fl->size = need_more - buf_size;
+ fl->offset = heap->mem_alloc + need_size;
+ fl->size = need_more - need_size;
fl->prev = NULL;
fl->next = heap->freelist;
if (heap->freelist) heap->freelist->prev = fl;
heap->freelist = fl;
#ifndef NDEBUG
- } else if (need_more>buf_size) {
+ } else if (need_more>need_size) {
fprintf (stderr, "H5H_insert: lost %lu bytes at line %d\n",
- (unsigned long)(need_more-buf_size), __LINE__);
+ (unsigned long)(need_more-need_size), __LINE__);
if (0==nmessages++) {
fprintf (stderr, "Messages from H5H_insert() will go away "
"when assertions are turned off.\n");
diff --git a/src/H5P.c b/src/H5P.c
index 5171c01..8e3651e 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -268,19 +268,22 @@ H5P_copy (const H5P_t *src)
case H5P_SIMPLE:
if (dst->u.simple.size) {
- dst->u.simple.size = H5MM_xmalloc (dst->u.simple.rank * sizeof(intn));
+ dst->u.simple.size = H5MM_xmalloc (dst->u.simple.rank *
+ sizeof(dst->u.simple.size[0]));
for (i=0; i<dst->u.simple.rank; i++) {
dst->u.simple.size[i] = src->u.simple.size[i];
}
}
if (dst->u.simple.max) {
- dst->u.simple.max = H5MM_xmalloc (dst->u.simple.rank * sizeof(intn));
+ dst->u.simple.max = H5MM_xmalloc (dst->u.simple.rank *
+ sizeof(dst->u.simple.max[0]));
for (i=0; i<dst->u.simple.rank; i++) {
dst->u.simple.max[i] = src->u.simple.max[i];
}
}
if (dst->u.simple.perm) {
- dst->u.simple.perm = H5MM_xmalloc (dst->u.simple.rank * sizeof(intn));
+ dst->u.simple.perm = H5MM_xmalloc (dst->u.simple.rank *
+ sizeof(dst->u.simple.perm[0]));
for (i=0; i<dst->u.simple.rank; i++) {
dst->u.simple.perm[i] = src->u.simple.perm[i];
}
@@ -811,7 +814,7 @@ done:
herr_t H5Pset_space(sid, rank, dims)
hid_t sid; IN: Dataspace object to query
intn rank; IN: # of dimensions for the dataspace
- const intn *dims; IN: Size of each dimension for the dataspace
+ const size_t *dims; IN: Size of each dimension for the dataspace
RETURNS
SUCCEED/FAIL
DESCRIPTION
@@ -823,7 +826,8 @@ done:
expand. Currently, only the first dimension in the array (the slowest) may
be unlimited in size.
--------------------------------------------------------------------------*/
-herr_t H5Pset_space(hid_t sid, intn rank, const intn *dims)
+herr_t
+H5Pset_space (hid_t sid, intn rank, const size_t *dims)
{
H5P_t *space=NULL; /* dataspace to modify */
intn u; /* local counting variable */
@@ -886,8 +890,8 @@ herr_t H5Pset_space(hid_t sid, intn rank, const intn *dims)
/* Set the rank and copy the dims */
space->u.simple.rank=rank;
- space->u.simple.size = H5MM_xcalloc (sizeof(intn), rank);
- HDmemcpy(space->u.simple.size,dims,sizeof(intn)*rank);
+ space->u.simple.size = H5MM_xcalloc (rank, sizeof(size_t));
+ HDmemcpy(space->u.simple.size,dims,sizeof(size_t)*rank);
/* check if there are unlimited dimensions and create the maximum dims array */
for(u=0; u<rank; u++)
@@ -897,8 +901,8 @@ herr_t H5Pset_space(hid_t sid, intn rank, const intn *dims)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL,
"unlimited dimensions not in the lowest "
"dimensionality");
- space->u.simple.max = H5MM_xcalloc (sizeof(intn),rank);
- HDmemcpy(space->u.simple.max,dims,sizeof(intn)*rank);
+ space->u.simple.max = H5MM_xcalloc (rank, sizeof(size_t));
+ HDmemcpy(space->u.simple.max,dims,sizeof(size_t)*rank);
space->u.simple.dim_flags|=H5P_VALID_MAX;
break;
} /* end if */
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 6cffdea..cc87ace 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -47,7 +47,7 @@ intn H5Pget_ndims (hid_t space_id);
intn H5Pget_dims (hid_t space_id, size_t dims[]);
hbool_t H5Pis_simple(hid_t space_id);
-herr_t H5Pset_space(hid_t space_id, intn rank, const intn *dims);
+herr_t H5Pset_space(hid_t space_id, intn rank, const size_t *dims);
#ifdef __cplusplus
}
diff --git a/src/H5T.c b/src/H5T.c
index 2618f14..414349a 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -139,74 +139,140 @@ H5Tcreate (H5T_class_t type, size_t size)
/*-------------------------------------------------------------------------
- * Function: H5T_create
+ * Function: H5Tcopy
*
- * Purpose: Creates a new data type and initializes it to reasonable
- * values. The new data type is SIZE bytes and an instance of
- * the class TYPE.
+ * Purpose: Copies a data type. The resulting data type is not locked.
+ * The data type should be closed when no longer needed by
+ * calling H5Tclose().
*
- * Return: Success: Pointer to the new type.
+ * Return: Success: The ID of a new data type.
*
- * Failure: NULL
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * Friday, December 5, 1997
+ * Tuesday, December 9, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-H5T_t *
-H5T_create (H5T_class_t type, size_t size)
+hid_t
+H5Tcopy (hid_t type_id)
{
H5T_t *dt = NULL;
+ H5T_t *new_dt = NULL;
+ hid_t ret_value = FAIL;
- FUNC_ENTER (H5T_create, NULL);
+ FUNC_ENTER (H5Tcopy, FAIL);
+ H5ECLEAR;
- assert (size>0);
+ /* 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");
+ }
- switch (type) {
- case H5T_FIXED:
- /* Default type is a native `int' */
- if (NULL==(dt=H5T_copy (H5Aatom_object (H5T_NATIVE_INT)))) {
- HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL,
- "can't derive type from native int");
- }
- break;
+ /* copy */
+ if (NULL==(new_dt = H5T_copy (dt))) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't copy");
+ }
- case H5T_FLOAT:
- /* Default type is a native `double' */
- if (NULL==(dt=H5T_copy (H5Aatom_object (H5T_NATIVE_DOUBLE)))) {
- HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL,
- "can't derive type from native double");
- }
- break;
+ /* atomize result */
+ if ((ret_value=H5Aregister_atom (H5_DATATYPE, new_dt))<0) {
+ H5T_close (new_dt);
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
+ "can't register data type atom");
+ }
- case H5T_DATE:
- case H5T_STRING:
- case H5T_BITFIELD:
- case H5T_OPAQUE:
- assert ("not implemented yet" && 0);
- HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, NULL,
- "not implemented yet");
+ FUNC_LEAVE (ret_value);
+}
- case H5T_COMPOUND:
- dt = H5MM_xcalloc (1, sizeof(H5T_t));
- dt->type = type;
- break;
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tclose
+ *
+ * Purpose: Frees a data type and all associated memory.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, December 9, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tclose (hid_t type_id)
+{
+ H5T_t *dt = NULL;
+
+ FUNC_ENTER (H5Tclose, FAIL);
+ H5ECLEAR;
- default:
- HRETURN_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, NULL,
- "unknown data type class");
+ /* 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");
+ }
+ if (dt->locked) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "predefined data type");
}
- dt->size = size;
- FUNC_LEAVE (dt);
+ /* When the reference count reaches zero the resources are freed */
+ if (H5A_dec_ref (type_id)<0) {
+ HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id");
+ }
+
+ FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5Tget_num_members
+ * Function: H5Tequal
+ *
+ * Purpose: Determines if two data types are equal.
+ *
+ * Return: Success: TRUE if equal, FALSE if unequal
+ *
+ * Failure: FAIL
+ *
+ * Errors:
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, December 10, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5Tequal (hid_t type1_id, hid_t type2_id)
+{
+ const H5T_t *dt1 = NULL;
+ const H5T_t *dt2 = NULL;
+ hbool_t ret_value = FAIL;
+
+ FUNC_ENTER (H5Tequal, FAIL);
+
+ /* check args */
+ if (H5_DATATYPE!=H5Aatom_group (type1_id) ||
+ NULL==(dt1=H5Aatom_object (type1_id)) ||
+ H5_DATATYPE!=H5Aatom_group (type2_id) ||
+ NULL==(dt2=H5Aatom_object (type2_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+
+ ret_value = (0==H5T_cmp (dt1, dt2));
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tget_nmembers
*
* Purpose: Determines how many members compound data type TYPE_ID has.
*
@@ -225,7 +291,7 @@ H5T_create (H5T_class_t type, size_t size)
*-------------------------------------------------------------------------
*/
intn
-H5Tget_num_members (hid_t type_id)
+H5Tget_nmembers (hid_t type_id)
{
H5T_t *dt = NULL;
@@ -278,7 +344,6 @@ H5Tget_class (hid_t type_id)
FUNC_LEAVE (dt->type);
}
-
/*-------------------------------------------------------------------------
* Function: H5Tget_size
@@ -321,36 +386,6 @@ H5Tget_size (hid_t type_id)
/*-------------------------------------------------------------------------
- * Function: H5T_get_size
- *
- * Purpose: Determines the total size of a data type in bytes.
- *
- * Return: Success: Size of the data type in bytes. The size of
- * the data type is the size of an instance of
- * that data type.
- *
- * Failure: 0 (valid data types are never zero size)
- *
- * Programmer: Robb Matzke
- * Tuesday, December 9, 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-size_t
-H5T_get_size (const H5T_t *dt)
-{
- FUNC_ENTER (H5T_get_size, 0);
-
- /* check args */
- assert (dt);
-
- FUNC_LEAVE (dt->size);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5Tinsert_member
*
* Purpose: Adds another member to the compound data type PARENT_ID. The
@@ -414,116 +449,83 @@ H5Tinsert_member (hid_t parent_id, const char *name, off_t offset,
FUNC_LEAVE (SUCCEED);
}
-
+
+
/*-------------------------------------------------------------------------
- * Function: H5T_insert_member
- *
- * 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
- * instance of PARENT will have the member begin at byte offset
- * OFFSET from the beginning.
- *
- * Return: Success: SUCCEED
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * Monday, December 8, 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
+ * API functions are above; library-private functions are below...
+ *-------------------------------------------------------------------------
*/
-herr_t
-H5T_insert_member (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);
- /* check args */
- assert (parent && H5T_COMPOUND==parent->type);
- assert (!parent->locked);
- assert (member && H5T_COMPOUND!=member->type);
- assert (name && *name);
- /* Does NAME already exist in PARENT? */
- for (i=0; i<parent->u.compnd.nmembs; i++) {
- if (!HDstrcmp (parent->u.compnd.memb[i].name, name)) {
- HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINSERT, FAIL,
- "member name is not unique");
- }
- }
- /* Increase member array if necessary */
- if (parent->u.compnd.nmembs>=parent->u.compnd.nalloc) {
- parent->u.compnd.nalloc += H5T_COMPND_INC;
- parent->u.compnd.memb = H5MM_xrealloc (parent->u.compnd.memb,
- (parent->u.compnd.nalloc*
- sizeof(H5T_member_t)));
- }
- /* Add member to end of member array */
- 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*/
-
- tmp = H5T_copy (member);
- parent->u.compnd.memb[i].type = *tmp;
- H5MM_xfree (tmp);
- FUNC_LEAVE (SUCCEED);
-}
/*-------------------------------------------------------------------------
- * Function: H5Tcopy
+ * Function: H5T_create
*
- * Purpose: Copies a data type. The resulting data type is not locked.
+ * Purpose: Creates a new data type and initializes it to reasonable
+ * values. The new data type is SIZE bytes and an instance of
+ * the class TYPE.
*
- * Return: Success: The ID of a new data type.
+ * Return: Success: Pointer to the new type.
*
- * Failure: FAIL
+ * Failure: NULL
*
* Programmer: Robb Matzke
- * Tuesday, December 9, 1997
+ * Friday, December 5, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-hid_t
-H5Tcopy (hid_t type_id)
+H5T_t *
+H5T_create (H5T_class_t type, size_t size)
{
H5T_t *dt = NULL;
- H5T_t *new_dt = NULL;
- hid_t ret_value = FAIL;
- FUNC_ENTER (H5Tcopy, FAIL);
- H5ECLEAR;
+ FUNC_ENTER (H5T_create, NULL);
- /* 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");
- }
+ assert (size>0);
- /* copy */
- if (NULL==(new_dt = H5T_copy (dt))) {
- HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't copy");
- }
+ switch (type) {
+ case H5T_FIXED:
+ /* Default type is a native `int' */
+ if (NULL==(dt=H5T_copy (H5Aatom_object (H5T_NATIVE_INT)))) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL,
+ "can't derive type from native int");
+ }
+ break;
- /* atomize result */
- if ((ret_value=H5Aregister_atom (H5_DATATYPE, new_dt))<0) {
- H5T_close (new_dt);
- HRETURN_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
- "can't register data type atom");
+ case H5T_FLOAT:
+ /* Default type is a native `double' */
+ if (NULL==(dt=H5T_copy (H5Aatom_object (H5T_NATIVE_DOUBLE)))) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL,
+ "can't derive type from native double");
+ }
+ break;
+
+ case H5T_DATE:
+ case H5T_STRING:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ assert ("not implemented yet" && 0);
+ HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, NULL,
+ "not implemented yet");
+
+ case H5T_COMPOUND:
+ dt = H5MM_xcalloc (1, sizeof(H5T_t));
+ dt->type = type;
+ break;
+
+ default:
+ HRETURN_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, NULL,
+ "unknown data type class");
}
- FUNC_LEAVE (ret_value);
+ dt->size = size;
+ FUNC_LEAVE (dt);
}
@@ -577,7 +579,7 @@ H5T_copy (const H5T_t *old_dt)
/*-------------------------------------------------------------------------
- * Function: H5Tclose
+ * Function: H5T_close
*
* Purpose: Frees a data type and all associated memory.
*
@@ -586,32 +588,31 @@ H5T_copy (const H5T_t *old_dt)
* Failure: FAIL
*
* Programmer: Robb Matzke
- * Tuesday, December 9, 1997
+ * Monday, December 8, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
-H5Tclose (hid_t type_id)
+H5T_close (H5T_t *dt)
{
- H5T_t *dt = NULL;
+ intn i;
- FUNC_ENTER (H5Tclose, FAIL);
- H5ECLEAR;
+ FUNC_ENTER (H5T_close, FAIL);
- /* 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");
- }
- if (dt->locked) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "predefined data type");
- }
+ assert (dt);
+ assert (!dt->locked);
- /* When the reference count reaches zero the resources are freed */
- if (H5A_dec_ref (type_id)<0) {
- HRETURN_ERROR (H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id");
+ if (dt && H5T_COMPOUND==dt->type) {
+ for (i=0; i<dt->u.compnd.nmembs; i++) {
+ H5MM_xfree (dt->u.compnd.memb[i].name);
+ }
+ H5MM_xfree (dt->u.compnd.memb);
+ H5MM_xfree (dt);
+
+ } else if (dt) {
+ H5MM_xfree (dt);
}
FUNC_LEAVE (SUCCEED);
@@ -619,85 +620,96 @@ H5Tclose (hid_t type_id)
/*-------------------------------------------------------------------------
- * Function: H5T_close
+ * Function: H5T_get_size
*
- * Purpose: Frees a data type and all associated memory.
+ * Purpose: Determines the total size of a data type in bytes.
*
- * Return: Success: SUCCEED
+ * Return: Success: Size of the data type in bytes. The size of
+ * the data type is the size of an instance of
+ * that data type.
*
- * Failure: FAIL
+ * Failure: 0 (valid data types are never zero size)
*
* Programmer: Robb Matzke
- * Monday, December 8, 1997
+ * Tuesday, December 9, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5T_close (H5T_t *dt)
+size_t
+H5T_get_size (const H5T_t *dt)
{
- intn i;
-
- FUNC_ENTER (H5T_close, FAIL);
+ FUNC_ENTER (H5T_get_size, 0);
+ /* check args */
assert (dt);
- assert (!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);
- }
- H5MM_xfree (dt->u.compnd.memb);
- H5MM_xfree (dt);
-
- } else if (dt) {
- H5MM_xfree (dt);
- }
-
- FUNC_LEAVE (SUCCEED);
+ FUNC_LEAVE (dt->size);
}
-
/*-------------------------------------------------------------------------
- * Function: H5Tequal
+ * Function: H5T_insert_member
*
- * Purpose: Determines if two data types are equal.
+ * 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
+ * instance of PARENT will have the member begin at byte offset
+ * OFFSET from the beginning.
*
- * Return: Success: TRUE if equal, FALSE if unequal
+ * Return: Success: SUCCEED
*
* Failure: FAIL
*
- * Errors:
- *
* Programmer: Robb Matzke
- * Wednesday, December 10, 1997
+ * Monday, December 8, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-hbool_t
-H5Tequal (hid_t type1_id, hid_t type2_id)
+herr_t
+H5T_insert_member (H5T_t *parent, const char *name, off_t offset,
+ const H5T_t *member)
{
- const H5T_t *dt1 = NULL;
- const H5T_t *dt2 = NULL;
- hbool_t ret_value = FAIL;
+ intn i;
+ H5T_t *tmp = NULL;
- FUNC_ENTER (H5Tequal, FAIL);
+ FUNC_ENTER (H5T_insert_member, FAIL);
/* check args */
- if (H5_DATATYPE!=H5Aatom_group (type1_id) ||
- NULL==(dt1=H5Aatom_object (type1_id)) ||
- H5_DATATYPE!=H5Aatom_group (type2_id) ||
- NULL==(dt2=H5Aatom_object (type2_id))) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ assert (parent && H5T_COMPOUND==parent->type);
+ assert (!parent->locked);
+ assert (member && H5T_COMPOUND!=member->type);
+ assert (name && *name);
+
+ /* Does NAME already exist in PARENT? */
+ for (i=0; i<parent->u.compnd.nmembs; i++) {
+ if (!HDstrcmp (parent->u.compnd.memb[i].name, name)) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINSERT, FAIL,
+ "member name is not unique");
+ }
}
- ret_value = (0==H5T_cmp (dt1, dt2));
+ /* Increase member array if necessary */
+ if (parent->u.compnd.nmembs>=parent->u.compnd.nalloc) {
+ parent->u.compnd.nalloc += H5T_COMPND_INC;
+ parent->u.compnd.memb = H5MM_xrealloc (parent->u.compnd.memb,
+ (parent->u.compnd.nalloc*
+ sizeof(H5T_member_t)));
+ }
- FUNC_LEAVE (ret_value);
+ /* Add member to end of member array */
+ 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*/
+
+ tmp = H5T_copy (member);
+ parent->u.compnd.memb[i].type = *tmp;
+ H5MM_xfree (tmp);
+
+ FUNC_LEAVE (SUCCEED);
}
@@ -778,6 +790,7 @@ H5T_cmp (const H5T_t *dt1, const H5T_t *dt2)
}
#ifndef NDEBUG
+ /* I don't quite trust the code above yet :-) --RPM */
for (i=0; i<dt1->u.compnd.nmembs; i++) {
assert (HDstrcmp (dt1->u.compnd.memb[idx1[i]].name,
dt1->u.compnd.memb[idx1[i+1]].name));
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index f1bbe9e..e2c1163 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -69,7 +69,7 @@ typedef enum H5T_cset_t {
typedef enum H5T_str_t {
H5T_STR_ERROR =-1, /*error */
H5T_STR_NULL =0, /*pad with null term like in C */
- H5T_STR_SPACE =1, /*pad with spaces like in Fortran */
+ H5T_STR_SPACE =1 /*pad with spaces like in Fortran */
} H5T_str_t;
@@ -101,7 +101,7 @@ hbool_t H5Tequal (hid_t type1_id, hid_t type2_id);
H5T_class_t H5Tget_class (hid_t type_id);
size_t H5Tget_size (hid_t type_id);
-intn H5Tget_num_members (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);
diff --git a/src/H5detect.c b/src/H5detect.c
index be77339..43464c4 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -270,7 +270,7 @@ print_results (int nd, detected_t *d) {
/* Include files */
printf ("\
-#define H5T_PACKAGE /*suppress error about including H5Tpkg.h*/
+#define H5T_PACKAGE /*suppress error about including H5Tpkg.h*/\n\
\n\
#include <H5private.h>\n\
#include <H5Eprivate.h>\n\