1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * Copyright by The HDF Group. * 3 * Copyright by the Board of Trustees of the University of Illinois. * 4 * All rights reserved. * 5 * * 6 * This file is part of HDF5. The full HDF5 copyright notice, including * 7 * terms governing use, modification, and redistribution, is contained in * 8 * the COPYING file, which can be found at the root of the source code * 9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * 10 * If you do not have access to either file, you may request a copy from * 11 * help@hdfgroup.org. * 12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 13 14 /* 15 * Header file for error values, etc. 16 */ 17 #ifndef _H5Eprivate_H 18 #define _H5Eprivate_H 19 20 #include "H5Epublic.h" 21 22 /* Private headers needed by this file */ 23 #include "H5private.h" 24 25 /* Typedef for error stack (defined in H5Epkg.h) */ 26 typedef struct H5E_t H5E_t; 27 28 /* 29 * HERROR macro, used to facilitate error reporting between a FUNC_ENTER() 30 * and a FUNC_LEAVE() within a function body. The arguments are the major 31 * error number, the minor error number, and a description of the error. 32 */ 33 #define HERROR(maj_id, min_id, ...) H5E_printf_stack(NULL, __FILE__, FUNC, __LINE__, H5E_ERR_CLS_g, maj_id, min_id, __VA_ARGS__) 34 35 /* 36 * HCOMMON_ERROR macro, used by HDONE_ERROR and HGOTO_ERROR 37 * (Shouldn't need to be used outside this header file) 38 */ 39 #define HCOMMON_ERROR(maj, min, ...) \ 40 HERROR(maj, min, __VA_ARGS__); \ 41 err_occurred = TRUE; \ 42 err_occurred = err_occurred; /* Shut GCC warnings up! */ 43 44 /* 45 * HDONE_ERROR macro, used to facilitate error reporting between a 46 * FUNC_ENTER() and a FUNC_LEAVE() within a function body, but _AFTER_ the 47 * "done:" label. The arguments are 48 * the major error number, the minor error number, a return value, and a 49 * description of the error. 50 * (This macro can also be used to push an error and set the return value 51 * without jumping to any labels) 52 */ 53 #define HDONE_ERROR(maj, min, ret_val, ...) { \ 54 HCOMMON_ERROR(maj, min, __VA_ARGS__); \ 55 ret_value = ret_val; \ 56 } 57 58 /* 59 * HGOTO_ERROR macro, used to facilitate error reporting between a 60 * FUNC_ENTER() and a FUNC_LEAVE() within a function body. The arguments are 61 * the major error number, the minor error number, the return value, and an 62 * error string. The return value is assigned to a variable `ret_value' and 63 * control branches to the `done' label. 64 */ 65 #define HGOTO_ERROR(maj, min, ret_val, ...) { \ 66 HCOMMON_ERROR(maj, min, __VA_ARGS__); \ 67 HGOTO_DONE(ret_val) \ 68 } 69 70 /* 71 * HGOTO_ERROR_TAG macro, used like HGOTO_ERROR between H5_BEGIN_TAG and 72 * H5_END_TAG statements. Resets the metadata tag before leaving the function. 73 */ 74 #define HGOTO_ERROR_TAG(maj, min, ret_val, ...) { \ 75 H5AC_tag(prv_tag, NULL); \ 76 HCOMMON_ERROR(maj, min, __VA_ARGS__); \ 77 HGOTO_DONE(ret_val) \ 78 } 79 80 /* 81 * HGOTO_DONE macro, used to facilitate normal return between a FUNC_ENTER() 82 * and a FUNC_LEAVE() within a function body. The argument is the return 83 * value which is assigned to the `ret_value' variable. Control branches to 84 * the `done' label. 85 */ 86 #define HGOTO_DONE(ret_val) {ret_value = ret_val; goto done;} 87 88 /* 89 * HGOTO_DONE_TAG macro, used like HGOTO_DONE between H5_BEGIN_TAG and 90 * H5_END_TAG statements. Resets the metadata tag before leaving the function. 91 */ 92 #define HGOTO_DONE_TAG(ret_val) { \ 93 H5AC_tag(prv_tag, NULL); \ 94 HGOTO_DONE(ret_val) \ 95 } 96 97 /* 98 * Macros handling system error messages as described in C standard. 99 * These macros assume errnum is a valid system error code. 100 */ 101 102 /* Retrieve the error code description string and push it onto the error 103 * stack. 104 */ 105 #define HSYS_DONE_ERROR(majorcode, minorcode, retcode, str) { \ 106 int myerrno = errno; \ 107 HDONE_ERROR(majorcode, minorcode, retcode, "%s, errno = %d, error message = '%s'", str, myerrno, HDstrerror(myerrno)); \ 108 } 109 #define HSYS_GOTO_ERROR(majorcode, minorcode, retcode, str) { \ 110 int myerrno = errno; \ 111 HGOTO_ERROR(majorcode, minorcode, retcode, "%s, errno = %d, error message = '%s'", str, myerrno, HDstrerror(myerrno)); \ 112 } 113 114 #ifdef H5_HAVE_PARALLEL 115 /* 116 * MPI error handling macros. 117 */ 118 119 extern char H5E_mpi_error_str[MPI_MAX_ERROR_STRING]; 120 extern int H5E_mpi_error_str_len; 121 122 #define HMPI_ERROR(mpierr){ \ 123 MPI_Error_string(mpierr, H5E_mpi_error_str, &H5E_mpi_error_str_len); \ 124 HERROR(H5E_INTERNAL, H5E_MPIERRSTR, "%s", H5E_mpi_error_str); \ 125 } 126 #define HMPI_DONE_ERROR(retcode, str, mpierr){ \ 127 HMPI_ERROR(mpierr); \ 128 HDONE_ERROR(H5E_INTERNAL, H5E_MPI, retcode, str); \ 129 } 130 #define HMPI_GOTO_ERROR(retcode, str, mpierr){ \ 131 HMPI_ERROR(mpierr); \ 132 HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, retcode, str); \ 133 } 134 #endif /* H5_HAVE_PARALLEL */ 135 136 137 /******************************************************************************/ 138 /* Revisions to Error Macros, to go with Revisions to FUNC_ENTER/LEAVE Macros */ 139 /******************************************************************************/ 140 141 /* 142 * H5E_PRINTF macro, used to facilitate error reporting between a BEGIN_FUNC() 143 * and an END_FUNC() within a function body. The arguments are the minor 144 * error number, a description of the error (as a printf-like format string), 145 * and an optional set of arguments for the printf format arguments. 146 */ 147 #define H5E_PRINTF(...) H5E_printf_stack(NULL, __FILE__, FUNC, __LINE__, H5E_ERR_CLS_g, H5_MY_PKG_ERR, __VA_ARGS__) 148 149 /* 150 * H5_LEAVE macro, used to facilitate control flow between a 151 * BEGIN_FUNC() and an END_FUNC() within a function body. The argument is 152 * the return value. 153 * The return value is assigned to a variable `ret_value' and control branches 154 * to the `catch_except' label, if we're not already past it. 155 */ 156 #define H5_LEAVE(v) { \ 157 ret_value = v; \ 158 if(!past_catch) \ 159 goto catch_except; \ 160 } 161 162 /* 163 * H5E_THROW macro, used to facilitate error reporting between a 164 * FUNC_ENTER() and a FUNC_LEAVE() within a function body. The arguments are 165 * the minor error number, and an error string. 166 * The return value is assigned to a variable `ret_value' and control branches 167 * to the `catch_except' label, if we're not already past it. 168 */ 169 #define H5E_THROW(...) { \ 170 H5E_PRINTF(__VA_ARGS__); \ 171 H5_LEAVE(fail_value) \ 172 } 173 174 /* Macro for "catching" flow of control when an error occurs. Note that the 175 * H5_LEAVE macro won't jump back here once it's past this point. 176 */ 177 #define CATCH catch_except:; past_catch = TRUE; 178 179 180 /* Library-private functions defined in H5E package */ 181 H5_DLL herr_t H5E_init(void); 182 H5_DLL herr_t H5E_printf_stack(H5E_t *estack, const char *file, const char *func, 183 unsigned line, hid_t cls_id, hid_t maj_id, hid_t min_id, const char *fmt, ...)H5_ATTR_FORMAT(printf, 8, 9); 184 H5_DLL herr_t H5E_clear_stack(H5E_t *estack); 185 H5_DLL herr_t H5E_dump_api_stack(hbool_t is_api); 186 187 #endif /* _H5Eprivate_H */ 188 189