diff options
Diffstat (limited to 'contrib/sendmail/include/sm/exc.h')
-rw-r--r-- | contrib/sendmail/include/sm/exc.h | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/contrib/sendmail/include/sm/exc.h b/contrib/sendmail/include/sm/exc.h new file mode 100644 index 0000000..afcb125 --- /dev/null +++ b/contrib/sendmail/include/sm/exc.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * All rights reserved. + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the sendmail distribution. + * + * $Id: exc.h,v 1.23 2001/06/07 20:04:53 ca Exp $ + */ + +/* +** libsm exception handling +** See libsm/exc.html for documentation. +*/ + +#ifndef SM_EXC_H +# define SM_EXC_H + +#include <sm/setjmp.h> +#include <sm/io.h> +#include <sm/gen.h> +#include <sm/assert.h> + +typedef struct sm_exc SM_EXC_T; +typedef struct sm_exc_type SM_EXC_TYPE_T; +typedef union sm_val SM_VAL_T; + +/* +** Exception types +*/ + +extern const char SmExcTypeMagic[]; + +struct sm_exc_type +{ + const char *sm_magic; + const char *etype_category; + const char *etype_argformat; + void (*etype_print) __P((SM_EXC_T *, SM_FILE_T *)); + const char *etype_printcontext; +}; + +extern const SM_EXC_TYPE_T SmEtypeOs; +extern const SM_EXC_TYPE_T SmEtypeErr; + +extern void +sm_etype_printf __P(( + SM_EXC_T *_exc, + SM_FILE_T *_stream)); + +/* +** Exception objects +*/ + +extern const char SmExcMagic[]; + +union sm_val +{ + int v_int; + long v_long; + char *v_str; + SM_EXC_T *v_exc; +}; + +struct sm_exc +{ + const char *sm_magic; + size_t exc_refcount; + const SM_EXC_TYPE_T *exc_type; + SM_VAL_T *exc_argv; +}; + +# define SM_EXC_INITIALIZER(type, argv) \ + { \ + SmExcMagic, \ + 0, \ + type, \ + argv, \ + } + +extern SM_EXC_T * +sm_exc_new_x __P(( + const SM_EXC_TYPE_T *_type, + ...)); + +extern SM_EXC_T * +sm_exc_addref __P(( + SM_EXC_T *_exc)); + +extern void +sm_exc_free __P(( + SM_EXC_T *_exc)); + +extern bool +sm_exc_match __P(( + SM_EXC_T *_exc, + const char *_pattern)); + +extern void +sm_exc_write __P(( + SM_EXC_T *_exc, + SM_FILE_T *_stream)); + +extern void +sm_exc_print __P(( + SM_EXC_T *_exc, + SM_FILE_T *_stream)); + +extern SM_DEAD(void +sm_exc_raise_x __P(( + SM_EXC_T *_exc))); + +extern SM_DEAD(void +sm_exc_raisenew_x __P(( + const SM_EXC_TYPE_T *_type, + ...))); + +/* +** Exception handling +*/ + +typedef void (*SM_EXC_DEFAULT_HANDLER_T) __P((SM_EXC_T *)); + +extern void +sm_exc_newthread __P(( + SM_EXC_DEFAULT_HANDLER_T _handle)); + +typedef struct sm_exc_handler SM_EXC_HANDLER_T; +struct sm_exc_handler +{ + SM_EXC_T *eh_value; + SM_JMPBUF_T eh_context; + SM_EXC_HANDLER_T *eh_parent; + int eh_state; +}; + +/* values for eh_state */ +enum +{ + SM_EH_PUSHED = 2, + SM_EH_POPPED = 0, + SM_EH_HANDLED = 1 +}; + +extern SM_EXC_HANDLER_T *SmExcHandler; + +# define SM_TRY { SM_EXC_HANDLER_T _h; \ + do { \ + _h.eh_value = NULL; \ + _h.eh_parent = SmExcHandler; \ + _h.eh_state = SM_EH_PUSHED; \ + SmExcHandler = &_h; \ + if (sm_setjmp_nosig(_h.eh_context) == 0) { + +# define SM_FINALLY SM_ASSERT(SmExcHandler == &_h); \ + } \ + if (sm_setjmp_nosig(_h.eh_context) == 0) { + +# define SM_EXCEPT(e,pat) } \ + if (_h.eh_state == SM_EH_HANDLED) \ + break; \ + if (_h.eh_state == SM_EH_PUSHED) { \ + SM_ASSERT(SmExcHandler == &_h); \ + SmExcHandler = _h.eh_parent; \ + } \ + _h.eh_state = sm_exc_match(_h.eh_value,pat) \ + ? SM_EH_HANDLED : SM_EH_POPPED; \ + if (_h.eh_state == SM_EH_HANDLED) { \ + SM_UNUSED(SM_EXC_T *e) = _h.eh_value; + +# define SM_END_TRY } \ + } while (0); \ + if (_h.eh_state == SM_EH_PUSHED) { \ + SM_ASSERT(SmExcHandler == &_h); \ + SmExcHandler = _h.eh_parent; \ + if (_h.eh_value != NULL) \ + sm_exc_raise_x(_h.eh_value); \ + } else if (_h.eh_state == SM_EH_POPPED) { \ + if (_h.eh_value != NULL) \ + sm_exc_raise_x(_h.eh_value); \ + } else \ + sm_exc_free(_h.eh_value); \ + } + +#endif /* SM_EXC_H */ |