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