-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtrycatch.h
More file actions
61 lines (49 loc) · 2.13 KB
/
trycatch.h
File metadata and controls
61 lines (49 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#ifndef TRYCATCH_H
#define TRYCATCH_H
#include <setjmp.h>
#include <stdlib.h>
typedef struct Exception {
size_t code;
void *data;
} Exception;
typedef struct ExceptionContext {
jmp_buf env;
struct ExceptionContext* prev;
Exception exception;
} ExceptionContext;
#ifndef EXCEPTION_CONTEXT
extern ExceptionContext *___try_catch_exception_context;
#define EXCEPTION_CONTEXT ___try_catch_exception_context
#endif
#define TCH_CONCAT(a,b) a##b
#define TCH_UNIQUE_NAME(a,b) TCH_CONCAT(a,b)
#define _pop_exception_context _pop_exception_context_impl(TCH_UNIQUE_NAME(_ctx_prev_, __COUNTER__))
#define _pop_exception_context_impl(__varname__) \
({ \
ExceptionContext *__varname__ = EXCEPTION_CONTEXT; \
EXCEPTION_CONTEXT = EXCEPTION_CONTEXT->prev; \
__varname__; \
})
#define _push_exception_context _push_exception_context_impl(TCH_UNIQUE_NAME(_ctx_, __COUNTER__))
#define _push_exception_context_impl(__varname__) \
({ \
volatile ExceptionContext __varname__; \
__varname__.prev = EXCEPTION_CONTEXT; \
EXCEPTION_CONTEXT = (ExceptionContext *)&__varname__; \
})
#define try \
if ((_push_exception_context, \
EXCEPTION_CONTEXT->exception.code = setjmp(EXCEPTION_CONTEXT->env)) == 0)
#define catch(decl_) catch_impl(decl_, TCH_UNIQUE_NAME(__once_, __COUNTER__))
#define catch_impl(decl_, __varname__) \
else for (char __varname__ = 1; __varname__;) \
for (__attribute__((unused)) decl_ = EXCEPTION_CONTEXT->exception; \
__varname__ && _pop_exception_context; __varname__ = 0)
#define finally ;
#define throw(x_, d_) \
({ \
EXCEPTION_CONTEXT->exception.data = (d_); \
longjmp(EXCEPTION_CONTEXT->env, (x_)); \
EXCEPTION_CONTEXT; \
})
#endif // TRYCATCH_H