xref: /freebsd/contrib/sendmail/include/sm/exc.h (revision ee7b0571c2c18bdec848ed2044223cc88db29bd8)
140266059SGregory Neil Shapiro /*
25dd76dd0SGregory Neil Shapiro  * Copyright (c) 2000-2001 Proofpoint, Inc. and its suppliers.
340266059SGregory Neil Shapiro  *	All rights reserved.
440266059SGregory Neil Shapiro  *
540266059SGregory Neil Shapiro  * By using this file, you agree to the terms and conditions set
640266059SGregory Neil Shapiro  * forth in the LICENSE file which can be found at the top level of
740266059SGregory Neil Shapiro  * the sendmail distribution.
840266059SGregory Neil Shapiro  *
9*4313cc83SGregory Neil Shapiro  *	$Id: exc.h,v 1.24 2013-11-22 20:51:31 ca Exp $
1040266059SGregory Neil Shapiro  */
1140266059SGregory Neil Shapiro 
1240266059SGregory Neil Shapiro /*
1340266059SGregory Neil Shapiro **  libsm exception handling
1440266059SGregory Neil Shapiro **  See libsm/exc.html for documentation.
1540266059SGregory Neil Shapiro */
1640266059SGregory Neil Shapiro 
1740266059SGregory Neil Shapiro #ifndef SM_EXC_H
1840266059SGregory Neil Shapiro # define SM_EXC_H
1940266059SGregory Neil Shapiro 
2040266059SGregory Neil Shapiro #include <sm/setjmp.h>
2140266059SGregory Neil Shapiro #include <sm/io.h>
2240266059SGregory Neil Shapiro #include <sm/gen.h>
2340266059SGregory Neil Shapiro #include <sm/assert.h>
2440266059SGregory Neil Shapiro 
2540266059SGregory Neil Shapiro typedef struct sm_exc SM_EXC_T;
2640266059SGregory Neil Shapiro typedef struct sm_exc_type SM_EXC_TYPE_T;
2740266059SGregory Neil Shapiro typedef union sm_val SM_VAL_T;
2840266059SGregory Neil Shapiro 
2940266059SGregory Neil Shapiro /*
3040266059SGregory Neil Shapiro **  Exception types
3140266059SGregory Neil Shapiro */
3240266059SGregory Neil Shapiro 
3340266059SGregory Neil Shapiro extern const char SmExcTypeMagic[];
3440266059SGregory Neil Shapiro 
3540266059SGregory Neil Shapiro struct sm_exc_type
3640266059SGregory Neil Shapiro {
3740266059SGregory Neil Shapiro 	const char	*sm_magic;
3840266059SGregory Neil Shapiro 	const char	*etype_category;
3940266059SGregory Neil Shapiro 	const char	*etype_argformat;
4040266059SGregory Neil Shapiro 	void		(*etype_print) __P((SM_EXC_T *, SM_FILE_T *));
4140266059SGregory Neil Shapiro 	const char	*etype_printcontext;
4240266059SGregory Neil Shapiro };
4340266059SGregory Neil Shapiro 
4440266059SGregory Neil Shapiro extern const SM_EXC_TYPE_T SmEtypeOs;
4540266059SGregory Neil Shapiro extern const SM_EXC_TYPE_T SmEtypeErr;
4640266059SGregory Neil Shapiro 
4740266059SGregory Neil Shapiro extern void
4840266059SGregory Neil Shapiro sm_etype_printf __P((
4940266059SGregory Neil Shapiro 	SM_EXC_T *_exc,
5040266059SGregory Neil Shapiro 	SM_FILE_T *_stream));
5140266059SGregory Neil Shapiro 
5240266059SGregory Neil Shapiro /*
5340266059SGregory Neil Shapiro **  Exception objects
5440266059SGregory Neil Shapiro */
5540266059SGregory Neil Shapiro 
5640266059SGregory Neil Shapiro extern const char SmExcMagic[];
5740266059SGregory Neil Shapiro 
5840266059SGregory Neil Shapiro union sm_val
5940266059SGregory Neil Shapiro {
6040266059SGregory Neil Shapiro 	int		v_int;
6140266059SGregory Neil Shapiro 	long		v_long;
6240266059SGregory Neil Shapiro 	char		*v_str;
6340266059SGregory Neil Shapiro 	SM_EXC_T	*v_exc;
6440266059SGregory Neil Shapiro };
6540266059SGregory Neil Shapiro 
6640266059SGregory Neil Shapiro struct sm_exc
6740266059SGregory Neil Shapiro {
6840266059SGregory Neil Shapiro 	const char		*sm_magic;
6940266059SGregory Neil Shapiro 	size_t			exc_refcount;
7040266059SGregory Neil Shapiro 	const SM_EXC_TYPE_T	*exc_type;
7140266059SGregory Neil Shapiro 	SM_VAL_T		*exc_argv;
7240266059SGregory Neil Shapiro };
7340266059SGregory Neil Shapiro 
7440266059SGregory Neil Shapiro # define SM_EXC_INITIALIZER(type, argv) \
7540266059SGregory Neil Shapiro 	{ \
7640266059SGregory Neil Shapiro 		SmExcMagic, \
7740266059SGregory Neil Shapiro 		0, \
7840266059SGregory Neil Shapiro 		type, \
7940266059SGregory Neil Shapiro 		argv, \
8040266059SGregory Neil Shapiro 	}
8140266059SGregory Neil Shapiro 
8240266059SGregory Neil Shapiro extern SM_EXC_T *
8340266059SGregory Neil Shapiro sm_exc_new_x __P((
8440266059SGregory Neil Shapiro 	const SM_EXC_TYPE_T *_type,
8540266059SGregory Neil Shapiro 	...));
8640266059SGregory Neil Shapiro 
8740266059SGregory Neil Shapiro extern SM_EXC_T *
8840266059SGregory Neil Shapiro sm_exc_addref __P((
8940266059SGregory Neil Shapiro 	SM_EXC_T *_exc));
9040266059SGregory Neil Shapiro 
9140266059SGregory Neil Shapiro extern void
9240266059SGregory Neil Shapiro sm_exc_free __P((
9340266059SGregory Neil Shapiro 	SM_EXC_T *_exc));
9440266059SGregory Neil Shapiro 
9540266059SGregory Neil Shapiro extern bool
9640266059SGregory Neil Shapiro sm_exc_match __P((
9740266059SGregory Neil Shapiro 	SM_EXC_T *_exc,
9840266059SGregory Neil Shapiro 	const char *_pattern));
9940266059SGregory Neil Shapiro 
10040266059SGregory Neil Shapiro extern void
10140266059SGregory Neil Shapiro sm_exc_write __P((
10240266059SGregory Neil Shapiro 	SM_EXC_T *_exc,
10340266059SGregory Neil Shapiro 	SM_FILE_T *_stream));
10440266059SGregory Neil Shapiro 
10540266059SGregory Neil Shapiro extern void
10640266059SGregory Neil Shapiro sm_exc_print __P((
10740266059SGregory Neil Shapiro 	SM_EXC_T *_exc,
10840266059SGregory Neil Shapiro 	SM_FILE_T *_stream));
10940266059SGregory Neil Shapiro 
11040266059SGregory Neil Shapiro extern SM_DEAD(void
11140266059SGregory Neil Shapiro sm_exc_raise_x __P((
11240266059SGregory Neil Shapiro 	SM_EXC_T *_exc)));
11340266059SGregory Neil Shapiro 
11440266059SGregory Neil Shapiro extern SM_DEAD(void
11540266059SGregory Neil Shapiro sm_exc_raisenew_x __P((
11640266059SGregory Neil Shapiro 	const SM_EXC_TYPE_T *_type,
11740266059SGregory Neil Shapiro 	...)));
11840266059SGregory Neil Shapiro 
11940266059SGregory Neil Shapiro /*
12040266059SGregory Neil Shapiro **  Exception handling
12140266059SGregory Neil Shapiro */
12240266059SGregory Neil Shapiro 
12340266059SGregory Neil Shapiro typedef void (*SM_EXC_DEFAULT_HANDLER_T) __P((SM_EXC_T *));
12440266059SGregory Neil Shapiro 
12540266059SGregory Neil Shapiro extern void
12640266059SGregory Neil Shapiro sm_exc_newthread __P((
12740266059SGregory Neil Shapiro 	SM_EXC_DEFAULT_HANDLER_T _handle));
12840266059SGregory Neil Shapiro 
12940266059SGregory Neil Shapiro typedef struct sm_exc_handler SM_EXC_HANDLER_T;
13040266059SGregory Neil Shapiro struct sm_exc_handler
13140266059SGregory Neil Shapiro {
13240266059SGregory Neil Shapiro 	SM_EXC_T		*eh_value;
13340266059SGregory Neil Shapiro 	SM_JMPBUF_T		eh_context;
13440266059SGregory Neil Shapiro 	SM_EXC_HANDLER_T	*eh_parent;
13540266059SGregory Neil Shapiro 	int			eh_state;
13640266059SGregory Neil Shapiro };
13740266059SGregory Neil Shapiro 
13840266059SGregory Neil Shapiro /* values for eh_state */
13940266059SGregory Neil Shapiro enum
14040266059SGregory Neil Shapiro {
14140266059SGregory Neil Shapiro 	SM_EH_PUSHED = 2,
14240266059SGregory Neil Shapiro 	SM_EH_POPPED = 0,
14340266059SGregory Neil Shapiro 	SM_EH_HANDLED = 1
14440266059SGregory Neil Shapiro };
14540266059SGregory Neil Shapiro 
14640266059SGregory Neil Shapiro extern SM_EXC_HANDLER_T *SmExcHandler;
14740266059SGregory Neil Shapiro 
14840266059SGregory Neil Shapiro # define SM_TRY		{ SM_EXC_HANDLER_T _h; \
14940266059SGregory Neil Shapiro 			  do { \
15040266059SGregory Neil Shapiro 			    _h.eh_value = NULL; \
15140266059SGregory Neil Shapiro 			    _h.eh_parent = SmExcHandler; \
15240266059SGregory Neil Shapiro 			    _h.eh_state = SM_EH_PUSHED; \
15340266059SGregory Neil Shapiro 			    SmExcHandler = &_h; \
15440266059SGregory Neil Shapiro 			    if (sm_setjmp_nosig(_h.eh_context) == 0) {
15540266059SGregory Neil Shapiro 
15640266059SGregory Neil Shapiro # define SM_FINALLY	      SM_ASSERT(SmExcHandler == &_h); \
15740266059SGregory Neil Shapiro 			    } \
15840266059SGregory Neil Shapiro 			    if (sm_setjmp_nosig(_h.eh_context) == 0) {
15940266059SGregory Neil Shapiro 
16040266059SGregory Neil Shapiro # define SM_EXCEPT(e,pat)   } \
16140266059SGregory Neil Shapiro 			    if (_h.eh_state == SM_EH_HANDLED) \
16240266059SGregory Neil Shapiro 			      break; \
16340266059SGregory Neil Shapiro 			    if (_h.eh_state == SM_EH_PUSHED) { \
16440266059SGregory Neil Shapiro 			      SM_ASSERT(SmExcHandler == &_h); \
16540266059SGregory Neil Shapiro 			      SmExcHandler = _h.eh_parent; \
16640266059SGregory Neil Shapiro 			    } \
16740266059SGregory Neil Shapiro 			    _h.eh_state = sm_exc_match(_h.eh_value,pat) \
16840266059SGregory Neil Shapiro 			      ? SM_EH_HANDLED : SM_EH_POPPED; \
16940266059SGregory Neil Shapiro 			    if (_h.eh_state == SM_EH_HANDLED) { \
17040266059SGregory Neil Shapiro 			      SM_UNUSED(SM_EXC_T *e) = _h.eh_value;
17140266059SGregory Neil Shapiro 
17240266059SGregory Neil Shapiro # define SM_END_TRY	  } \
17340266059SGregory Neil Shapiro 			  } while (0); \
17440266059SGregory Neil Shapiro 			  if (_h.eh_state == SM_EH_PUSHED) { \
17540266059SGregory Neil Shapiro 			    SM_ASSERT(SmExcHandler == &_h); \
17640266059SGregory Neil Shapiro 			    SmExcHandler = _h.eh_parent; \
17740266059SGregory Neil Shapiro 			    if (_h.eh_value != NULL) \
17840266059SGregory Neil Shapiro 			      sm_exc_raise_x(_h.eh_value); \
17940266059SGregory Neil Shapiro 			  } else if (_h.eh_state == SM_EH_POPPED) { \
18040266059SGregory Neil Shapiro 			    if (_h.eh_value != NULL) \
18140266059SGregory Neil Shapiro 			      sm_exc_raise_x(_h.eh_value); \
18240266059SGregory Neil Shapiro 			  } else \
18340266059SGregory Neil Shapiro 			    sm_exc_free(_h.eh_value); \
18440266059SGregory Neil Shapiro 			}
18540266059SGregory Neil Shapiro 
18640266059SGregory Neil Shapiro #endif /* SM_EXC_H */
187