#include "exception.h" #include // Translation Helpers: #define CLEANUP(function) \ struct __cleanup_hook __hidden_hook __attribute__((cleanup(function))) // Local Print On Exit: struct raii_base_type { const char * area; }; void raii_dtor(struct raii_base_type * this) { printf("Exiting: %s\n", this->area); } #define raii_t __attribute__((cleanup(raii_dtor))) struct raii_base_type // Runtime code (post-translation). void terminate(int except_value) { raii_t a = {"terminate function"}; __throw_terminate(except_value); printf("terminate returned\n"); } void resume(int except_value) { raii_t a = {"resume function"}; __throw_resume(except_value); printf("resume returned\n"); } // Termination Test: Two handlers: no catch, catch void bar() { void bar_try1() { terminate(4); } void bar_catch1(int index, exception except) { switch(except) { case 1: printf("bar caught exception.\n"); break; default: printf("INVALID INDEX in bar: %d\n", except); } } int bar_match1(exception except) { if (3 == except) { return 1; } else { return 0; } } __try_terminate(bar_try1, bar_catch1, bar_match1); } void foo() { void foo_try1() { bar(); } void foo_catch1(int index, exception except) { switch(except) { case 1: printf("foo caught exception 4.\n"); break; case 2: printf("foo caught exception 2.\n"); break; default: printf("INVALID INDEX in foo: %d\n", except); } } int foo_match1(exception except) { if (4 == except) { return 1; } else if (2 == except) { return 2; } else { return 0; } } __try_terminate(foo_try1, foo_catch1, foo_match1); } int main(int argc, char * argv[]) { raii_t a = {"main function"}; foo(); }