OSSP CVS Repository

ossp - ossp-pkg/ex/ex.h 1.3
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/ex/ex.h 1.3
/*
**  Copyright (c) 2001-2002 The OSSP Project <http://www.ossp.org/>
**  Copyright (c) 2001-2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
**
**  This file is part of OSSP ex, an exception library
**  which can be found at http://www.ossp.org/pkg/ex/.
**
**  This program is free software; you can redistribute it and/or
**  modify it under the terms of the GNU General Public  License
**  as published by the Free Software Foundation; either version
**  2.0 of the License, or (at your option) any later version.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
**  General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this file; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
**  USA, or contact the OSSP project <ossp@ossp.org>.
**
**  ex.h: exception handling (pre-processor part)
*/

#ifndef __EX_H__
#define __EX_H__

/* the required ISO-C standard facilities */
#include <stdio.h>   /* for NULL */
#include <setjmp.h>  /* for jmp_buf, setjmp(3), longjmp(3) */

/* determine how the current function name can be fetched */
#if (   defined(__STDC__) \
     && defined(__STDC_VERSION__) \
     && __STDC_VERSION__ >= 199901L)
#define __EX_FUNC__ __func__      /* ISO C99 compliant */
#elif (   defined(__GNUC__) \
       && defined(__GNUC_MINOR__) \
       && (   __GNUC__ > 2 \
           || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)))
#define __EX_FUNC__ __FUNCTION__  /* gcc >= 2.8 */
#else
#define __EX_FUNC__ "#NA#"        /* not available */
#endif

/* the machine context */
#ifndef __ex_mctx_st
#define __ex_mctx_st             struct { jmp_buf jb; }
#endif
#ifndef __ex_mctx_save
#define __ex_mctx_save(mctx)     (setjmp((mctx)->jb) == 0)
#endif
#ifndef __ex_mctx_restore
#define __ex_mctx_restore(mctx)  (void)longjmp((mctx)->jb, 1)
#endif
#ifndef __ex_mctx_restored
#define __ex_mctx_restored(mctx) /* NOOP */
#endif
typedef __ex_mctx_st __ex_mctx_t;

/* declare the exception type (public) */
typedef struct {
    /* throw value */
    void *ex_class;
    void *ex_object;
    void *ex_value;
    /* throw point */
    char *ex_file; 
    int   ex_line; 
    char *ex_func;
} ex_t;

/* declare the exception context type (private) */
typedef struct {
    __ex_mctx_t  *ctx_mctx_prev; /* previous jump buffer */
    int           ctx_caught;    /* flag whether exception was caught */
    volatile ex_t ctx_ex;        /* the exception temporary storage */
} ex_ctx_t;

/* exception context */
#ifndef __ex_ctx
#define __ex_ctx (&__ex_ctx_global)
#ifdef __EX_STATIC_CTX__
static ex_ctx_t __ex_ctx_global; /* for very small environments */
#else
extern ex_ctx_t __ex_ctx_global; /* for non-MT environments (require libex.a) */
#endif
#endif

/* block for trying execution */
#define ex_try \
    { \
        __ex_mctx_t *__ex_mctx_prev; \
        __ex_mctx_t __ex_mctx_me; \
        __ex_mctx_prev = __ex_ctx->ctx_mctx_prev; \
        __ex_ctx->ctx_mctx_prev = &__ex_mctx_me; \
        if (__ex_mctx_save(&__ex_mctx_me)) { \
            if (1)

/* block for catching an exception */
#define ex_catch(e) \
            else { \
            } \
            __ex_ctx->ctx_caught = 0; \
        } \
        else { \
            __ex_mctx_restored(&__ex_mctx_me); \
            __ex_ctx->ctx_caught = 1; \
        } \
        __ex_ctx->ctx_mctx_prev = __ex_mctx_prev; \
    } \
    if (!__ex_ctx->ctx_caught || ((e) = __ex_ctx->ctx_ex, 0)) { \
    } \
    else

/* throw a new exception */
#define ex_throw(c,o,v) \
    (__ex_ctx->ctx_mctx_prev == NULL ? \
     (abort(), 0) : \
     ( __ex_ctx->ctx_ex.ex_class  = (void *)(c), \
       __ex_ctx->ctx_ex.ex_object = (void *)(o), \
       __ex_ctx->ctx_ex.ex_value  = (void *)(v), \
       __ex_ctx->ctx_ex.ex_file   = __FILE__, \
       __ex_ctx->ctx_ex.ex_line   = __LINE__, \
       __ex_ctx->ctx_ex.ex_func   = __EX_FUNC__, \
       __ex_mctx_restore(__ex_ctx->ctx_mctx_prev), \
       0 \
     ) \
    )

/* re-throw a caught exception */
#define ex_rethrow \
    (__ex_ctx->ctx_mctx_prev == NULL ? \
     (abort(), 0) : \
     (__ex_mctx_restore(__ex_ctx->ctx_mctx_prev), 0) \
    )

/* optional namespace mapping */
#if !defined(__cplusplus) && !defined(__EX_NO_CXX_NS__)
#define try      ex_try
#define catch    ex_catch
#define throw    ex_throw
#define rethrow  ex_rethrow
#endif
#if !defined(__EX_NO_SIMPLE_NS__)
#define Try      ex_try
#define Catch    ex_catch
#define Throw    ex_throw
#define Rethrow  ex_rethrow
#endif

#endif /* __EX_H__ */


CVSTrac 2.0.1