#ifndef MLEXCEPTION_H #define MLEXCEPTION_H #include struct except { char *name; struct except *id; }; typedef struct except exception; extern void exception_pop( exception); extern void exception_push( exception); extern int exception_search( exception); extern void *exception_jmp_buf( exception); extern void exception_uncaught( exception, char*, int); extern int exception_raised(void); extern unsigned char exception_flag; extern exception exception_last_raised; #define DEFINE_EXCEPTION(_E_) \ struct except _E_= {#_E_,&_E_} #define USE_EXCEPTION(_E_) \ extern struct except _E_ #define HANDLE(_E_,_EXP_) \ (exception_push(_E_), \ setjmp(exception_jmp_buf((_E_)))==0 \ ? ((_EXP_),(exception_flag=0)) : \ (exception_flag=1 ), \ exception_pop(_E_)) #define RAISE(_E_) \ (exception_last_raised =_E_, \ (exception_search(_E_) \ ? longjmp(exception_jmp_buf(_E_),1) \ : exception_uncaught(_E_, __FILE__, __LINE__))) #define ECHECK(_E_) \ ((_E_).id == exception_last_raised.id) /* Multiple handler "a la SML" the user ***MUST*** respect the following syntax HANDLE_ANY() ON_NO_EXCEPTION ON_EXCEPTION(e1) ON_EXCEPTION(e2) ... [ ON_ANY_OTHER ] */ #define HANDLE_ANY(_EXP_) \ HANDLE(any, _EXP_) ; \ if(! (exception_raised())) #define ON_NO_EXCEPTION /* mandatory */ #define ON_EXCEPTION(_E_) \ else if ECHECK(_E_) #define ON_ANY_OTHER \ else #define RERAISE_IT \ (exception_search(exception_last_raised) \ ? longjmp(exception_jmp_buf(exception_last_raised),1) \ : exception_uncaught(exception_last_raised, __FILE__, __LINE__)) #endif USE_EXCEPTION(any);