RTPS: Now PID_ENTITY_NAME and PID_ROLE_NAME use different filters
[metze/wireshark/wip.git] / epan / except.h
1 /*
2  * Portable Exception Handling for ANSI C.
3  * Copyright (C) 1999 Kaz Kylheku <kaz@ashi.footprints.net>
4  *
5  * Free Software License:
6  *
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.
16  *
17  */
18
19 /**
20  * @file
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  * "g_strdup_sprintf()", 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
27  * not freeing that).
28  */
29
30 #ifndef XCEPT_H
31 #define XCEPT_H
32
33 #include <glib.h>
34 #include <setjmp.h>
35 #include <stdlib.h>
36 #include <assert.h>
37 #include "ws_symbol_export.h"
38
39 #define XCEPT_GROUP_ANY 0
40 #define XCEPT_CODE_ANY  0
41 #define XCEPT_BAD_ALLOC 1
42
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46
47 enum { except_no_call, except_call };
48
49 typedef struct {
50     unsigned long except_group;
51     unsigned long except_code;
52 } except_id_t;
53
54 typedef struct {
55     except_id_t volatile except_id;
56     const char *volatile except_message;
57     void *volatile except_dyndata;
58 } except_t;
59
60 struct except_cleanup {
61     void (*except_func)(void *);
62     void *except_context;
63 };
64
65 struct except_catch {
66     const except_id_t *except_id;
67     size_t except_size;
68     except_t except_obj;
69     jmp_buf except_jmp;
70 };
71
72 enum except_stacktype {
73     XCEPT_CLEANUP, XCEPT_CATCHER
74 };
75
76 struct except_stacknode {
77     struct except_stacknode *except_down;
78     enum except_stacktype except_type;
79     union {
80         struct except_catch *except_catcher;
81         struct except_cleanup *except_cleanup;
82     } except_info;
83 };
84
85 /* private functions made external so they can be used in macros */
86 extern void except_setup_clean(struct except_stacknode *,
87         struct except_cleanup *, void (*)(void *), void *);
88 WS_DLL_PUBLIC void except_setup_try(struct except_stacknode *,
89         struct except_catch *, const except_id_t [], size_t);
90 WS_DLL_PUBLIC struct except_stacknode *except_pop(void);
91
92 /* public interface functions */
93 WS_DLL_PUBLIC int except_init(void);
94 WS_DLL_PUBLIC void except_deinit(void);
95 WS_DLL_PUBLIC WS_MSVC_NORETURN void except_rethrow(except_t *) G_GNUC_NORETURN;
96 WS_DLL_PUBLIC WS_MSVC_NORETURN void except_throw(long, long, const char *) G_GNUC_NORETURN;
97 WS_DLL_PUBLIC WS_MSVC_NORETURN void except_throwd(long, long, const char *, void *) G_GNUC_NORETURN;
98 WS_DLL_PUBLIC WS_MSVC_NORETURN void except_throwf(long, long, const char *, ...)
99     G_GNUC_NORETURN G_GNUC_PRINTF(3, 4);
100 WS_DLL_PUBLIC void (*except_unhandled_catcher(void (*)(except_t *)))(except_t *);
101 extern unsigned long except_code(except_t *);
102 extern unsigned long except_group(except_t *);
103 extern const char *except_message(except_t *);
104 extern void *except_data(except_t *);
105 WS_DLL_PUBLIC void *except_take_data(except_t *);
106 WS_DLL_PUBLIC void except_set_allocator(void *(*)(size_t), void (*)(void *));
107 WS_DLL_PUBLIC void *except_alloc(size_t);
108 WS_DLL_PUBLIC void except_free(void *);
109
110 #define except_code(E) ((E)->except_id.except_code)
111 #define except_group(E) ((E)->except_id.except_group)
112 #define except_message(E) ((E)->except_message)
113 #define except_data(E) ((E)->except_dyndata)
114
115 #ifdef __cplusplus
116 }
117 #endif
118
119 /*
120  * void except_cleanup_push(void (*)(void *), void *);
121  * void except_cleanup_pop(int);
122  * void except_checked_cleanup_pop(void (*)(void *), int);
123  * void except_try_push(const except_id_t [], size_t, except_t **);
124  * void except_try_pop(void);
125  */
126
127 #define except_cleanup_push(F, C)                               \
128     {                                                           \
129         struct except_stacknode except_sn;                      \
130         struct except_cleanup except_cl;                        \
131         except_setup_clean(&except_sn, &except_cl, F, C)
132
133 #define except_cleanup_pop(E)                                   \
134         except_pop();                                           \
135         if (E)                                                  \
136             except_cl.except_func(except_cl.except_context);    \
137     }
138
139 #define except_checked_cleanup_pop(F, E)                        \
140             except_pop();                                       \
141         assert (except_cl.except_func == (F));                  \
142         if (E)                                                  \
143             except_cl.except_func(except_cl.except_context);    \
144     }
145
146
147 /* --- Variants to allow nesting of except_cleanup_push w/o "shadowing" variables */
148 #define except_cleanup_push_pfx(pfx, F, C)                      \
149     {                                                           \
150         struct except_stacknode pfx##_except_sn;                \
151         struct except_cleanup pfx##_except_cl;                  \
152         except_setup_clean(&pfx##_except_sn, &pfx##_except_cl, F, C)
153
154 #define except_cleanup_pop_pfx(pfx, E)                          \
155         except_pop();                                           \
156         if (E)                                                  \
157             pfx##_except_cl.except_func(pfx##_except_cl.except_context);\
158     }
159
160 #define except_checked_cleanup_pop_pfx(pfx, F, E)               \
161             except_pop();                                       \
162         assert (pfx##_except_cl.except_func == (F));            \
163         if (E)                                                  \
164             pfx##_except_cl.except_func(pfx##_except_cl.except_context);\
165     }
166 /* ---------- */
167
168
169 #define except_try_push(ID, NUM, PPE)                           \
170      {                                                          \
171         struct except_stacknode except_sn;                      \
172         struct except_catch except_ch;                          \
173         except_setup_try(&except_sn, &except_ch, ID, NUM);      \
174         if (setjmp(except_ch.except_jmp))                       \
175             *(PPE) = &except_ch.except_obj;                     \
176         else                                                    \
177             *(PPE) = 0
178
179 #define except_try_pop()                                        \
180         except_free(except_ch.except_obj.except_dyndata);       \
181         except_pop();                                           \
182     }
183
184 #endif /* XCEPT_H */
185
186 /*
187  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
188  *
189  * Local variables:
190  * c-basic-offset: 4
191  * tab-width: 8
192  * indent-tabs-mode: nil
193  * End:
194  *
195  * vi: set shiftwidth=4 tabstop=8 expandtab:
196  * :indentSize=4:tabSize=8:noTabs=true:
197  */