-/*
+/* Copyright (c) 2005-2017. The SimGrid Team.
+ * All rights reserved. */
+
+/* Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com> */
+/* Copyright (c) 2002-2004 The OSSP Project <http://www.ossp.org/> */
+/* Copyright (c) 2002-2004 Cable & Wireless <http://www.cw.com/> */
+/* All rights reserved. */
+
+/* This code is inspirated from the OSSP version (as retrieved back in 2004)*/
+/* It was heavily modified to fit the SimGrid framework. */
+
+/* The OSSP version has the following copyright notice:
** OSSP ex - Exception Handling
** Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com>
** Copyright (c) 2002-2004 The OSSP Project <http://www.ossp.org/>
** the above copyright notice and this permission notice appear in all
** copies.
**
-** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+** THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESSED OR IMPLIED
** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
-**
-** ex.h: exception handling (pre-processor part)
-*/
-
-#ifndef __EX_H__
-#define __EX_H__
-
-/* required ISO-C standard facilities */
-#include <stdio.h>
-
-/* convenience define */
-#ifndef NULL
-#define NULL (void *)0
-#endif
-
-/* 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 */
-#if defined(__EX_MCTX_MCSC__)
-#include <ucontext.h> /* POSIX.1 ucontext(3) */
-#define __ex_mctx_struct ucontext_t uc;
-#define __ex_mctx_save(mctx) (getcontext(&(mctx)->uc) == 0)
-#define __ex_mctx_restored(mctx) /* noop */
-#define __ex_mctx_restore(mctx) (void)setcontext(&(mctx)->uc)
-
-#elif defined(__EX_MCTX_SSJLJ__)
-#include <setjmp.h> /* POSIX.1 sigjmp_buf(3) */
-#define __ex_mctx_struct sigjmp_buf jb;
-#define __ex_mctx_save(mctx) (sigsetjmp((mctx)->jb, 1) == 0)
-#define __ex_mctx_restored(mctx) /* noop */
-#define __ex_mctx_restore(mctx) (void)siglongjmp((mctx)->jb, 1)
-
-#elif defined(__EX_MCTX_SJLJ__) || !defined(__EX_MCTX_CUSTOM__)
-#include <setjmp.h> /* ISO-C jmp_buf(3) */
-#define __ex_mctx_struct jmp_buf jb;
-#define __ex_mctx_save(mctx) (setjmp((mctx)->jb) == 0)
-#define __ex_mctx_restored(mctx) /* noop */
-#define __ex_mctx_restore(mctx) (void)longjmp((mctx)->jb, 1)
-#endif
-
-/* declare the machine context type */
-typedef struct { __ex_mctx_struct } __ex_mctx_t;
-
-/* declare the exception type (public) */
-typedef struct {
- /* throw value */
- void *ex_class;
- void *ex_object;
- void *ex_value;
- /* throw point */
- const char *ex_file;
- int ex_line;
- const char *ex_func;
-} ex_t;
-
-/* declare the context type (private) */
-typedef struct {
- __ex_mctx_t *ctx_mctx; /* permanent machine context of enclosing try/catch */
- int ctx_deferred; /* permanent flag whether exception is deferred */
- int ctx_deferring;/* permanent counter of exception deferring level */
- int ctx_defer; /* temporary flag for exception deferring macro */
- int ctx_shielding;/* permanent counter of exception shielding level */
- int ctx_shield; /* temporary flag for exception shielding macro */
- int ctx_caught; /* temporary flag whether exception was caught */
- volatile ex_t ctx_ex; /* temporary exception storage */
-} ex_ctx_t;
-
-/* the static and dynamic initializers for a context structure */
-#define EX_CTX_INITIALIZER \
- { NULL, 0, 0, 0, 0, 0, 0, { NULL, NULL, NULL, NULL, 0, NULL } }
-#define EX_CTX_INITIALIZE(ctx) \
- do { \
- (ctx)->ctx_mctx = NULL; \
- (ctx)->ctx_deferred = 0; \
- (ctx)->ctx_deferring = 0; \
- (ctx)->ctx_defer = 0; \
- (ctx)->ctx_shielding = 0; \
- (ctx)->ctx_shield = 0; \
- (ctx)->ctx_caught = 0; \
- (ctx)->ctx_ex.ex_class = NULL; \
- (ctx)->ctx_ex.ex_object = NULL; \
- (ctx)->ctx_ex.ex_value = NULL; \
- (ctx)->ctx_ex.ex_file = NULL; \
- (ctx)->ctx_ex.ex_line = 0; \
- (ctx)->ctx_ex.ex_func = NULL; \
- } while (0)
-
-/* the exception context */
-typedef ex_ctx_t *(*ex_ctx_cb_t)(void);
-extern ex_ctx_cb_t __ex_ctx;
-extern ex_ctx_t *__ex_ctx_default(void);
-
-/* the termination handler */
-typedef void (*ex_term_cb_t)(ex_t *);
-extern ex_term_cb_t __ex_terminate;
-extern void __ex_terminate_default(ex_t *e);
-
-/* the block for trying execution */
-#define ex_try \
- { \
- ex_ctx_t *__ex_ctx_ptr = __ex_ctx(); \
- int __ex_cleanup = 0; \
- __ex_mctx_t *__ex_mctx_en; \
- __ex_mctx_t __ex_mctx_me; \
- __ex_mctx_en = __ex_ctx_ptr->ctx_mctx; \
- __ex_ctx_ptr->ctx_mctx = &__ex_mctx_me; \
- if (__ex_mctx_save(&__ex_mctx_me)) { \
- if (1)
-
-/* the optional(!) block for cleanup */
-#define ex_cleanup \
- else { \
- } \
- __ex_ctx_ptr->ctx_caught = 0; \
- } \
- else { \
- __ex_mctx_restored(&__ex_mctx_me); \
- __ex_ctx_ptr->ctx_caught = 1; \
- } \
- __ex_ctx_ptr->ctx_mctx = __ex_mctx_en; \
- __ex_cleanup = 1; \
- if (1) { \
- if (1)
-
-/* the block for catching an exception */
-#define ex_catch(e) \
- else { \
- } \
- if (!(__ex_cleanup)) \
- __ex_ctx_ptr->ctx_caught = 0; \
- } \
- else { \
- if (!(__ex_cleanup)) { \
- __ex_mctx_restored(&__ex_mctx_me); \
- __ex_ctx_ptr->ctx_caught = 1; \
- } \
- } \
- __ex_ctx_ptr->ctx_mctx = __ex_mctx_en; \
- } \
- if ( !(__ex_ctx()->ctx_caught) \
- || ((e) = __ex_ctx()->ctx_ex, 0)) { \
- } \
- else
-
-/* the throwing of a new exception */
-#define ex_throw(c,o,v) \
- (( __ex_ctx()->ctx_shielding > 0 \
- || (__ex_ctx()->ctx_deferring > 0 && __ex_ctx()->ctx_deferred == 1)) ? 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_ctx()->ctx_deferred = 1, \
- (__ex_ctx()->ctx_deferring > 0 ? 0 : \
- (__ex_ctx()->ctx_mctx == NULL \
- ? (__ex_terminate((ex_t *)&(__ex_ctx()->ctx_ex)), -1) \
- : (__ex_mctx_restore(__ex_ctx()->ctx_mctx), 1) ))))
-
-/* the re-throwing of an already caught exception */
-#define ex_rethrow \
- (( __ex_ctx()->ctx_shielding > 0 \
- || __ex_ctx()->ctx_deferring > 0) ? 0 : \
- ( __ex_ctx()->ctx_mctx == NULL \
- ? (__ex_terminate((ex_t *)&(__ex_ctx()->ctx_ex)), -1) \
- : (__ex_mctx_restore(__ex_ctx()->ctx_mctx), 1) ))
-
-/* shield an operation from exception handling */
-#define ex_shield \
- for (__ex_ctx()->ctx_shielding++, \
- __ex_ctx()->ctx_shield = 1; \
- __ex_ctx()->ctx_shield == 1; \
- __ex_ctx()->ctx_shield = 0, \
- __ex_ctx()->ctx_shielding--)
-
-/* defer immediate exception handling */
-#define ex_defer \
- for (((__ex_ctx()->ctx_deferring)++ == 0 ? __ex_ctx()->ctx_deferred = 0 : 0), \
- __ex_ctx()->ctx_defer = 1; \
- __ex_ctx()->ctx_defer == 1; \
- __ex_ctx()->ctx_defer = 0, \
- ((--(__ex_ctx()->ctx_deferring) == 0 && __ex_ctx()->ctx_deferred == 1) ? ex_rethrow : 0))
-
-/* exception handling tests */
-#define ex_catching \
- (__ex_ctx()->ctx_mctx != NULL)
-#define ex_shielding \
- (__ex_ctx()->ctx_shielding > 0)
-#define ex_deferring \
- (__ex_ctx()->ctx_deferring > 0)
-
-/* optional namespace mapping */
-#if defined(__EX_NS_UCCXX__)
-#define Try ex_try
-#define Cleanup ex_cleanup
-#define Catch ex_catch
-#define Throw ex_throw
-#define Rethrow ex_rethrow
-#define Shield ex_shield
-#define Defer ex_defer
-#elif defined(__EX_NS_CXX__) || (!defined(__cplusplus) && !defined(__EX_NS_CUSTOM__))
-#define try ex_try
-#define cleanup ex_cleanup
-#define catch ex_catch
-#define throw ex_throw
-#define rethrow ex_rethrow
-#define shield ex_shield
-#define defer ex_defer
-#endif
-
-#endif /* __EX_H__ */
-
+ */
+
+/* The extensions made for the SimGrid project can either be distributed */
+/* under the same license, or under the LGPL v2.1 */
+
+#ifndef XBT_EX_H
+#define XBT_EX_H
+
+#include <stdlib.h>
+
+#include "xbt/base.h"
+#include "xbt/sysdep.h"
+#include "xbt/misc.h"
+#include "xbt/virtu.h"
+
+/** @addtogroup XBT_ex_c
+ * @brief Exceptions support (C)
+ *
+ * Those fonctions are used to throw C++ exceptions from C code. This feature
+ * should probably be removed in the future because C and exception do not
+ * exactly play nicely together.
+ */
+
+/** Categories of errors
+ *
+ * This very similar to std::error_catgory and should probably be replaced
+ * by this in the future.
+ *
+ * @ingroup XBT_ex_c
+ */
+typedef enum {
+ unknown_error = 0, /**< unknown error */
+ arg_error, /**< Invalid argument */
+ bound_error, /**< Out of bounds argument */
+ mismatch_error, /**< The provided ID does not match */
+ not_found_error, /**< The searched element was not found */
+ system_error, /**< a syscall did fail */
+ network_error, /**< error while sending/receiving data */
+ timeout_error, /**< not quick enough, dude */
+ cancel_error, /**< an action was canceled */
+ thread_error, /**< error while [un]locking */
+ host_error, /**< host failed */
+ tracing_error, /**< error during the simulation tracing */
+ io_error, /**< disk or file error */
+ vm_error /**< vm error */
+} xbt_errcat_t;
+
+SG_BEGIN_DECL()
+
+/** Get the name of a category
+ * @ingroup XBT_ex_c
+ */
+XBT_PUBLIC(const char *) xbt_ex_catname(xbt_errcat_t cat);
+
+typedef struct xbt_ex xbt_ex_t;
+
+/** Helper function used to throw exceptions in C */
+XBT_ATTRIB_NORETURN XBT_PUBLIC(void)
+ _xbt_throw(char* message, xbt_errcat_t errcat, int value, const char* file, int line, const char* func);
+
+/** Builds and throws an exception
+ * @ingroup XBT_ex_c
+ * @hideinitializer
+ */
+#define THROW(c, v) { _xbt_throw(NULL, (xbt_errcat_t) c, v, __FILE__, __LINE__, __func__); }
+
+/** Builds and throws an exception with a printf-like formatted message
+ * @ingroup XBT_ex_c
+ * @hideinitializer
+ */
+#define THROWF(c, v, ...) _xbt_throw(bprintf(__VA_ARGS__), (xbt_errcat_t) c, v, __FILE__, __LINE__, __func__)
+
+/** Throw an exception because someting impossible happened
+ * @ingroup XBT_ex_c
+ */
+#define THROW_IMPOSSIBLE \
+ THROWF(unknown_error, 0, "The Impossible Did Happen (yet again)")
+
+/** Throw an exception because someting unimplemented stuff has been attempted
+ * @ingroup XBT_ex_c
+ */
+#define THROW_UNIMPLEMENTED \
+ THROWF(unknown_error, 0, "Function %s unimplemented",__func__)
+
+/** Throw an exception because some dead code was reached
+ * @ingroup XBT_ex_c
+ */
+#define THROW_DEADCODE \
+ THROWF(unknown_error, 0, "Function %s was supposed to be DEADCODE, but it's not",__func__)
+
+/** Die because something impossible happened
+ * @ingroup XBT_ex_c
+ */
+#define DIE_IMPOSSIBLE xbt_die("The Impossible Did Happen (yet again)")
+
+/** Display an exception */
+XBT_PUBLIC(void) xbt_ex_display(xbt_ex_t * e);
+
+SG_END_DECL()
+
+/** @} */
+#endif /* __XBT_EX_H__ */