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