Set the svn:eol-style property on all text files to "native", so that
[obnox/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  * $Id$
18  * $Name:  $
19  */
20
21 #ifndef XCEPT_H
22 #define XCEPT_H
23
24 #include <setjmp.h>
25 #include <stdlib.h>
26 #include <assert.h>
27
28 #define XCEPT_GROUP_ANY 0
29 #define XCEPT_CODE_ANY  0
30 #define XCEPT_BAD_ALLOC 1
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 enum { except_no_call, except_call };
37
38 typedef struct {
39     unsigned long except_group;
40     unsigned long except_code;
41 } except_id_t;
42
43 typedef struct {
44     except_id_t volatile except_id;
45     const char *volatile except_message;
46     void *volatile except_dyndata;
47 } except_t;
48
49 struct except_cleanup {
50     void (*except_func)(void *);
51     void *except_context;
52 };
53
54 struct except_catch {
55     const except_id_t *except_id;
56     size_t except_size;
57     except_t except_obj;
58     jmp_buf except_jmp;
59 };
60
61 enum except_stacktype {
62     XCEPT_CLEANUP, XCEPT_CATCHER
63 };
64
65 struct except_stacknode {
66     struct except_stacknode *except_down;
67     enum except_stacktype except_type;
68     union {
69         struct except_catch *except_catcher;
70         struct except_cleanup *except_cleanup;
71     } except_info;
72 };
73
74 /* private functions made external so they can be used in macros */
75 extern void except_setup_clean(struct except_stacknode *,
76         struct except_cleanup *, void (*)(void *), void *);
77 extern void except_setup_try(struct except_stacknode *,
78         struct except_catch *, const except_id_t [], size_t);
79 extern struct except_stacknode *except_pop(void);
80
81 /* public interface functions */
82 extern int except_init(void);
83 extern void except_deinit(void);
84 extern void except_rethrow(except_t *);
85 extern void except_throw(long, long, const char *);
86 extern void except_throwd(long, long, const char *, void *);
87 extern void except_throwf(long, long, const char *, ...);
88 extern void (*except_unhandled_catcher(void (*)(except_t *)))(except_t *);
89 extern unsigned long except_code(except_t *);
90 extern unsigned long except_group(except_t *);
91 extern const char *except_message(except_t *);
92 extern void *except_data(except_t *);
93 extern void *except_take_data(except_t *);
94 extern void except_set_allocator(void *(*)(size_t), void (*)(void *));
95 extern void *except_alloc(size_t);
96 extern void except_free(void *);
97
98 #define except_code(E) ((E)->except_id.except_code)
99 #define except_group(E) ((E)->except_id.except_group)
100 #define except_message(E) ((E)->except_message)
101 #define except_data(E) ((E)->except_dyndata)
102
103 #ifdef __cplusplus
104 }
105 #endif
106
107 /*
108  * void except_cleanup_push(void (*)(void *), void *);
109  * void except_cleanup_pop(int);
110  * void except_checked_cleanup_pop(void (*)(void *), int);
111  * void except_try_push(const except_id_t [], size_t, except_t **);
112  * void except_try_pop(void);
113  */
114
115 #define except_cleanup_push(F, C)                               \
116     {                                                           \
117         struct except_stacknode except_sn;                      \
118         struct except_cleanup except_cl;                        \
119         except_setup_clean(&except_sn, &except_cl, F, C)
120
121 #define except_cleanup_pop(E)                                   \
122         except_pop();                                           \
123         if (E)                                                  \
124             except_cl.except_func(except_cl.except_context);    \
125     }
126
127 #define except_checked_cleanup_pop(F, E)                        \
128         except_pop();                                           \
129         assert (except_cl.except_func == (F));                  \
130         if (E)                                                  \
131             except_cl.except_func(except_cl.except_context);    \
132     }
133
134 #define except_try_push(ID, NUM, PPE)                           \
135      {                                                          \
136         struct except_stacknode except_sn;                      \
137         struct except_catch except_ch;                          \
138         except_setup_try(&except_sn, &except_ch, ID, NUM);      \
139         if (setjmp(except_ch.except_jmp))                       \
140             *(PPE) = &except_ch.except_obj;                     \
141         else                                                    \
142             *(PPE) = 0
143
144 #define except_try_pop()                                        \
145         except_free(except_ch.except_obj.except_dyndata);       \
146         except_pop();                                           \
147     }
148
149 #endif