2 Copyright (c) 2004/2005 KJK::Hyperion
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in
6 the Software without restriction, including without limitation the rights to
7 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8 of the Software, and to permit persons to whom the Software is furnished to do
9 so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 #ifndef KJK_PSEH_NATIVE_H_
24 #define KJK_PSEH_NATIVE_H_
27 #include <pseh/excpt.h>
30 Note: just define __inline to an empty symbol if your C compiler doesn't
35 # define __inline inline
39 typedef long (__stdcall
* _SEHFilter_t
)
42 struct _EXCEPTION_POINTERS
*,
46 typedef void (__stdcall
* _SEHFinally_t
)
52 static __inline
long _SEHCallFilter
54 _SEHFilter_t _SEHFilter
,
55 long _SEHExceptionCode
,
56 struct _EXCEPTION_POINTERS
* _SEHExceptionPointers
,
60 if(_SEHFilter
== _SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER
))
61 return _SEH_EXECUTE_HANDLER
;
62 else if(_SEHFilter
== _SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH
))
63 return _SEH_CONTINUE_SEARCH
;
64 else if(_SEHFilter
== _SEH_STATIC_FILTER(_SEH_CONTINUE_EXECUTION
))
65 return _SEH_CONTINUE_EXECUTION
;
67 return _SEHFilter(_SEHExceptionCode
, _SEHExceptionPointers
, _SEHPVLocals
);
69 return _SEH_CONTINUE_SEARCH
;
72 static __inline
void _SEHCallFinally
74 _SEHFinally_t _SEHFinally
,
75 int _SEHAbnormalTermination
,
80 (_SEHFinally
)(_SEHAbnormalTermination
, _SEHPVLocals
);
84 /* Access the locals for the current frame */
85 #define _SEH_ACCESS_LOCALS(LOCALS_) \
86 _SEH_LOCALS_TYPENAME(LOCALS_) * _SEHPLocals; \
87 _SEHPLocals = _SEH_PVOID_CAST(_SEH_LOCALS_TYPENAME(LOCALS_) *, _SEHPVLocals);
89 /* Access local variable VAR_ */
90 #define _SEH_VAR(VAR_) _SEHPLocals->VAR_
92 /* FILTER FUNCTIONS */
93 /* Declares a filter function's prototype */
94 #define _SEH_FILTER(NAME_) \
95 long __stdcall NAME_ \
97 long _SEHExceptionCode, \
98 struct _EXCEPTION_POINTERS * _SEHExceptionPointers, \
102 /* Declares a static filter */
103 #define _SEH_STATIC_FILTER(ACTION_) ((_SEHFilter_t)((ACTION_) + 2))
105 /* Declares a PSEH filter wrapping a regular filter function */
106 #define _SEH_WRAP_FILTER(WRAPPER_, NAME_) \
107 static __inline _SEH_FILTER(WRAPPER_) \
109 return (NAME_)(_SEHExceptionPointers); \
112 /* FINALLY FUNCTIONS */
113 /* Declares a finally function's prototype */
114 #define _SEH_FINALLYFUNC(NAME_) \
115 void __stdcall NAME_ \
117 int _SEHAbnormalTermination, \
118 void * _SEHPVLocals \
121 /* Declares a PSEH finally function wrapping a regular function */
122 #define _SEH_WRAP_FINALLY(WRAPPER_, NAME_) \
123 _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ())
125 #define _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ARGS_) \
126 static __inline _SEH_FINALLYFUNC(WRAPPER_) \
131 #define _SEH_WRAP_FINALLY_LOCALS_ARGS(WRAPPER_, LOCALS_, NAME_, ARGS_) \
132 static __inline _SEH_FINALLYFUNC(WRAPPER_) \
134 _SEH_ACCESS_LOCALS(LOCALS_); \
139 #define _SEH_TRY_FINALLY(FINALLY_) \
140 _SEH_TRY_FILTER_FINALLY \
142 _SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH), \
146 #define _SEH_END_FINALLY _SEH_HANDLE _SEH_END
148 #define _SEH_TRY_FILTER(FILTER_) \
149 _SEH_TRY_FILTER_FINALLY((FILTER_), NULL)
151 #define _SEH_TRY_HANDLE_FINALLY(FINALLY_) \
152 _SEH_TRY_FILTER_FINALLY \
154 _SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER), \
159 _SEH_TRY_HANDLE_FINALLY(NULL)
161 #define _SEH_CALL_FILTER(FILTER_) \
165 GetExceptionCode(), \
166 GetExceptionPointers(), \
170 #define _SEH_CALL_FINALLY(FINALLY_) \
171 _SEHCallFinally((FINALLY_), (AbnormalTermination() != 0), _SEHPVLocals)
173 #define _SEH_TRY_FILTER_FINALLY(FILTER_, FINALLY_) \
176 _SEHFinally_t _SEHFinally = (FINALLY_); \
177 _SEHFilter_t _SEHFilter = (FILTER_); \
178 void * _SEHPVLocals = &_SEHLocals; \
179 (void)_SEHPVLocals; \
184 #define _SEH_HANDLE \
186 __except(_SEH_CALL_FILTER(_SEHFilter)) \
188 struct _EXCEPTION_POINTERS * _SEHExceptionPointers = GetExceptionPointers();\
189 long _SEHExceptionCode = GetExceptionCode(); \
196 _SEH_CALL_FINALLY(_SEHFinally); \
199 #define _SEH_LEAVE __leave
201 #define _SEH_GetExceptionCode() (_SEHExceptionCode)
202 #define _SEH_GetExceptionPointers() (_SEHExceptionPointers)
203 #define _SEH_AbnormalTermination() (_SEHAbnormalTermination)
209 void * _SEHPVLocals = &_SEHLocals; \
210 (void)_SEHPVLocals; \
215 #define _SEH2_EXCEPT(FILTER_) \
217 __except(_SEH_CALL_FILTER(FILTER_)) \
219 struct _EXCEPTION_POINTERS * _SEHExceptionPointers = GetExceptionPointers();\
220 long _SEHExceptionCode = GetExceptionCode(); \
222 #define _SEH2_FINALLY(FINALLY_) \
226 _SEH_CALL_FINALLY(FINALLY_)
232 #define _SEH2_HANDLE _SEH2_EXCEPT(_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER))
234 #define _SEH2_LEAVE _SEH_LEAVE
236 #define _SEH2_GetExceptionCode _SEH_GetExceptionCode
237 #define _SEH2_GetExceptionPointers _SEH_GetExceptionPointers
238 #define _SEH2_AbnormalTermination _SEH_AbnormalTermination