2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
9 * $Id: exc.h,v 1.23 2001/06/07 20:04:53 ca Exp $
12 #pragma ident "%Z%%M% %I% %E% SMI"
15 ** libsm exception handling
16 ** See libsm/exc.html for documentation.
22 #include <sm/setjmp.h>
25 #include <sm/assert.h>
27 typedef struct sm_exc SM_EXC_T
;
28 typedef struct sm_exc_type SM_EXC_TYPE_T
;
29 typedef union sm_val SM_VAL_T
;
35 extern const char SmExcTypeMagic
[];
40 const char *etype_category
;
41 const char *etype_argformat
;
42 void (*etype_print
) __P((SM_EXC_T
*, SM_FILE_T
*));
43 const char *etype_printcontext
;
46 extern const SM_EXC_TYPE_T SmEtypeOs
;
47 extern const SM_EXC_TYPE_T SmEtypeErr
;
58 extern const char SmExcMagic
[];
72 const SM_EXC_TYPE_T
*exc_type
;
76 # define SM_EXC_INITIALIZER(type, argv) \
86 const SM_EXC_TYPE_T
*_type
,
100 const char *_pattern
));
105 SM_FILE_T
*_stream
));
110 SM_FILE_T
*_stream
));
117 sm_exc_raisenew_x
__P((
118 const SM_EXC_TYPE_T
*_type
,
122 ** Exception handling
125 typedef void (*SM_EXC_DEFAULT_HANDLER_T
) __P((SM_EXC_T
*));
128 sm_exc_newthread
__P((
129 SM_EXC_DEFAULT_HANDLER_T _handle
));
131 typedef struct sm_exc_handler SM_EXC_HANDLER_T
;
132 struct sm_exc_handler
135 SM_JMPBUF_T eh_context
;
136 SM_EXC_HANDLER_T
*eh_parent
;
140 /* values for eh_state */
148 extern SM_EXC_HANDLER_T
*SmExcHandler
;
150 # define SM_TRY { SM_EXC_HANDLER_T _h; \
152 _h.eh_value = NULL; \
153 _h.eh_parent = SmExcHandler; \
154 _h.eh_state = SM_EH_PUSHED; \
155 SmExcHandler = &_h; \
156 if (sm_setjmp_nosig(_h.eh_context) == 0) {
158 # define SM_FINALLY SM_ASSERT(SmExcHandler == &_h); \
160 if (sm_setjmp_nosig(_h.eh_context) == 0) {
162 # define SM_EXCEPT(e,pat) } \
163 if (_h.eh_state == SM_EH_HANDLED) \
165 if (_h.eh_state == SM_EH_PUSHED) { \
166 SM_ASSERT(SmExcHandler == &_h); \
167 SmExcHandler = _h.eh_parent; \
169 _h.eh_state = sm_exc_match(_h.eh_value,pat) \
170 ? SM_EH_HANDLED : SM_EH_POPPED; \
171 if (_h.eh_state == SM_EH_HANDLED) { \
172 SM_UNUSED(SM_EXC_T *e) = _h.eh_value;
174 # define SM_END_TRY } \
176 if (_h.eh_state == SM_EH_PUSHED) { \
177 SM_ASSERT(SmExcHandler == &_h); \
178 SmExcHandler = _h.eh_parent; \
179 if (_h.eh_value != NULL) \
180 sm_exc_raise_x(_h.eh_value); \
181 } else if (_h.eh_state == SM_EH_POPPED) { \
182 if (_h.eh_value != NULL) \
183 sm_exc_raise_x(_h.eh_value); \
185 sm_exc_free(_h.eh_value); \
188 #endif /* SM_EXC_H */