

#ifndef exception_h__
#define exception_h__

#include "setjmp.h"
#include "stdlib.h"
// #include "mystdlib.h"

#define THROW_LOG__MAX_SIZE 1024


typedef struct _jmp_fram{
  struct _jmp_fram *next;
  struct _jmp_fram *last;
  // map_def *mem;
  jmp_buf fram;
}jmp_fram;


typedef struct{
  size_t jmp_num;
  jmp_fram *jmp_head;
  int ret;
  char *file;
  int line;
  char log[THROW_LOG__MAX_SIZE];
}exception_def;



#define jmp_next(j) {\
  if((*j)){\
    (*j)->next=calloc(sizeof(jmp_fram),1);\
    (*j)->next->last=(*j);\
    (*j)=(*j)->next;\
  }else{\
    (*j)=calloc(sizeof(jmp_fram),1);\
  }\
}

#define jmp_last(j) {\
  if((*j)){\
    jmp_fram *l=(*j)->last;\
    /*if(l){\
      __mem_mov(&(l)->mem,&(*j)->mem);\
    }*/\
    free(*j);\
    (*j)=l;\
    if(*j){\
      (*j)->next=0;\
    }\
  }\
}


#define jmp_clear(j) {\
  if((*j)){\
    jmp_fram *l=(*j)->last;\
    /*__mem_clear(&(*j)->mem);*/\
    free(*j);\
    (*j)=l;\
    if(*j){\
      (*j)->next=0;\
    }\
  }\
}

/*
 try 的时候保存当前回溯点，如果setjmp返回不为0 则已经产生异常回溯了，
 这时最后一个回溯点的使命已经完成，所以删除最后一个回溯点
*/
#define __try(){\
  exception_def *f=exception();\
  jmp_fram **h=&f->jmp_head;\
  int ret;\
  jmp_next(h);\
  ret = setjmp(((*h)->fram));\
  if(ret){\
    jmp_clear(h);\
  }\
  f->ret=ret;\
}

#define try_ __try();if(exception()->ret==0){

/*
  如果try一直执行到这里则不会产生回溯了，最后一个回溯点的使命也已经完成了，
  所以这里删除最后一个回溯点
*/
#define catch_ {\
  exception_def *f=exception();\
  jmp_fram **h=&f->jmp_head;\
  jmp_last(h);\
}}else

#define throw_(fmt,...) __throw(__FILE__,__LINE__,fmt,##__VA_ARGS__)

exception_def *exception();
void __throw(char *file,int line,const char *fmt,...);




int test_add(int a,int b);






#endif

