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