summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/include/sm/exc.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/include/sm/exc.h')
-rw-r--r--contrib/sendmail/include/sm/exc.h186
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 */
OpenPOWER on IntegriCloud