/*************************************************************************/ /* 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. */ /* ---- */ /*************************************************************************/ #include "except.h" #include "as.h" #if !_EX_THRD GLOVAR _ex_cx_t *_ex_curr = NULL; GLOVAR p_ex_t _ex_id; GLOVAR ptrint _ex_info; #endif EXPORT string ex_str (p_ex) p_ex_t p_ex; {return p_ex;} LOCAL void ex_bomb P_((void)); LOCAL void ex_bomb () { char s[100]; as_wr(" Exception desc is : \""); as_wr(EX_ID); as_wl("\"."); as_wr(" Exception id is : "); sprintf(s,"%lu (= %lX)",ULONG(EX_ID),ULONG(EX_ID)); as_wl(s); as_wr(" Exception info is : "); sprintf(s,"%lu (= %lX)",ULONG(EX_INFO),ULONG(EX_INFO)); as_wl(s); as_bomb("Aborting program after exception error."); } EXPORT void _exrai (p_ex) p_ex_t p_ex; { #if _EX_FAST as_bomb("_exrai: This function should not be called with _EX_FAST==TRUE."); #else _ex_cx_t * p_curr = _EX_CURR; _EX_ID = p_ex; if (p_curr == NULL) {as_wl("_exrai: Unhandled exception."); ex_bomb();} if (UWIDE(&p_curr) > UWIDE(&p_curr->_ex_jmbf)) { as_wl("_exrai: Target exception context is no longer legitimate."); as_wl(" Exception context resides beneath the top of stack."); as_wl(" This means that earlier on, control must have left an"); as_wl(" exception context without first popping its handler."); as_wl(" Look for jumps out of exception contexts that are not"); as_wl(" immediately preceded by calls to EX_POP."); ex_bomb(); } if ((p_curr->_ex_mag1 != _EX_MAG1) || (p_curr->_ex_mag2 != _EX_MAG2)) { as_wl("_exrai: Target exception context has been corrupted. This could"); as_wl(" be because an exception context wasn't popped, or it"); as_wl(" could be just a common garden-variety C corruption :-)"); ex_bomb(); } longjmp(p_curr->_ex_jmbf,NON_ZERO); #endif } EXPORT void _expop (p_check) _ex_cx_t *p_check; { #if _EX_FAST as_bomb("_exrai: This function should not be called with _EX_FAST==TRUE."); #else _ex_cx_t * p_curr = _EX_CURR; if (p_curr != p_check) { if (p_curr == NULL) as_bomb("_expop: Context stack is empty."); else as_bomb("_expop: Top of context stack is not the current context."); } if ((p_curr->_ex_mag1 != _EX_MAG1) || (p_curr->_ex_mag2 != _EX_MAG2)) { as_wl("_ex_rai: Target exception context has been corrupted. This could"); as_wl(" be because an exception context wasn't popped, or it"); as_wl(" could be just a common garden-variety C corruption :-)"); as_bomb("Aborting program after exception error."); } p_curr->_ex_mag1 = ~_EX_MAG1; p_curr->_ex_mag2 = ~_EX_MAG2; _EX_CURR = p_curr->_ex_prev; #endif }