diff options
Diffstat (limited to 'src/H5E.c')
-rw-r--r-- | src/H5E.c | 166 |
1 files changed, 122 insertions, 44 deletions
@@ -49,7 +49,6 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5CXprivate.h" /* API Contexts */ #include "H5Epkg.h" /* Error handling */ #include "H5FLprivate.h" /* Free lists */ #include "H5Iprivate.h" /* IDs */ @@ -86,6 +85,7 @@ static H5E_t * H5E__get_current_stack(void); static herr_t H5E__set_current_stack(H5E_t *estack); static herr_t H5E__close_stack(H5E_t *err_stack); static ssize_t H5E__get_num(const H5E_t *err_stack); +static herr_t H5E__append_stack(H5E_t *dst_estack, const H5E_t *src_stack); /*********************/ /* Package Variables */ @@ -378,7 +378,7 @@ H5E__get_stack(void) #endif /* H5_HAVE_THREADSAFE */ /*------------------------------------------------------------------------- - * Function: H5E_free_class + * Function: H5E__free_class * * Purpose: Private function to free an error class. * @@ -390,9 +390,9 @@ H5E__get_stack(void) *------------------------------------------------------------------------- */ static herr_t -H5E_free_class(H5E_cls_t *cls) +H5E__free_class(H5E_cls_t *cls) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check arguments */ HDassert(cls); @@ -404,7 +404,7 @@ H5E_free_class(H5E_cls_t *cls) cls = H5FL_FREE(H5E_cls_t, cls); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5E_free_class() */ +} /* end H5E__free_class() */ /*------------------------------------------------------------------------- * Function: H5Eregister_class @@ -487,7 +487,7 @@ H5E__register_class(const char *cls_name, const char *lib_name, const char *vers done: if (!ret_value) - if (cls && H5E_free_class(cls) < 0) + if (cls && H5E__free_class(cls) < 0) HDONE_ERROR(H5E_ERROR, H5E_CANTRELEASE, NULL, "unable to free error class") FUNC_LEAVE_NOAPI(ret_value) @@ -498,9 +498,9 @@ done: * * Purpose: Closes an error class. * - * Return: SUCCEED/FAIL + * Return: Non-negative value on success/Negative on failure * - * Programmer: Raymond Lu + * Programmer: Raymond Lu * Friday, July 11, 2003 * *------------------------------------------------------------------------- @@ -555,7 +555,7 @@ H5E__unregister_class(H5E_cls_t *cls) HGOTO_ERROR(H5E_ERROR, H5E_BADITER, FAIL, "unable to free all messages in this error class") /* Free error class structure */ - if (H5E_free_class(cls) < 0) + if (H5E__free_class(cls) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTRELEASE, FAIL, "unable to free error class") done: @@ -576,13 +576,13 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5Eget_class_name(hid_t class_id, char *name, size_t size) +H5Eget_class_name(hid_t class_id, char *name /*out*/, size_t size) { H5E_cls_t *cls; /* Pointer to error class */ ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) - H5TRACE3("Zs", "i*sz", class_id, name, size); + H5TRACE3("Zs", "ixz", class_id, name, size); /* Get the error class */ if (NULL == (cls = (H5E_cls_t *)H5I_object_verify(class_id, H5I_ERROR_CLASS))) @@ -1319,16 +1319,13 @@ done: * *------------------------------------------------------------------------- */ +H5_ATTR_FORMAT(printf, 8, 9) herr_t H5Epush2(hid_t err_stack, const char *file, const char *func, unsigned line, hid_t cls_id, hid_t maj_id, hid_t min_id, const char *fmt, ...) { - va_list ap; /* Varargs info */ - H5E_t * estack; /* Pointer to error stack to modify */ -#ifndef H5_HAVE_VASPRINTF - int tmp_len; /* Current size of description buffer */ - int desc_len; /* Actual length of description when formatted */ -#endif /* H5_HAVE_VASPRINTF */ + va_list ap; /* Varargs info */ + H5E_t * estack; /* Pointer to error stack to modify */ char * tmp = NULL; /* Buffer to place formatted description in */ hbool_t va_started = FALSE; /* Whether the variable argument list is open */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1357,31 +1354,9 @@ H5Epush2(hid_t err_stack, const char *file, const char *func, unsigned line, hid HDva_start(ap, fmt); va_started = TRUE; -#ifdef H5_HAVE_VASPRINTF /* Use the vasprintf() routine, since it does what we're trying to do below */ if (HDvasprintf(&tmp, fmt, ap) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") -#else /* H5_HAVE_VASPRINTF */ - /* Allocate space for the formatted description buffer */ - tmp_len = 128; - if (NULL == (tmp = H5MM_malloc((size_t)tmp_len))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* If the description doesn't fit into the initial buffer size, allocate more space and try again */ - while ((desc_len = HDvsnprintf(tmp, (size_t)tmp_len, fmt, ap)) > (tmp_len - 1)) { - /* shutdown & restart the va_list */ - HDva_end(ap); - HDva_start(ap, fmt); - - /* Release the previous description, it's too small */ - H5MM_xfree(tmp); - - /* Allocate a description of the appropriate length */ - tmp_len = desc_len + 1; - if (NULL == (tmp = H5MM_malloc((size_t)tmp_len))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - } /* end while */ -#endif /* H5_HAVE_VASPRINTF */ /* Push the error on the stack */ if (H5E__push_stack(estack, file, func, line, cls_id, maj_id, min_id, tmp) < 0) @@ -1390,16 +1365,11 @@ H5Epush2(hid_t err_stack, const char *file, const char *func, unsigned line, hid done: if (va_started) HDva_end(ap); -#ifdef H5_HAVE_VASPRINTF /* Memory was allocated with HDvasprintf so it needs to be freed * with HDfree */ if (tmp) HDfree(tmp); -#else /* H5_HAVE_VASPRINTF */ - if (tmp) - H5MM_xfree(tmp); -#endif /* H5_HAVE_VASPRINTF */ FUNC_LEAVE_API(ret_value) } /* end H5Epush2() */ @@ -1698,3 +1668,111 @@ H5Eauto_is_v2(hid_t estack_id, unsigned *is_stack) done: FUNC_LEAVE_API(ret_value) } /* end H5Eauto_is_v2() */ + +/*------------------------------------------------------------------------- + * Function: H5Eappend_stack + * + * Purpose: Appends one error stack to another, optionally closing the + * source stack. + * + * Return: Non-negative value on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, October 7, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Eappend_stack(hid_t dst_stack_id, hid_t src_stack_id, hbool_t close_source_stack) +{ + H5E_t *dst_stack, *src_stack; /* Error stacks */ + herr_t ret_value = SUCCEED; /* Return value */ + + /* Don't clear the error stack! :-) */ + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "iib", dst_stack_id, src_stack_id, close_source_stack); + + /* Check args */ + if (NULL == (dst_stack = (H5E_t *)H5I_object_verify(dst_stack_id, H5I_ERROR_STACK))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dst_stack_id not a error stack ID") + if (NULL == (src_stack = (H5E_t *)H5I_object_verify(src_stack_id, H5I_ERROR_STACK))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "src_stack_id not a error stack ID") + + /* Append the source stack to the destination stack */ + if (H5E__append_stack(dst_stack, src_stack) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTAPPEND, FAIL, "can't append stack") + + /* Close source error stack, if requested */ + if (close_source_stack) + /* Decrement the counter on the error stack. It will be freed if the + * count reaches zero. + */ + if (H5I_dec_app_ref(src_stack_id) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on source error stack") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Eappend_stack() */ + +/*------------------------------------------------------------------------- + * Function: H5E__append_stack + * + * Purpose: Private function to append error stacks. + * + * Return: Non-negative value on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, October 7, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5E__append_stack(H5E_t *dst_stack, const H5E_t *src_stack) +{ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(dst_stack); + HDassert(src_stack); + + /* Copy the errors from the source stack to the destination stack */ + for (u = 0; u < src_stack->nused; u++) { + const H5E_error2_t *src_error; /* Pointers to source error on stack */ + H5E_error2_t * dst_error; /* Pointers to destination error on stack */ + + /* Get pointers into the current error stack location */ + src_error = &(src_stack->slot[u]); + dst_error = &(dst_stack->slot[dst_stack->nused]); + + /* Increment the IDs to indicate that they are used in this stack */ + if (H5I_inc_ref(src_error->cls_id, FALSE) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class") + dst_error->cls_id = src_error->cls_id; + if (H5I_inc_ref(src_error->maj_num, FALSE) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error message") + dst_error->maj_num = src_error->maj_num; + if (H5I_inc_ref(src_error->min_num, FALSE) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error message") + dst_error->min_num = src_error->min_num; + if (NULL == (dst_error->func_name = H5MM_xstrdup(src_error->func_name))) + HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed") + if (NULL == (dst_error->file_name = H5MM_xstrdup(src_error->file_name))) + HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed") + dst_error->line = src_error->line; + if (NULL == (dst_error->desc = H5MM_xstrdup(src_error->desc))) + HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed") + + /* Increment # of errors in destination stack */ + dst_stack->nused++; + + /* Check for destination stack full */ + if (dst_stack->nused >= H5E_NSLOTS) + break; + } /* end for */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5E__append_stack() */ |