/* catch.h -- more exception handling in C (non-thread safe) * $Id: catch.h,v 1.5 2023/05/18 13:45:48 oj14ozun Exp $ * * Lisp-like jumping up up the call-stack to specific blocks: * * int foo() { * throw(bar); * } * * int main() { * catch(bar) { * foo(); * } * } * * See http://clhs.lisp.se/Body/s_catch.htm. * * To initialise, add * * struct catch_stack *catch_tos = NULL; * * to your main file. */ #ifndef _CATCH_H #define _CATCH_H #include #include #include #include struct catch_stack { sigjmp_buf frame; char *name; struct catch_stack *prev; bool done; }; extern struct catch_stack *catch_tos; #define __catch(fid, _name) \ for (struct catch_stack fid = { \ .name = _name, \ .prev = catch_tos, \ }; (!fid.done && !setjmp(fid.frame)) ? \ (catch_tos = &fid, 1) : (catch_tos = fid.prev, 0); \ fid.done = true) #define catch(name) __catch(_catch_ ## __COUNTER__ ## name, #name) /* Implicit-catch, deriving the function name */ #define icatch catch(__func__) #define throw(_name) \ do { \ struct catch_stack *i = catch_tos; \ while (i) { \ if (!strcmp(#_name, i->name)) { \ catch_tos = i; \ longjmp(i->frame, 1); \ abort(); \ } \ i = i->prev; \ } \ abort(); \ } while (0) #endif