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