#include <setjmp.h>
Data Structures | |
struct | except_t |
struct | except_frame_t |
Defines | |
#define | EXCEPT_RAISE(e) except_raise(&(e), __FILE__, __LINE__) |
raises exception e . | |
#define | EXCEPT_RERAISE except_raise(except_frame.exception, except_frame.file, except_frame.line) |
raises the exception again that has been raised most recently. | |
#define | EXCEPT_RETURN switch(except_stack=except_stack->prev, 0) default: return |
returns to the caller function within a TRY-EXCEPT statement. | |
#define | EXCEPT_TRY |
starts a TRY statement. | |
#define | EXCEPT_EXCEPT(e) |
starts an EXCEPT(e) clause. | |
#define | EXCEPT_ELSE |
starts an ELSE clause. | |
#define | EXCEPT_FINALLY |
starts a FINALLY clause. | |
#define | EXCEPT_END |
ends a TRY-EXCEPT or TRY-FINALLY statement. | |
Enumerations | |
enum | { EXCEPT_ENTERED = 0, EXCEPT_RAISED, EXCEPT_HANDLED, EXCEPT_FINALIZED } |
Functions | |
exception raising functions: | |
void | except_raise (const except_t *, const char *, int) |
raises an exception and set its information properly. | |
Variables | |
except_frame_t * | except_stack |
stack for handling nested exceptions. |
Header for Exception Handling Library (CBL).
#define EXCEPT_ELSE |
Value:
if (except_flag == EXCEPT_ENTERED) \ except_stack = except_stack->prev; \ } else { \ except_flag = EXCEPT_HANDLED;
If there is no matched EXCEPT clause for a raised exception the control moves to the statements following the ELSE clause.
#define EXCEPT_END |
Value:
if (except_flag == EXCEPT_ENTERED) \ except_stack = except_stack->prev; \ } \ if (except_flag == EXCEPT_RAISED) \ EXCEPT_RERAISE; \ }
If a raised exception is not handled by the current handler, it will be handled by the previous handler if any.
#define EXCEPT_EXCEPT | ( | e | ) |
Value:
if (except_flag == EXCEPT_ENTERED) \ except_stack = except_stack->prev; \ } else if (except_frame.exception == &(e)) { \ except_flag = EXCEPT_HANDLED;
When an exception e
is raised, its following statements are executed. Finishing them moves the control to the end of the TRY statement.
#define EXCEPT_FINALLY |
Value:
if (except_flag == EXCEPT_ENTERED) \ except_stack = except_stack->prev; \ } \ { \ if (except_flag == EXCEPT_ENTERED) \ except_flag = EXCEPT_FINALIZED;
It is used to construct a TRY-FINALLY statement, which is useful when some clean-up is necessary before exiting the TRY-FINALLY statement; the statements under the FINALLY clause are executed whether or not an exception occurs. EXCEPT_RERAISE
macro can be used to hand over the not-yet-handled exception to the previous handler.
#define EXCEPT_RETURN switch(except_stack=except_stack->prev, 0) default: return |
returns to the caller function within a TRY-EXCEPT statement.
In order to maintain the stack handling nested exceptions, the ordinary return statement should be avoided in statements (referred to as S
below; see the explanation for EXCEPT_TRY
) following EXCEPT_TRY
. Because return has no idea about the exception frame, retruning without using EXCEPT_RETURN
from S
spoils the exception stack. EXCEPT_RETURN
adjusts the stack properly by popping the current exception frame before returning to the caller.
S
and before the control moves to one of EXCEPT, ELSE and FINALLY clauses, which means using EXCEPT_RETURN
there is not allowed since it affects the previous, not the current, exception frame. #define EXCEPT_TRY |
Value:
{ \ volatile int except_flag; \ /* volatile */ except_frame_t except_frame; \ except_frame.prev = except_stack; \ except_stack = &except_frame; \ except_flag = setjmp(except_frame.env); \ if (except_flag == EXCEPT_ENTERED) {
Statements (referred to as S
hereafter) whose exception is to be handled in EXCEPT, ELSE or FINALLY clause follow.
EXCEPT_RETURN
when returning from S
. See EXCEPT_RETURN
for more details. Besides, The TRY-EXCEPT/FINALLY statement uses the non-local jump mechanism provided by <setjmp.h>, which means any restriction applied to <setjmp.h> also applies to the TRY-EXCEPT/FINALLY statement. For example, the standard does not guarantee that an automatic non-volatile variable belonging to the function which contains setjmp() preserves its last stored value when it is updated between a call to setjmp() and a call to longjmp() with the same jmp_buf
.
anonymous enum |
void except_raise | ( | const except_t * | e, | |
const char * | file, | |||
int | line | |||
) |
raises an exception and set its information properly.
EXCEPT_RAISE
and EXCEPT_RERAISE
macros call except_raise() with __FILE__
and __LINE__
predefined macros (and __func__
if C99 supported) for the file
and line
parameters. So in general there is little chance to call except_raise() directly in application code.
Possible exceptions: assert_exceptfail
Unchecked errors: foreign data structure given for e
[in] | e | exception to raise |
[in] | file | file name where exception occurred |
[in] | func | function name where exception occurred (if C99 supported) |
[in] | line | line number where exception occurred |