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