summaryrefslogtreecommitdiffstats
path: root/tools/lib/h5tools_error.h
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/h5tools_error.h')
-rw-r--r--tools/lib/h5tools_error.h233
1 files changed, 177 insertions, 56 deletions
diff --git a/tools/lib/h5tools_error.h b/tools/lib/h5tools_error.h
index 2cdaf74..764fb91 100644
--- a/tools/lib/h5tools_error.h
+++ b/tools/lib/h5tools_error.h
@@ -18,12 +18,16 @@
#define H5TOOLS_ERROR_H_
#include "H5Epublic.h"
+#include "H5Eprivate.h" /* Error handling */
/* tools-HDF5 Error variables */
+H5TOOLS_DLLVAR int H5tools_INDENT_g;
H5TOOLS_DLLVAR hid_t H5tools_ERR_STACK_g;
H5TOOLS_DLLVAR hid_t H5tools_ERR_CLS_g;
H5TOOLS_DLLVAR hid_t H5E_tools_g;
H5TOOLS_DLLVAR hid_t H5E_tools_min_id_g;
+H5TOOLS_DLLVAR hid_t H5E_tools_min_info_id_g;
+H5TOOLS_DLLVAR hid_t H5E_tools_min_dbg_id_g;
/* Use FUNC to safely handle variations of C99 __func__ keyword handling */
#ifdef H5_HAVE_C99_FUNC
@@ -37,52 +41,184 @@ H5TOOLS_DLLVAR hid_t H5E_tools_min_id_g;
/*
* H5TOOLS_INIT_ERROR macro, used to initialize error reporting.
*/
-#define H5TOOLS_INIT_ERROR() { \
- H5tools_ERR_CLS_g = H5Eregister_class("H5tools", "HDF5:tools", lib_str); \
- H5E_tools_g= H5Ecreate_msg(H5tools_ERR_CLS_g, H5E_MAJOR, "Failure in tools library"); \
- H5E_tools_min_id_g = H5Ecreate_msg(H5tools_ERR_CLS_g, H5E_MINOR, "error in function"); \
-}
+#define H5TOOLS_INIT_ERROR() \
+do { \
+ char lib_str[256]; \
+ \
+ /* Initialize library version string for error class */ \
+ HDsnprintf(lib_str, sizeof(lib_str), "%d.%d.%d", H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE); \
+ \
+ /* Create new HDF5 error stack for the tools to use */ \
+ if ((H5tools_ERR_STACK_g = H5Ecreate_stack()) < 0) \
+ HDfprintf(stderr, "Failed to create HDF5 tools error stack\n"); \
+ \
+ /* Register errors from the HDF5 tools as a new error class */ \
+ if ((H5tools_ERR_CLS_g = H5Eregister_class("H5tools", "HDF5:tools", lib_str)) < 0) \
+ HDfprintf(stderr, "Failed to register HDF5 tools error class\n"); \
+ \
+ /* Create a new HDF5 major error message for errors from the tools library */ \
+ if ((H5E_tools_g = H5Ecreate_msg(H5tools_ERR_CLS_g, H5E_MAJOR, "Failure in tools library")) < 0) \
+ HDfprintf(stderr, "Failed to register major error message for tools library errors\n"); \
+ \
+ /* Create a new HDF5 minor error message for errors from the tools library */ \
+ if ((H5E_tools_min_id_g = H5Ecreate_msg(H5tools_ERR_CLS_g, H5E_MINOR, "error in function")) < 0) \
+ HDfprintf(stderr, "Failed to register minor error message for tools library errors\n"); \
+ \
+ /* Create a new HDF5 minor error message for info messages from the tools library */ \
+ if ((H5E_tools_min_info_id_g = H5Ecreate_msg(H5tools_ERR_CLS_g, H5E_MINOR, "function info")) < 0) \
+ HDfprintf(stderr, "Failed to register minor error message for tools library info messages\n"); \
+ \
+ /* Create a new HDF5 minor error message for debug messages from the tools library */ \
+ if ((H5E_tools_min_dbg_id_g = H5Ecreate_msg(H5tools_ERR_CLS_g, H5E_MINOR, "function debug")) < 0) \
+ HDfprintf(stderr, "Failed to register minor error message for tools library debug messages\n"); \
+} while(0)
/*
- * H5TOOLS_CLOSE_ERROR macro, used to initialize error reporting.
+ * H5TOOLS_CLOSE_ERROR macro, used to terminate error reporting.
*/
-#define H5TOOLS_CLOSE_ERROR() { \
- H5Eclose_msg(H5E_tools_min_id_g); \
- H5Eclose_msg(H5E_tools_g); \
- H5Eunregister_class(H5tools_ERR_CLS_g); \
-}
+#define H5TOOLS_CLOSE_ERROR() \
+do { \
+ /* Close all error messages created by H5TOOLS_INIT_ERROR() */ \
+ if (H5Eclose_msg(H5E_tools_min_dbg_id_g) < 0) \
+ HDfprintf(stderr, "Failed to close minor error message for tools library debug messages\n"); \
+ if (H5Eclose_msg(H5E_tools_min_info_id_g) < 0) \
+ HDfprintf(stderr, "Failed to close minor error message for tools library info messages\n"); \
+ if (H5Eclose_msg(H5E_tools_min_id_g) < 0) \
+ HDfprintf(stderr, "Failed to close minor error message for tools library errors\n"); \
+ if (H5Eclose_msg(H5E_tools_g) < 0) \
+ HDfprintf(stderr, "Failed to close major error message for tools library errors\n"); \
+ \
+ /* Unregister the HDF5 tools error class */ \
+ if (H5Eunregister_class(H5tools_ERR_CLS_g) < 0) \
+ HDfprintf(stderr, "Failed to unregister the HDF5 tools error class\n"); \
+ \
+ /* Close the tools error stack */ \
+ if (H5Eclose_stack(H5tools_ERR_STACK_g) < 0) \
+ HDfprintf(stderr, "Failed to close HDF5 tools error stack\n"); \
+} while(0)
/*
- * HERR_INIT macro, used to facilitate error reporting. Declaration and assignments of error variables.
- * Use at the beginning of a function using error handling macros.
+ * H5TOOLS_PUSH_ERROR macro, used to push an error to an error stack. Not meant to
+ * be called directly.
*/
-#define HERR_INIT(ret_typ, ret_init) \
- hbool_t past_catch = FALSE; \
- ret_typ ret_value = ret_init;
+#define H5TOOLS_PUSH_ERROR(estack_id, err_cls, maj_err_id, min_err_id, ...) \
+do { \
+ if (enable_error_stack > 0) { \
+ if (estack_id >= 0 && err_cls >= 0) \
+ H5Epush2(estack_id, __FILE__, FUNC, __LINE__, err_cls, maj_err_id, min_err_id, __VA_ARGS__); \
+ else { \
+ HDfprintf(stderr, __VA_ARGS__); \
+ HDfprintf(stderr, "\n"); \
+ } \
+ } \
+} while(0)
+/*
+ * H5TOOLS_ERROR macro, used to facilitate error reporting within a function body.
+ * The arguments are the return value and an error string. The return value is assigned
+ * to a variable `ret_value'. This macro is meant to be used for reporting an error without
+ * having control branch to the `done' label. This is often used when an error occurs
+ * after the `done' label, in which case an infinite loop would ensue if control branched
+ * backwards.
+ */
+#define H5TOOLS_ERROR(ret_val, ...) \
+do { \
+ H5TOOLS_PUSH_ERROR(H5tools_ERR_STACK_g, H5tools_ERR_CLS_g, H5E_tools_g, H5E_tools_min_id_g, __VA_ARGS__); \
+ ret_value = ret_val; \
+} while(0)
+
+/*
+ * H5TOOLS_GOTO_ERROR macro, used to facilitate error reporting within a function body.
+ * The arguments are the return value and an error string. The return value is assigned
+ * to a variable `ret_value' and control branches to the `done' label.
+ */
+#define H5TOOLS_GOTO_ERROR(ret_val, ...) \
+do { \
+ H5TOOLS_PUSH_ERROR(H5tools_ERR_STACK_g, H5tools_ERR_CLS_g, H5E_tools_g, H5E_tools_min_id_g, __VA_ARGS__); \
+ H5TOOLS_GOTO_DONE(ret_val); \
+} while(0)
+
+/*
+ * H5TOOLS_GOTO_DONE macro, used to facilitate normal return within a function body.
+ * The argument is the return value which is assigned to the `ret_value'
+ * variable. Control branches to the `done' label.
+ */
+#define H5TOOLS_GOTO_DONE(ret_val) \
+do { \
+ ret_value = ret_val; \
+ goto done; \
+} while(0)
/*
- * H5TOOLS_INFO macro, used to facilitate error reporting . The arguments are the major
- * error number, the minor error number, and a description of the error.
+ * H5TOOLS_GOTO_DONE_NO_RET macro, used to facilitate normal return within a function body.
+ * Control simply branches to the `done' label without setting any return value.
*/
-#define H5TOOLS_INFO(min_id, ...) { \
- H5Epush2(H5tools_ERR_STACK_g, __FILE__, FUNC, __LINE__, H5tools_ERR_CLS_g, H5E_tools_g, min_id, __VA_ARGS__); \
-}
+#define H5TOOLS_GOTO_DONE_NO_RET() \
+do { \
+ goto done; \
+} while(0)
/*
- * HERROR macro, used to facilitate error reporting . The arguments are the major
- * error number, the minor error number, and a description of the error.
+ * H5TOOLS_INFO macro, used to facilitate error reporting. The arguments are
+ * a description of the error.
*/
-#define HERROR(maj_id, min_id, ...) { \
- H5Epush2(H5tools_ERR_STACK_g, __FILE__, FUNC, __LINE__, H5tools_ERR_CLS_g, maj_id, min_id, __VA_ARGS__); \
- ret_value = FAIL; \
-}
+#define H5TOOLS_INFO(...) \
+do { \
+ H5TOOLS_PUSH_ERROR(H5tools_ERR_STACK_g, H5tools_ERR_CLS_g, H5E_tools_g, H5E_tools_min_info_id_g, __VA_ARGS__); \
+} while(0)
+
+#ifdef H5_TOOLS_DEBUG
+
+#define H5TOOLS_START_DEBUG(...) \
+do { \
+ H5tools_INDENT_g += 2; \
+ HDfprintf(stderr, "%*sENTER %s:%d in %s()...", H5tools_INDENT_g, "", __FILE__, __LINE__, FUNC); \
+ HDfprintf(stderr, __VA_ARGS__); \
+ HDfprintf(stderr, "\n"); \
+ HDfflush(stderr); \
+} while(0)
+
+#define H5TOOLS_DEBUG(...) \
+do { \
+ HDfprintf(stderr, "%*s %s:%d in %s()...", H5tools_INDENT_g, "", __FILE__, __LINE__, FUNC); \
+ HDfprintf(stderr, __VA_ARGS__); \
+ HDfprintf(stderr, "\n"); \
+ HDfflush(stderr); \
+} while(0)
+
+#define H5TOOLS_ENDDEBUG(...) \
+do { \
+ HDfprintf(stderr, "%*sEXIT %s:%d in %s()...", H5tools_INDENT_g, "", __FILE__, __LINE__, FUNC); \
+ HDfprintf(stderr, __VA_ARGS__); \
+ HDfprintf(stderr, "\n"); \
+ H5tools_INDENT_g -= 2; \
+ HDfflush(stderr); \
+} while(0)
+
+#else
+
+#define H5TOOLS_START_DEBUG(...) \
+do { \
+ ; \
+} while(0)
+
+#define H5TOOLS_DEBUG(...) \
+do { \
+ ; \
+} while(0)
+
+#define H5TOOLS_ENDDEBUG(...) \
+do { \
+ ; \
+} while(0)
+
+#endif
/* Macro for "catching" flow of control when an error occurs. Note that the
* H5_LEAVE macro won't jump back here once it's past this point.
*/
-#define CATCH catch_except:; past_catch = TRUE;
+/* #define CATCH catch_except:; past_catch = TRUE; defined in H5Eprivate.h */
/*
* H5_LEAVE macro, used to facilitate control flow between a
@@ -91,40 +227,25 @@ H5TOOLS_DLLVAR hid_t H5E_tools_min_id_g;
* The return value is assigned to a variable `ret_value' and control branches
* to the `catch_except' label, if we're not already past it.
*/
-#define H5_LEAVE(v) { \
- ret_value = v; \
- if(!past_catch) \
- goto catch_except; \
-}
+/*
+ * #define H5_LEAVE(v) { \
+ * ret_value = v; \
+ * if(!past_catch) \
+ * goto catch_except; \
+ * }
+ * defined in H5Eprivate.h */
/*
- * H5E_THROW macro, used to facilitate error reporting within a function body.
+ * H5TOOLS_THROW macro, used to facilitate error reporting within a function body.
* The arguments are the minor error number, and an error string.
* The return value is assigned to a variable `ret_value' and control branches
* to the `catch_except' label, if we're not already past it.
*/
-#define H5E_THROW(fail_value, min_id, ...) { \
- H5Epush2(H5tools_ERR_STACK_g, __FILE__, FUNC, __LINE__, H5tools_ERR_CLS_g, H5E_tools_g, min_id, __VA_ARGS__); \
- H5_LEAVE(fail_value) \
-}
-
-/*
- * HGOTO_ERROR macro, used to facilitate error reporting within a function body. The arguments are
- * the major error number, the minor error number, the return value, and an
- * error string. The return value is assigned to a variable `ret_value' and
- * control branches to the `done' label.
- */
-#define HGOTO_ERROR(fail_value, min_id, ...) { \
- HERROR(H5E_tools_g, min_id, __VA_ARGS__); \
- HGOTO_DONE(fail_value) \
-}
-
-/*
- * HGOTO_DONE macro, used to facilitate normal return within a function body.
- * The argument is the return value which is assigned to the `ret_value'
- * variable. Control branches to the `done' label.
- */
-#define HGOTO_DONE(ret_val) {ret_value = ret_val; goto done;}
+#define H5TOOLS_THROW(ret_val, ...) \
+do { \
+ H5TOOLS_PUSH_ERROR(H5tools_ERR_STACK_g, H5tools_ERR_CLS_g, H5E_tools_g, H5E_tools_min_id_g, __VA_ARGS__); \
+ H5_LEAVE(ret_val) \
+} while(0)
#endif /* H5TOOLS_ERROR_H_ */