From: bernie Date: Sat, 8 Sep 2007 20:52:48 +0000 (+0000) Subject: Structured exceptions support for C programs. X-Git-Tag: 1.0.0~435 X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;h=4bf15025c3fe95a226686b793e39a44f5f08d7da;p=bertos.git Structured exceptions support for C programs. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@806 38d2e660-2303-0410-9eaa-f027e97ec537 --- diff --git a/mware/except.h b/mware/except.h new file mode 100755 index 00000000..fc7f1421 --- /dev/null +++ b/mware/except.h @@ -0,0 +1,106 @@ +/** + * \file + * + * + * \brief C++-like structured exception handling for C programs + * + * \version $Id$ + * \author Bernardo Innocenti + */ +#ifndef MWARE_EXCEPT_H +#define MWARE_EXCEPT_H + +#include + +#include + +#define EXCEPT_CONTEXTS 8 + +/** + * A stack of jump buffers used to record try sites + * so they can be reached from throw sites. + * + * The stack contains return points for each nested + * context. jmp_buf's are pushed into the stack at + * try points and popped out when the try block ends + * normally or when an exception is thrown. + */ +extern jmp_buf except_stack[EXCEPT_CONTEXTS]; +extern int except_top; + +#ifdef _DEBUG +# define PUSH_ABORT ASSERT(abort_top < ABORT_CONTEXTS), setjmp(abort_stack[abort_top++])) +# define POP_ABORT (ASSERT(abort_top > 0), --abort_top) +# define DO_ABORT (ASSERT(abort_top > 0), longjmp(abort_stack[--abort_top], true)) +#else +# define PUSH_ABORT (setjmp(abort_stack[abort_top++])) +# define POP_ABORT (--abort_top) +# define DO_ABORT (longjmp(abort_stack[--abort_top], true)) +#endif + +/** + * Jump buffer to use when throwing an exception or aborting an operation + * + * User code can throw exceptions like this: + * + * \code + * void a_function_throwing_exceptions(void) + * { + * if (some_error_condition) + * THROW; + * } + * \endcode + * + * Catching exceptions (brackets are optional): + * + * \code + * EXCEPT_DEFINE; + * + * void a_function_catching_an_exception(void) + * { + * TRY + * { + * printf("Entered try block\n"); + * a_function_throwing_exceptions(); + * printf("Survived execution of critical code\n"); + * } + * CATCH + * { + * printf("Exception caught!\n"); + * } + * CATCH_END + * } + * \endcode + * + * Simple syntax when you don't need to do anything when catching an excaption: + * + * \code + * TRY + * printf("Entered try block\n"); + * a_function_throwing_exceptions(); + * printf("Survived execution of critical code\n"); + * TRY_END + * \endcode + * + * You also need to declare the exception stack once in + * your global declarations: + * \code + * EXCEPT_DEFINE; + * \endcode + */ +#define TRY if (PUSH_ABORT) { { +#define TRY_END } POP_ABORT; } +#define CATCH } POP_ABORT; } else { +#define CATCH_END } +#define THROW DO_ABORT + + +#define EXCEPT_DEFINE \ + jmp_buf abort_stack[ABORT_CONTEXTS]; \ + int abort_top; + +#endif /* MWARE_EXCEPT_H */