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