/** 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
|