summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2003-07-18 01:46:40 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2003-07-18 01:46:40 (GMT)
commit8dadcdb1016ee6ea9399ac308ab72993eb5329dc (patch)
treee58c7ae836bd9b18902d609e26964282101d2601
parent528a2d03e698db6352b30f99ca6c3ec53d29e701 (diff)
downloadhdf5-8dadcdb1016ee6ea9399ac308ab72993eb5329dc.zip
hdf5-8dadcdb1016ee6ea9399ac308ab72993eb5329dc.tar.gz
hdf5-8dadcdb1016ee6ea9399ac308ab72993eb5329dc.tar.bz2
[svn-r7241] Purpose: Gradual checkin for error API
Platforms tested: h5committest, RH 8 Misc. update:
-rw-r--r--src/H5E.c587
-rw-r--r--src/H5Eprivate.h11
-rw-r--r--src/H5Epublic.h9
-rw-r--r--test/errors.c155
4 files changed, 713 insertions, 49 deletions
diff --git a/src/H5E.c b/src/H5E.c
index 2e76649..acc4071 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -275,6 +275,8 @@ void *H5E_auto_data_g = NULL;
static herr_t H5E_init_interface (void);
#ifndef NEW_ERR
static int H5E_close_msg_cb(void *obj_ptr, hid_t obj_id, void *key);
+static herr_t H5E_walk_cb_new(int n, H5E_error_t_new *err_desc, void *client_data);
+static htri_t H5E_same_class(H5E_cls_t *cls);
#endif /* NEW_ERR */
static herr_t H5E_walk_cb (int n, H5E_error_t *err_desc, void *client_data);
@@ -527,12 +529,12 @@ H5E_unregister_class(H5E_cls_t *cls)
if(cls) {
if(cls->cls_name)
- H5MM_xfree(cls->cls_name);
+ H5MM_xfree((void*)cls->cls_name);
if(cls->lib_name)
- H5MM_xfree(cls->lib_name);
+ H5MM_xfree((void*)cls->lib_name);
if(cls->lib_vers)
- H5MM_xfree(cls->lib_vers);
- H5MM_xfree(cls);
+ H5MM_xfree((void*)cls->lib_vers);
+ H5MM_xfree((void*)cls);
}
done:
@@ -541,7 +543,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5Eget_class
+ * Function: H5Eget_class_name
*
* Purpose: Retrieves error class name.
*
@@ -556,18 +558,18 @@ done:
*-------------------------------------------------------------------------
*/
ssize_t
-H5Eget_class(hid_t class_id, char *name, size_t size)
+H5Eget_class_name(hid_t class_id, char *name, size_t size)
{
ssize_t ret_value; /* Return value */
H5E_cls_t *cls;
- FUNC_ENTER_API(H5Eget_class, FAIL);
+ FUNC_ENTER_API(H5Eget_class_name, FAIL);
H5TRACE3("Zs","isz",class_id,name,size);
/* Need to check for errors */
cls = H5I_object_verify(class_id, H5I_ERROR_CLASS);
- ret_value = H5E_get_class(cls, name, size);
+ ret_value = H5E_get_class_name(cls, name, size);
done:
FUNC_LEAVE_API(ret_value);
@@ -575,7 +577,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5E_get_class
+ * Function: H5E_get_class_name
*
* Purpose: Private function to retrieve error class name.
*
@@ -590,12 +592,12 @@ done:
*-------------------------------------------------------------------------
*/
ssize_t
-H5E_get_class(H5E_cls_t *cls, char *name, size_t size)
+H5E_get_class_name(H5E_cls_t *cls, char *name, size_t size)
{
ssize_t ret_value; /* Return value */
ssize_t len;
- FUNC_ENTER_NOAPI(H5E_get_class, FAIL);
+ FUNC_ENTER_NOAPI(H5E_get_class_name, FAIL);
len = HDstrlen(cls->cls_name);
@@ -704,8 +706,8 @@ H5E_close_msg(H5E_msg_t *err)
/* Doesn't free err->cls here */
if(err) {
if(err->msg)
- H5MM_xfree(err->msg);
- H5MM_xfree(err);
+ H5MM_xfree((void*)err->msg);
+ H5MM_xfree((void*)err);
}
done:
@@ -972,11 +974,11 @@ H5E_get_current_stack(void)
for(i=0; i<current_stack->nused; i++) {
current_error = &(current_stack->slot[i]);
if(current_error->func_name)
- H5MM_xfree(current_error->func_name);
+ H5MM_xfree((void*)current_error->func_name);
if(current_error->file_name)
- H5MM_xfree(current_error->file_name);
+ H5MM_xfree((void*)current_error->file_name);
if(current_error->desc)
- H5MM_xfree(current_error->desc);
+ H5MM_xfree((void*)current_error->desc);
}
HDmemset(current_stack->slot, 0, sizeof(H5E_error_t_new)*current_stack->nused);
current_stack->nused = 0;
@@ -1055,11 +1057,11 @@ H5E_set_current_stack(H5E_t_new *estack)
for(i=0; i<current_stack->nused; i++) {
current_error = &(current_stack->slot[i]);
if(current_error->func_name)
- H5MM_xfree(current_error->func_name);
+ H5MM_xfree((void*)current_error->func_name);
if(current_error->file_name)
- H5MM_xfree(current_error->file_name);
+ H5MM_xfree((void*)current_error->file_name);
if(current_error->desc)
- H5MM_xfree(current_error->desc);
+ H5MM_xfree((void*)current_error->desc);
}
HDmemset(current_stack->slot, 0, sizeof(H5E_error_t_new)*current_stack->nused);
current_stack->nused = 0;
@@ -1155,13 +1157,13 @@ H5E_close_stack(H5E_t_new *err_stack)
error = &(err_stack->slot[i]);
if(error->func_name)
- H5MM_xfree(error->func_name);
+ H5MM_xfree((void*)error->func_name);
if(error->file_name)
- H5MM_xfree(error->file_name);
+ H5MM_xfree((void*)error->file_name);
if(error->desc)
- H5MM_xfree(error->desc);
+ H5MM_xfree((void*)error->desc);
}
- H5MM_xfree(err_stack);
+ H5MM_xfree((void*)err_stack);
}
done:
@@ -1235,6 +1237,109 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Epop
+ *
+ * Purpose: Deletes some error messages from the top of error stack.
+ *
+ * Return: Non-negative value on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Friday, July 16, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Epop(hid_t err_stack, size_t count)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5E_t_new *estack;
+
+ FUNC_ENTER_API(H5Epop, FAIL);
+ H5TRACE2("e","iz",err_stack,count);
+
+ /* Need to check for errors */
+ if(err_stack == H5E_DEFAULT)
+ estack = H5E_get_my_stack_new();
+ else
+ estack = H5I_object_verify(err_stack, H5I_ERROR_STACK);
+
+ if(count > estack->nused)
+ count = estack->nused;
+
+ /* Add HGOTO_ERROR later */
+ ret_value=H5E_pop(estack, count);
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_pop
+ *
+ * Purpose: Private function to delete some error messages from the top
+ * of error stack.
+ *
+ * Return: Non-negative value on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Friday, July 16, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5E_pop(H5E_t_new *err_stack, size_t count)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5E_error_t_new *old_head, *new_head, *delete_head;
+ size_t delete_count;
+ int i;
+
+ FUNC_ENTER_NOAPI(H5E_pop, FAIL);
+
+ assert(err_stack);
+
+ /* Do an in-place move. Shift the remaining errors to the top of stack. */
+ if(count != err_stack->nused) {
+ old_head = &(err_stack->slot[0]);
+ new_head = &(err_stack->slot[count]);
+
+ /* Free memory for the errors to be deleted */
+ for(i=0; i<count; i++) {
+ H5E_error_t_new *error = &(err_stack->slot[i]);
+ if(error->func_name)
+ H5MM_xfree((void*)error->func_name);
+ if(error->file_name)
+ H5MM_xfree((void*)error->file_name);
+ if(error->desc)
+ H5MM_xfree((void*)error->desc);
+ }
+
+ /* Move the rest errors to the top of stack. Watch out: func_name, file_name, desc in new slot
+ * each points to the same location as the old slot. Do not free them when deleting the old
+ * slot. */
+ HDmemmove(old_head, new_head, (err_stack->nused-count)*sizeof(H5E_error_t_new));
+
+ /* Point to the beginning of errors to be removed, delete the old moved slots. */
+ delete_head = &(err_stack->slot[err_stack->nused-count]);
+ delete_count = count;
+ HDmemset(delete_head, 0, delete_count*sizeof(H5E_error_t_new));
+
+ err_stack->nused = err_stack->nused - count;
+ } else {
+ H5E_clear_new(err_stack);
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5Epush_new
*
* Purpose: Pushes a new error record onto error stack for the current
@@ -1271,7 +1376,7 @@ H5Epush_new(hid_t err_stack, const char *file, const char *func, unsigned line,
H5E_msg_t *maj_ptr, *min_ptr;
va_list ap;
hid_t cls_id;
- char tmp[128];
+ char tmp[128]; /* What's the maximal length? */
FUNC_ENTER_API(H5Epush_new, FAIL);
H5TRACE7("e","issIuiis",err_stack,file,func,line,maj_id,min_id,fmt);
@@ -1358,16 +1463,444 @@ H5E_push_new(H5E_t_new *estack, const char *file, const char *func, unsigned lin
estack->slot[estack->nused].cls_id = cls_id;
estack->slot[estack->nused].maj_id = maj_id;
estack->slot[estack->nused].min_id = min_id;
- estack->slot[estack->nused].func_name = func;
- estack->slot[estack->nused].file_name = file;
+ estack->slot[estack->nused].func_name = HDstrdup(func);
+ estack->slot[estack->nused].file_name = HDstrdup(file);
estack->slot[estack->nused].line = line;
- estack->slot[estack->nused].desc = desc;
+ estack->slot[estack->nused].desc = HDstrdup(desc);
estack->nused++;
}
FUNC_LEAVE_NOAPI(SUCCEED);
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Eclear_new
+ *
+ * Purpose: Clears the error stack for the specified error stack.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Wednesday, July 16, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Eclear_new(hid_t err_stack)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+ H5E_t_new *estack_ptr;
+
+ FUNC_ENTER_API(H5Eclear_new, FAIL);
+ H5TRACE1("e","i",err_stack);
+ /* FUNC_ENTER() does all the work */
+
+ /* Need to check for errors */
+ if(err_stack == H5E_DEFAULT)
+ estack_ptr = H5E_get_my_stack_new();
+ else
+ estack_ptr = H5I_object_verify(err_stack, H5I_ERROR_STACK);
+
+ ret_value = H5E_clear_new(estack_ptr);
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_clear_new
+ *
+ * Purpose: Private function to clear the error stack for the
+ * specified error stack.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Wednesday, July 16, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5E_clear_new(H5E_t_new *estack)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+ H5E_error_t_new *error;
+ int i;
+
+ FUNC_ENTER_NOAPI(H5E_clear_new, FAIL);
+
+ /* Empty the error stack */
+fprintf(stderr, "%s: %d\n", FUNC, __LINE__);
+ if (estack) {
+fprintf(stderr, "%s: %d nused=%d\n", FUNC, __LINE__, estack->nused);
+ for(i=0; i<estack->nused; i++) {
+fprintf(stderr, "%s: %d\n", FUNC, __LINE__);
+ error = &(estack->slot[i]);
+fprintf(stderr, "%s: %d error=%p, func_name=%p, func_name=%s\n", FUNC, __LINE__, error,
+ error->func_name, error->func_name);
+ if(error->func_name)
+ H5MM_xfree((void*)error->func_name);
+fprintf(stderr, "%s: %d\n file_name=%p", FUNC, __LINE__, error->file_name);
+ if(error->file_name)
+ H5MM_xfree((void*)error->file_name);
+fprintf(stderr, "%s: %d desc=%p\n", FUNC, __LINE__, error->desc);
+ if(error->desc)
+ H5MM_xfree((void*)error->desc);
+fprintf(stderr, "%s: %d\n", FUNC, __LINE__);
+ }
+fprintf(stderr, "%s: %d\n", FUNC, __LINE__);
+ HDmemset(estack->slot, 0, sizeof(H5E_error_t_new)*estack->nused);
+fprintf(stderr, "%s: %d\n", FUNC, __LINE__);
+ estack->nused = 0;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_print_new
+ *
+ * Purpose: Prints the error stack in some default way. This is just a
+ * convenience function for H5Ewalk() with a function that
+ * prints error messages. Users are encouraged to write there
+ * own more specific error handlers.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Friday, February 27, 1998
+ *
+ * Modifications:
+ * Albert Cheng, 2000/12/02
+ * Show MPI process rank id if applicable.
+ * Albert Cheng, 2001/07/14
+ * Show HDF5 library version information string too.
+ *
+ * Raymond Lu, 2003/7/16
+ * Print for specified error stack. A line will appear before the error
+ * messages of each error class. It states the information of library
+ * name, version number and thread ID.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Eprint_new(hid_t err_stack, FILE *stream)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+ H5E_t_new *estack_ptr;
+
+ /* Don't clear the error stack! :-) */
+ FUNC_ENTER_API_NOCLEAR(H5Eprint_new, FAIL);
+ /*NO TRACE*/
+
+ /* Need to check for errors */
+ if(err_stack == H5E_DEFAULT)
+ estack_ptr = H5E_get_my_stack_new();
+ else
+ estack_ptr = H5I_object_verify(err_stack, H5I_ERROR_STACK);
+
+ ret_value = H5E_print_new(estack_ptr, stream);
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_print_new
+ *
+ * Purpose: Private function to print the error stack in some default
+ * way. This is just a convenience function for H5Ewalk()
+ * with a function that prints error messages. Users are
+ * encouraged to write there own more specific error handlers.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Friday, February 27, 1998
+ *
+ * Modifications:
+ * Albert Cheng, 2000/12/02
+ * Show MPI process rank id if applicable.
+ * Albert Cheng, 2001/07/14
+ * Show HDF5 library version information string too.
+ *
+ * Raymond Lu, 2003/7/16
+ * Print for specified error stack. A line will appear before the error
+ * messages of each error class. It states the information of library
+ * name, version number and thread ID.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5E_print_new(H5E_t_new *estack, FILE *stream)
+{
+ /*herr_t ret_value = FAIL;*/
+ herr_t ret_value = SUCCEED;
+
+ /* Don't clear the error stack! :-) */
+ FUNC_ENTER_API_NOCLEAR(H5Eprint, FAIL);
+ /*NO TRACE*/
+
+ if (!stream) stream = stderr;
+
+ ret_value = H5E_walk_new (estack, H5E_WALK_DOWNWARD, H5E_walk_cb_new, (void*)stream);
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Ewalk_new
+ *
+ * Purpose: Walks the error stack for the current thread and calls some
+ * function for each error along the way.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Friday, February 27, 1998
+ *
+ * Modifications:
+ *
+ * Raymond Lu
+ * Wednesday, July 16, 2003
+ * Let it walk through specified error stack.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Ewalk_new(hid_t err_stack, H5E_direction_t direction, H5E_walk_t_new func, void *client_data)
+{
+ H5E_t_new *estack_ptr;
+ herr_t ret_value;
+
+ /* Don't clear the error stack! :-) */
+ FUNC_ENTER_API_NOCLEAR(H5Ewalk_new, FAIL);
+ H5TRACE4("e","iEdxx",err_stack,direction,func,client_data);
+
+ /* Need to check for errors */
+ if(err_stack == H5E_DEFAULT)
+ estack_ptr = H5E_get_my_stack_new();
+ else
+ estack_ptr = H5I_object_verify(err_stack, H5I_ERROR_STACK);
+
+ ret_value = H5E_walk_new (estack_ptr, direction, func, client_data);
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_walk_new
+ *
+ * Purpose: Private function for H5Ewalk_new.
+ * Walks the error stack, calling the specified function for
+ * each error on the stack. The DIRECTION argument determines
+ * whether the stack is walked from the inside out or the
+ * outside in. The value H5E_WALK_UPWARD means begin with the
+ * most specific error and end at the API; H5E_WALK_DOWNWARD
+ * means to start at the API and end at the inner-most function
+ * where the error was first detected.
+ *
+ * The function pointed to by FUNC will be called for each error
+ * in the error stack. It's arguments will include an index
+ * number (beginning at zero regardless of stack traversal
+ * direction), an error stack entry, and the CLIENT_DATA pointer
+ * passed to H5E_print.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Friday, December 12, 1997
+ *
+ * Modifications:
+ *
+ * Raymond Lu
+ * Wednesday, July 16, 2003
+ * Let it walk through specified error stack.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5E_walk_new (H5E_t_new *estack, H5E_direction_t direction, H5E_walk_t_new func, void *client_data)
+{
+ int i;
+ herr_t status;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5E_walk_new, FAIL);
+
+ /* check args, but rather than failing use some default value */
+ if (direction!=H5E_WALK_UPWARD && direction!=H5E_WALK_DOWNWARD) {
+ direction = H5E_WALK_UPWARD;
+ }
+
+ /* walk the stack */
+ assert (estack);
+
+ if (func && H5E_WALK_UPWARD==direction) {
+ for (i=0, status=SUCCEED; i<estack->nused && status>=0; i++) {
+ status = (func)(i, estack->slot+i, client_data);
+ }
+ } else if (func && H5E_WALK_DOWNWARD==direction) {
+ for (i=estack->nused-1, status=SUCCEED; i>=0 && status>=0; --i) {
+ status = (func)(estack->nused-(i+1), estack->slot+i, client_data);
+ }
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_walk_cb_new
+ *
+ * Purpose: This is a default error stack traversal callback function
+ * that prints error messages to the specified output stream.
+ * It is not meant to be called directly but rather as an
+ * argument to the H5Ewalk() function. This function is called
+ * also by H5Eprint(). Application writers are encouraged to
+ * use this function as a model for their own error stack
+ * walking functions.
+ *
+ * N is a counter for how many times this function has been
+ * called for this particular traversal of the stack. It always
+ * begins at zero for the first error on the stack (either the
+ * top or bottom error, or even both, depending on the traversal
+ * direction and the size of the stack).
+ *
+ * ERR_DESC is an error description. It contains all the
+ * information about a particular error.
+ *
+ * CLIENT_DATA is the same pointer that was passed as the
+ * CLIENT_DATA argument of H5Ewalk(). It is expected to be a
+ * file pointer (or stderr if null).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Friday, December 12, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5E_walk_cb_new(int n, H5E_error_t_new *err_desc, void *client_data)
+{
+ FILE *stream = (FILE *)client_data;
+ H5E_cls_t *cls_ptr = NULL;
+ H5E_msg_t *maj_ptr = NULL;
+ H5E_msg_t *min_ptr = NULL;
+ const char *maj_str = NULL;
+ const char *min_str = NULL;
+ const char *cls_str = NULL;
+ const int indent = 2;
+
+ FUNC_ENTER_NOINIT(H5E_walk_cb_new);
+ /*NO TRACE*/
+
+ /* Check arguments */
+ assert (err_desc);
+ if (!client_data) client_data = stderr;
+
+ /* Get descriptions for the major and minor error numbers */
+ /* Need to check for errors */
+ maj_ptr = H5I_object_verify(err_desc->maj_id, H5I_ERROR_MSG);
+ min_ptr = H5I_object_verify(err_desc->min_id, H5I_ERROR_MSG);
+ maj_str = maj_ptr->msg;
+ min_str = min_ptr->msg;
+
+ /* Get error class info */
+ /* add error checking later */
+ if(HDstrcmp(maj_ptr->cls->cls_name, min_ptr->cls->cls_name))
+ ;
+ cls_ptr = maj_ptr->cls;
+ cls_str = maj_ptr->cls->cls_name;
+
+ /* Print error message */
+ if(!H5E_same_class(cls_ptr)) {
+ fprintf (stream, "%s-DIAG: Error detected in %s ", cls_ptr->lib_name, cls_ptr->lib_vers);
+
+ /* try show the process or thread id in multiple processes cases*/
+#ifdef H5_HAVE_PARALLEL
+ { int mpi_rank, mpi_initialized;
+ MPI_Initialized(&mpi_initialized);
+ if (mpi_initialized){
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+ fprintf (stream, "MPI-process %d.", mpi_rank);
+ }else
+ fprintf (stream, "thread 0.");
+ }
+#elif defined(H5_HAVE_THREADSAFE)
+ fprintf (stream, "thread %d.", (int)pthread_self());
+#else
+ fprintf (stream, "thread 0.");
+#endif
+ /* Don't know what this is for */
+ /*if (estack && estack->nused>0) fprintf (stream, " Back trace follows.");*/
+ HDfputc ('\n', stream);
+ }
+
+ fprintf (stream, "%*s#%03d: %s line %u in %s(): %s\n",
+ indent, "", n, err_desc->file_name, err_desc->line,
+ err_desc->func_name, err_desc->desc);
+ fprintf (stream, "%*sclass: %s\n", indent*2, "", cls_str);
+ fprintf (stream, "%*smajor: %s\n", indent*2, "", maj_str);
+ fprintf (stream, "%*sminor: %s\n", indent*2, "", min_str);
+
+ FUNC_LEAVE_NOAPI(SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5E_same_class
+ *
+ * Purpose: Compare the error class name with the one in record.
+ *
+ * Return: Non-zero value when true/zero when false
+ *
+ * Programmer: Robb Matzke
+ * Friday, December 12, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5E_same_class(H5E_cls_t *cls)
+{
+ htri_t ret_value = FALSE;
+ static H5E_cls_t origin_cls={"Unknown class", "Unknown library", "Unknown library version"};
+
+ FUNC_ENTER_NOINIT(H5E_same_class);
+ /*NO TRACE*/
+
+ /* Check arguments */
+ assert (cls);
+
+ if(strcmp(cls->lib_name, origin_cls.lib_name)) {
+ origin_cls.cls_name = HDstrdup(cls->cls_name);
+ origin_cls.lib_name = HDstrdup(cls->lib_name);
+ origin_cls.lib_vers = HDstrdup(cls->lib_vers);
+ ret_value = FALSE;
+ } else
+ ret_value = TRUE;
+
+ FUNC_LEAVE_NOAPI(ret_value);
+}
#endif /* NEW_ERR */
diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h
index c993c69..a08a727 100644
--- a/src/H5Eprivate.h
+++ b/src/H5Eprivate.h
@@ -204,7 +204,11 @@ typedef struct H5E_t_new {
* and a FUNC_LEAVE() within a function body. The arguments are the major
* error number, the minor error number, and a description of the error.
*/
+#ifdef NEW_ERR
+#define HERROR(maj, min, str) H5E_push_new(H5E_DEFAULT, __FILE__, FUNC, __LINE__, maj, min, str)
+#else
#define HERROR(maj, min, str) H5E_push(maj, min, FUNC, __FILE__, __LINE__, str)
+#endif /* NEW_ERR */
/*
* HCOMMON_ERROR macro, used by HDONE_ERROR and HGOTO_ERROR
@@ -288,12 +292,17 @@ H5_DLL herr_t H5E_close_msg(H5E_msg_t *err);
H5_DLL hid_t H5E_create_msg(hid_t cls_id, H5E_type_t msg_type, const char *msg);
H5_DLL hid_t H5E_get_current_stack(void);
H5_DLL herr_t H5E_close_stack(H5E_t_new *err_stack);
-H5_DLL ssize_t H5E_get_class(H5E_cls_t *cls, char *name, size_t size);
+H5_DLL ssize_t H5E_get_class_name(H5E_cls_t *cls, char *name, size_t size);
H5_DLL ssize_t H5E_get_msg(H5E_msg_t *msg_ptr, H5E_type_t *type, char *msg, size_t size);
H5_DLL int H5E_get_num(H5E_t_new *err_stack);
H5_DLL herr_t H5E_set_current_stack(H5E_t_new *estack);
H5_DLL herr_t H5E_push_new(H5E_t_new *estack, const char *file, const char *func, unsigned line,
hid_t cls_id, hid_t maj_id, hid_t min_id, const char *desc);
+H5_DLL herr_t H5E_pop(H5E_t_new *err_stack, size_t count);
+H5_DLL herr_t H5E_clear_new(H5E_t_new *estack);
+H5_DLL herr_t H5E_print_new(H5E_t_new *estack, FILE *stream);
+H5_DLL herr_t H5E_walk_new (H5E_t_new *estack, H5E_direction_t direction, H5E_walk_t_new func,
+ void *client_data);
#endif /* NEW_ERR */
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index 038acc2..e579dae 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -449,14 +449,19 @@ H5_DLL herr_t H5Eclose_msg(hid_t err_id);
H5_DLL hid_t H5Ecreate_msg(hid_t cls, H5E_type_t msg_type, const char *msg);
H5_DLL hid_t H5Eget_current_stack(void);
H5_DLL herr_t H5Eclose_stack(hid_t stack_id);
-H5_DLL ssize_t H5Eget_class(hid_t class_id, char *name, size_t size);
+H5_DLL ssize_t H5Eget_class_name(hid_t class_id, char *name, size_t size);
H5_DLL ssize_t H5Eget_msg(hid_t msg_id, H5E_type_t *type, char *msg, size_t size);
H5_DLL int H5Eget_num(hid_t error_stack_id);
H5_DLL herr_t H5Eset_current_stack(hid_t err_stack_id);
H5_DLL herr_t H5Epush_new(hid_t err_stack, const char *file, const char *func, unsigned line,
hid_t maj_id, hid_t min_id, const char *msg, ...);
+H5_DLL herr_t H5Epop(hid_t err_stack, size_t count);
+H5_DLL herr_t H5Eclear_new(hid_t err_stack);
+H5_DLL herr_t H5Eprint_new(hid_t err_stack, FILE *stream);
+typedef herr_t (*H5E_walk_t_new)(int n, H5E_error_t_new *err_desc, void *client_data);
+H5_DLL herr_t H5Ewalk_new(hid_t err_stack, H5E_direction_t direction, H5E_walk_t_new func,
+ void *client_data);
-
#ifdef __cplusplus
}
#endif
diff --git a/test/errors.c b/test/errors.c
index e7373d5..975a3ec 100644
--- a/test/errors.c
+++ b/test/errors.c
@@ -32,29 +32,40 @@ const char *FILENAME[] = {
int ipoints2[DIM0][DIM1], icheck2[DIM0][DIM1];
hid_t ERR_CLS;
+hid_t ERR_STACK;
hid_t ERR_MAJ_TEST;
hid_t ERR_MAJ_IO;
+hid_t ERR_MAJ_API;
hid_t ERR_MIN_SUBROUTINE;
+hid_t ERR_MIN_ERRSTACK;
hid_t ERR_MIN_CREATE;
+hid_t ERR_MIN_GETNUM;
#define DSET_NAME "a_dataset"
#define ERR_CLS_NAME "Error Test"
#define PROG_NAME "Error Program"
#define PROG_VERS "1.0"
+
#define ERR_MAJ_TEST_MSG "Error in test"
#define ERR_MAJ_IO_MSG "Error in IO"
+#define ERR_MAJ_API_MSG "Error in API"
#define ERR_MIN_SUBROUTINE_MSG "Error in subroutine"
+#define ERR_MIN_ERRSTACK_MSG "Error in error stack"
#define ERR_MIN_CREATE_MSG "Error in H5Dcreate"
+#define ERR_MIN_GETNUM_MSG "Error in H5Eget_num"
+#define MSG_SIZE 64
#define SPACE1_DIM1 4
#define SPACE1_RANK 1
#define SPACE2_RANK 2
#define SPACE2_DIM1 10
#define SPACE2_DIM2 10
+herr_t custom_print_cb(int n, H5E_error_t_new *err_desc, void* client_data);
+
/*-------------------------------------------------------------------------
* Function: test_error
@@ -81,7 +92,7 @@ test_error(hid_t file)
int i, j, n;
hsize_t dims[2];
void *tmp;
- char *FUNC_test_error="test_error()";
+ const char *FUNC_test_error="test_error";
TESTING("error API based on atomic datatype");
@@ -99,14 +110,16 @@ test_error(hid_t file)
/*------------------- Test data values ------------------------*/
/* Create the dataset */
+ /* Make it H5Dcreate fail */
+ /*file = 0;*/
if ((dataset = H5Dcreate(file, DSET_NAME, H5T_STD_I32BE, space,
H5P_DEFAULT))<0) {
#ifndef NEW_ERR
H5Epush_new(H5E_DEFAULT, __FILE__, FUNC_test_error, __LINE__, ERR_MAJ_IO, ERR_MIN_CREATE,
"H5Dcreate failed");
#endif /* NEW_ERR */
-
- TEST_ERROR;
+ goto error;
+ /*TEST_ERROR;*/
}
/* Write the data to the dataset */
@@ -192,16 +205,18 @@ test_error(hid_t file)
static herr_t
init_error(void)
{
- size_t cls_size = strlen(ERR_CLS_NAME)+1;
+ ssize_t cls_size = strlen(ERR_CLS_NAME)+1;
char *cls_name = malloc(strlen(ERR_CLS_NAME)+1);
- size_t msg_size = strlen(ERR_MIN_SUBROUTINE_MSG) + 1;
+ ssize_t msg_size = strlen(ERR_MIN_SUBROUTINE_MSG) + 1;
char *msg = malloc(strlen(ERR_MIN_SUBROUTINE_MSG)+1);
H5E_type_t *msg_type= malloc(sizeof(H5E_type_t));
if((ERR_CLS = H5Eregister_class(ERR_CLS_NAME, PROG_NAME, PROG_VERS))<0)
TEST_ERROR;
+ if((ERR_CLS = H5Eregister_class(ERR_CLS_NAME, PROG_NAME, PROG_VERS))<0)
+ TEST_ERROR;
- if(cls_size != H5Eget_class(ERR_CLS, cls_name, cls_size) + 1)
+ if(cls_size != H5Eget_class_name(ERR_CLS, cls_name, (size_t)cls_size) + 1)
TEST_ERROR;
if(strcmp(ERR_CLS_NAME, cls_name))
TEST_ERROR;
@@ -210,13 +225,19 @@ init_error(void)
TEST_ERROR;
if((ERR_MAJ_IO = H5Ecreate_msg(ERR_CLS, H5E_MAJOR_new, ERR_MAJ_IO_MSG))<0)
TEST_ERROR;
+ if((ERR_MAJ_API = H5Ecreate_msg(ERR_CLS, H5E_MAJOR_new, ERR_MAJ_API_MSG))<0)
+ TEST_ERROR;
if((ERR_MIN_SUBROUTINE = H5Ecreate_msg(ERR_CLS, H5E_MINOR_new, ERR_MIN_SUBROUTINE_MSG))<0)
TEST_ERROR;
+ if((ERR_MIN_ERRSTACK = H5Ecreate_msg(ERR_CLS, H5E_MINOR_new, ERR_MIN_ERRSTACK_MSG))<0)
+ TEST_ERROR;
if((ERR_MIN_CREATE = H5Ecreate_msg(ERR_CLS, H5E_MINOR_new, ERR_MIN_CREATE_MSG))<0)
TEST_ERROR;
+ if((ERR_MIN_GETNUM = H5Ecreate_msg(ERR_CLS, H5E_MINOR_new, ERR_MIN_GETNUM_MSG))<0)
+ TEST_ERROR;
- if(msg_size != H5Eget_msg(ERR_MIN_SUBROUTINE, msg_type, msg, msg_size) + 1)
+ if(msg_size != H5Eget_msg(ERR_MIN_SUBROUTINE, msg_type, msg, (size_t)msg_size) + 1)
TEST_ERROR;
if(*msg_type != H5E_MINOR_new)
TEST_ERROR;
@@ -255,23 +276,30 @@ init_error(void)
static herr_t
error_stack(void)
{
- hid_t err_stack;
int err_num;
+ const char *FUNC_error_stack="error_stack";
if((err_num = H5Eget_num(H5E_DEFAULT))<0)
TEST_ERROR;
if(err_num)
TEST_ERROR;
- if((err_stack = H5Eget_current_stack())<0)
+ if((ERR_STACK = H5Eget_current_stack())<0)
TEST_ERROR;
- if((err_num = H5Eget_num(err_stack))<0)
- TEST_ERROR;
+ /* Make it push error */
+ if((err_num = H5Eget_num(ERR_STACK))<0) {
+ H5Epush_new(ERR_STACK, __FILE__, FUNC_error_stack, __LINE__, ERR_MAJ_API, ERR_MIN_GETNUM,
+ "Get number test failed, returned %d", err_num);
+ goto error;
+ /*TEST_ERROR;*/
+ }
if(err_num)
TEST_ERROR;
-
- if(H5Eclose_stack(err_stack)<0)
+
+ if(H5Eclear_new(ERR_STACK)<0)
+ TEST_ERROR;
+ if(H5Eclose_stack(ERR_STACK)<0)
TEST_ERROR;
PASSED();
@@ -281,6 +309,86 @@ error_stack(void)
return -1;
}
+
+/*-------------------------------------------------------------------------
+ * Function: dump_error
+ *
+ * Purpose: Prints error stack in default and customized ways.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Raymond Lu
+ * July 17, 2003
+ *
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+dump_error(hid_t estack)
+{
+ /* Print errors in library default way */
+ fprintf(stderr, "********* Print error stack in HDF5 default way *********\n");
+ H5Eprint_new(estack, stderr);
+
+ /* Customized way to print errors */
+ fprintf(stderr, "\n********* Print error stack in customized way *********\n");
+ H5Ewalk_new(estack, H5E_WALK_UPWARD, custom_print_cb, stderr);
+
+ PASSED();
+ return 0;
+
+ error:
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: custom_print_cb
+ *
+ * Purpose: Callback function to print error stack in customized way.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Raymond Lu
+ * July 17, 2003
+ *
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+custom_print_cb(int n, H5E_error_t_new *err_desc, void* client_data)
+{
+ FILE *stream = (FILE *)client_data;
+ char maj[MSG_SIZE];
+ char min[MSG_SIZE];
+ char cls[MSG_SIZE];
+ const int indent = 4;
+
+ /* Get descriptions for the major and minor error numbers */
+ H5Eget_class_name(err_desc->cls_id, cls, MSG_SIZE);
+ H5Eget_msg(err_desc->maj_id, NULL, maj, MSG_SIZE);
+ H5Eget_msg(err_desc->maj_id, NULL, min, MSG_SIZE);
+
+ fprintf (stream, "%*serror #%03d: %s in %s(): line %u\n",
+ indent, "", n, err_desc->file_name,
+ err_desc->func_name, err_desc->line);
+ fprintf (stream, "%*sclass: %s\n", indent*2, "", cls);
+ fprintf (stream, "%*smajor: %s\n", indent*2, "", maj);
+ fprintf (stream, "%*sminor: %s\n", indent*2, "", min);
+
+ PASSED();
+ return 0;
+
+ error:
+ return -1;
+}
/*-------------------------------------------------------------------------
@@ -340,7 +448,7 @@ main(void)
{
hid_t file, fapl;
char filename[1024];
- const char *FUNC_main="main()";
+ const char *FUNC_main="main";
h5_reset();
#ifndef NEW_ERR
@@ -355,16 +463,25 @@ main(void)
TEST_ERROR ;
#ifndef NEW_ERR
- if(error_stack()<0)
- TEST_ERROR ;
+ if(error_stack()<0) {
+ H5Epush_new(ERR_STACK, __FILE__, FUNC_main, __LINE__, ERR_MAJ_TEST, ERR_MIN_ERRSTACK,
+ "Error stack test failed");
+ H5Epop(ERR_STACK, 1);
+ dump_error(ERR_STACK);
+ /*H5Eprint_new(ERR_STACK, stderr);*/
+ H5Eclose_stack(ERR_STACK);
+ TEST_ERROR;
+ }
#endif /* NEW_ERR */
if(test_error(file)<0) {
#ifndef NEW_ERR
H5Epush_new(H5E_DEFAULT, __FILE__, FUNC_main, __LINE__, ERR_MAJ_TEST, ERR_MIN_SUBROUTINE,
- "Error test failed because %s", "it's wrong");
-#endif /* NEW_ERR */
- TEST_ERROR ;
+ "Error test failed, %s", "it's wrong");
+ H5Eprint_new(H5E_DEFAULT, stderr);
+#endif /* NEW_ERR */
+ goto error;
+ /*TEST_ERROR;*/
}
if (H5Fclose(file)<0) TEST_ERROR ;