8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sendmail / include / sm / exc.h
blobeea62b1188e4c4608f634bd82c77735988840bb5
1 /*
2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
9 * $Id: exc.h,v 1.23 2001/06/07 20:04:53 ca Exp $
12 #pragma ident "%Z%%M% %I% %E% SMI"
15 ** libsm exception handling
16 ** See libsm/exc.html for documentation.
19 #ifndef SM_EXC_H
20 # define SM_EXC_H
22 #include <sm/setjmp.h>
23 #include <sm/io.h>
24 #include <sm/gen.h>
25 #include <sm/assert.h>
27 typedef struct sm_exc SM_EXC_T;
28 typedef struct sm_exc_type SM_EXC_TYPE_T;
29 typedef union sm_val SM_VAL_T;
32 ** Exception types
35 extern const char SmExcTypeMagic[];
37 struct sm_exc_type
39 const char *sm_magic;
40 const char *etype_category;
41 const char *etype_argformat;
42 void (*etype_print) __P((SM_EXC_T *, SM_FILE_T *));
43 const char *etype_printcontext;
46 extern const SM_EXC_TYPE_T SmEtypeOs;
47 extern const SM_EXC_TYPE_T SmEtypeErr;
49 extern void
50 sm_etype_printf __P((
51 SM_EXC_T *_exc,
52 SM_FILE_T *_stream));
55 ** Exception objects
58 extern const char SmExcMagic[];
60 union sm_val
62 int v_int;
63 long v_long;
64 char *v_str;
65 SM_EXC_T *v_exc;
68 struct sm_exc
70 const char *sm_magic;
71 size_t exc_refcount;
72 const SM_EXC_TYPE_T *exc_type;
73 SM_VAL_T *exc_argv;
76 # define SM_EXC_INITIALIZER(type, argv) \
77 { \
78 SmExcMagic, \
79 0, \
80 type, \
81 argv, \
84 extern SM_EXC_T *
85 sm_exc_new_x __P((
86 const SM_EXC_TYPE_T *_type,
87 ...));
89 extern SM_EXC_T *
90 sm_exc_addref __P((
91 SM_EXC_T *_exc));
93 extern void
94 sm_exc_free __P((
95 SM_EXC_T *_exc));
97 extern bool
98 sm_exc_match __P((
99 SM_EXC_T *_exc,
100 const char *_pattern));
102 extern void
103 sm_exc_write __P((
104 SM_EXC_T *_exc,
105 SM_FILE_T *_stream));
107 extern void
108 sm_exc_print __P((
109 SM_EXC_T *_exc,
110 SM_FILE_T *_stream));
112 extern SM_DEAD(void
113 sm_exc_raise_x __P((
114 SM_EXC_T *_exc)));
116 extern SM_DEAD(void
117 sm_exc_raisenew_x __P((
118 const SM_EXC_TYPE_T *_type,
119 ...)));
122 ** Exception handling
125 typedef void (*SM_EXC_DEFAULT_HANDLER_T) __P((SM_EXC_T *));
127 extern void
128 sm_exc_newthread __P((
129 SM_EXC_DEFAULT_HANDLER_T _handle));
131 typedef struct sm_exc_handler SM_EXC_HANDLER_T;
132 struct sm_exc_handler
134 SM_EXC_T *eh_value;
135 SM_JMPBUF_T eh_context;
136 SM_EXC_HANDLER_T *eh_parent;
137 int eh_state;
140 /* values for eh_state */
141 enum
143 SM_EH_PUSHED = 2,
144 SM_EH_POPPED = 0,
145 SM_EH_HANDLED = 1
148 extern SM_EXC_HANDLER_T *SmExcHandler;
150 # define SM_TRY { SM_EXC_HANDLER_T _h; \
151 do { \
152 _h.eh_value = NULL; \
153 _h.eh_parent = SmExcHandler; \
154 _h.eh_state = SM_EH_PUSHED; \
155 SmExcHandler = &_h; \
156 if (sm_setjmp_nosig(_h.eh_context) == 0) {
158 # define SM_FINALLY SM_ASSERT(SmExcHandler == &_h); \
160 if (sm_setjmp_nosig(_h.eh_context) == 0) {
162 # define SM_EXCEPT(e,pat) } \
163 if (_h.eh_state == SM_EH_HANDLED) \
164 break; \
165 if (_h.eh_state == SM_EH_PUSHED) { \
166 SM_ASSERT(SmExcHandler == &_h); \
167 SmExcHandler = _h.eh_parent; \
169 _h.eh_state = sm_exc_match(_h.eh_value,pat) \
170 ? SM_EH_HANDLED : SM_EH_POPPED; \
171 if (_h.eh_state == SM_EH_HANDLED) { \
172 SM_UNUSED(SM_EXC_T *e) = _h.eh_value;
174 # define SM_END_TRY } \
175 } while (0); \
176 if (_h.eh_state == SM_EH_PUSHED) { \
177 SM_ASSERT(SmExcHandler == &_h); \
178 SmExcHandler = _h.eh_parent; \
179 if (_h.eh_value != NULL) \
180 sm_exc_raise_x(_h.eh_value); \
181 } else if (_h.eh_state == SM_EH_POPPED) { \
182 if (_h.eh_value != NULL) \
183 sm_exc_raise_x(_h.eh_value); \
184 } else \
185 sm_exc_free(_h.eh_value); \
188 #endif /* SM_EXC_H */