/*
 * Provide substitute defintitions for pthreads exception package for
 * system (.i.e. linux) that don't provide this capability.  Currently
 * the definitions are non-functional.
 */
#include <pthread.h>
#include <setjmp.h>
#ifndef TRY
/*
 *   Define scope block for manage nested exceptions.
 */
typedef struct { int type; int value; char *description; } EXCEPTION;
typedef struct pte_scope {
    struct pte_scope *prev;
    EXCEPTION *cur;			/* null if no pending */
    int state;				/* current pending exception */
    int matched;			/* true if 'caught' */
    int raised;
    jmp_buf env;			/* saved state */
} pte_scope_t;
/*
 * Define macros.  States:
 *     state     matched    raised
 *       0         N/A        N/A	! normal execution
 *      !0          0          1        ! Exception raised, looking for match
 *      !0          1          0        ! pte_match_exeception branch taken
 *      !0          0          0        ! catch_all branch taken.
 *      !0          1          1        ! finally branch taken. (reraise).
 */
#define TRY { pte_scope_t pte_blk; pte_try_begin(&pte_blk);\
  pte_blk.state = setjmp(pte_blk.env); if ( pte_blk.state == 0 ) {

#define ENDTRY } pte_try_finish(&pte_blk); }

#define RERAISE pte_reraise ( &pte_blk );

#define CATCH(code) } else if ( pte_match_exception(&pte_blk,&code) ) {

#define CATCH_ALL } else { pte_blk.raised = 0;

#define FINALLY } if (1==(pte_blk.matched=1)) {

#define THIS_CATCH pte_blk.cur
/*
 * Proto-types for exception emulation support functions.
 */
void pte_try_begin ( pte_scope_t *blk );
void pte_try_finish ( pte_scope_t *blk );
void pte_reraise ( pte_scope_t *blk );
int pte_match_exception ( pte_scope_t *blk, EXCEPTION * );
#define EXCEPTION_INIT(X) pte_init_exception(&X)
void pte_init_exception ( EXCEPTION * );
/*
 * Define builtin excecption objects.
 */
extern EXCEPTION pthread_exc_SIGILL_e;
extern EXCEPTION pthread_exc_SIGTRAP_e;
extern EXCEPTION pthread_exc_SIGIOT_e;
extern EXCEPTION pthread_exc_SIGEMT_e;
extern EXCEPTION pthread_exc_SIGFPE_e;
extern EXCEPTION pthread_exc_SIGBUS_e;
extern EXCEPTION pthread_exc_SIGSEGV_e;
extern EXCEPTION pthread_exc_SIGPIPE_e;
#define exc_SIGPIPE_e pthread_exc_SIGPIPE_e
extern EXCEPTION pthread_exc_SIGSYS_e;
extern EXCEPTION pthread_exc_SIGABRT_e;
extern EXCEPTION pthread_cancel_e;
extern EXCEPTION pthread_exit_e;
extern EXCEPTION pthread_existence_e;
extern EXCEPTION pthread_in_use_e;
extern EXCEPTION pthread_use_error_e;
extern EXCEPTION pthread_badparam_e;
extern EXCEPTION pthread_stackovf_e;
extern EXCEPTION pthread_nostackmem_e;
extern EXCEPTION pthread_defer_q_full_e;
extern EXCEPTION pthread_unimp_e;
extern EXCEPTION pthread_notcmastack_e;
#endif
