exception.h


1
#ifndef EXCEPTION_H
2
#define EXCEPTION_H
3
4
#include <limits.h>
5
#include <stdbool.h>
6
#include <string.h>
7
#include <setjmp.h>
8
9
#define BEFORE_AND_AFTER_BLOCK(X,BEFORE,AFTER,T) \
10
  for( struct{bool BAAB_V;T;}X={.BAAB_V=true}; X.BAAB_V&&(EX_UNPACK BEFORE); X.BAAB_V=(EX_UNPACK AFTER) )
11
12
#define EX_UNPACK(...) __VA_ARGS__
13
14
#define try BEFORE_AND_AFTER_BLOCK( ex_baab, (beginTry(&ex_baab.ex_ejs),!setjmp(ex_baab.ex_ejs.current)||endTry(&ex_baab.ex_ejs)), (endTry(&ex_baab.ex_ejs),false), struct exceptionJmpStorage ex_ejs )
15
#define catch( T, VAR ) \
16
  for( struct T##_type* VAR=(struct T##_type*)exception; \
17
  catchMatch( T ); exception = (void*)1 )
18
#define finally( VAR ) for( struct exception* VAR=exception; exception&&exception!=(void*)1; (void)VAR,exception=0 )
19
#define throw(T,V) do { \
20
  lastException.T = (struct T##_type){ EX_UNPACK V }; \
21
  exception = (void*)&lastException; \
22
  exception->type = T; \
23
  longjmp( *exception_jmp_buf, 1 );\
24
} while(0)
25
#define rethrow() longjmp( *exception_jmp_buf, 1 )
26
27
struct exception;
28
struct exception {
29
  int type;
30
};
31
32
struct exceptionJmpStorage {
33
  jmp_buf* last;
34
  jmp_buf current;
35
};
36
37
extern union anyException lastException;
38
extern struct exception* exception;
39
extern jmp_buf* exception_jmp_buf;
40
41
void beginTry( struct exceptionJmpStorage* );
42
bool endTry( struct exceptionJmpStorage* );
43
bool catchMatch( int type );
44
bool finallyBefore( void );
45
void finallyAfter( void );
46
47
#endif