00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef CUFLOWP_IN_WIND_H
00019 # error This shall be included through ccf/wind.h, not directly.
00020 #endif
00021 #ifndef CUFLOW_WIND_SETJMP_H
00022 #define CUFLOW_WIND_SETJMP_H
00023
00024 #include <cuflow/fwd.h>
00025 #include <cu/tstate.h>
00026 #include <setjmp.h>
00027 #include <assert.h>
00028
00029 CU_BEGIN_DECLARATIONS
00030
00031 typedef struct cuflowP_windstate *cuflowP_windstate_t;
00032
00033 struct cuflowP_windstate
00034 {
00035 cuflowP_windstate_t prev;
00036 sigjmp_buf door;
00037 cuflowP_windargs_t windargs;
00038 };
00039
00040 #define cuflowP_wind_gotos(on_unw, on_rew, on_xc) \
00041 struct cuflowP_windstate cuflowP_windstate; \
00042 cuflowP_push_windstate(&cuflowP_windstate); \
00043 if (sigsetjmp(cuflowP_windstate.door, 1)) \
00044 switch (cuflowP_windstate.windargs->direction) { \
00045 case cuflow_wind_direction_unwind: \
00046 on_unw; \
00047 case cuflow_wind_direction_rewind: \
00048 on_rew; \
00049 case cuflow_wind_direction_except: \
00050 on_xc; \
00051 default: \
00052 assert(!"Not reached."); \
00053 break; \
00054 }
00055
00056 CU_ATTR_NORETURN void cuflowP_unwind(cuflowP_windstate_t);
00057 CU_ATTR_NORETURN void cuflowP_rewind(cuflowP_windstate_t);
00058 #define cuflow_rewind_continue cuflowP_rewind(&cuflowP_windstate)
00059 #define cuflow_unwind_continue cuflowP_unwind(&cuflowP_windstate)
00060 #define cuflow_except_continue cuflowP_unwind(&cuflowP_windstate)
00061 #define cuflow_wind_return(val) \
00062 do { \
00063 cuP_tstate()->windstate = cuflowP_windstate.prev; \
00064 return val; \
00065 } while (0)
00066 CU_ATTR_NORETURN void cuflowP_throw(cuflowP_windargs_t windargs);
00067
00068 void cuflowP_push_windstate(cuflowP_windstate_t wst);
00069
00070 CU_END_DECLARATIONS
00071
00072 #endif