2 * Portable Exception Handling for ANSI C.
3 * Copyright (C) 1999 Kaz Kylheku <kaz@ashi.footprints.net>
5 * Free Software License:
7 * All rights are reserved by the author, with the following exceptions:
8 * Permission is granted to freely reproduce and distribute this software,
9 * possibly in exchange for a fee, provided that this copyright notice appears
10 * intact. Permission is also granted to adapt this software to produce
11 * derivative works, as long as the modified versions carry this copyright
12 * notice and additional notices stating that the work has been modified.
13 * This source code may be translated into executable form and incorporated
14 * into proprietary software; there is no requirement for such software to
15 * contain a copyright notice related to this source.
21 * Portable Exception Handling for ANSI C.<BR>
22 * Modified to support throwing an exception with a null message pointer,
23 * and to have the message not be const (as we generate messages with
24 * "ws_strdup_printf()", which means they need to be freed; using
25 * a null message means that we don't have to use a special string
26 * for exceptions with no message, and don't have to worry about
38 #include "ws_symbol_export.h"
39 #include "ws_attributes.h"
41 #define XCEPT_GROUP_ANY 0
42 #define XCEPT_CODE_ANY 0
43 #define XCEPT_BAD_ALLOC 1
49 enum { except_no_call
, except_call
};
52 unsigned long except_group
;
53 unsigned long except_code
;
57 except_id_t
volatile except_id
;
58 const char *volatile except_message
;
59 void *volatile except_dyndata
;
62 struct except_cleanup
{
63 void (*except_func
)(void *);
68 const except_id_t
*except_id
;
74 enum except_stacktype
{
75 XCEPT_CLEANUP
, XCEPT_CATCHER
78 struct except_stacknode
{
79 struct except_stacknode
*except_down
;
80 enum except_stacktype except_type
;
82 struct except_catch
*except_catcher
;
83 struct except_cleanup
*except_cleanup
;
87 /* private functions made external so they can be used in macros */
88 extern void except_setup_clean(struct except_stacknode
*,
89 struct except_cleanup
*, void (*)(void *), void *);
90 WS_DLL_PUBLIC
void except_setup_try(struct except_stacknode
*,
91 struct except_catch
*, const except_id_t
[], size_t);
92 WS_DLL_PUBLIC
struct except_stacknode
*except_pop(void);
94 /* public interface functions */
95 WS_DLL_PUBLIC
int except_init(void);
96 WS_DLL_PUBLIC
void except_deinit(void);
97 WS_DLL_PUBLIC WS_NORETURN
void except_rethrow(except_t
*);
98 WS_DLL_PUBLIC WS_NORETURN
void except_throw(long, long, const char *);
99 WS_DLL_PUBLIC WS_NORETURN
void except_throwd(long, long, const char *, void *);
100 WS_DLL_PUBLIC WS_NORETURN
void except_vthrowf(long group
, long code
, const char *fmt
, va_list vl
);
101 WS_DLL_PUBLIC WS_NORETURN
void except_throwf(long, long, const char *, ...)
103 WS_DLL_PUBLIC
void (*except_unhandled_catcher(void (*)(except_t
*)))(except_t
*);
104 extern unsigned long except_code(except_t
*);
105 extern unsigned long except_group(except_t
*);
106 extern const char *except_message(except_t
*);
107 extern void *except_data(except_t
*);
108 WS_DLL_PUBLIC
void *except_take_data(except_t
*);
109 WS_DLL_PUBLIC
void except_set_allocator(void *(*)(size_t), void (*)(void *));
110 WS_DLL_PUBLIC
void *except_alloc(size_t);
111 WS_DLL_PUBLIC
void except_free(void *);
113 #define except_code(E) ((E)->except_id.except_code)
114 #define except_group(E) ((E)->except_id.except_group)
115 #define except_message(E) ((E)->except_message)
116 #define except_data(E) ((E)->except_dyndata)
123 * void except_cleanup_push(void (*)(void *), void *);
124 * void except_cleanup_pop(int);
125 * void except_checked_cleanup_pop(void (*)(void *), int);
126 * void except_try_push(const except_id_t [], size_t, except_t **);
127 * void except_try_pop(void);
130 #define except_cleanup_push(F, C) \
132 struct except_stacknode except_sn; \
133 struct except_cleanup except_cl; \
134 except_setup_clean(&except_sn, &except_cl, F, C)
136 #define except_cleanup_pop(E) \
139 except_cl.except_func(except_cl.except_context); \
142 #define except_checked_cleanup_pop(F, E) \
144 assert (except_cl.except_func == (F)); \
146 except_cl.except_func(except_cl.except_context); \
150 /* --- Variants to allow nesting of except_cleanup_push w/o "shadowing" variables */
151 #define except_cleanup_push_pfx(pfx, F, C) \
153 struct except_stacknode pfx##_except_sn; \
154 struct except_cleanup pfx##_except_cl; \
155 except_setup_clean(&pfx##_except_sn, &pfx##_except_cl, F, C)
157 #define except_cleanup_pop_pfx(pfx, E) \
160 pfx##_except_cl.except_func(pfx##_except_cl.except_context);\
163 #define except_checked_cleanup_pop_pfx(pfx, F, E) \
165 assert (pfx##_except_cl.except_func == (F)); \
167 pfx##_except_cl.except_func(pfx##_except_cl.except_context);\
172 #define except_try_push(ID, NUM, PPE) \
174 struct except_stacknode except_sn; \
175 struct except_catch except_ch; \
176 except_setup_try(&except_sn, &except_ch, ID, NUM); \
177 if (setjmp(except_ch.except_jmp)) \
178 *(PPE) = &except_ch.except_obj; \
182 #define except_try_pop() \
183 except_free(except_ch.except_obj.except_dyndata); \
190 * Editor modelines - https://www.wireshark.org/tools/modelines.html
195 * indent-tabs-mode: nil
198 * vi: set shiftwidth=4 tabstop=8 expandtab:
199 * :indentSize=4:tabSize=8:noTabs=true: