/** exceptions2.c -- by James Lin (2001-05-19) * a set of macros to simulate exception handling * * This version is more like the try/catch syntax used in Java, where * each exception type has a separate catch block. It is, however, * less flexible. * * 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_BEGIN * CATCH(<E1>) * { ... * } * CATCH(<E2>) * { ... * } * * ... * * CATCH_DEFAULT // optional * { ... * } * * CATCH_COMMON // optional * { ... * } * CATCH_END // no trailing semicolon * * Exception-throwing syntax: * THROW(<E>); * RETHROW(); // re-throw the current exception * * Notes: * Exceptions are represented as ints. * * If neither CATCH_DEFAULT nor CATCH_COMMON is present, any uncaught * exception will be re-thrown. * * Order matters; CATCH blocks must appear before CATCH_DEFAULT, and * CATCH_DEFAULT must appear before CATCH_COMMON. * * 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_BEGIN \ JMP_BUF_COPY(_cur_exception.env, _old_exception_env); \ } \ else \ { JMP_BUF_COPY(_cur_exception.env, _old_exception_env); \ if (0) { } #define CATCH(e) \ else if (_cur_exception.err == (e)) #define CATCH_DEFAULT \ else if (1) #define CATCH_COMMON \ if (1) #define CATCH_END \ else \ { RETHROW(); \ } \ } \ } #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 #define RETHROW() THROW(_cur_exception.err) /* GLOBALS ------------------------------------------------------------- */ exception_t _cur_exception; #endif ... more stuff ___________________________________________________________________________ page updated: (see above) home . about . stuff . links copyright (c) 2001 james lin |