/** exceptions.c -- by James Lin (2001-05-19) * a set of macros to simulate exception handling * * Copyright (c) 2001 James Lin * This code may be modified freely, provided that this copyright notice * remains intact and is clearly visible in all derivative works. */ /** Exception-handling syntax: * TRY * { ... * } * CATCH(int <err>) * { * switch (<err>) * { * case <E1> : * ... * break; * * case <E2> : * ... * break; * * ... * * default : * ... * break; * } * } END_CATCH; * * Exception-throwing syntax: * THROW(<E>); * * Notes: * Exceptions are represented as ints. * * Uncaught exceptions are NOT re-thrown automatically. * * Code that uses these TRY/CATCH/THROW macros must not use the * following variables: * _cur_exception * _old_exception_env * * Local, automatic variables modified within a TRY block should be * declared as volatile. * * This is non-portable. Works with gcc but apparently not with MSVC. */ #ifndef JDL_EXCEPTIONS_C #define JDL_EXCEPTIONS_C #include <setjmp.h> #if DEBUG > 1 #include <stdio.h> #endif /* TYPEDEFS ------------------------------------------------------------ */ typedef struct { jmp_buf env; int err; #if DEBUG > 0 char* file; unsigned int line; #endif } exception_t; /* MACROS -------------------------------------------------------------- */ /* this macro may not be portable */ #define JMP_BUF_COPY(jbDest, jbSrc) (*(jbDest) = *(jbSrc)) #define TRY \ { \ jmp_buf _old_exception_env; \ JMP_BUF_COPY(_old_exception_env, _cur_exception.env); \ if ((_cur_exception.err = setjmp(_cur_exception.env)) == 0) \ { #define CATCH(errDecl) \ JMP_BUF_COPY(_cur_exception.env, _old_exception_env); \ } \ else \ { \ errDecl = _cur_exception.err; \ JMP_BUF_COPY(_cur_exception.env, _old_exception_env); #define END_CATCH \ } \ } #if DEBUG > 0 #if DEBUG > 1 #define THROW(e) \ (_cur_exception.file = __FILE__, \ _cur_exception.line = __LINE__, \ fprintf(stderr, \ "throwing exception %u (" __FILE__ ", %u)\n", \ (e), __LINE__), \ longjmp(_cur_exception.env, (e))) #else #define THROW(e) \ (_cur_exception.file = __FILE__, \ _cur_exception.line = __LINE__, \ longjmp(_cur_exception.env, (e))) #endif #else #define THROW(e) (longjmp(_cur_exception.env, (e))) #endif /* GLOBALS ------------------------------------------------------------- */ exception_t _cur_exception; #endif ... more stuff ___________________________________________________________________________ page updated: (see above) home . about . stuff . links copyright (c) 2001 james lin |