00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef NPS_EXC_H
00019 #define NPS_EXC_H
00020 #include <setjmp.h>
00021 #include "../msg.h"
00022
00023 typedef struct Nps_exc_t {
00024 char *name;
00025 } Nps_exc_t;
00026
00027 struct Nps_exc_frame_t {
00028 struct Nps_exc_frame_t *prev;
00029 jmp_buf target;
00030 const char *file;
00031 long line;
00032 char *msg;
00033 const Nps_exc_t *exc;
00034 };
00035
00036 typedef struct Nps_exc_frame_t Nps_exc_frame_t;
00037
00038 enum { Nps_exc_entered=0, Nps_exc_thrown, Nps_exc_handled};
00039
00040 extern Nps_exc_frame_t *Nps_exc_stack;
00041
00042 void nps_throw(const Nps_exc_t *e,const char *file, long line,const char*,...);
00043
00044 #define THROW(e,...) nps_throw(&(e),__FILE__,__LINE__,"" __VA_ARGS__)
00045 #define RETHROW nps_throw(_exc_top.exc,_exc_top.file, \
00046 _exc_top.line, _exc_top.msg)
00047
00048 #define TRY do { \
00049 volatile int Nps_exc_flag; \
00050 Nps_exc_frame_t _exc_top; \
00051 _exc_top.msg = NULL; \
00052 _exc_top.prev = Nps_exc_stack; \
00053 Nps_exc_stack = &_exc_top; \
00054 Nps_exc_flag = setjmp(Nps_exc_stack->target); \
00055 if (Nps_exc_flag == Nps_exc_entered) {
00056
00057 #define CATCH \
00058 } \
00059 if (Nps_exc_stack != &_exc_top) { \
00060 fprintf(stderr,"Exception stack is corrupted!\n"); exit(1); \
00061 } \
00062 Nps_exc_stack=Nps_exc_stack->prev; \
00063 for (long nps_exc_catch_block=0; !nps_exc_catch_block && (Nps_exc_flag == Nps_exc_thrown); \
00064 nps_exc_catch_block=(Nps_exc_flag == Nps_exc_thrown ? RETHROW , 1 : \
00065 free(_exc_top.msg),_exc_top.msg=NULL,1 ))
00066
00067
00068 #define ON(e) \
00069 for (long _nps_exc_on_block=0; (!_nps_exc_on_block && &(e) == _exc_top.exc); \
00070 ++_nps_exc_on_block,Nps_exc_flag=Nps_exc_handled) \
00071
00072 #define END_TRY \
00073 if (_exc_top.msg) fprintf(stderr,"Corrupted exception stack\n"),exit(1); \
00074 } while (0);
00075
00076 #define RETURN switch (Nps_exc_stack = Nps_exc_stack->prev,0) default: return
00077
00078 #endif
00079