#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