Coverage Report

Created: 2025-04-03 08:43

/src/wireshark/epan/except.h
Line
Count
Source (jump to first uncovered line)
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
 * "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
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 <stdarg.h>
37
#include <assert.h>
38
#include "ws_symbol_export.h"
39
#include "ws_attributes.h"
40
41
317k
#define XCEPT_GROUP_ANY 0
42
958k
#define XCEPT_CODE_ANY  0
43
0
#define XCEPT_BAD_ALLOC 1
44
45
#ifdef __cplusplus
46
extern "C" {
47
#endif
48
49
enum { except_no_call, except_call };
50
51
typedef struct {
52
    unsigned long except_group;
53
    unsigned long except_code;
54
} except_id_t;
55
56
typedef struct {
57
    except_id_t volatile except_id;
58
    const char *volatile except_message;
59
    void *volatile except_dyndata;
60
} except_t;
61
62
struct except_cleanup {
63
    void (*except_func)(void *);
64
    void *except_context;
65
};
66
67
struct except_catch {
68
    const except_id_t *except_id;
69
    size_t except_size;
70
    except_t except_obj;
71
    jmp_buf except_jmp;
72
};
73
74
enum except_stacktype {
75
    XCEPT_CLEANUP, XCEPT_CATCHER
76
};
77
78
struct except_stacknode {
79
    struct except_stacknode *except_down;
80
    enum except_stacktype except_type;
81
    union {
82
        struct except_catch *except_catcher;
83
        struct except_cleanup *except_cleanup;
84
    } except_info;
85
};
86
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);
93
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 *, ...)
102
    G_GNUC_PRINTF(3, 4);
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 *);
112
113
77.5k
#define except_code(E) ((E)->except_id.except_code)
114
#define except_group(E) ((E)->except_id.except_group)
115
77.5k
#define except_message(E) ((E)->except_message)
116
#define except_data(E) ((E)->except_dyndata)
117
118
#ifdef __cplusplus
119
}
120
#endif
121
122
/*
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);
128
 */
129
130
#define except_cleanup_push(F, C)                               \
131
12.2M
    {                                                           \
132
12.2M
        struct except_stacknode except_sn;                      \
133
12.2M
        struct except_cleanup except_cl;                        \
134
12.2M
        except_setup_clean(&except_sn, &except_cl, F, C)
135
136
#define except_cleanup_pop(E)                                   \
137
12.2M
        except_pop();                                           \
138
12.2M
        if (E)                                                  \
139
12.2M
            except_cl.except_func(except_cl.except_context);    \
140
12.2M
    }
141
142
#define except_checked_cleanup_pop(F, E)                        \
143
            except_pop();                                       \
144
        assert (except_cl.except_func == (F));                  \
145
        if (E)                                                  \
146
            except_cl.except_func(except_cl.except_context);    \
147
    }
148
149
150
/* --- Variants to allow nesting of except_cleanup_push w/o "shadowing" variables */
151
#define except_cleanup_push_pfx(pfx, F, C)                      \
152
0
    {                                                           \
153
0
        struct except_stacknode pfx##_except_sn;                \
154
0
        struct except_cleanup pfx##_except_cl;                  \
155
0
        except_setup_clean(&pfx##_except_sn, &pfx##_except_cl, F, C)
156
157
#define except_cleanup_pop_pfx(pfx, E)                          \
158
0
        except_pop();                                           \
159
0
        if (E)                                                  \
160
0
            pfx##_except_cl.except_func(pfx##_except_cl.except_context);\
161
0
    }
162
163
#define except_checked_cleanup_pop_pfx(pfx, F, E)               \
164
            except_pop();                                       \
165
        assert (pfx##_except_cl.except_func == (F));            \
166
        if (E)                                                  \
167
            pfx##_except_cl.except_func(pfx##_except_cl.except_context);\
168
    }
169
/* ---------- */
170
171
172
#define except_try_push(ID, NUM, PPE)                           \
173
641k
     {                                                          \
174
641k
        struct except_stacknode except_sn;                      \
175
641k
        struct except_catch except_ch;                          \
176
641k
        except_setup_try(&except_sn, &except_ch, ID, NUM);      \
177
641k
        if (setjmp(except_ch.except_jmp))                       \
178
641k
            *(PPE) = &except_ch.except_obj;                     \
179
641k
        else                                                    \
180
641k
            *(PPE) = 0
181
182
#define except_try_pop()                                        \
183
626k
        except_free(except_ch.except_obj.except_dyndata);       \
184
626k
        except_pop();                                           \
185
626k
    }
186
187
#endif /* XCEPT_H */
188
189
/*
190
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
191
 *
192
 * Local variables:
193
 * c-basic-offset: 4
194
 * tab-width: 8
195
 * indent-tabs-mode: nil
196
 * End:
197
 *
198
 * vi: set shiftwidth=4 tabstop=8 expandtab:
199
 * :indentSize=4:tabSize=8:noTabs=true:
200
 */