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