00001
00002
00003
00004 #ifndef NPS_EXCEPT_H
00005 #define NPS_EXCEPT_H
00006 #include <setjmp.h>
00007 #include "../msg.h"
00008
00009 typedef struct Nps_exc_t {
00010 char *name;
00011 char backtrace;
00012 } Nps_exc_t;
00013
00014 struct Nps_exc_frame_t {
00015 struct Nps_exc_frame_t *prev;
00016 jmp_buf target;
00017 const char *file;
00018 long line;
00019 char *msg;
00020 const Nps_exc_t *exc;
00021 };
00022
00023 typedef struct Nps_exc_frame_t Nps_exc_frame_t;
00024
00025 enum { Nps_exc_entered=0, Nps_exc_thrown, Nps_exc_handled};
00026
00027
00028 extern Nps_exc_frame_t *Nps_exc_stack;
00029
00030 void nps_throw(const Nps_exc_t *e,const char *file, long line,const char*,...);
00031
00032
00033 #define THROW(e,...) nps_throw(&(e),__FILE__,__LINE__,"" __VA_ARGS__)
00034 #define RETHROW nps_throw(Nps_exc_stack->exc,Nps_exc_stack->file, \
00035 Nps_exc_stack->line, Nps_exc_stack->msg)
00036
00037 #define TRY do { \
00038 volatile int Nps_exc_flag; \
00039 Nps_exc_frame_t curr_layer; \
00040 curr_layer.msg = NULL; \
00041 curr_layer.prev = Nps_exc_stack; \
00042 Nps_exc_stack = &curr_layer; \
00043 Nps_exc_flag = setjmp(Nps_exc_stack->target); \
00044 if (Nps_exc_flag == Nps_exc_entered) {
00045
00046
00047 #define END_TRY \
00048 if (Nps_exc_flag == Nps_exc_entered) { \
00049 if (Nps_exc_stack != &curr_layer) \
00050 MSG(DIE-1,"Exception Stack Corruption.\n"); \
00051 if (Nps_exc_stack->msg) free(Nps_exc_stack->msg); \
00052 Nps_exc_stack = Nps_exc_stack->prev; \
00053 } \
00054 } if (Nps_exc_flag == Nps_exc_thrown) THROW(*(Nps_exc_stack->exc)); \
00055 } while(0)
00056
00057 #define CATCH(e) \
00058 if (Nps_exc_flag == Nps_exc_entered) Nps_exc_stack = Nps_exc_stack->prev; \
00059 } else if (Nps_exc_stack->exc == &(e)) { \
00060 Nps_exc_flag = Nps_exc_handled; \
00061
00062
00063
00064
00065
00066 #endif
00067