1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*===
24215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Projectcexcept.h 2.0.1 (2008-Jul-19-Sat)
34215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Projecthttp://www.nicemice.net/cexcept/
44215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source ProjectAdam M. Costello
54215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Projecthttp://www.nicemice.net/amc/
6893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
7893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectAn interface for exception-handling in ANSI C (C89 and subsequent ISO
84215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Projectstandards), developed jointly with Cosmin Truta.
94215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project    Copyright (c) 2000-2008 Adam M. Costello and Cosmin Truta.
114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project    This software may be modified only if its author and version
124215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project    information is updated accurately, and may be redistributed
134215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project    only if accompanied by this unaltered notice.  Subject to those
144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project    restrictions, permission is granted to anyone to do anything
154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project    with this software.  The copyright holders make no guarantees
164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project    regarding this software, and are not responsible for any damage
174215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project    resulting from its use.
184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
194215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source ProjectThe cexcept interface is not compatible with and cannot interact
204215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Projectwith system exceptions (like division by zero or memory segmentation
214215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Projectviolation), compiler-generated exceptions (like C++ exceptions), or
224215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Projectother exception-handling interfaces.
234215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
244215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source ProjectWhen using this interface across multiple .c files, do not include
25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectthis header file directly.  Instead, create a wrapper header file that
26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectincludes this header file and then invokes the define_exception_type
274215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Projectmacro (see below).  The .c files should then include that header file.
28893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
29893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectThe interface consists of one type, one well-known name, and six macros.
30893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
31893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectdefine_exception_type(type_name);
33893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    This macro is used like an external declaration.  It specifies
35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    the type of object that gets copied from the exception thrower to
36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    the exception catcher.  The type_name can be any type that can be
37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    assigned to, that is, a non-constant arithmetic type, struct, union,
38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    or pointer.  Examples:
39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        define_exception_type(int);
41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        enum exception { out_of_memory, bad_arguments, disk_full };
43893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        define_exception_type(enum exception);
44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        struct exception { int code; const char *msg; };
46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        define_exception_type(struct exception);
47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Because throwing an exception causes the object to be copied (not
49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    just once, but twice), programmers may wish to consider size when
50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    choosing the exception type.
51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
52893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
53893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstruct exception_context;
54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    This type may be used after the define_exception_type() macro has
56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    been invoked.  A struct exception_context must be known to both
57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    the thrower and the catcher.  It is expected that there be one
58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    context for each thread that uses exceptions.  It would certainly
59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    be dangerous for multiple threads to access the same context.
60893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    One thread can use multiple contexts, but that is likely to be
61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    confusing and not typically useful.  The application can allocate
62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    this structure in any way it pleases--automatic, static, or dynamic.
63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    The application programmer should pretend not to know the structure
64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    members, which are subject to change.
65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstruct exception_context *the_exception_context;
68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    The Try/Catch and Throw statements (described below) implicitly
70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    refer to a context, using the name the_exception_context.  It is
71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    the application's responsibility to make sure that this name yields
72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    the address of a mutable (non-constant) struct exception_context
73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    wherever those statements are used.  Subject to that constraint, the
74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    application may declare a variable of this name anywhere it likes
75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    (inside a function, in a parameter list, or externally), and may
76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    use whatever storage class specifiers (static, extern, etc) or type
77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    qualifiers (const, volatile, etc) it likes.  Examples:
78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        static struct exception_context
80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          * const the_exception_context = &foo;
81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        { struct exception_context *the_exception_context = bar; ... }
83893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
84893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int blah(struct exception_context *the_exception_context, ...);
85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        extern struct exception_context the_exception_context[1];
87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    The last example illustrates a trick that avoids creating a pointer
89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    object separate from the structure object.
90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    The name could even be a macro, for example:
92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
93893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        struct exception_context ec_array[numthreads];
94893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        #define the_exception_context (ec_array + thread_id)
95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Be aware that the_exception_context is used several times by the
97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Try/Catch/Throw macros, so it shouldn't be expensive or have side
98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    effects.  The expansion must be a drop-in replacement for an
99893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    identifier, so it's safest to put parentheses around it.
100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid init_exception_context(struct exception_context *ec);
103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    For context structures allocated statically (by an external
105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    definition or using the "static" keyword), the implicit
106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    initialization to all zeros is sufficient, but contexts allocated
107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    by other means must be initialized using this macro before they
108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    are used by a Try/Catch statement.  It does no harm to initialize
109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    a context more than once (by using this macro on a statically
110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    allocated context, or using this macro twice on the same context),
111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    but a context must not be re-initialized after it has been used by a
112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Try/Catch statement.
113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectTry statement
116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectCatch (expression) statement
117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    The Try/Catch/Throw macros are capitalized in order to avoid
119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    confusion with the C++ keywords, which have subtly different
120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    semantics.
121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    A Try/Catch statement has a syntax similar to an if/else statement,
123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    except that the parenthesized expression goes after the second
124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    keyword rather than the first.  As with if/else, there are two
125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    clauses, each of which may be a simple statement ending with a
126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    semicolon or a brace-enclosed compound statement.  But whereas
127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    the else clause is optional, the Catch clause is required.  The
128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    expression must be a modifiable lvalue (something capable of being
129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    assigned to) of the same type (disregarding type qualifiers) that
130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    was passed to define_exception_type().
131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    If a Throw that uses the same exception context as the Try/Catch is
133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    executed within the Try clause (typically within a function called
134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    by the Try clause), and the exception is not caught by a nested
135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    Try/Catch statement, then a copy of the exception will be assigned
136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    to the expression, and control will jump to the Catch clause.  If no
137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    such Throw is executed, then the assignment is not performed, and
138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    the Catch clause is not executed.
139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    The expression is not evaluated unless and until the exception is
141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    caught, which is significant if it has side effects, for example:
142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Try foo();
144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        Catch (p[++i].e) { ... }
145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    IMPORTANT: Jumping into or out of a Try clause (for example via
147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return, break, continue, goto, longjmp) is forbidden--the compiler
148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    will not complain, but bad things will happen at run-time.  Jumping
149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    into or out of a Catch clause is okay, and so is jumping around
150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    inside a Try clause.  In many cases where one is tempted to return
151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    from a Try clause, it will suffice to use Throw, and then return
152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    from the Catch clause.  Another option is to set a flag variable and
153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    use goto to jump to the end of the Try clause, then check the flag
154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    after the Try/Catch statement.
155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    IMPORTANT: The values of any non-volatile automatic variables
157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    changed within the Try clause are undefined after an exception is
158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    caught.  Therefore, variables modified inside the Try block whose
159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    values are needed later outside the Try block must either use static
160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    storage or be declared with the "volatile" type qualifier.
161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectThrow expression;
164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    A Throw statement is very much like a return statement, except that
166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    the expression is required.  Whereas return jumps back to the place
167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    where the current function was called, Throw jumps back to the Catch
168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    clause of the innermost enclosing Try clause.  The expression must
169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    be compatible with the type passed to define_exception_type().  The
170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    exception must be caught, otherwise the program may crash.
171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project    Slight limitation:  If the expression is a comma-expression, it must
173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    be enclosed in parentheses.
174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectTry statement
177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectCatch_anonymous statement
178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    When the value of the exception is not needed, a Try/Catch statement
180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    can use Catch_anonymous instead of Catch (expression).
181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectEverything below this point is for the benefit of the compiler.  The
184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectapplication programmer should pretend not to know any of it, because it
185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectis subject to change.
186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project===*/
188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef CEXCEPT_H
191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define CEXCEPT_H
192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <setjmp.h>
195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define define_exception_type(etype) \
197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstruct exception_context { \
198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  jmp_buf *penv; \
199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int caught; \
200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  volatile struct { etype etmp; } v; \
201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* etmp must be volatile because the application might use automatic */
204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* storage for the_exception_context, and etmp is modified between   */
205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* the calls to setjmp() and longjmp().  A wrapper struct is used to */
206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* avoid warnings about a duplicate volatile qualifier in case etype */
207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* already includes it.                                              */
208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define init_exception_context(ec) ((void)((ec)->penv = 0))
210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define Try \
212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  { \
213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    jmp_buf *exception__prev, exception__env; \
214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    exception__prev = the_exception_context->penv; \
215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    the_exception_context->penv = &exception__env; \
216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (setjmp(exception__env) == 0) { \
2174215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      do
218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define exception__catch(action) \
2204215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      while (the_exception_context->caught = 0, \
2214215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project             the_exception_context->caught); \
222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } \
223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else { \
224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      the_exception_context->caught = 1; \
225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } \
226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    the_exception_context->penv = exception__prev; \
227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  } \
228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (!the_exception_context->caught || action) { } \
229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else
230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define Catch(e) exception__catch(((e) = the_exception_context->v.etmp, 0))
232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define Catch_anonymous exception__catch(0)
233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2344215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project/* Try ends with do, and Catch begins with while(0) and ends with     */
2354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project/* else, to ensure that Try/Catch syntax is similar to if/else        */
2364215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project/* syntax.                                                            */
237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*                                                                    */
2384215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project/* The 0 in while(0) is expressed as x=0,x in order to appease        */
2394215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project/* compilers that warn about constant expressions inside while().     */
2404215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project/* Most compilers should still recognize that the condition is always */
2414215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project/* false and avoid generating code for it.                            */
242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define Throw \
244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  for (;; longjmp(*the_exception_context->penv, 1)) \
245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    the_exception_context->v.etmp =
246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* CEXCEPT_H */
249