/*************************************************************************/ /* Package name : Except. */ /* Version : 1.0 */ /* Completed : April 1993. */ /* Released : 29 September 1993. */ /* First created : This package was first created in April 1993. */ /* Summary : This package provides Ada-like exceptions for C. */ /* Components : except.fw - FunnelWeb source file. */ /* except.h - Exported header file. */ /* except.c - Implementation file. */ /* ex_test.c - C test program. */ /* Requires : style.h, as.h, as.c. */ /* Author : Ross N. Williams (ross@guest.adelaide.edu.au) */ /* Rocksoft^tm Pty Ltd */ /* 16 Lerwick Avenue, Hazelwood Park 5066, Australia. */ /* FTP Archive : This file can be found in */ /* "ftp.adelaide.edu.au/pub/funnelweb/examples/" */ /* Disclaimer : This program is distributed WITHOUT ANY WARRANTY; */ /* without even the implied warranty of MERCHANTABILITY */ /* or FITNESS FOR A PARTICULAR PURPOSE. */ /* Copyright : Copyright (C) Ross Williams 1993. */ /* However, permission is granted for anyone to copy, */ /* modify, and distribute this work for any purpose, */ /* commercial or non-commercial, so long as this notice */ /* is included verbatim, and so long as all */ /* modifications are recorded in the change log below. */ /* Changes : Please log any changes to this software either in the */ /* originating FunnelWeb source file, or, if you must, */ /* in the C source files produced from the FunnelWeb */ /* file. */ /* ---- */ /* ??-Apr-93: RNW: Created this package. */ /* 29-Sep-93: RNW: Released this package. */ /* ---- */ /*************************************************************************/ #ifndef _EX_DONE #define _EX_DONE 1 #include "style.h" #include typedef string p_ex_t; #define EX_EXCEPT(NAME) extern const p_ex_t NAME #define EX_EXPORT(NAME,DESC) const p_ex_t NAME = DESC #define EX_LOCAL(NAME,DESC) static const p_ex_t NAME = DESC #define _EX_FAST FALSE /* Set _EX_FAST to TRUE to turn on inlining and turn off checking. */ #define _EX_THRD FALSE /* To configure this package to work under a multi-threaded environment, */ /* set _EX_THRD to TRUE and modify the k_var calls later on in the file. */ typedef struct _ex_cxt_ { #if !_EX_FAST ulong _ex_mag1; /* Header magic number. */ #endif jmp_buf _ex_jmbf; /* Exception block context. */ struct _ex_cxt_ *_ex_prev; /* Pointer to previous stack record. */ #if !_EX_FAST ulong _ex_mag2; /* Trailer magic number. */ #endif } _ex_cx_t; #define _EX_MAG1 0xFB8A5D30 #define _EX_MAG2 0x09F2E7A2 #if !_EX_THRD extern _ex_cx_t *_ex_curr; extern p_ex_t _ex_id; extern ptrint _ex_info; #endif #if !_EX_THRD /* Non-threaded system macros simply point to variables. */ #define _EX_CURR _ex_curr #define EX_ID ((p_ex_t) _ex_id) #define _EX_ID _ex_id #define EX_INFO _ex_info #else /* Threaded system macros translate to kernel calls. */ /* To make this package work in a multi-threaded environment, */ /* set _EX_THRD to TRUE and modify these definitions. */ /* Note: The kernel should initialize _EX_CURR to NULL. */ #define _EX_CURR (* ((_ex_cx_t *) k_var(51))) #define EX_ID ((p_ex_t) (* ((p_ex_t *) k_var(52)))) #define _EX_ID (* ((p_ex_t *) k_var(52))) #define EX_INFO (* ((ptrint *) k_var(53))) #endif #if _EX_FAST #define EX_RAISE(P_EX) {_EX_ID = (P_EX); longjmp(_EX_CURR->_ex_jmbf,NON_ZERO);} #else #define EX_RAISE(P_EX) {_exrai(P_EX);} #endif #if _EX_FAST #define EX_BEGIN \ {_ex_cx_t _ex_cxlc; \ _ex_cxlc._ex_prev = _EX_CURR; \ _EX_CURR = &_ex_cxlc; \ if (!setjmp(_ex_cxlc._ex_jmbf)) { #define EX_FORGET ;EX_POP} else {EX_POP; if (FALSE) { #define EX_WHEN(P_EX) } else if ((P_EX) == (EX_ID)) { #define EX_OTHERS } else if (TRUE) { #define EX_END } else longjmp(_EX_CURR->_ex_jmbf,NON_ZERO); }} #define EX_POP {_EX_CURR = _EX_CURR->_ex_prev;} #else #define EX_BEGIN \ {_ex_cx_t _ex_cxlc; \ _ex_cxlc._ex_mag1 = _EX_MAG1; \ _ex_cxlc._ex_mag2 = _EX_MAG2; \ _ex_cxlc._ex_prev = _EX_CURR; \ _EX_CURR = &_ex_cxlc; \ if (!setjmp(_ex_cxlc._ex_jmbf)) { #define EX_FORGET ;EX_POP} else {EX_POP; if (FALSE) { #define EX_WHEN(P_EX) } else if ((P_EX) == (EX_ID)) { #define EX_OTHERS } else if (TRUE) { #define EX_END } else _exrai(EX_ID); }} #define EX_POP {_expop(&_ex_cxlc);} #endif EXPORT string ex_str P_((p_ex_t)); EXPORT void _exrai P_((p_ex_t)); EXPORT void _expop P_((_ex_cx_t *)); #endif