FreeCalypso > hg > freecalypso-sw
view gsm-fw/riviera/support/exception.h @ 196:3daa8ebbe74d
pirexplore: a bit of refactoring
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sat, 14 Dec 2013 07:55:22 +0000 |
parents | afceeeb2cba1 |
children |
line wrap: on
line source
/* ****************************** * * * Initialial version: Laurent Deniau, Laurent.Deniau@cern.ch * * For more information, please see the paper: * http://cern.ch/Laurent.Deniau/html/oopc/exception.html * * ----------------------------------------------------------- * * Strong rework and adaption to riviera by Christophe Favergeon * ****************************** */ #ifndef RVF_EXCEPTION_H #define RVF_EXCEPTION_H #include "../rvf/rvf_api.h" #include "../rvf/rvf_target.h" #include <string.h> //#ifndef __STDC__ //# error "exception.h needs ISO C compiler to work properly" //#endif #include <setjmp.h> typedef enum K_RVF_EXCEPTIONS { E_invalid=1, E_not_enough_memory,E_unknown } T_RVF_EXCEPTIONS; typedef void (*T_RVF_RELEASE_PROTECTED_POINTER)(void *p); /* choose context savings */ #define rvf_save_context_buffer_(context) setjmp(context) #define rvf_restore_context_buffer_(context, val) longjmp(context, val) /* some hidden types used to handle exceptions */ /* type of stack of protected pointer */ struct _protectedPtr_ { struct _protectedPtr_ *next; struct _protectedPtr_ *previous; void *ptr; T_RVF_RELEASE_PROTECTED_POINTER func; }; /* type of stack of exception */ struct _exceptionContext_ { struct _exceptionContext_ *next; struct _protectedPtr_ *stack; jmp_buf context; }; extern struct _exceptionContext_ *const _returnExceptionContext_[MAX_RVF_TASKS]; extern struct _exceptionContext_ *_currentExceptionContext_[MAX_RVF_TASKS]; /* exception keywords */ #define try \ do { \ struct _exceptionContext_ _localExceptionContext_ ;\ memset(&_localExceptionContext_,0,sizeof(struct _exceptionContext_));\ _localExceptionContext_.next=_currentExceptionContext_[rvf_get_taskid()];\ _currentExceptionContext_[rvf_get_taskid()] = &_localExceptionContext_; \ do { \ int const exception = \ rvf_save_context_buffer_(_currentExceptionContext_[rvf_get_taskid()]->context); \ if (!exception) { #define catch(except) \ } else if ((int)(except) == exception) { \ _currentExceptionContext_[rvf_get_taskid()] = _currentExceptionContext_[rvf_get_taskid()]->next; #define catch_any \ } else { \ _currentExceptionContext_[rvf_get_taskid()] = _currentExceptionContext_[rvf_get_taskid()]->next; #define endtry \ } \ } while(0); \ if (_currentExceptionContext_[rvf_get_taskid()] == &_localExceptionContext_) { \ rvf_forget_protected_ptr();\ _currentExceptionContext_[rvf_get_taskid()] = _currentExceptionContext_[rvf_get_taskid()]->next; \ } \ } while(0) #define rethrow throw(exception) #define break_try break /* #define return_try(...) \ do { \ _currentExceptionContext_ = _returnExceptionContext_; \ return __VA_ARGS__; \ } while(0) */ #define throw(except) _exceptionThrow_((int)(except)) /* extern declarations */ extern void _exceptionThrow_(int except); extern void rvf_forget_protected_ptr(); extern void rvf_protect_pointer(T_RVF_MB_ID mb_id,void *p,T_RVF_RELEASE_PROTECTED_POINTER func); #define RVF_PROTECT(bank,p) rvf_protect_pointer(bank,p,(T_RVF_RELEASE_PROTECTED_POINTER)rvf_free_buf) #define THROW_IF_ERROR(err) if (err!=0) throw(E_unknown) #define THROW_IF_NULL(p) if (p==NULL) throw(E_not_enough_memory) #define THROW_IF_YELLOW(b,p) if ((p==NULL) || (rvf_get_mb_status(b)==RVF_YELLOW)) throw(E_not_enough_memory) #endif