#include <stdio.h> #include <stdlib.h> #include <string.h> #include <setjmp.h> struct env{ jmp_buf x; //jmp_buf seems to be an array }; env* make_env(){ env* res=(env*)malloc(sizeof(env)) ; return res; } struct ex_stack{ env* s[100]; int top; void (*push)(ex_stack*,env*); env* (*peek)(ex_stack*); void (*pop)(ex_stack*); }; env* peek(ex_stack*self){ return self->s[self->top-1]; } void push(ex_stack* self,env* x){ self->s[self->top++]=x; } void pop(ex_stack* self){ self->top--; } ex_stack* make_ex_stack(){ ex_stack* res=(ex_stack*)malloc(sizeof(ex_stack)); res->top=0; res->push=push; res->pop=pop; res->peek=peek; return res; } static ex_stack* s=make_ex_stack(); struct exception{ char msg[100]; int id; }*cur_ex; exception* make_exception(int id,char* msg){ exception* res=(exception*)malloc(sizeof(exception)); res->id=id; res->msg[0]=0; strcat(res->msg,msg); return res; } void throw_exception(exception* e){ cur_ex=e; if(s->top>0)longjmp(s->peek(s)->x,1); } void second(int b){ if(b==1) throw_exception(make_exception(2,"Exception 2 from second")); if(b==2) throw_exception(make_exception(3,"Exception 3 from second")); puts("In second"); } void first(int a,int b){ bool handled=false; s->push(s,make_env()); switch(setjmp(s->peek(s)->x)){ case 0: //code in try block if(a==1) throw_exception(make_exception(1,"Exception 1 from first")); second(b); handled=true; //no exception thrown break; case 1: //handle exceptions switch(cur_ex->id){ case 3: handled=true; printf("%s/n",cur_ex->msg); break; } break; } s->pop(s); puts("In first"); //finally if(!handled){ //not handled exception, throw to outer frame throw_exception(cur_ex); } puts("In first: this might not always get printed"); } int main(){ int a,b; while(1){ scanf("%d%d",&a,&b); bool handled=false; s->push(s,make_env()); switch(setjmp(s->peek(s)->x)){ case 0: //code in try block first(a,b); puts("This might not get printed"); handled=true; //no exception thrown break; case 1: //handle exceptions switch(cur_ex->id){ case 1: printf("%s/n",cur_ex->msg); break; case 2: printf("%s/n",cur_ex->msg); break; } break; } s->pop(s); if(!handled){ //not handled exception, throw to outer frame throw_exception(cur_ex); } } } correspondingjava code: class Exception1 extends RuntimeException { public Exception1(String s) { super(s) ; } } class Exception2 extends RuntimeException { public Exception2(String s) { super(s) ; } } class Exception3 extends RuntimeException { public Exception3(String s) { super(s) ; } } public class ExceptionExample { public static void main ( String [] args ) { try { first(Integer.parseInt(args[0]),Integer.parseInt(args[1])) ; System.out.println("In main: this might not get printed") ; } catch (Exception1 e) { System.out.println(e) ; } catch (Exception2 e) { System.out.println(e) ; } } public static void first (int a, int b) { try { if ( a == 1 ) throw new Exception1("Exception 1 from first") ; second(b) ; } catch (Exception3 e) { System.out.println(e) ; } finally { System.out.println("In first: always printed"); } System.out.println("In first: this might not always get printed") ; } public static void second (int b) { if ( b == 1 ) throw new Exception2("Exception 2 from second") ; if ( b == 2 ) throw new Exception3("Exception 3 from second") ; System.out.println("In second") ; } }