From e615fc7a982c1817cf7d4c24adf9323604692310 Mon Sep 17 00:00:00 2001 From: Robb Matzke Date: Tue, 16 Dec 1997 16:08:26 -0500 Subject: [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. --- src/H5.c | 4 +- src/H5B.c | 2 +- src/H5C.c | 5 +- src/H5Cpublic.h | 2 +- src/H5E.c | 792 ++++++++++++++++++++++++++++++++----------------------- src/H5Eprivate.h | 90 ++++--- src/H5Epublic.h | 24 +- src/H5F.c | 23 +- src/H5Fstdio.c | 2 +- src/H5H.c | 35 ++- src/H5P.c | 22 +- src/H5Ppublic.h | 2 +- src/H5T.c | 447 ++++++++++++++++--------------- src/H5Tpublic.h | 4 +- src/H5detect.c | 2 +- 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_MAX) { +#ifndef NDEBUG + group>=H5_TEMPLATE_MAX || +#endif + group /* Generic Functions */ -#include /* Atoms */ -#include /* Private error routines */ +#include /* Generic Functions */ +#include /* Atoms */ +#include /* Private error routines */ +#include /* 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; itop; 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; itop; i++) { + + /* Find major and minor error strings */ + for (j=0, maj_str="??"; jstack[i].maj_num) { + maj_str = H5E_major_mesg_g[j].str; + break; + } + } + for (j=0, min_str="??"; jstack[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 /*FILE arg of H5Eprint() */ + /* Public headers needed by this file */ #include +#include /* * 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_hintdirty += 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; iu.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; iu.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; iu.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; uu.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; iu.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; iu.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; iu.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; iu.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; iu.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 \n\ #include \n\ -- cgit v0.12