#include "H5Emodule.h"
#include "H5private.h"
#include "H5Epkg.h"
#include "H5FLprivate.h"
#include "H5Iprivate.h"
#include "H5MMprivate.h"
#define H5E_CLS_NAME "HDF5"
#define H5E_CLS_LIB_NAME "HDF5"
static herr_t H5E__set_default_auto(H5E_t *stk);
static H5E_cls_t *H5E__register_class(const char *cls_name, const char *lib_name, const char *version);
static herr_t H5E__unregister_class(H5E_cls_t *cls);
static ssize_t H5E__get_class_name(const H5E_cls_t *cls, char *name, size_t size);
static int H5E__close_msg_cb(void *obj_ptr, hid_t obj_id, void *udata);
static herr_t H5E__close_msg(H5E_msg_t *err);
static H5E_msg_t *H5E__create_msg(H5E_cls_t *cls, H5E_type_t msg_type, const char *msg);
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);
hbool_t H5_PKG_INIT_VAR = FALSE;
H5FL_DEFINE_STATIC(H5E_t);
H5FL_DEFINE_STATIC(H5E_cls_t);
H5FL_DEFINE_STATIC(H5E_msg_t);
static const H5I_class_t H5I_ERRCLS_CLS[1] = {{
H5I_ERROR_CLASS,
0,
0,
(H5I_free_t)H5E__unregister_class
}};
static const H5I_class_t H5I_ERRMSG_CLS[1] = {{
H5I_ERROR_MSG,
0,
0,
(H5I_free_t)H5E__close_msg
}};
static const H5I_class_t H5I_ERRSTK_CLS[1] = {{
H5I_ERROR_STACK,
0,
0,
(H5I_free_t)H5E__close_stack
}};
herr_t
H5E_init(void)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5E__init_package(void)
{
H5E_cls_t *cls;
H5E_msg_t *msg;
char lib_vers[128];
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
if(H5I_register_type(H5I_ERRCLS_CLS) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group")
if(H5I_register_type(H5I_ERRMSG_CLS) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group")
if(H5I_register_type(H5I_ERRSTK_CLS) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group")
#ifndef H5_HAVE_THREADSAFE
H5E_stack_g[0].nused = 0;
H5E__set_default_auto(H5E_stack_g);
#endif
HDassert(H5E_ERR_CLS_g == (-1));
HDsnprintf(lib_vers, sizeof(lib_vers), "%u.%u.%u%s", H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE, (HDstrlen(H5_VERS_SUBRELEASE) > 0 ? "-"H5_VERS_SUBRELEASE : ""));
if(NULL == (cls = H5E__register_class(H5E_CLS_NAME, H5E_CLS_LIB_NAME, lib_vers)))
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "class initialization failed")
if((H5E_ERR_CLS_g = H5I_register(H5I_ERROR_CLASS, cls, FALSE)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error class")
#include "H5Einit.h"
done:
FUNC_LEAVE_NOAPI(ret_value)
}
int
H5E_term_package(void)
{
int n = 0;
FUNC_ENTER_NOAPI_NOINIT_NOERR
if(H5_PKG_INIT_VAR) {
int64_t ncls, nmsg, nstk;
ncls = H5I_nmembers(H5I_ERROR_CLASS);
nmsg = H5I_nmembers(H5I_ERROR_MSG);
nstk = H5I_nmembers(H5I_ERROR_STACK);
if((ncls + nmsg + nstk) > 0) {
if(nstk > 0)
(void)H5I_clear_type(H5I_ERROR_STACK, FALSE, FALSE);
if(ncls > 0) {
(void)H5I_clear_type(H5I_ERROR_CLASS, FALSE, FALSE);
if(H5I_nmembers(H5I_ERROR_CLASS) == 0)
H5E_ERR_CLS_g = -1;
}
if(nmsg > 0) {
(void)H5I_clear_type(H5I_ERROR_MSG, FALSE, FALSE);
if(H5I_nmembers(H5I_ERROR_MSG) == 0) {
#include "H5Eterm.h"
}
}
n++;
}
else {
n += (H5I_dec_type_ref(H5I_ERROR_STACK) > 0);
n += (H5I_dec_type_ref(H5I_ERROR_CLASS) > 0);
n += (H5I_dec_type_ref(H5I_ERROR_MSG) > 0);
if(0 == n)
H5_PKG_INIT_VAR = FALSE;
}
}
FUNC_LEAVE_NOAPI(n)
}
static herr_t
H5E__set_default_auto(H5E_t *stk)
{
FUNC_ENTER_STATIC_NOERR
#ifndef H5_NO_DEPRECATED_SYMBOLS
#ifdef H5_USE_16_API_DEFAULT
stk->auto_op.vers = 1;
#else
stk->auto_op.vers = 2;
#endif
stk->auto_op.func1 = stk->auto_op.func1_default = (H5E_auto1_t)H5Eprint1;
stk->auto_op.func2 = stk->auto_op.func2_default = (H5E_auto2_t)H5Eprint2;
stk->auto_op.is_default = TRUE;
#else
stk->auto_op.func2 = (H5E_auto2_t)H5Eprint2;
#endif
stk->auto_data = NULL;
FUNC_LEAVE_NOAPI(SUCCEED)
}
#ifdef H5_HAVE_THREADSAFE
H5E_t *
H5E__get_stack(void)
{
H5E_t *estack = NULL;
FUNC_ENTER_PACKAGE_NOERR
estack = (H5E_t *)H5TS_get_thread_local_value(H5TS_errstk_key_g);
if(!estack) {
#ifdef H5_HAVE_WIN_THREADS
estack = (H5E_t *)LocalAlloc(LPTR, sizeof(H5E_t));
#else
estack = (H5E_t *)HDmalloc(sizeof(H5E_t));
#endif
HDassert(estack);
estack->nused = 0;
H5E__set_default_auto(estack);
H5TS_set_thread_local_value(H5TS_errstk_key_g, (void *)estack);
}
FUNC_LEAVE_NOAPI(estack)
}
#endif
static herr_t
H5E__free_class(H5E_cls_t *cls)
{
FUNC_ENTER_STATIC_NOERR
HDassert(cls);
cls->cls_name = (char *)H5MM_xfree((void*)cls->cls_name);
cls->lib_name = (char *)H5MM_xfree((void*)cls->lib_name);
cls->lib_vers = (char *)H5MM_xfree((void*)cls->lib_vers);
cls = H5FL_FREE(H5E_cls_t, cls);
FUNC_LEAVE_NOAPI(SUCCEED)
}
hid_t
H5Eregister_class(const char *cls_name, const char *lib_name, const char *version)
{
H5E_cls_t *cls;
hid_t ret_value = H5I_INVALID_HID;
FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE3("i", "*s*s*s", cls_name, lib_name, version);
if(cls_name == NULL || lib_name == NULL || version == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid string")
if(NULL == (cls = H5E__register_class(cls_name, lib_name, version)))
HGOTO_ERROR(H5E_ERROR, H5E_CANTCREATE, H5I_INVALID_HID, "can't create error class")
if((ret_value = H5I_register(H5I_ERROR_CLASS, cls, TRUE)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register error class")
done:
FUNC_LEAVE_API(ret_value)
}
static H5E_cls_t *
H5E__register_class(const char *cls_name, const char *lib_name, const char *version)
{
H5E_cls_t *cls = NULL;
H5E_cls_t *ret_value = NULL;
FUNC_ENTER_STATIC
HDassert(cls_name);
HDassert(lib_name);
HDassert(version);
if(NULL == (cls = H5FL_CALLOC(H5E_cls_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
if(NULL == (cls->cls_name = H5MM_xstrdup(cls_name)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
if(NULL == (cls->lib_name = H5MM_xstrdup(lib_name)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
if(NULL == (cls->lib_vers = H5MM_xstrdup(version)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
ret_value = cls;
done:
if(!ret_value)
if(cls && H5E__free_class(cls) < 0)
HDONE_ERROR(H5E_ERROR, H5E_CANTRELEASE, NULL, "unable to free error class")
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5Eunregister_class(hid_t class_id)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE1("e", "i", class_id);
if(H5I_ERROR_CLASS != H5I_get_type(class_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error class")
if(H5I_dec_app_ref(class_id) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error class")
done:
FUNC_LEAVE_API(ret_value)
}
static herr_t
H5E__unregister_class(H5E_cls_t *cls)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
HDassert(cls);
if(H5I_iterate(H5I_ERROR_MSG, H5E__close_msg_cb, cls, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_BADITER, FAIL, "unable to free all messages in this error class")
if(H5E__free_class(cls) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTRELEASE, FAIL, "unable to free error class")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
ssize_t
H5Eget_class_name(hid_t class_id, char *name, size_t size)
{
H5E_cls_t *cls;
ssize_t ret_value = -1;
FUNC_ENTER_API((-1))
H5TRACE3("Zs", "i*sz", class_id, name, size);
if(NULL == (cls = (H5E_cls_t *)H5I_object_verify(class_id, H5I_ERROR_CLASS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not a error class ID")
if((ret_value = H5E__get_class_name(cls, name, size)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, (-1), "can't get error class name")
done:
FUNC_LEAVE_API(ret_value)
}
static ssize_t
H5E__get_class_name(const H5E_cls_t *cls, char *name, size_t size)
{
ssize_t len = -1;
FUNC_ENTER_STATIC_NOERR
HDassert(cls);
len = (ssize_t)HDstrlen(cls->cls_name);
if(name) {
HDstrncpy(name, cls->cls_name, MIN((size_t)(len + 1), size));
if((size_t)len >= size)
name[size - 1] = '\0';
}
FUNC_LEAVE_NOAPI(len)
}
static int
H5E__close_msg_cb(void *obj_ptr, hid_t obj_id, void *udata)
{
H5E_msg_t *err_msg = (H5E_msg_t*)obj_ptr;
H5E_cls_t *cls = (H5E_cls_t*)udata;
int ret_value = H5_ITER_CONT;
FUNC_ENTER_STATIC
HDassert(err_msg);
if(err_msg->cls == cls) {
if(H5E__close_msg(err_msg) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTCLOSEOBJ, H5_ITER_ERROR, "unable to close error message")
if(NULL == H5I_remove(obj_id))
HGOTO_ERROR(H5E_ERROR, H5E_CANTREMOVE, H5_ITER_ERROR, "unable to remove error message")
}
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5Eclose_msg(hid_t err_id)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE1("e", "i", err_id);
if(H5I_ERROR_MSG != H5I_get_type(err_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error class")
if(H5I_dec_app_ref(err_id) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error message")
done:
FUNC_LEAVE_API(ret_value)
}
static herr_t
H5E__close_msg(H5E_msg_t *err)
{
FUNC_ENTER_STATIC_NOERR
HDassert(err);
err->msg = (char *)H5MM_xfree((void *)err->msg);
err = H5FL_FREE(H5E_msg_t, err);
FUNC_LEAVE_NOAPI(SUCCEED)
}
hid_t
H5Ecreate_msg(hid_t class_id, H5E_type_t msg_type, const char *msg_str)
{
H5E_cls_t *cls;
H5E_msg_t *msg;
hid_t ret_value = H5I_INVALID_HID;
FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE3("i", "iEt*s", class_id, msg_type, msg_str);
if(msg_type != H5E_MAJOR && msg_type != H5E_MINOR)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "not a valid message type")
if(msg_str == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "message is NULL")
if(NULL == (cls = (H5E_cls_t *)H5I_object_verify(class_id, H5I_ERROR_CLASS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an error class ID")
if(NULL == (msg = H5E__create_msg(cls, msg_type, msg_str)))
HGOTO_ERROR(H5E_ERROR, H5E_CANTCREATE, H5I_INVALID_HID, "can't create error message")
if((ret_value = H5I_register(H5I_ERROR_MSG, msg, TRUE)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register error message")
done:
FUNC_LEAVE_API(ret_value)
}
static H5E_msg_t *
H5E__create_msg(H5E_cls_t *cls, H5E_type_t msg_type, const char *msg_str)
{
H5E_msg_t *msg = NULL;
H5E_msg_t *ret_value = NULL;
FUNC_ENTER_STATIC
HDassert(cls);
HDassert(msg_type == H5E_MAJOR || msg_type == H5E_MINOR);
HDassert(msg_str);
if(NULL == (msg = H5FL_MALLOC(H5E_msg_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
msg->cls = cls;
msg->type = msg_type;
if(NULL == (msg->msg = H5MM_xstrdup(msg_str)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
ret_value = msg;
done:
if(!ret_value)
if(msg && H5E__close_msg(msg) < 0)
HDONE_ERROR(H5E_ERROR, H5E_CANTCLOSEOBJ, NULL, "unable to close error message")
FUNC_LEAVE_NOAPI(ret_value)
}
ssize_t
H5Eget_msg(hid_t msg_id, H5E_type_t *type, char *msg_str, size_t size)
{
H5E_msg_t *msg;
ssize_t ret_value = -1;
FUNC_ENTER_API_NOCLEAR((-1))
H5TRACE4("Zs", "i*Et*sz", msg_id, type, msg_str, size);
if(NULL == (msg = (H5E_msg_t *)H5I_object_verify(msg_id, H5I_ERROR_MSG)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not a error message ID")
if((ret_value = H5E__get_msg(msg, type, msg_str, size)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, (-1), "can't get error message text")
done:
FUNC_LEAVE_API(ret_value)
}
hid_t
H5Ecreate_stack(void)
{
H5E_t *stk;
hid_t ret_value = H5I_INVALID_HID;
FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE0("i","");
if(NULL == (stk = H5FL_CALLOC(H5E_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5I_INVALID_HID, "memory allocation failed")
H5E__set_default_auto(stk);
if((ret_value = H5I_register(H5I_ERROR_STACK, stk, TRUE)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, H5I_INVALID_HID, "can't create error stack")
done:
FUNC_LEAVE_API(ret_value)
}
hid_t
H5Eget_current_stack(void)
{
H5E_t *stk;
hid_t ret_value = H5I_INVALID_HID;
FUNC_ENTER_API_NOCLEAR(H5I_INVALID_HID)
H5TRACE0("i","");
if(NULL == (stk = H5E__get_current_stack()))
HGOTO_ERROR(H5E_ERROR, H5E_CANTCREATE, H5I_INVALID_HID, "can't create error stack")
if((ret_value = H5I_register(H5I_ERROR_STACK, stk, TRUE)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, H5I_INVALID_HID, "can't create error stack")
done:
FUNC_LEAVE_API(ret_value)
}
static H5E_t *
H5E__get_current_stack(void)
{
H5E_t *current_stack;
H5E_t *estack_copy = NULL;
unsigned u;
H5E_t *ret_value = NULL;
FUNC_ENTER_STATIC
if(NULL == (current_stack = H5E__get_my_stack()))
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, NULL, "can't get current error stack")
if(NULL == (estack_copy = H5FL_CALLOC(H5E_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
estack_copy->nused = current_stack->nused;
for(u = 0; u < current_stack->nused; u++) {
H5E_error2_t *current_error, *new_error;
current_error = &(current_stack->slot[u]);
new_error = &(estack_copy->slot[u]);
if(H5I_inc_ref(current_error->cls_id, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, NULL, "unable to increment ref count on error class")
new_error->cls_id = current_error->cls_id;
if(H5I_inc_ref(current_error->maj_num, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, NULL, "unable to increment ref count on error message")
new_error->maj_num = current_error->maj_num;
if(H5I_inc_ref(current_error->min_num, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, NULL, "unable to increment ref count on error message")
new_error->min_num = current_error->min_num;
if(NULL == (new_error->func_name = H5MM_xstrdup(current_error->func_name)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
if(NULL == (new_error->file_name = H5MM_xstrdup(current_error->file_name)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
new_error->line = current_error->line;
if(NULL == (new_error->desc = H5MM_xstrdup(current_error->desc)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
}
estack_copy->auto_op = current_stack->auto_op;
estack_copy->auto_data = current_stack->auto_data;
H5E_clear_stack(current_stack);
ret_value = estack_copy;
done:
if(ret_value == NULL)
if(estack_copy)
estack_copy = H5FL_FREE(H5E_t, estack_copy);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5Eset_current_stack(hid_t err_stack)
{
H5E_t *estack;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE1("e", "i", err_stack);
if(err_stack != H5E_DEFAULT) {
if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
if(H5E__set_current_stack(estack) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "unable to set error stack")
if(H5I_dec_app_ref(err_stack) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error stack")
}
done:
FUNC_LEAVE_API(ret_value)
}
static herr_t
H5E__set_current_stack(H5E_t *estack)
{
H5E_t *current_stack;
unsigned u;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
HDassert(estack);
if(NULL == (current_stack = H5E__get_my_stack ()))
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack")
H5E_clear_stack(current_stack);
current_stack->nused = estack->nused;
for(u = 0; u < current_stack->nused; u++) {
H5E_error2_t *current_error, *new_error;
current_error = &(current_stack->slot[u]);
new_error = &(estack->slot[u]);
if(H5I_inc_ref(new_error->cls_id, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class")
current_error->cls_id = new_error->cls_id;
if(H5I_inc_ref(new_error->maj_num, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class")
current_error->maj_num = new_error->maj_num;
if(H5I_inc_ref(new_error->min_num, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class")
current_error->min_num = new_error->min_num;
if(NULL == (current_error->func_name = H5MM_xstrdup(new_error->func_name)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
if(NULL == (current_error->file_name = H5MM_xstrdup(new_error->file_name)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
current_error->line = new_error->line;
if(NULL == (current_error->desc = H5MM_xstrdup(new_error->desc)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
}
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5Eclose_stack(hid_t stack_id)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE1("e", "i", stack_id);
if(H5E_DEFAULT != stack_id) {
if(H5I_ERROR_STACK != H5I_get_type(stack_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
if(H5I_dec_app_ref(stack_id) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error stack")
}
done:
FUNC_LEAVE_API(ret_value)
}
static herr_t
H5E__close_stack(H5E_t *estack)
{
FUNC_ENTER_STATIC_NOERR
HDassert(estack);
H5E_clear_stack(estack);
estack = H5FL_FREE(H5E_t, estack);
FUNC_LEAVE_NOAPI(SUCCEED)
}
ssize_t
H5Eget_num(hid_t error_stack_id)
{
H5E_t *estack;
ssize_t ret_value;
FUNC_ENTER_API_NOCLEAR((-1))
H5TRACE1("Zs", "i", error_stack_id);
if(error_stack_id == H5E_DEFAULT) {
if(NULL == (estack = H5E__get_my_stack()))
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, (-1), "can't get current error stack")
}
else {
H5E_clear_stack(NULL);
if(NULL == (estack = (H5E_t *)H5I_object_verify(error_stack_id, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not an error stack ID")
}
if((ret_value = H5E__get_num(estack)) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, (-1), "can't get number of errors")
done:
FUNC_LEAVE_API(ret_value)
}
static ssize_t
H5E__get_num(const H5E_t *estack)
{
FUNC_ENTER_STATIC_NOERR
HDassert(estack);
FUNC_LEAVE_NOAPI((ssize_t)estack->nused)
}
herr_t
H5Epop(hid_t err_stack, size_t count)
{
H5E_t *estack;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API_NOCLEAR(FAIL)
H5TRACE2("e", "iz", err_stack, count);
if(err_stack == H5E_DEFAULT) {
if(NULL == (estack = H5E__get_my_stack()))
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack")
}
else {
H5E_clear_stack(NULL);
if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
}
if(count > estack->nused)
count = estack->nused;
if(H5E__pop(estack, count) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTRELEASE, FAIL, "can't pop errors from stack")
done:
FUNC_LEAVE_API(ret_value)
}
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;
H5E_t *estack;
#ifndef H5_HAVE_VASPRINTF
int tmp_len;
int desc_len;
#endif
char *tmp = NULL;
hbool_t va_started = FALSE;
herr_t ret_value=SUCCEED;
FUNC_ENTER_API_NOCLEAR(FAIL)
H5TRACE8("e", "i*s*sIuiii*s", err_stack, file, func, line, cls_id, maj_id,
min_id, fmt);
if(err_stack == H5E_DEFAULT)
estack = NULL;
else {
H5E_clear_stack(NULL);
if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
}
HDva_start(ap, fmt);
va_started = TRUE;
#ifdef H5_HAVE_VASPRINTF
if(HDvasprintf(&tmp, fmt, ap) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
#else
tmp_len = 128;
if(NULL == (tmp = H5MM_malloc((size_t)tmp_len)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
while((desc_len = HDvsnprintf(tmp, (size_t)tmp_len, fmt, ap)) > (tmp_len - 1)) {
HDva_end(ap);
HDva_start(ap, fmt);
H5MM_xfree(tmp);
tmp_len = desc_len + 1;
if(NULL == (tmp = H5MM_malloc((size_t)tmp_len)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
}
#endif
if(H5E__push_stack(estack, file, func, line, cls_id, maj_id, min_id, tmp) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't push error on stack")
done:
if(va_started)
HDva_end(ap);
#ifdef H5_HAVE_VASPRINTF
if(tmp)
HDfree(tmp);
#else
if(tmp)
H5MM_xfree(tmp);
#endif
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Eclear2(hid_t err_stack)
{
H5E_t *estack;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API_NOCLEAR(FAIL)
H5TRACE1("e", "i", err_stack);
if(err_stack == H5E_DEFAULT)
estack = NULL;
else {
H5E_clear_stack(NULL);
if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
}
if(H5E_clear_stack(estack) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't clear error stack")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Eprint2(hid_t err_stack, FILE *stream)
{
H5E_t *estack;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API_NOCLEAR(FAIL)
if(err_stack == H5E_DEFAULT) {
if(NULL == (estack = H5E__get_my_stack()))
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack")
}
else {
H5E_clear_stack(NULL);
if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
}
if(H5E__print(estack, stream, FALSE) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTLIST, FAIL, "can't display error stack")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Ewalk2(hid_t err_stack, H5E_direction_t direction, H5E_walk2_t stack_func, void *client_data)
{
H5E_t *estack;
H5E_walk_op_t op;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API_NOCLEAR(FAIL)
if(err_stack == H5E_DEFAULT) {
if(NULL == (estack = H5E__get_my_stack()))
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack")
}
else {
H5E_clear_stack(NULL);
if(NULL == (estack = (H5E_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
}
op.vers = 2;
op.u.func2 = stack_func;
if((ret_value = H5E__walk(estack, direction, &op, client_data)) < 0)
HERROR(H5E_ERROR, H5E_CANTLIST, "can't walk error stack");
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Eget_auto2(hid_t estack_id, H5E_auto2_t *func, void **client_data)
{
H5E_t *estack;
H5E_auto_op_t op;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE3("e", "i*x**x", estack_id, func, client_data);
if(estack_id == H5E_DEFAULT) {
if(NULL == (estack = H5E__get_my_stack()))
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack")
}
else
if(NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
if(H5E__get_auto(estack, &op, client_data) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info")
#ifndef H5_NO_DEPRECATED_SYMBOLS
if(!op.is_default && op.vers == 1)
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "wrong API function, H5Eset_auto1 has been called")
#endif
if(func)
*func = op.func2;
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Eset_auto2(hid_t estack_id, H5E_auto2_t func, void *client_data)
{
H5E_t *estack;
H5E_auto_op_t op;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API_NOCLEAR(FAIL)
H5TRACE3("e", "ix*x", estack_id, func, client_data);
if(estack_id == H5E_DEFAULT) {
if(NULL == (estack = H5E__get_my_stack()))
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack")
}
else
if(NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
#ifndef H5_NO_DEPRECATED_SYMBOLS
if(H5E__get_auto(estack, &op, NULL) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info")
if(func != op.func2_default)
op.is_default = FALSE;
else
op.is_default = TRUE;
op.vers = 2;
#endif
op.func2 = func;
if(H5E__set_auto(estack, &op, client_data) < 0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't set automatic error info")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Eauto_is_v2(hid_t estack_id, unsigned *is_stack)
{
H5E_t *estack;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE2("e", "i*Iu", estack_id, is_stack);
if(estack_id == H5E_DEFAULT) {
if(NULL == (estack = H5E__get_my_stack()))
HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack")
}
else
if(NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID")
if(is_stack)
#ifndef H5_NO_DEPRECATED_SYMBOLS
*is_stack = estack->auto_op.vers > 1;
#else
*is_stack = 1;
#endif
done:
FUNC_LEAVE_API(ret_value)
}