189099Sfjoe/* 289099Sfjoe * Copyright (c) 2000-2001 Proofpoint, Inc. and its suppliers. 389099Sfjoe * All rights reserved. 4139823Simp * 589099Sfjoe * By using this file, you agree to the terms and conditions set 689099Sfjoe * forth in the LICENSE file which can be found at the top level of 789099Sfjoe * the sendmail distribution. 889099Sfjoe * 989099Sfjoe * $Id: exc.h,v 1.24 2013-11-22 20:51:31 ca Exp $ 1089099Sfjoe */ 1189099Sfjoe 1289099Sfjoe/* 1389099Sfjoe** libsm exception handling 1489099Sfjoe** See libsm/exc.html for documentation. 1589099Sfjoe*/ 1689099Sfjoe 1789099Sfjoe#ifndef SM_EXC_H 1889099Sfjoe# define SM_EXC_H 1989099Sfjoe 2089099Sfjoe#include <sm/setjmp.h> 2189099Sfjoe#include <sm/io.h> 2289099Sfjoe#include <sm/gen.h> 2389099Sfjoe#include <sm/assert.h> 2489099Sfjoe 2589099Sfjoetypedef struct sm_exc SM_EXC_T; 2689099Sfjoetypedef struct sm_exc_type SM_EXC_TYPE_T; 2789099Sfjoetypedef union sm_val SM_VAL_T; 2889099Sfjoe 2989099Sfjoe/* 3089099Sfjoe** Exception types 3189099Sfjoe*/ 3289099Sfjoe 3389099Sfjoeextern const char SmExcTypeMagic[]; 3489099Sfjoe 3589099Sfjoestruct sm_exc_type 3689099Sfjoe{ 3789099Sfjoe const char *sm_magic; 3889099Sfjoe const char *etype_category; 3989099Sfjoe const char *etype_argformat; 4089099Sfjoe void (*etype_print) __P((SM_EXC_T *, SM_FILE_T *)); 4189099Sfjoe const char *etype_printcontext; 4289099Sfjoe}; 43109771Sfjoe 4489099Sfjoeextern const SM_EXC_TYPE_T SmEtypeOs; 4589099Sfjoeextern const SM_EXC_TYPE_T SmEtypeErr; 4689099Sfjoe 4789099Sfjoeextern void 48129880Sphksm_etype_printf __P(( 4989099Sfjoe SM_EXC_T *_exc, 5089099Sfjoe SM_FILE_T *_stream)); 5189099Sfjoe 5289099Sfjoe/* 5389099Sfjoe** Exception objects 5489099Sfjoe*/ 5589099Sfjoe 5689099Sfjoeextern const char SmExcMagic[]; 5789099Sfjoe 5889099Sfjoeunion sm_val 5989099Sfjoe{ 6089099Sfjoe int v_int; 6189099Sfjoe long v_long; 6289099Sfjoe char *v_str; 6389099Sfjoe SM_EXC_T *v_exc; 6489099Sfjoe}; 6589099Sfjoe 6689099Sfjoestruct sm_exc 67186119Sqingli{ 6889099Sfjoe const char *sm_magic; 6989099Sfjoe size_t exc_refcount; 7089099Sfjoe const SM_EXC_TYPE_T *exc_type; 7189099Sfjoe SM_VAL_T *exc_argv; 7289099Sfjoe}; 7389099Sfjoe 7489099Sfjoe# define SM_EXC_INITIALIZER(type, argv) \ 7589099Sfjoe { \ 7689099Sfjoe SmExcMagic, \ 7789099Sfjoe 0, \ 7889099Sfjoe type, \ 79109771Sfjoe argv, \ 80109771Sfjoe } 81109771Sfjoe 82109771Sfjoeextern SM_EXC_T * 83109771Sfjoesm_exc_new_x __P(( 8489099Sfjoe const SM_EXC_TYPE_T *_type, 8589099Sfjoe ...)); 8692725Salfred 87109771Sfjoeextern SM_EXC_T * 88109771Sfjoesm_exc_addref __P(( 8989099Sfjoe SM_EXC_T *_exc)); 9089099Sfjoe 9189099Sfjoeextern void 92110106Sfjoesm_exc_free __P(( 93110106Sfjoe SM_EXC_T *_exc)); 9489099Sfjoe 95109771Sfjoeextern bool 96109771Sfjoesm_exc_match __P(( 9789099Sfjoe SM_EXC_T *_exc, 9889099Sfjoe const char *_pattern)); 9989099Sfjoe 10089099Sfjoeextern void 10189099Sfjoesm_exc_write __P(( 10289099Sfjoe SM_EXC_T *_exc, 10389099Sfjoe SM_FILE_T *_stream)); 104157681Srwatson 105191148Skmacyextern void 10689099Sfjoesm_exc_print __P(( 10789099Sfjoe SM_EXC_T *_exc, 10889099Sfjoe SM_FILE_T *_stream)); 10989099Sfjoe 110109771Sfjoeextern SM_DEAD(void 111110106Sfjoesm_exc_raise_x __P(( 112193891Sbz SM_EXC_T *_exc))); 113186119Sqingli 114193891Sbzextern SM_DEAD(void 11589099Sfjoesm_exc_raisenew_x __P(( 116148887Srwatson const SM_EXC_TYPE_T *_type, 117148887Srwatson ...))); 11889099Sfjoe 11989099Sfjoe/* 12089099Sfjoe** Exception handling 12189099Sfjoe*/ 12289099Sfjoe 12389099Sfjoetypedef void (*SM_EXC_DEFAULT_HANDLER_T) __P((SM_EXC_T *)); 12489099Sfjoe 12589099Sfjoeextern void 12689099Sfjoesm_exc_newthread __P(( 12789099Sfjoe SM_EXC_DEFAULT_HANDLER_T _handle)); 12889099Sfjoe 12989099Sfjoetypedef struct sm_exc_handler SM_EXC_HANDLER_T; 13089099Sfjoestruct sm_exc_handler 13189099Sfjoe{ 13289099Sfjoe SM_EXC_T *eh_value; 133128636Sluigi SM_JMPBUF_T eh_context; 134191148Skmacy SM_EXC_HANDLER_T *eh_parent; 135191148Skmacy int eh_state; 136128636Sluigi}; 137128636Sluigi 138128636Sluigi/* values for eh_state */ 13989099Sfjoeenum 14089099Sfjoe{ 14189099Sfjoe SM_EH_PUSHED = 2, 14289099Sfjoe SM_EH_POPPED = 0, 143127260Smdodd SM_EH_HANDLED = 1 144127260Smdodd}; 145127260Smdodd 146127260Smdoddextern SM_EXC_HANDLER_T *SmExcHandler; 147127260Smdodd 148127260Smdodd# define SM_TRY { SM_EXC_HANDLER_T _h; \ 149127260Smdodd do { \ 150127260Smdodd _h.eh_value = NULL; \ 151127260Smdodd _h.eh_parent = SmExcHandler; \ 152127260Smdodd _h.eh_state = SM_EH_PUSHED; \ 153127260Smdodd SmExcHandler = &_h; \ 154127275Smdodd if (sm_setjmp_nosig(_h.eh_context) == 0) { 155127260Smdodd 156127260Smdodd# define SM_FINALLY SM_ASSERT(SmExcHandler == &_h); \ 157127260Smdodd } \ 158127260Smdodd if (sm_setjmp_nosig(_h.eh_context) == 0) { 159127275Smdodd 160127260Smdodd# define SM_EXCEPT(e,pat) } \ 161127260Smdodd if (_h.eh_state == SM_EH_HANDLED) \ 162127260Smdodd break; \ 163127260Smdodd if (_h.eh_state == SM_EH_PUSHED) { \ 164127290Smdodd SM_ASSERT(SmExcHandler == &_h); \ 165127260Smdodd SmExcHandler = _h.eh_parent; \ 166127290Smdodd } \ 167127260Smdodd _h.eh_state = sm_exc_match(_h.eh_value,pat) \ 168127260Smdodd ? SM_EH_HANDLED : SM_EH_POPPED; \ 169127260Smdodd if (_h.eh_state == SM_EH_HANDLED) { \ 17089099Sfjoe SM_UNUSED(SM_EXC_T *e) = _h.eh_value; 17189099Sfjoe 17289099Sfjoe# define SM_END_TRY } \ 173186217Sqingli } while (0); \ 174128636Sluigi if (_h.eh_state == SM_EH_PUSHED) { \ 175128636Sluigi SM_ASSERT(SmExcHandler == &_h); \ 17689099Sfjoe SmExcHandler = _h.eh_parent; \ 17789099Sfjoe if (_h.eh_value != NULL) \ 17889099Sfjoe sm_exc_raise_x(_h.eh_value); \ 179109771Sfjoe } else if (_h.eh_state == SM_EH_POPPED) { \ 180109771Sfjoe if (_h.eh_value != NULL) \ 181109771Sfjoe sm_exc_raise_x(_h.eh_value); \ 182109771Sfjoe } else \ 183109771Sfjoe sm_exc_free(_h.eh_value); \ 184109771Sfjoe } 185109771Sfjoe 186109771Sfjoe#endif /* SM_EXC_H */ 18789099Sfjoe