#ifndef EXCEPT_INCLUDED #define EXCEPT_INCLUDED #include struct Exception { const char *reason; }; typedef struct Exception Exception; struct Except_Frame { struct Except_Frame *prev; jmp_buf env; const char *file; int line; const struct Exception *exception; }; typedef struct Except_Frame Except_Frame; enum { EXCEPT_STATE_ENTERED=0, EXCEPT_STATE_RAISED, EXCEPT_STATE_HANDLED, EXCEPT_STATE_FINALIZED, EXCEPT_STATE_COUNT }; extern struct Except_Frame *except_stack; extern const struct Exception assert_failed; void except_raise(const struct Exception *e, const char *file, int line); // Try Catch MACROS - LINUX #define RAISE(e) except_raise(&(e), __FILE__, __LINE__) #define RERAISE except_raise(except_frame.exception, \ except_frame.file, except_frame.line) #define RETURN switch (except_stack = except_stack->prev,0) default: return #define TRY do { \ volatile int except_flag; \ Except_Frame except_frame; \ except_frame.prev = except_stack; \ except_stack = &except_frame; \ except_flag = setjmp(except_frame.env); \ if (except_flag == EXCEPT_STATE_ENTERED) { #define EXCEPT(e) \ if (except_flag == EXCEPT_STATE_ENTERED) except_stack = except_stack->prev; \ } else if (except_frame.exception == &(e)) { \ except_flag = EXCEPT_STATE_HANDLED; #define ELSE \ if (except_flag == EXCEPT_STATE_ENTERED) except_stack = except_stack->prev; \ } else { \ except_flag = EXCEPT_STATE_HANDLED; #define FINALLY \ if (except_flag == EXCEPT_STATE_ENTERED) except_stack = except_stack->prev; \ } { \ if (except_flag == EXCEPT_STATE_ENTERED) \ except_flag = EXCEPT_STATE_FINALIZED; #define END_TRY \ if (except_flag == EXCEPT_STATE_ENTERED) except_stack = except_stack->prev; \ } if (except_flag == EXCEPT_STATE_RAISED) RERAISE; \ } while (0) // Try Catch MACROS - WIN32 #ifdef WIN32 #include extern int except_index; extern void except_init(void); extern void except_push(Except_Frame *fp); extern void except_pop(void); #define RAISE(e) except_raise(&(e), __FILE__, __LINE__) #define RERAISE except_raise(except_frame.exception, \ except_frame.file, except_frame.line) #define RETURN switch (except_pop(),0) default: return #define TRY do { \ volatile int except_flag; \ Except_Frame except_frame; \ if (except_index == -1) \ except_init(); \ except_push(&except_frame); \ except_flag = setjmp(except_frame.env); \ if (except_flag == EXCEPT_STATE_ENTERED) { #define EXCEPT(e) \ if (except_flag == EXCEPT_STATE_ENTERED) except_pop(); \ } else if (except_frame.exception == &(e)) { \ except_flag = EXCEPT_STATE_HANDLED; #define ELSE \ if (except_flag == EXCEPT_STATE_ENTERED) except_pop(); \ } else { \ except_flag = EXCEPT_STATE_HANDLED; #define FINALLY \ if (except_flag == EXCEPT_STATE_ENTERED) except_pop(); \ } { \ if (except_flag == EXCEPT_STATE_ENTERED) \ except_flag = EXCEPT_STATE_FINALIZED; #define END_TRY \ if (except_flag == EXCEPT_STATE_ENTERED) except_pop(); \ } if (except_flag == EXCEPT_STATE_RAISED) RERAISE; \ } while (0) #endif #endif // except.h