/* ** Copyright (c) 2001-2002 The OSSP Project ** Copyright (c) 2001-2002 Cable & Wireless Deutschland ** ** 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 . ** ** ex.h: exception handling (pre-processor part) */ #ifndef __EX_H__ #define __EX_H__ /* the required ISO-C standard facilities */ #include /* for NULL */ #include /* 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__ */