Initial commit
This commit is contained in:
		
							
								
								
									
										81
									
								
								include/except.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								include/except.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| #ifndef EXCEPT_INCLUDED | ||||
| #define EXCEPT_INCLUDED | ||||
|  | ||||
| #include <setjmp.h> | ||||
| #define UNUSED(x) (void)(x) | ||||
|  | ||||
| struct Exception { | ||||
| 	const char *reason; | ||||
| }; | ||||
| typedef struct Exception Exception; | ||||
|  | ||||
| struct ExceptFrame { | ||||
| 	struct ExceptFrame *prev;   // Exception Stack | ||||
| 	jmp_buf env;                // Enviroment Buffer | ||||
|     	const char *file;           // Exception File | ||||
| 	int line;                   // Exception Line | ||||
| 	const Exception *exception; // Exception Reason | ||||
| }; | ||||
| typedef struct ExceptFrame ExceptFrame; | ||||
|  | ||||
| // Exception States  | ||||
| enum { EXCEPT_ENTERED=0, EXCEPT_RAISED, EXCEPT_HANDLED, EXCEPT_FINALIZED}; | ||||
|  | ||||
| void except_raise(const Exception *e, const char *file,int line); // Raise exceptions | ||||
|  | ||||
| // External declarations  | ||||
| extern ExceptFrame *except_stack; // Global exception stack | ||||
| extern const Exception assert_failed; // Forward declaration for assert.  | ||||
| extern void asserted(int e); | ||||
|  | ||||
| #ifdef NDEBUG | ||||
| #define ASSERTED(e) ((void)0) | ||||
| #else | ||||
| #define ASSERTED(e) ((void)((e)||(RAISE(assert_failed),0))) | ||||
| #endif | ||||
|  | ||||
| // Raise an Exception. | ||||
| #define RAISE(e) except_raise(&(e), __FILE__, __LINE__) | ||||
|  | ||||
| // Reraise the currect exception. | ||||
| #define RERAISE except_raise(except_frame.exception, \ | ||||
| 	except_frame.file, except_frame.line) | ||||
|  | ||||
| // Switch to the previous exception frame and return. | ||||
| #define RETURN switch (except_stack = except_stack->prev,0) default: return | ||||
|  | ||||
| // Start a try block. | ||||
| #define TRY do { \ | ||||
| 	volatile int except_flag; \ | ||||
| 	ExceptFrame except_frame; \ | ||||
| 	except_frame.prev = except_stack; \ | ||||
| 	except_stack = &except_frame;  \ | ||||
| 	except_flag = setjmp(except_frame.env); \ | ||||
| 	if (except_flag == EXCEPT_ENTERED) { | ||||
|  | ||||
| // Handle specific example. | ||||
| #define EXCEPT(e) \ | ||||
| 		if (except_flag == EXCEPT_ENTERED) except_stack = except_stack->prev; \ | ||||
| 	} else if (except_frame.exception == &(e)) { \ | ||||
| 		except_flag = EXCEPT_HANDLED; | ||||
|  | ||||
| // Catch all other exceptions.         | ||||
| #define ELSE \ | ||||
| 		if (except_flag == EXCEPT_ENTERED) except_stack = except_stack->prev; \ | ||||
| 	} else { \ | ||||
| 		except_flag = EXCEPT_HANDLED; | ||||
|  | ||||
| // Execute finalization code.         | ||||
| #define FINALLY \ | ||||
| 		if (except_flag == EXCEPT_ENTERED) except_stack = except_stack->prev; \ | ||||
| 	} { \ | ||||
| 		if (except_flag == EXCEPT_ENTERED) \ | ||||
| 			except_flag = EXCEPT_FINALIZED; | ||||
|  | ||||
| // End Try block.          | ||||
| #define END_TRY \ | ||||
| 		if (except_flag == EXCEPT_ENTERED) except_stack = except_stack->prev; \ | ||||
| 		} if (except_flag == EXCEPT_RAISED) RERAISE; \ | ||||
| } while (0) | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user