xref: /illumos-gate/usr/src/cmd/sendmail/include/sm/exc.h (revision 2a8bcb4e)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3*7c478bd9Sstevel@tonic-gate  *	All rights reserved.
4*7c478bd9Sstevel@tonic-gate  *
5*7c478bd9Sstevel@tonic-gate  * By using this file, you agree to the terms and conditions set
6*7c478bd9Sstevel@tonic-gate  * forth in the LICENSE file which can be found at the top level of
7*7c478bd9Sstevel@tonic-gate  * the sendmail distribution.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  *	$Id: exc.h,v 1.23 2001/06/07 20:04:53 ca Exp $
10*7c478bd9Sstevel@tonic-gate  */
11*7c478bd9Sstevel@tonic-gate 
12*7c478bd9Sstevel@tonic-gate /*
13*7c478bd9Sstevel@tonic-gate **  libsm exception handling
14*7c478bd9Sstevel@tonic-gate **  See libsm/exc.html for documentation.
15*7c478bd9Sstevel@tonic-gate */
16*7c478bd9Sstevel@tonic-gate 
17*7c478bd9Sstevel@tonic-gate #ifndef SM_EXC_H
18*7c478bd9Sstevel@tonic-gate # define SM_EXC_H
19*7c478bd9Sstevel@tonic-gate 
20*7c478bd9Sstevel@tonic-gate #include <sm/setjmp.h>
21*7c478bd9Sstevel@tonic-gate #include <sm/io.h>
22*7c478bd9Sstevel@tonic-gate #include <sm/gen.h>
23*7c478bd9Sstevel@tonic-gate #include <sm/assert.h>
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate typedef struct sm_exc SM_EXC_T;
26*7c478bd9Sstevel@tonic-gate typedef struct sm_exc_type SM_EXC_TYPE_T;
27*7c478bd9Sstevel@tonic-gate typedef union sm_val SM_VAL_T;
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate /*
30*7c478bd9Sstevel@tonic-gate **  Exception types
31*7c478bd9Sstevel@tonic-gate */
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate extern const char SmExcTypeMagic[];
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate struct sm_exc_type
36*7c478bd9Sstevel@tonic-gate {
37*7c478bd9Sstevel@tonic-gate 	const char	*sm_magic;
38*7c478bd9Sstevel@tonic-gate 	const char	*etype_category;
39*7c478bd9Sstevel@tonic-gate 	const char	*etype_argformat;
40*7c478bd9Sstevel@tonic-gate 	void		(*etype_print) __P((SM_EXC_T *, SM_FILE_T *));
41*7c478bd9Sstevel@tonic-gate 	const char	*etype_printcontext;
42*7c478bd9Sstevel@tonic-gate };
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate extern const SM_EXC_TYPE_T SmEtypeOs;
45*7c478bd9Sstevel@tonic-gate extern const SM_EXC_TYPE_T SmEtypeErr;
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate extern void
48*7c478bd9Sstevel@tonic-gate sm_etype_printf __P((
49*7c478bd9Sstevel@tonic-gate 	SM_EXC_T *_exc,
50*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *_stream));
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate /*
53*7c478bd9Sstevel@tonic-gate **  Exception objects
54*7c478bd9Sstevel@tonic-gate */
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate extern const char SmExcMagic[];
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate union sm_val
59*7c478bd9Sstevel@tonic-gate {
60*7c478bd9Sstevel@tonic-gate 	int		v_int;
61*7c478bd9Sstevel@tonic-gate 	long		v_long;
62*7c478bd9Sstevel@tonic-gate 	char		*v_str;
63*7c478bd9Sstevel@tonic-gate 	SM_EXC_T	*v_exc;
64*7c478bd9Sstevel@tonic-gate };
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate struct sm_exc
67*7c478bd9Sstevel@tonic-gate {
68*7c478bd9Sstevel@tonic-gate 	const char		*sm_magic;
69*7c478bd9Sstevel@tonic-gate 	size_t			exc_refcount;
70*7c478bd9Sstevel@tonic-gate 	const SM_EXC_TYPE_T	*exc_type;
71*7c478bd9Sstevel@tonic-gate 	SM_VAL_T		*exc_argv;
72*7c478bd9Sstevel@tonic-gate };
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate # define SM_EXC_INITIALIZER(type, argv) \
75*7c478bd9Sstevel@tonic-gate 	{ \
76*7c478bd9Sstevel@tonic-gate 		SmExcMagic, \
77*7c478bd9Sstevel@tonic-gate 		0, \
78*7c478bd9Sstevel@tonic-gate 		type, \
79*7c478bd9Sstevel@tonic-gate 		argv, \
80*7c478bd9Sstevel@tonic-gate 	}
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate extern SM_EXC_T *
83*7c478bd9Sstevel@tonic-gate sm_exc_new_x __P((
84*7c478bd9Sstevel@tonic-gate 	const SM_EXC_TYPE_T *_type,
85*7c478bd9Sstevel@tonic-gate 	...));
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate extern SM_EXC_T *
88*7c478bd9Sstevel@tonic-gate sm_exc_addref __P((
89*7c478bd9Sstevel@tonic-gate 	SM_EXC_T *_exc));
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate extern void
92*7c478bd9Sstevel@tonic-gate sm_exc_free __P((
93*7c478bd9Sstevel@tonic-gate 	SM_EXC_T *_exc));
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate extern bool
96*7c478bd9Sstevel@tonic-gate sm_exc_match __P((
97*7c478bd9Sstevel@tonic-gate 	SM_EXC_T *_exc,
98*7c478bd9Sstevel@tonic-gate 	const char *_pattern));
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate extern void
101*7c478bd9Sstevel@tonic-gate sm_exc_write __P((
102*7c478bd9Sstevel@tonic-gate 	SM_EXC_T *_exc,
103*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *_stream));
104*7c478bd9Sstevel@tonic-gate 
105*7c478bd9Sstevel@tonic-gate extern void
106*7c478bd9Sstevel@tonic-gate sm_exc_print __P((
107*7c478bd9Sstevel@tonic-gate 	SM_EXC_T *_exc,
108*7c478bd9Sstevel@tonic-gate 	SM_FILE_T *_stream));
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate extern SM_DEAD(void
111*7c478bd9Sstevel@tonic-gate sm_exc_raise_x __P((
112*7c478bd9Sstevel@tonic-gate 	SM_EXC_T *_exc)));
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate extern SM_DEAD(void
115*7c478bd9Sstevel@tonic-gate sm_exc_raisenew_x __P((
116*7c478bd9Sstevel@tonic-gate 	const SM_EXC_TYPE_T *_type,
117*7c478bd9Sstevel@tonic-gate 	...)));
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate /*
120*7c478bd9Sstevel@tonic-gate **  Exception handling
121*7c478bd9Sstevel@tonic-gate */
122*7c478bd9Sstevel@tonic-gate 
123*7c478bd9Sstevel@tonic-gate typedef void (*SM_EXC_DEFAULT_HANDLER_T) __P((SM_EXC_T *));
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate extern void
126*7c478bd9Sstevel@tonic-gate sm_exc_newthread __P((
127*7c478bd9Sstevel@tonic-gate 	SM_EXC_DEFAULT_HANDLER_T _handle));
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate typedef struct sm_exc_handler SM_EXC_HANDLER_T;
130*7c478bd9Sstevel@tonic-gate struct sm_exc_handler
131*7c478bd9Sstevel@tonic-gate {
132*7c478bd9Sstevel@tonic-gate 	SM_EXC_T		*eh_value;
133*7c478bd9Sstevel@tonic-gate 	SM_JMPBUF_T		eh_context;
134*7c478bd9Sstevel@tonic-gate 	SM_EXC_HANDLER_T	*eh_parent;
135*7c478bd9Sstevel@tonic-gate 	int			eh_state;
136*7c478bd9Sstevel@tonic-gate };
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate /* values for eh_state */
139*7c478bd9Sstevel@tonic-gate enum
140*7c478bd9Sstevel@tonic-gate {
141*7c478bd9Sstevel@tonic-gate 	SM_EH_PUSHED = 2,
142*7c478bd9Sstevel@tonic-gate 	SM_EH_POPPED = 0,
143*7c478bd9Sstevel@tonic-gate 	SM_EH_HANDLED = 1
144*7c478bd9Sstevel@tonic-gate };
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate extern SM_EXC_HANDLER_T *SmExcHandler;
147*7c478bd9Sstevel@tonic-gate 
148*7c478bd9Sstevel@tonic-gate # define SM_TRY		{ SM_EXC_HANDLER_T _h; \
149*7c478bd9Sstevel@tonic-gate 			  do { \
150*7c478bd9Sstevel@tonic-gate 			    _h.eh_value = NULL; \
151*7c478bd9Sstevel@tonic-gate 			    _h.eh_parent = SmExcHandler; \
152*7c478bd9Sstevel@tonic-gate 			    _h.eh_state = SM_EH_PUSHED; \
153*7c478bd9Sstevel@tonic-gate 			    SmExcHandler = &_h; \
154*7c478bd9Sstevel@tonic-gate 			    if (sm_setjmp_nosig(_h.eh_context) == 0) {
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate # define SM_FINALLY	      SM_ASSERT(SmExcHandler == &_h); \
157*7c478bd9Sstevel@tonic-gate 			    } \
158*7c478bd9Sstevel@tonic-gate 			    if (sm_setjmp_nosig(_h.eh_context) == 0) {
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate # define SM_EXCEPT(e,pat)   } \
161*7c478bd9Sstevel@tonic-gate 			    if (_h.eh_state == SM_EH_HANDLED) \
162*7c478bd9Sstevel@tonic-gate 			      break; \
163*7c478bd9Sstevel@tonic-gate 			    if (_h.eh_state == SM_EH_PUSHED) { \
164*7c478bd9Sstevel@tonic-gate 			      SM_ASSERT(SmExcHandler == &_h); \
165*7c478bd9Sstevel@tonic-gate 			      SmExcHandler = _h.eh_parent; \
166*7c478bd9Sstevel@tonic-gate 			    } \
167*7c478bd9Sstevel@tonic-gate 			    _h.eh_state = sm_exc_match(_h.eh_value,pat) \
168*7c478bd9Sstevel@tonic-gate 			      ? SM_EH_HANDLED : SM_EH_POPPED; \
169*7c478bd9Sstevel@tonic-gate 			    if (_h.eh_state == SM_EH_HANDLED) { \
170*7c478bd9Sstevel@tonic-gate 			      SM_UNUSED(SM_EXC_T *e) = _h.eh_value;
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate # define SM_END_TRY	  } \
173*7c478bd9Sstevel@tonic-gate 			  } while (0); \
174*7c478bd9Sstevel@tonic-gate 			  if (_h.eh_state == SM_EH_PUSHED) { \
175*7c478bd9Sstevel@tonic-gate 			    SM_ASSERT(SmExcHandler == &_h); \
176*7c478bd9Sstevel@tonic-gate 			    SmExcHandler = _h.eh_parent; \
177*7c478bd9Sstevel@tonic-gate 			    if (_h.eh_value != NULL) \
178*7c478bd9Sstevel@tonic-gate 			      sm_exc_raise_x(_h.eh_value); \
179*7c478bd9Sstevel@tonic-gate 			  } else if (_h.eh_state == SM_EH_POPPED) { \
180*7c478bd9Sstevel@tonic-gate 			    if (_h.eh_value != NULL) \
181*7c478bd9Sstevel@tonic-gate 			      sm_exc_raise_x(_h.eh_value); \
182*7c478bd9Sstevel@tonic-gate 			  } else \
183*7c478bd9Sstevel@tonic-gate 			    sm_exc_free(_h.eh_value); \
184*7c478bd9Sstevel@tonic-gate 			}
185*7c478bd9Sstevel@tonic-gate 
186*7c478bd9Sstevel@tonic-gate #endif /* SM_EXC_H */
187