190792Sgshapiro/* 2261194Sgshapiro * Copyright (c) 2000-2001 Proofpoint, Inc. and its suppliers. 390792Sgshapiro * All rights reserved. 490792Sgshapiro * 590792Sgshapiro * By using this file, you agree to the terms and conditions set 690792Sgshapiro * forth in the LICENSE file which can be found at the top level of 790792Sgshapiro * the sendmail distribution. 890792Sgshapiro * 9266527Sgshapiro * $Id: exc.h,v 1.24 2013-11-22 20:51:31 ca Exp $ 1090792Sgshapiro */ 1190792Sgshapiro 1290792Sgshapiro/* 1390792Sgshapiro** libsm exception handling 1490792Sgshapiro** See libsm/exc.html for documentation. 1590792Sgshapiro*/ 1690792Sgshapiro 1790792Sgshapiro#ifndef SM_EXC_H 1890792Sgshapiro# define SM_EXC_H 1990792Sgshapiro 2090792Sgshapiro#include <sm/setjmp.h> 2190792Sgshapiro#include <sm/io.h> 2290792Sgshapiro#include <sm/gen.h> 2390792Sgshapiro#include <sm/assert.h> 2490792Sgshapiro 2590792Sgshapirotypedef struct sm_exc SM_EXC_T; 2690792Sgshapirotypedef struct sm_exc_type SM_EXC_TYPE_T; 2790792Sgshapirotypedef union sm_val SM_VAL_T; 2890792Sgshapiro 2990792Sgshapiro/* 3090792Sgshapiro** Exception types 3190792Sgshapiro*/ 3290792Sgshapiro 3390792Sgshapiroextern const char SmExcTypeMagic[]; 3490792Sgshapiro 3590792Sgshapirostruct sm_exc_type 3690792Sgshapiro{ 3790792Sgshapiro const char *sm_magic; 3890792Sgshapiro const char *etype_category; 3990792Sgshapiro const char *etype_argformat; 4090792Sgshapiro void (*etype_print) __P((SM_EXC_T *, SM_FILE_T *)); 4190792Sgshapiro const char *etype_printcontext; 4290792Sgshapiro}; 4390792Sgshapiro 4490792Sgshapiroextern const SM_EXC_TYPE_T SmEtypeOs; 4590792Sgshapiroextern const SM_EXC_TYPE_T SmEtypeErr; 4690792Sgshapiro 4790792Sgshapiroextern void 4890792Sgshapirosm_etype_printf __P(( 4990792Sgshapiro SM_EXC_T *_exc, 5090792Sgshapiro SM_FILE_T *_stream)); 5190792Sgshapiro 5290792Sgshapiro/* 5390792Sgshapiro** Exception objects 5490792Sgshapiro*/ 5590792Sgshapiro 5690792Sgshapiroextern const char SmExcMagic[]; 5790792Sgshapiro 5890792Sgshapirounion sm_val 5990792Sgshapiro{ 6090792Sgshapiro int v_int; 6190792Sgshapiro long v_long; 6290792Sgshapiro char *v_str; 6390792Sgshapiro SM_EXC_T *v_exc; 6490792Sgshapiro}; 6590792Sgshapiro 6690792Sgshapirostruct sm_exc 6790792Sgshapiro{ 6890792Sgshapiro const char *sm_magic; 6990792Sgshapiro size_t exc_refcount; 7090792Sgshapiro const SM_EXC_TYPE_T *exc_type; 7190792Sgshapiro SM_VAL_T *exc_argv; 7290792Sgshapiro}; 7390792Sgshapiro 7490792Sgshapiro# define SM_EXC_INITIALIZER(type, argv) \ 7590792Sgshapiro { \ 7690792Sgshapiro SmExcMagic, \ 7790792Sgshapiro 0, \ 7890792Sgshapiro type, \ 7990792Sgshapiro argv, \ 8090792Sgshapiro } 8190792Sgshapiro 8290792Sgshapiroextern SM_EXC_T * 8390792Sgshapirosm_exc_new_x __P(( 8490792Sgshapiro const SM_EXC_TYPE_T *_type, 8590792Sgshapiro ...)); 8690792Sgshapiro 8790792Sgshapiroextern SM_EXC_T * 8890792Sgshapirosm_exc_addref __P(( 8990792Sgshapiro SM_EXC_T *_exc)); 9090792Sgshapiro 9190792Sgshapiroextern void 9290792Sgshapirosm_exc_free __P(( 9390792Sgshapiro SM_EXC_T *_exc)); 9490792Sgshapiro 9590792Sgshapiroextern bool 9690792Sgshapirosm_exc_match __P(( 9790792Sgshapiro SM_EXC_T *_exc, 9890792Sgshapiro const char *_pattern)); 9990792Sgshapiro 10090792Sgshapiroextern void 10190792Sgshapirosm_exc_write __P(( 10290792Sgshapiro SM_EXC_T *_exc, 10390792Sgshapiro SM_FILE_T *_stream)); 10490792Sgshapiro 10590792Sgshapiroextern void 10690792Sgshapirosm_exc_print __P(( 10790792Sgshapiro SM_EXC_T *_exc, 10890792Sgshapiro SM_FILE_T *_stream)); 10990792Sgshapiro 11090792Sgshapiroextern SM_DEAD(void 11190792Sgshapirosm_exc_raise_x __P(( 11290792Sgshapiro SM_EXC_T *_exc))); 11390792Sgshapiro 11490792Sgshapiroextern SM_DEAD(void 11590792Sgshapirosm_exc_raisenew_x __P(( 11690792Sgshapiro const SM_EXC_TYPE_T *_type, 11790792Sgshapiro ...))); 11890792Sgshapiro 11990792Sgshapiro/* 12090792Sgshapiro** Exception handling 12190792Sgshapiro*/ 12290792Sgshapiro 12390792Sgshapirotypedef void (*SM_EXC_DEFAULT_HANDLER_T) __P((SM_EXC_T *)); 12490792Sgshapiro 12590792Sgshapiroextern void 12690792Sgshapirosm_exc_newthread __P(( 12790792Sgshapiro SM_EXC_DEFAULT_HANDLER_T _handle)); 12890792Sgshapiro 12990792Sgshapirotypedef struct sm_exc_handler SM_EXC_HANDLER_T; 13090792Sgshapirostruct sm_exc_handler 13190792Sgshapiro{ 13290792Sgshapiro SM_EXC_T *eh_value; 13390792Sgshapiro SM_JMPBUF_T eh_context; 13490792Sgshapiro SM_EXC_HANDLER_T *eh_parent; 13590792Sgshapiro int eh_state; 13690792Sgshapiro}; 13790792Sgshapiro 13890792Sgshapiro/* values for eh_state */ 13990792Sgshapiroenum 14090792Sgshapiro{ 14190792Sgshapiro SM_EH_PUSHED = 2, 14290792Sgshapiro SM_EH_POPPED = 0, 14390792Sgshapiro SM_EH_HANDLED = 1 14490792Sgshapiro}; 14590792Sgshapiro 14690792Sgshapiroextern SM_EXC_HANDLER_T *SmExcHandler; 14790792Sgshapiro 14890792Sgshapiro# define SM_TRY { SM_EXC_HANDLER_T _h; \ 14990792Sgshapiro do { \ 15090792Sgshapiro _h.eh_value = NULL; \ 15190792Sgshapiro _h.eh_parent = SmExcHandler; \ 15290792Sgshapiro _h.eh_state = SM_EH_PUSHED; \ 15390792Sgshapiro SmExcHandler = &_h; \ 15490792Sgshapiro if (sm_setjmp_nosig(_h.eh_context) == 0) { 15590792Sgshapiro 15690792Sgshapiro# define SM_FINALLY SM_ASSERT(SmExcHandler == &_h); \ 15790792Sgshapiro } \ 15890792Sgshapiro if (sm_setjmp_nosig(_h.eh_context) == 0) { 15990792Sgshapiro 16090792Sgshapiro# define SM_EXCEPT(e,pat) } \ 16190792Sgshapiro if (_h.eh_state == SM_EH_HANDLED) \ 16290792Sgshapiro break; \ 16390792Sgshapiro if (_h.eh_state == SM_EH_PUSHED) { \ 16490792Sgshapiro SM_ASSERT(SmExcHandler == &_h); \ 16590792Sgshapiro SmExcHandler = _h.eh_parent; \ 16690792Sgshapiro } \ 16790792Sgshapiro _h.eh_state = sm_exc_match(_h.eh_value,pat) \ 16890792Sgshapiro ? SM_EH_HANDLED : SM_EH_POPPED; \ 16990792Sgshapiro if (_h.eh_state == SM_EH_HANDLED) { \ 17090792Sgshapiro SM_UNUSED(SM_EXC_T *e) = _h.eh_value; 17190792Sgshapiro 17290792Sgshapiro# define SM_END_TRY } \ 17390792Sgshapiro } while (0); \ 17490792Sgshapiro if (_h.eh_state == SM_EH_PUSHED) { \ 17590792Sgshapiro SM_ASSERT(SmExcHandler == &_h); \ 17690792Sgshapiro SmExcHandler = _h.eh_parent; \ 17790792Sgshapiro if (_h.eh_value != NULL) \ 17890792Sgshapiro sm_exc_raise_x(_h.eh_value); \ 17990792Sgshapiro } else if (_h.eh_state == SM_EH_POPPED) { \ 18090792Sgshapiro if (_h.eh_value != NULL) \ 18190792Sgshapiro sm_exc_raise_x(_h.eh_value); \ 18290792Sgshapiro } else \ 18390792Sgshapiro sm_exc_free(_h.eh_value); \ 18490792Sgshapiro } 18590792Sgshapiro 18690792Sgshapiro#endif /* SM_EXC_H */ 187